| 
					
				 | 
			
			
				@@ -3,6 +3,7 @@ package door 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"bytes" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"fmt" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"log" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"strings" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"time" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -39,8 +40,11 @@ type WOPR struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Index          int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Ticker         *time.Ticker 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	StopIt         chan bool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	output         *bytes.Buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const DEBUG_WOPR bool = true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (w *WOPR) Clear() []byte { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var output bytes.Buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	output.Write(w.ElapsedPanel.Clear()) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -55,6 +59,7 @@ func (w *WOPR) Init(elapsed time.Time, remaining time.Time, color string) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if color == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		color = ColorText("BLACK ON CYAN") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	w.output = &bytes.Buffer{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.Elapsed = elapsed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.Remaining = remaining 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.Index = 0 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -62,97 +67,86 @@ func (w *WOPR) Init(elapsed time.Time, remaining time.Time, color string) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		BorderColor: color, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		Style:       SINGLE} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var gameBuff bytes.Buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	gameBuff.WriteString("      GAME      ") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, Line{Text: gameBuff}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var elapsedBuff bytes.Buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	elapsedBuff.WriteString("  TIME ELAPSED  ") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, Line{Text: elapsedBuff}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, NewLine("      GAME      ")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, NewLine("  TIME ELAPSED  ")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var ehour Line = Line{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	ehour.UpdateF = func() []byte { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ehour.UpdateF = func(u *bytes.Buffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		var hours int = int(w.ElapsedD.Hours()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var output []byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		fmt.Append(output, "     %02d HRS     ", hours%100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return output 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		u.Reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		fmt.Fprintf(u, "     %02d HRS     ", hours%100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	ehour.Text.Write(ehour.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ehour.Update() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// ehour.Text.Write(ehour.update) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, ehour) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var eminsec Line = Line{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	eminsec.UpdateF = func() []byte { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	eminsec.UpdateF = func(u *bytes.Buffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		var mins int = int(w.ElapsedD.Minutes()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		var secs int = int(w.ElapsedD.Seconds()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var output []byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		output = fmt.Appendf(output, " %02d MIN  %02d SEC ", mins, secs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return output 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		u.Reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		fmt.Fprintf(u, " %02d MIN  %02d SEC ", mins, secs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	eminsec.Text.Write(eminsec.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	eminsec.Update() // Text.Write(eminsec.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, eminsec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var eanimate Line = Line{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	eanimate.UpdateF = func() []byte { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var output bytes.Buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	eanimate.UpdateF = func(u *bytes.Buffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		u.Reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// Left to Right 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if Unicode { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			var buffer []rune = []rune(strings.Repeat(" ", 16)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			buffer[w.Index] = '\u25a0' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			output.WriteString(string(buffer)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			u.WriteString(string(buffer)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			var buffer []byte = bytes.Repeat([]byte(" "), 16) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			buffer[w.Index] = '\xfe' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			output.WriteString(string(buffer)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			u.WriteString(string(buffer)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return output.Bytes() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	eanimate.Text.Write(eanimate.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	eanimate.Update() // Text.Write(eanimate.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, eanimate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.RemainingPanel = Panel{Width: 16, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		BorderColor: color, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		Style:       SINGLE} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, Line{Text: gameBuff}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var remainBuff bytes.Buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	remainBuff.WriteString(" TIME REMAINING ") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, Line{Text: remainBuff}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, NewLine("      GAME      ")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, NewLine(" TIME REMAINING ")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var rhour Line = Line{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	rhour.UpdateF = func() []byte { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	rhour.UpdateF = func(u *bytes.Buffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		var hours int = int(w.RemainingD.Hours()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var output []byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		output = fmt.Appendf(output, "     %02d HRS     ", hours%100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return output 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		u.Reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		fmt.Fprintf(u, "     %02d HRS     ", hours%100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	rhour.Text.Write(rhour.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	rhour.Update() // Text.Write(rhour.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, rhour) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var rminsec Line = Line{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	rminsec.UpdateF = func() []byte { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	rminsec.UpdateF = func(u *bytes.Buffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		var mins int = int(w.RemainingD.Minutes()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		var secs int = int(w.RemainingD.Seconds()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var output []byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		output = fmt.Appendf(output, " %02d MIN  %02d SEC ", mins, secs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return output 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		u.Reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		fmt.Fprintf(u, " %02d MIN  %02d SEC ", mins, secs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	rminsec.Text.Write(rminsec.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	rminsec.Update() // Text.Write(rminsec.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, rminsec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var ranimate Line = Line{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	ranimate.UpdateF = func() []byte { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var output bytes.Buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ranimate.UpdateF = func(u *bytes.Buffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		u.Reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// Left to Right 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if Unicode { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			var buffer []rune = []rune(strings.Repeat(" ", 16)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			buffer[15-w.Index] = '\u25a0' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			output.WriteString(string(buffer)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			u.WriteString(string(buffer)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			var buffer []byte = bytes.Repeat([]byte(" "), 16) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			buffer[15-w.Index] = '\xfe' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			output.WriteString(string(buffer)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			u.WriteString(string(buffer)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return output.Bytes() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	ranimate.Text.Write(ranimate.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ranimate.Update() // Text.Write(ranimate.UpdateF()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, ranimate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -160,8 +154,8 @@ func (w *WOPR) Inc() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.Index++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if w.Index == 16 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		w.Index = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		w.ElapsedPanel.Updater() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		w.RemainingPanel.Updater() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.ElapsedPanel.Update() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.RemainingPanel.Update() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		w.RemainingD = time.Duration(w.RemainingD.Seconds()-1) * time.Second 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		w.ElapsedD = time.Duration(w.ElapsedD.Seconds()+1) * time.Second 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -187,7 +181,7 @@ func (w *WOPR) Animate(d *Door) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.RemainingD = time.Until(w.Remaining) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.StopIt = make(chan bool) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	go func(d *Door) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	go func(d *Door, output *bytes.Buffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// til := time.Now().UnixNano() % int64(time.Second) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		sec16 := int64(time.Second) / 16 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -202,7 +196,7 @@ func (w *WOPR) Animate(d *Door) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// time.Second / 16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		w.Ticker = time.NewTicker(time.Duration(sec16)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var output bytes.Buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// var output bytes.Buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		for { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			select { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -210,13 +204,21 @@ func (w *WOPR) Animate(d *Door) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			case <-w.Ticker.C: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				w.ElapsedPanel.Updater() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				w.RemainingPanel.Updater() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				w.ElapsedPanel.Update() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				w.RemainingPanel.Update() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var using int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				using = output.Cap() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				output.Reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				output.WriteString(SavePos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				output.Write(w.ElapsedPanel.Output()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				output.Write(w.RemainingPanel.Output()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				output.WriteString(RestorePos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if DEBUG_WOPR { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if output.Cap() > using { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						using = output.Cap() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						log.Printf("WOPR: now %d\n", using) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if !d.Writer.IsClosed() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					d.Write(output.Bytes()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					output.Reset() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -228,7 +230,7 @@ func (w *WOPR) Animate(d *Door) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				w.Inc() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	}(d) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}(d, w.output) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (w *WOPR) Stop() { 
			 |