func calcBucketsLengths(a *stack.Aggregated, pf pathFormat) (int, int) {
	srcLen := 0
	pkgLen := 0
	for _, e := range a.Buckets {
		for _, line := range e.Signature.Stack.Calls {
			if l := len(pf.formatCall(&line)); l > srcLen {
				srcLen = l
			}
			if l := len(line.Func.DirName); l > pkgLen {
				pkgLen = l
			}
		}
	}
	return srcLen, pkgLen
}
calcBucketsLengths returns the maximum length of the source lines and
package names.
package internal
import (
	"fmt"
	"strings"
	"github.com/maruel/panicparse/v2/stack"
)
type Palette struct {
	EOLReset string
	RoutineFirst string  
	Routine      string  
	CreatedBy    string
	Race         string
	Package                     string
	SrcFile                     string
	FuncMain                    string
	FuncLocationUnknown         string
	FuncLocationUnknownExported string
	FuncGoMod                   string
	FuncGoModExported           string
	FuncGOPATH                  string
	FuncGOPATHExported          string
	FuncGoPkg                   string
	FuncGoPkgExported           string
	FuncStdLib                  string
	FuncStdLibExported          string
	Arguments                   string
}
type pathFormat int
const (
	fullPath pathFormat = iota
	relPath
	basePath
)
func (pf pathFormat) formatCall(c *stack.Call) string {
	switch pf {
	case relPath:
		if c.RelSrcPath != "" {
			return fmt.Sprintf("%s:%d", c.RelSrcPath, c.Line)
		}
		fallthrough
	case fullPath:
		if c.LocalSrcPath != "" {
			return fmt.Sprintf("%s:%d", c.LocalSrcPath, c.Line)
		}
		return fmt.Sprintf("%s:%d", c.RemoteSrcPath, c.Line)
	default:
		return fmt.Sprintf("%s:%d", c.SrcName, c.Line)
	}
}
func (pf pathFormat) createdByString(s *stack.Signature) string {
	if len(s.CreatedBy.Calls) == 0 {
		return ""
	}
	return s.CreatedBy.Calls[0].Func.DirName + "." + s.CreatedBy.Calls[0].Func.Name + " @ " + pf.formatCall(&s.CreatedBy.Calls[0])
}