Split project into several packages
The source code of the project has been split up into several packages, each one pertaining to different aspects of the system. Currently there is a main package, a drw package, containing all the funcitons regarding the drawing of the calendar, and a util package containing time-related project specific functions and general utility functions for the project. There are plenty of subsystems in the program which have not even been developed yet, and new packages will be made pertaining to those. The package tree may be heavily reorganized in the near future.
This commit is contained in:
parent
1a194cc368
commit
9fa8301ba6
294
Main.go
294
Main.go
|
@ -3,293 +3,43 @@ package main
|
|||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
|
||||
"gitlab.com/tvrdosrz/ck/drw"
|
||||
"gitlab.com/tvrdosrz/ck/util"
|
||||
)
|
||||
|
||||
const (
|
||||
dayWidth = 2
|
||||
smallGap = 1
|
||||
largeGap = 3
|
||||
maxMonthWidth = 7*dayWidth + 6*smallGap
|
||||
maxMonthHeight = (31+6+(7-1))/7 + 2
|
||||
/* maxMonthHeight is the height of a 31-day month starting on Sunday (month
|
||||
name and weekdays included) */
|
||||
|
||||
titleHeight = smallGap + 1
|
||||
)
|
||||
|
||||
var (
|
||||
months = [...]string{"", "Јануар", "Фебруар", "Март", "Април", "Мај", "Јун",
|
||||
"Јул", "Август", "Септембар", "Октобар", "Новембар", "Децембар"}
|
||||
weekdays = [...]string{"Недеља", "Понедељак", "Уторак", "Среда", "Четвртак",
|
||||
"Петак", "Субота"}
|
||||
)
|
||||
|
||||
var (
|
||||
wall tcell.Screen
|
||||
defStyle tcell.Style
|
||||
todayStyle tcell.Style
|
||||
selStyle tcell.Style
|
||||
|
||||
monthsWide int
|
||||
monthsHigh int
|
||||
monthsDrawn int
|
||||
)
|
||||
|
||||
var (
|
||||
selTime time.Time
|
||||
today time.Time
|
||||
)
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func date(year int, month time.Month, day int) time.Time {
|
||||
return time.Date(year, month, day, 0, 0, 0, 0, time.Local)
|
||||
}
|
||||
|
||||
func lastDay(m time.Month) time.Time {
|
||||
return date(selTime.Year(), m+1, 0)
|
||||
}
|
||||
|
||||
func monthHeight(m time.Month) int {
|
||||
return (offset(m) + lastDay(m).Day() - 1) / 7
|
||||
}
|
||||
|
||||
func centeredText(s string, x, y, width int, scr tcell.Screen, style tcell.Style) {
|
||||
start := x + max((width-utf8.RuneCountInString(s))/2, 0)
|
||||
i := 0
|
||||
for ; x+i < start; i++ {
|
||||
scr.SetContent(x+i, y, ' ', nil, style)
|
||||
}
|
||||
for _, char := range s {
|
||||
if i >= width {
|
||||
break
|
||||
}
|
||||
|
||||
scr.SetContent(x+i, y, char, nil, style)
|
||||
i++
|
||||
}
|
||||
for ; x+i < start; i++ {
|
||||
scr.SetContent(x+i, y, ' ', nil, style)
|
||||
}
|
||||
}
|
||||
|
||||
func wrappedText(s string, scr tcell.Screen, style tcell.Style) {
|
||||
x := 0
|
||||
y := 0
|
||||
w, h := scr.Size()
|
||||
for _, char := range s {
|
||||
if x >= w {
|
||||
if y >= h {
|
||||
break
|
||||
}
|
||||
x = 0
|
||||
y++
|
||||
}
|
||||
scr.SetContent(x, y, char, nil, style)
|
||||
x++
|
||||
}
|
||||
}
|
||||
|
||||
func bottomOfMonth(m time.Month, w time.Weekday) (time time.Time) {
|
||||
last := lastDay(m)
|
||||
day := last.Day()
|
||||
|
||||
if w > last.Weekday() {
|
||||
day -= 7
|
||||
}
|
||||
|
||||
day += int(w - last.Weekday())
|
||||
|
||||
time = date(selTime.Year(), m, day)
|
||||
return
|
||||
}
|
||||
|
||||
func topOfMonth(m time.Month, w time.Weekday) (time time.Time) {
|
||||
first := date(selTime.Year(), m, 1)
|
||||
day := 1
|
||||
|
||||
if w < first.Weekday() {
|
||||
day += 7
|
||||
}
|
||||
|
||||
day += int(w - first.Weekday())
|
||||
|
||||
time = date(selTime.Year(), m, day)
|
||||
return
|
||||
}
|
||||
|
||||
func moveUp() {
|
||||
weekday := selTime.Weekday()
|
||||
newTime := selTime.AddDate(0, 0, -7)
|
||||
if newTime.Month() == selTime.Month() {
|
||||
selTime = newTime
|
||||
} else if int(selTime.Month()) > monthsWide {
|
||||
newMonth := selTime.Month() - time.Month(monthsWide)
|
||||
selTime = bottomOfMonth(newMonth, weekday)
|
||||
}
|
||||
}
|
||||
|
||||
func moveDown() {
|
||||
weekday := selTime.Weekday()
|
||||
newTime := selTime.AddDate(0, 0, +7)
|
||||
if newTime.Month() == selTime.Month() {
|
||||
selTime = newTime
|
||||
} else if int(selTime.Month()) <= (12-1)/monthsWide*monthsWide {
|
||||
newMonth := selTime.Month() + time.Month(monthsWide)
|
||||
selTime = topOfMonth(newMonth, weekday)
|
||||
}
|
||||
}
|
||||
|
||||
func offset(m time.Month) int {
|
||||
return (int(date(selTime.Year(), m, 1).Weekday()) + 6) % 7
|
||||
|
||||
}
|
||||
|
||||
func rowInMonth(m time.Month, day int) int {
|
||||
return (day + offset(m) - 1) / 7
|
||||
}
|
||||
|
||||
func leftmostInRow(m time.Month, row int) time.Time {
|
||||
if row == 0 {
|
||||
return date(selTime.Year(), m, 1)
|
||||
}
|
||||
if row > monthHeight(m) {
|
||||
row = monthHeight(m)
|
||||
}
|
||||
|
||||
day := row*7 + 1 - offset(m)
|
||||
|
||||
return date(selTime.Year(), m, day)
|
||||
}
|
||||
|
||||
func rightmostInRow(m time.Month, row int) time.Time {
|
||||
if row >= monthHeight(m) {
|
||||
return lastDay(m)
|
||||
}
|
||||
|
||||
day := row*7 + 7 - offset(m)
|
||||
|
||||
return date(selTime.Year(), m, day)
|
||||
}
|
||||
|
||||
func moveRight() {
|
||||
if selTime.Weekday() != time.Sunday && selTime.Day() != lastDay(selTime.Month()).Day() {
|
||||
selTime = selTime.AddDate(0, 0, 1)
|
||||
} else if int(selTime.Month())%monthsWide != 0 {
|
||||
selTime = leftmostInRow(selTime.Month()+1, rowInMonth(selTime.Month(), selTime.Day()))
|
||||
}
|
||||
}
|
||||
|
||||
func moveLeft() {
|
||||
if selTime.Weekday() != time.Monday && selTime.Day() != 1 {
|
||||
selTime = selTime.AddDate(0, 0, -1)
|
||||
} else if int(selTime.Month())%monthsWide != 1 && monthsWide != 1 { // special case, if monthsWide
|
||||
// is 1, (x%monthsWide) is 0
|
||||
selTime = rightmostInRow(selTime.Month()-1, rowInMonth(selTime.Month(), selTime.Day()))
|
||||
}
|
||||
}
|
||||
|
||||
func drawMonth(m time.Month, x, y int) {
|
||||
centeredText(months[m], x, y, maxMonthWidth, wall, defStyle)
|
||||
|
||||
for i := 1; i <= 7; i++ {
|
||||
centeredText(weekdays[i%7], x+(i-1)*(dayWidth+smallGap), y+1, dayWidth, wall, defStyle)
|
||||
}
|
||||
|
||||
dayNum := date(selTime.Year(), m+1, 0).Day()
|
||||
for i := 1; i <= dayNum; i++ {
|
||||
weekday := int(date(selTime.Year(), m, i).Weekday())
|
||||
style := defStyle
|
||||
if today.Day() == i && today.Month() == m {
|
||||
style = todayStyle
|
||||
} else if selTime.Day() == i && selTime.Month() == m {
|
||||
style = selStyle
|
||||
}
|
||||
centeredText(
|
||||
strconv.Itoa(i),
|
||||
x+((weekday-1+7)%7)*(dayWidth+smallGap),
|
||||
y+2,
|
||||
2,
|
||||
wall,
|
||||
style)
|
||||
if weekday == 0 {
|
||||
y++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func drawWall() {
|
||||
wall.Clear()
|
||||
w, h := wall.Size()
|
||||
if w < maxMonthWidth+2*smallGap || h < maxMonthHeight+2*smallGap+titleHeight {
|
||||
wrappedText("Екран је премали за календар.", wall, defStyle)
|
||||
return
|
||||
}
|
||||
monthsWide = (w - 2*smallGap + largeGap) / (maxMonthWidth + largeGap)
|
||||
monthsHigh = (h - smallGap - titleHeight) / (maxMonthHeight + smallGap)
|
||||
monthsDrawn = min(monthsHigh*monthsWide, 12)
|
||||
|
||||
startingMonth := time.Month((int(selTime.Month())-1)/monthsDrawn*monthsDrawn + 1)
|
||||
endingMonth := time.Month(min(12, int(startingMonth)+monthsDrawn-1))
|
||||
|
||||
centerVert := (w - monthsWide*maxMonthWidth - (monthsWide-1)*largeGap) / 2
|
||||
for i, m := 0, startingMonth; i < monthsHigh; i++ {
|
||||
for j := 0; j < monthsWide; j++ {
|
||||
drawMonth(m, centerVert+j*(maxMonthWidth+largeGap), titleHeight+smallGap+i*(maxMonthHeight+smallGap))
|
||||
if m >= endingMonth {
|
||||
return
|
||||
}
|
||||
m++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
today = time.Now()
|
||||
selTime = today
|
||||
util.Today = time.Now()
|
||||
util.SelTime = util.Today
|
||||
var err error
|
||||
wall, err = tcell.NewScreen()
|
||||
drw.Wall, err = tcell.NewScreen()
|
||||
if err != nil {
|
||||
log.Fatalf("%+v", err)
|
||||
}
|
||||
if err := wall.Init(); err != nil {
|
||||
if err := drw.Wall.Init(); err != nil {
|
||||
log.Fatalf("%+v", err)
|
||||
}
|
||||
defStyle = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorReset)
|
||||
todayStyle = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.GetColor("blue")).Bold(true).Reverse(true)
|
||||
selStyle = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.GetColor("green")).Bold(true)
|
||||
drw.DefStyle = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorReset)
|
||||
drw.TodayStyle = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.GetColor("blue")).Bold(true).Reverse(true)
|
||||
drw.SelStyle = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.GetColor("green")).Bold(true)
|
||||
|
||||
wall.SetStyle(defStyle)
|
||||
wall.Clear()
|
||||
drawWall()
|
||||
drw.Wall.SetStyle(drw.DefStyle)
|
||||
drw.Wall.Clear()
|
||||
drw.DrawWall()
|
||||
|
||||
quit := func() {
|
||||
wall.Fini()
|
||||
drw.Wall.Fini()
|
||||
os.Exit(0)
|
||||
}
|
||||
for {
|
||||
// Update screen
|
||||
wall.Show()
|
||||
drw.Wall.Show()
|
||||
|
||||
// Poll event
|
||||
ev := wall.PollEvent()
|
||||
ev := drw.Wall.PollEvent()
|
||||
|
||||
// Process event
|
||||
switch ev := ev.(type) {
|
||||
|
@ -301,17 +51,17 @@ func main() {
|
|||
}
|
||||
switch ev.Rune() {
|
||||
case 'h':
|
||||
moveLeft()
|
||||
drw.MoveLeft()
|
||||
case 'j':
|
||||
moveDown()
|
||||
drw.MoveDown()
|
||||
case 'k':
|
||||
moveUp()
|
||||
drw.MoveUp()
|
||||
case 'l':
|
||||
moveRight()
|
||||
drw.MoveRight()
|
||||
}
|
||||
}
|
||||
|
||||
drawWall()
|
||||
wall.Sync()
|
||||
drw.DrawWall()
|
||||
drw.Wall.Sync()
|
||||
}
|
||||
}
|
||||
|
|
57
drw/drw.go
Normal file
57
drw/drw.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
package drw
|
||||
|
||||
import (
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"gitlab.com/tvrdosrz/ck/util"
|
||||
)
|
||||
|
||||
var (
|
||||
months = [...]string{"", "Јануар", "Фебруар", "Март", "Април", "Мај", "Јун",
|
||||
"Јул", "Август", "Септембар", "Октобар", "Новембар", "Децембар"}
|
||||
weekdays = [...]string{"Недеља", "Понедељак", "Уторак", "Среда", "Четвртак",
|
||||
"Петак", "Субота"}
|
||||
)
|
||||
|
||||
var (
|
||||
DefStyle tcell.Style
|
||||
TodayStyle tcell.Style
|
||||
SelStyle tcell.Style
|
||||
)
|
||||
|
||||
func centeredText(s string, x, y, width int, scr tcell.Screen, style tcell.Style) {
|
||||
start := x + util.Max((width-utf8.RuneCountInString(s))/2, 0)
|
||||
i := 0
|
||||
for ; x+i < start; i++ {
|
||||
scr.SetContent(x+i, y, ' ', nil, style)
|
||||
}
|
||||
for _, char := range s {
|
||||
if i >= width {
|
||||
break
|
||||
}
|
||||
|
||||
scr.SetContent(x+i, y, char, nil, style)
|
||||
i++
|
||||
}
|
||||
for ; x+i < start; i++ {
|
||||
scr.SetContent(x+i, y, ' ', nil, style)
|
||||
}
|
||||
}
|
||||
|
||||
func wrappedText(s string, scr tcell.Screen, style tcell.Style) {
|
||||
x := 0
|
||||
y := 0
|
||||
w, h := scr.Size()
|
||||
for _, char := range s {
|
||||
if x >= w {
|
||||
if y >= h {
|
||||
break
|
||||
}
|
||||
x = 0
|
||||
y++
|
||||
}
|
||||
scr.SetContent(x, y, char, nil, style)
|
||||
x++
|
||||
}
|
||||
}
|
192
drw/wall.go
Normal file
192
drw/wall.go
Normal file
|
@ -0,0 +1,192 @@
|
|||
package drw
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
|
||||
"gitlab.com/tvrdosrz/ck/util"
|
||||
)
|
||||
|
||||
const (
|
||||
dayWidth = 2
|
||||
smallGap = 1
|
||||
largeGap = 3
|
||||
maxMonthWidth = 7*dayWidth + 6*smallGap
|
||||
maxMonthHeight = (31+6+(7-1))/7 + 2
|
||||
/* maxMonthHeight is the height of a 31-day month starting on Sunday (month
|
||||
name and weekdays included) */
|
||||
|
||||
titleHeight = smallGap + 1
|
||||
)
|
||||
|
||||
var (
|
||||
Wall tcell.Screen
|
||||
|
||||
monthsWide int
|
||||
monthsHigh int
|
||||
monthsDrawn int
|
||||
)
|
||||
|
||||
func offset(m time.Month) int {
|
||||
return (int(util.Date(util.SelTime.Year(), m, 1).Weekday()) + 6) % 7
|
||||
|
||||
}
|
||||
|
||||
func lastDay(m time.Month) time.Time {
|
||||
return util.Date(util.SelTime.Year(), m+1, 0)
|
||||
}
|
||||
|
||||
func monthHeight(m time.Month) int {
|
||||
return (offset(m) + lastDay(m).Day() - 1) / 7
|
||||
}
|
||||
|
||||
func bottomOfMonth(m time.Month, w time.Weekday) (time time.Time) {
|
||||
last := lastDay(m)
|
||||
day := last.Day()
|
||||
|
||||
if w > last.Weekday() {
|
||||
day -= 7
|
||||
}
|
||||
|
||||
day += int(w - last.Weekday())
|
||||
|
||||
time = util.Date(util.SelTime.Year(), m, day)
|
||||
return
|
||||
}
|
||||
|
||||
func topOfMonth(m time.Month, w time.Weekday) (time time.Time) {
|
||||
first := util.Date(util.SelTime.Year(), m, 1)
|
||||
day := 1
|
||||
|
||||
if w < first.Weekday() {
|
||||
day += 7
|
||||
}
|
||||
|
||||
day += int(w - first.Weekday())
|
||||
|
||||
time = util.Date(util.SelTime.Year(), m, day)
|
||||
return
|
||||
}
|
||||
|
||||
func rowInMonth(m time.Month, day int) int {
|
||||
return (day + offset(m) - 1) / 7
|
||||
}
|
||||
|
||||
func leftmostInRow(m time.Month, row int) time.Time {
|
||||
if row == 0 {
|
||||
return util.Date(util.SelTime.Year(), m, 1)
|
||||
}
|
||||
if row > monthHeight(m) {
|
||||
row = monthHeight(m)
|
||||
}
|
||||
|
||||
day := row*7 + 1 - offset(m)
|
||||
|
||||
return util.Date(util.SelTime.Year(), m, day)
|
||||
}
|
||||
|
||||
func rightmostInRow(m time.Month, row int) time.Time {
|
||||
if row >= monthHeight(m) {
|
||||
return lastDay(m)
|
||||
}
|
||||
|
||||
day := row*7 + 7 - offset(m)
|
||||
|
||||
return util.Date(util.SelTime.Year(), m, day)
|
||||
}
|
||||
|
||||
func MoveUp() {
|
||||
weekday := util.SelTime.Weekday()
|
||||
newTime := util.SelTime.AddDate(0, 0, -7)
|
||||
if newTime.Month() == util.SelTime.Month() {
|
||||
util.SelTime = newTime
|
||||
} else if int(util.SelTime.Month()) > monthsWide {
|
||||
newMonth := util.SelTime.Month() - time.Month(monthsWide)
|
||||
util.SelTime = bottomOfMonth(newMonth, weekday)
|
||||
}
|
||||
}
|
||||
|
||||
func MoveDown() {
|
||||
weekday := util.SelTime.Weekday()
|
||||
newTime := util.SelTime.AddDate(0, 0, +7)
|
||||
if newTime.Month() == util.SelTime.Month() {
|
||||
util.SelTime = newTime
|
||||
} else if int(util.SelTime.Month()) <= (12-1)/monthsWide*monthsWide {
|
||||
newMonth := util.SelTime.Month() + time.Month(monthsWide)
|
||||
util.SelTime = topOfMonth(newMonth, weekday)
|
||||
}
|
||||
}
|
||||
|
||||
func MoveRight() {
|
||||
if util.SelTime.Weekday() != time.Sunday && util.SelTime.Day() != lastDay(util.SelTime.Month()).Day() {
|
||||
util.SelTime = util.SelTime.AddDate(0, 0, 1)
|
||||
} else if int(util.SelTime.Month())%monthsWide != 0 {
|
||||
util.SelTime = leftmostInRow(util.SelTime.Month()+1, rowInMonth(util.SelTime.Month(), util.SelTime.Day()))
|
||||
}
|
||||
}
|
||||
|
||||
func MoveLeft() {
|
||||
if util.SelTime.Weekday() != time.Monday && util.SelTime.Day() != 1 {
|
||||
util.SelTime = util.SelTime.AddDate(0, 0, -1)
|
||||
} else if int(util.SelTime.Month())%monthsWide != 1 && monthsWide != 1 { // special case, if monthsWide
|
||||
// is 1, (x%monthsWide) is 0
|
||||
util.SelTime = rightmostInRow(util.SelTime.Month()-1, rowInMonth(util.SelTime.Month(), util.SelTime.Day()))
|
||||
}
|
||||
}
|
||||
|
||||
func drawMonth(m time.Month, x, y int) {
|
||||
centeredText(months[m], x, y, maxMonthWidth, Wall, DefStyle)
|
||||
|
||||
for i := 1; i <= 7; i++ {
|
||||
centeredText(weekdays[i%7], x+(i-1)*(dayWidth+smallGap), y+1, dayWidth, Wall, DefStyle)
|
||||
}
|
||||
|
||||
dayNum := util.Date(util.SelTime.Year(), m+1, 0).Day()
|
||||
for i := 1; i <= dayNum; i++ {
|
||||
weekday := int(util.Date(util.SelTime.Year(), m, i).Weekday())
|
||||
style := DefStyle
|
||||
if util.Today.Day() == i && util.Today.Month() == m {
|
||||
style = TodayStyle
|
||||
} else if util.SelTime.Day() == i && util.SelTime.Month() == m {
|
||||
style = SelStyle
|
||||
}
|
||||
centeredText(
|
||||
strconv.Itoa(i),
|
||||
x+((weekday-1+7)%7)*(dayWidth+smallGap),
|
||||
y+2,
|
||||
2,
|
||||
Wall,
|
||||
style)
|
||||
if weekday == 0 {
|
||||
y++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DrawWall() {
|
||||
Wall.Clear()
|
||||
w, h := Wall.Size()
|
||||
if w < maxMonthWidth+2*smallGap || h < maxMonthHeight+2*smallGap+titleHeight {
|
||||
wrappedText("Екран је премали за календар.", Wall, DefStyle)
|
||||
return
|
||||
}
|
||||
monthsWide = (w - 2*smallGap + largeGap) / (maxMonthWidth + largeGap)
|
||||
monthsHigh = (h - smallGap - titleHeight) / (maxMonthHeight + smallGap)
|
||||
monthsDrawn = util.Min(monthsHigh*monthsWide, 12)
|
||||
|
||||
startingMonth := time.Month((int(util.SelTime.Month())-1)/monthsDrawn*monthsDrawn + 1)
|
||||
endingMonth := time.Month(util.Min(12, int(startingMonth)+monthsDrawn-1))
|
||||
|
||||
centerVert := (w - monthsWide*maxMonthWidth - (monthsWide-1)*largeGap) / 2
|
||||
for i, m := 0, startingMonth; i < monthsHigh; i++ {
|
||||
for j := 0; j < monthsWide; j++ {
|
||||
drawMonth(m, centerVert+j*(maxMonthWidth+largeGap), titleHeight+smallGap+i*(maxMonthHeight+smallGap))
|
||||
if m >= endingMonth {
|
||||
return
|
||||
}
|
||||
m++
|
||||
}
|
||||
}
|
||||
}
|
12
util/cal.go
Normal file
12
util/cal.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package util
|
||||
|
||||
import "time"
|
||||
|
||||
var (
|
||||
SelTime time.Time
|
||||
Today time.Time
|
||||
)
|
||||
|
||||
func Date(year int, month time.Month, day int) time.Time {
|
||||
return time.Date(year, month, day, 0, 0, 0, 0, time.Local)
|
||||
}
|
15
util/util.go
Normal file
15
util/util.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package util
|
||||
|
||||
func Max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func Min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
Loading…
Reference in a new issue