// Grid generates a graph-paperlike set of grid lines on the current page.
515814
func (g GridType) Grid(pdf *Fpdf) {
	var st StateType
	var yLen, xLen int
	var textSz, halfTextSz, yMin, yMax, xMin, xMax, yDiv, xDiv float64
	var str string
	var strOfs, strWd, tp, bt, lf, rt, drawX, drawY float64

	xLen = len(g.xTicks)
	yLen = len(g.yTicks)
	if xLen > 1 && yLen > 1 {

		st = StateGet(pdf)

		line := func(x1, y1, x2, y2 float64, heavy bool) {
			if heavy {
				lineAttr(pdf, g.ClrMain, g.WdMain)
			} else {
				lineAttr(pdf, g.ClrSub, g.WdSub)
			}
			pdf.Line(x1, y1, x2, y2)
		}

		textSz = pdf.PointToUnitConvert(g.TextSize)
		halfTextSz = textSz / 2

		pdf.SetAutoPageBreak(false, 0)
		pdf.SetFontUnitSize(textSz)
		strOfs = pdf.GetStringWidth("0")
		pdf.SetFillColor(255, 255, 255)
		pdf.SetCellMargin(0)

		xMin = g.xTicks[0]
		xMax = g.xTicks[xLen-1]

		yMin = g.yTicks[0]
		yMax = g.yTicks[yLen-1]

		lf = g.X(xMin)
		rt = g.X(xMax)
		bt = g.Y(yMin)
		tp = g.Y(yMax)

		// Verticals along X axis
		xDiv = g.xTicks[1] - g.xTicks[0]
		if g.XDiv > 0 {
			xDiv = xDiv / float64(g.XDiv)
		}
		xDiv = g.Wd(xDiv)
		for j, x := range g.xTicks {
			drawX = g.X(x)
			line(drawX, tp, drawX, bt, true)
			if j < xLen-1 {
				for k := 1; k < g.XDiv; k++ {
					drawX += xDiv
					line(drawX, tp, drawX, bt, false)
				}
			}
		}

		// Horizontals along Y axis
		yDiv = g.yTicks[1] - g.yTicks[0]
		if g.YDiv > 0 {
			yDiv = yDiv / float64(g.YDiv)
		}
		yDiv = g.Ht(yDiv)
		for j, y := range g.yTicks {
			drawY = g.Y(y)
			line(lf, drawY, rt, drawY, true)
			if j < yLen-1 {
				for k := 1; k < g.YDiv; k++ {
					drawY += yDiv
					line(lf, drawY, rt, drawY, false)
				}
			}
		}

		// X labels
		if g.XTickStr != nil {
			drawY = bt
			for _, x := range g.xTicks {
				str = g.XTickStr(x, g.xPrecision)
				strWd = pdf.GetStringWidth(str)
				drawX = g.X(x)
				if g.XLabelRotate {
					pdf.TransformBegin()
					pdf.TransformRotate(90, drawX, drawY)
					if g.XLabelIn {
						pdf.SetXY(drawX+strOfs, drawY-halfTextSz)
					} else {
						pdf.SetXY(drawX-strOfs-strWd, drawY-halfTextSz)
					}
					pdf.CellFormat(strWd, textSz, str, "", 0, "L", true, 0, "")
					pdf.TransformEnd()
				} else {
					drawX -= strWd / 2.0
					if g.XLabelIn {
						pdf.SetXY(drawX, drawY-textSz-strOfs)
					} else {
						pdf.SetXY(drawX, drawY+strOfs)
					}
					pdf.CellFormat(strWd, textSz, str, "", 0, "L", true, 0, "")
				}
			}
		}

		// Y labels
		if g.YTickStr != nil {
			drawX = lf
			for _, y := range g.yTicks {
				// str = strconv.FormatFloat(y, 'f', g.yPrecision, 64)
				str = g.YTickStr(y, g.yPrecision)
				strWd = pdf.GetStringWidth(str)
				if g.YLabelIn {
					pdf.SetXY(drawX+strOfs, g.Y(y)-halfTextSz)
				} else {
					pdf.SetXY(lf-strOfs-strWd, g.Y(y)-halfTextSz)
				}
				pdf.CellFormat(strWd, textSz, str, "", 0, "L", true, 0, "")
			}
		}

		// Restore drawing attributes
		st.Put(pdf)

	}

}
1124369
func (g *Virtual) Edge(v, w int) bool {
	if v < 0 || v >= g.order || w < 0 || w >= g.order {
		return false
	}
	return g.edge(v, w)
}
146806
func (g *Graph) Sort() (sorted []util.T, ok bool) {
	if g.sorted != nil {
		return g.sorted, true
	}

	sort := &graphSort{
		sorted: make([]util.T, 0, len(g.nodes)),
		deps:   g.Dependencies,
		marked: map[util.T]struct{}{},
		temp:   map[util.T]struct{}{},
	}

	for node := range g.nodes {
		if !sort.Visit(node) {
			return nil, false
		}
	}

	g.sorted = sort.sorted
	return g.sorted, true
}
859772
func (p *parser) generateParagraph(out *bytes.Buffer, data []byte) {
	generate := func() bool {
		p.inline(out, bytes.Trim(data, " "))
		return true
	}
	p.r.Paragraph(out, generate)
}
684838
func GraphDot(g *Graph, opts *dag.DotOpts) (string, error) {
	return string(g.Dot(opts)), nil
}
342182
func (m Mat3x2) Rows() (row0, row1, row2 Vec2) {
	return m.Row(0), m.Row(1), m.Row(2)
}
325879
func (c *BoxChart) Plot(g Graphics) {
	// layout
	layout := layout(g, c.Title, c.XRange.Label, c.YRange.Label,
		c.XRange.TicSetting.Hide || c.XRange.TicSetting.HideLabels,
		c.YRange.TicSetting.Hide || c.YRange.TicSetting.HideLabels,
		&c.Key)
	width, height := layout.Width, layout.Height
	topm, leftm := layout.Top, layout.Left
	numxtics, numytics := layout.NumXtics, layout.NumYtics
	// fontwidth, fontheight, _ := g.FontMetrics(DataStyle{})

	g.Begin()

	c.XRange.Setup(numxtics, numxtics+2, width, leftm, false)
	c.YRange.Setup(numytics, numytics+1, height, topm, true)

	if c.Title != "" {
		drawTitle(g, c.Title, elementStyle(c.Options, TitleElement))
	}

	g.XAxis(c.XRange, topm+height, topm, c.Options)
	g.YAxis(c.YRange, leftm, leftm+width, c.Options)

	yf := c.YRange.Data2Screen
	nan := math.NaN()
	for _, data := range c.Data {
		// Samples
		nums := len(data.Samples)
		bw := width / (2*nums - 1)

		boxes := make([]Box, len(data.Samples))
		for i, d := range data.Samples {
			x := float64(c.XRange.Data2Screen(d.X))
			// DebugLogger.Printf("Q1=%.2f  Q3=%.3f", d.Q1, d.Q3)
			q1, q3 := float64(yf(d.Q1)), float64(yf(d.Q3))
			med, avg := nan, nan
			high, low := nan, nan
			if !math.IsNaN(d.Med) {
				med = float64(yf(d.Med))
			}
			if !math.IsNaN(d.Avg) {
				avg = float64(yf(d.Avg))
			}
			if !math.IsNaN(d.High) {
				high = float64(yf(d.High))
			}
			if !math.IsNaN(d.Low) {
				low = float64(yf(d.Low))
			}

			outliers := make([]float64, len(d.Outliers))
			for j, ol := range d.Outliers {
				outliers[j] = float64(c.YRange.Data2Screen(ol))
			}
			boxes[i].X = x
			boxes[i].Q1 = q1
			boxes[i].Q3 = q3
			boxes[i].Med = med
			boxes[i].Avg = avg
			boxes[i].High = high
			boxes[i].Low = low
			boxes[i].Outliers = outliers
		}
		g.Boxes(boxes, bw, data.Style)
	}

	if !c.Key.Hide {
		g.Key(layout.KeyX, layout.KeyY, c.Key, c.Options)
	}

	g.End()
}
50939
func (g *Grid) RemoveRow(index int) {
	if index < g.rows {
		g.rows--
		for i := index; i <= g.rows; i++ {
			for j := 0; j < g.cols; j++ {
				if i == g.rows {
					delete(g.cells, image.Point{j, g.rows})
				} else {
					g.cells[image.Point{j, i}] = g.cells[image.Point{j, i + 1}]
				}
			}
		}
	}
}
610436
func (g *Grid) Focus(delegate func(p Primitive)) {
	for _, item := range g.items {
		if item.Focus {
			delegate(item.Item)
			return
		}
	}
	g.hasFocus = true
}
805253
func (l *ListArea) Draw(state *Peco, parent Layout, perPage int, options *DrawOptions) {
	if pdebug.Enabled {
		g := pdebug.Marker("ListArea.Draw pp = %d, options = %#v", perPage, options)
		defer g.End()
	}

	if perPage < 1 {
		panic("perPage < 1 (was " + strconv.Itoa(perPage) + ")")
	}

	loc := state.Location()

	linebuf := state.CurrentLineBuffer()

	// Should only get into this clause if we are RUNNING A QUERY.
	// regular paging shouldn't be affected. This clause basically
	// makes sure that we never have an empty screen when we are
	// at a large enough page, but we don't have enough entries
	// to fill that many pages in the buffer
	if options != nil && options.RunningQuery {
		bufsiz := linebuf.Size()
		page := loc.Page()

		for page > 1 {
			if (loc.PerPage()*(page-1) < bufsiz) &&
				(loc.PerPage()*page) >= bufsiz {
				break
			}

			page--
		}
		if loc.Page() != page {
			loc.SetPage(page)
			parent.DrawPrompt(state)
		}
	}

	pf := loc.PageCrop()
	if pdebug.Enabled {
		pdebug.Printf("Cropping linebuf which contains %d lines at page %d (%d entries per page)", linebuf.Size(), pf.currentPage, pf.perPage)
	}
	buf := pf.Crop(linebuf)
	bufsiz := buf.Size()

	// This protects us from losing the selected line in case our selected
	// line is greater than the buffer
	if lbufsiz := linebuf.Size(); lbufsiz > 0 && loc.LineNumber() >= lbufsiz {
		loc.SetLineNumber(lbufsiz - 1)
	}

	// The max column size is calculated by buf. we check against where the
	// loc variable thinks we should be scrolling to, and make sure that this
	// falls in range with what we got
	width, _ := state.screen.Size()
	if max := maxOf(buf.MaxColumn()-width, 0); loc.Column() > max {
		loc.SetColumn(max)
	}

	// previously drawn lines are cached. first, truncate the cache
	// to current size of the drawable area
	if ldc := int(len(l.displayCache)); ldc != perPage {
		newCache := make([]line.Line, perPage)
		copy(newCache, l.displayCache)
		l.displayCache = newCache
	} else if perPage > bufsiz {
		l.displayCache = l.displayCache[:bufsiz]
	}

	var y int
	start := l.AnchorPosition()

	// If our buffer is smaller than perPage, we may need to
	// clear some lines
	if pdebug.Enabled {
		pdebug.Printf("ListArea.Draw: buffer size is %d, our view area is %d", bufsiz, perPage)
	}

	for n := bufsiz; n < perPage; n++ {
		if l.sortTopDown {
			y = n + start
		} else {
			y = start - n
		}

		l.screen.Print(PrintArgs{
			Y:    y,
			Fg:   l.styles.Basic.fg,
			Bg:   l.styles.Basic.bg,
			Fill: true,
		})
	}

	var cached, written int
	var fgAttr, bgAttr termbox.Attribute
	var selectionPrefix = state.selectionPrefix
	var prefix = ""

	var prefixCurrentSelection string
	var prefixSavedSelection string
	var prefixDefault string
	if len := len(selectionPrefix); len > 0 {
		prefixCurrentSelection = selectionPrefix + " "
		prefixSavedSelection = "*" + strings.Repeat(" ", len)
		prefixDefault = strings.Repeat(" ", len+1)
	}

	for n := 0; n < perPage; n++ {
		if len(selectionPrefix) > 0 {
			switch {
			case n+loc.Offset() == loc.LineNumber():
				prefix = prefixCurrentSelection
			case selectionContains(state, n+loc.Offset()):
				prefix = prefixSavedSelection
			default:
				prefix = prefixDefault
			}
		} else {
			switch {
			case n+loc.Offset() == loc.LineNumber():
				fgAttr = l.styles.Selected.fg
				bgAttr = l.styles.Selected.bg
			case selectionContains(state, n+loc.Offset()):
				fgAttr = l.styles.SavedSelection.fg
				bgAttr = l.styles.SavedSelection.bg
			default:
				fgAttr = l.styles.Basic.fg
				bgAttr = l.styles.Basic.bg
			}
		}

		if n >= bufsiz {
			break
		}

		if l.sortTopDown {
			y = n + start
		} else {
			y = start - n
		}

		target, err := buf.LineAt(n)
		if err != nil {
			break
		}

		if (options != nil && options.DisableCache) || l.IsDirty() || target.IsDirty() {
			target.SetDirty(false)
		} else if l.displayCache[n] == target {
			cached++
			continue
		}

		written++
		l.displayCache[n] = target

		x := -1 * loc.Column()
		xOffset := loc.Column()
		line := target.DisplayString()

		if len := len(prefix); len > 0 {
			l.screen.Print(PrintArgs{
				X:       x,
				Y:       y,
				XOffset: xOffset,
				Fg:      fgAttr,
				Bg:      bgAttr,
				Msg:     prefix,
			})
			x += len
		}
		if state.SingleKeyJumpMode() || state.SingleKeyJumpShowPrefix() {
			prefixes := state.SingleKeyJumpPrefixes()
			if n < int(len(prefixes)) {
				l.screen.Print(PrintArgs{
					X:       x,
					Y:       y,
					XOffset: xOffset,
					Fg:      fgAttr | termbox.AttrBold | termbox.AttrReverse,
					Bg:      bgAttr,
					Msg:     string(prefixes[n]),
				})
				l.screen.Print(PrintArgs{
					X:       x + 1,
					Y:       y,
					XOffset: xOffset,
					Fg:      fgAttr,
					Bg:      bgAttr,
					Msg:     " ",
				})
			} else {
				l.screen.Print(PrintArgs{
					X:       x,
					Y:       y,
					XOffset: xOffset,
					Fg:      fgAttr,
					Bg:      bgAttr,
					Msg:     "  ",
				})
			}

			x += 2
		}

		ix, ok := target.(MatchIndexer)
		if !ok {
			l.screen.Print(PrintArgs{
				X:       x,
				Y:       y,
				XOffset: xOffset,
				Fg:      fgAttr,
				Bg:      bgAttr,
				Msg:     line,
				Fill:    true,
			})
			continue
		}

		matches := ix.Indices()
		prev := x
		index := 0

		for _, m := range matches {
			if m[0] > index {
				c := line[index:m[0]]
				n := l.screen.Print(PrintArgs{
					X:       prev,
					Y:       y,
					XOffset: xOffset,
					Fg:      fgAttr,
					Bg:      bgAttr,
					Msg:     c,
				})
				prev += n
				index += len(c)
			}
			c := line[m[0]:m[1]]

			n := l.screen.Print(PrintArgs{
				X:       prev,
				Y:       y,
				XOffset: xOffset,
				Fg:      l.styles.Matched.fg,
				Bg:      mergeAttribute(bgAttr, l.styles.Matched.bg),
				Msg:     c,
				Fill:    true,
			})
			prev += n
			index += len(c)
		}

		m := matches[len(matches)-1]
		if m[0] > index {
			l.screen.Print(PrintArgs{
				X:       prev,
				Y:       y,
				XOffset: xOffset,
				Fg:      l.styles.Query.fg,
				Bg:      mergeAttribute(bgAttr, l.styles.Query.bg),
				Msg:     line[m[0]:m[1]],
				Fill:    true,
			})
		} else if len(line) > m[1] {
			l.screen.Print(PrintArgs{
				X:       prev,
				Y:       y,
				XOffset: xOffset,
				Fg:      fgAttr,
				Bg:      bgAttr,
				Msg:     line[m[1]:len(line)],
				Fill:    true,
			})
		}
	}
	l.SetDirty(false)
	if pdebug.Enabled {
		pdebug.Printf("ListArea.Draw: Written total of %d lines (%d cached)", written+cached, cached)
	}
}
576271
func (g GridType) X(dataX float64) float64 {
	return g.xm*dataX + g.xb
}
1137157
func (r *Row) Render(style *renderStyle) string {
	// pre-render and shove into an array... helps with cleanly adding borders
	renderedCells := []string{}
	for _, c := range r.cells {
		renderedCells = append(renderedCells, c.Render(style))
	}

	// format final output
	return style.BorderY + strings.Join(renderedCells, style.BorderY) + style.BorderY
}
964227
func (m Mat3x4) Rows() (row0, row1, row2 Vec4) {
	return m.Row(0), m.Row(1), m.Row(2)
}
1080254
func (m *Multi) Page() []byte {
	return m.page[:len(m.page):len(m.page)]
}
1156897
func (e *eltTicks) computeTicks() {
	const tickDistance = 30 // TODO: Theme. Min pixels between tick labels.

	_, _, w, h := e.ticksFor.Layout()
	var dim float64
	switch e.axis {
	case 'x':
		dim = w
	case 'y':
		dim = h
	}

	// Compute max ticks assuming the labels are zero sized.
	maxTicks := int(dim / tickDistance)

	// Optimize ticks, keeping labels at least tickDistance apart.
	e.ticks = make(map[Scaler]plotEltTicks)
	for s := range e.scales() {
		pred := func(ticks, _ table.Slice, labels []string) bool {
			if len(labels) <= 1 {
				return true
			}
			// Check distance between labels.
			pos := e.mapTicks(s, ticks)
			// Ticks are in value order, but we need them
			// in position order.
			sort.Float64s(pos)
			var last float64
			for i, p := range pos {
				if i > 0 && p-last < tickDistance {
					// Labels i-1 and i are too close.
					return false
				}
				metrics := measureString(fontSize, labels[i])
				switch e.axis {
				case 'x':
					last = p + metrics.width
				case 'y':
					last = p + metrics.leading
				}
			}

			return true
		}
		major, minor, labels := s.Ticks(maxTicks, pred)
		e.ticks[s] = plotEltTicks{major, minor, labels}
	}
}
1168011
func (l *BasicLayout) DrawScreen(state *Peco, options *DrawOptions) {
	if pdebug.Enabled {
		g := pdebug.Marker("BasicLayout.DrawScreen")
		defer g.End()
	}

	perPage := l.linesPerPage()

	if err := l.CalculatePage(state, perPage); err != nil {
		return
	}

	l.DrawPrompt(state)
	l.list.Draw(state, l, perPage, options)

	if err := l.screen.Flush(); err != nil {
		return
	}
}
497476
func (p *Polygon) Edge(e int) Edge {
	var i int

	if len(p.cumulativeEdges) > 0 {
		for i = range p.cumulativeEdges {
			if i+1 >= len(p.cumulativeEdges) || e < p.cumulativeEdges[i+1] {
				e -= p.cumulativeEdges[i]
				break
			}
		}
	} else {
		// When the number of loops is small, use linear search. Most often
		// there is exactly one loop and the code below executes zero times.
		for i = 0; e >= len(p.Loop(i).vertices); i++ {
			e -= len(p.Loop(i).vertices)
		}
	}

	return Edge{p.Loop(i).OrientedVertex(e), p.Loop(i).OrientedVertex(e + 1)}
}