func (m *Model) HalfViewUp() (lines []string) {
	if m.AtTop() {
		return nil
	}
	m.SetYOffset(m.YOffset - m.Height/2)
	return m.visibleLines()
}
HalfViewUp moves the view up by half the height of the viewport.
package viewport
import (
	"math"
	"strings"
	tea "github.com/charmbracelet/bubbletea"
)
const (
	spacebar        = " "
	mouseWheelDelta = 3
)
type Model struct {
	Width  int
	Height int
	YOffset int
	YPosition int
	HighPerformanceRendering bool
	lines []string
}
func (m Model) AtTop() bool {
	return m.YOffset <= 0
}
func (m Model) AtBottom() bool {
	return m.YOffset >= len(m.lines)-m.Height
}
func (m Model) PastBottom() bool {
	return m.YOffset > len(m.lines)-m.Height
}
func (m Model) ScrollPercent() float64 {
	if m.Height >= len(m.lines) {
		return 1.0
	}
	y := float64(m.YOffset)
	h := float64(m.Height)
	t := float64(len(m.lines) - 1)
	v := y / (t - h)
	return math.Max(0.0, math.Min(1.0, v))
}
func (m *Model) SetContent(s string) {
	s = strings.ReplaceAll(s, "\r\n", "\n")  
	m.lines = strings.Split(s, "\n")
	if m.YOffset > len(m.lines)-1 {
		m.GotoBottom()
	}
}
func (m Model) visibleLines() (lines []string) {
	if len(m.lines) > 0 {
		top := max(0, m.YOffset)
		bottom := clamp(m.YOffset+m.Height, top, len(m.lines))
		lines = m.lines[top:bottom]
	}
	return lines
}
func (m Model) scrollArea() (top, bottom int) {
	top = max(0, m.YPosition)
	bottom = max(top, top+m.Height)
	if top > 0 && bottom > top {
		bottom--
	}
	return top, bottom
}
func (m *Model) SetYOffset(n int) {
	m.YOffset = clamp(n, 0, len(m.lines)-m.Height)
}
func (m *Model) ViewDown() []string {
	if m.AtBottom() {
		return nil
	}
	m.SetYOffset(m.YOffset + m.Height)
	return m.visibleLines()
}
func (m *Model) ViewUp() []string {
	if m.AtTop() {
		return nil
	}
	m.SetYOffset(m.YOffset - m.Height)
	return m.visibleLines()
}
func (m *Model) HalfViewDown() (lines []string) {
	if m.AtBottom() {
		return nil
	}
	m.SetYOffset(m.YOffset + m.Height/2)
	return m.visibleLines()
}