This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git


The following commit(s) were added to refs/heads/master by this push:
     new 840e904  WIP on migration.
840e904 is described below

commit 840e9043be65039f2eb6c7616e656868169fe6cd
Author: Aaron Radzinski <[email protected]>
AuthorDate: Tue Oct 5 10:46:16 2021 -0700

    WIP on migration.
---
 .../org/apache/nlpcraft/common/ansi/NCAnsi.scala   | 225 +++++++++++++++++
 .../org/apache/nlpcraft/common/util/NCUtils.scala  | 281 +++++++++++++++++++++
 2 files changed, 506 insertions(+)

diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ansi/NCAnsi.scala 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ansi/NCAnsi.scala
new file mode 100644
index 0000000..b215ce1
--- /dev/null
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ansi/NCAnsi.scala
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nlpcraft.common.ansi
+
+import com.typesafe.scalalogging.LazyLogging
+import org.apache.nlpcraft.common.*
+import org.apache.nlpcraft.common.util.NCUtils
+
+/**
+  *
+  */
+sealed trait NCAnsi extends LazyLogging:
+    import NCAnsi.*
+
+    private final val ESC = "\u001b"
+    private final val BELL = "\u0007"
+    private final val CSI = s"$ESC["
+    private final val OSC = s"$ESC]"
+    private final val RESET = s"${CSI}0m"
+
+    // 4-bit colors.
+    private final val BLACK = s"${CSI}30m"
+    private final val RED = s"${CSI}31m"
+    private final val GREEN = s"${CSI}32m"
+    private final val YELLOW = s"${CSI}33m"
+    private final val BLUE = s"${CSI}34m"
+    private final val MAGENTA = s"${CSI}35m"
+    private final val CYAN = s"${CSI}36m"
+    private final val WHITE = s"${CSI}37m"
+    private final val BLACK_B = s"${CSI}40m"
+    private final val RED_B = s"${CSI}41m"
+    private final val GREEN_B = s"${CSI}42m"
+    private final val YELLOW_B = s"${CSI}43m"
+    private final val BLUE_B = s"${CSI}44m"
+    private final val MAGENTA_B = s"${CSI}45m"
+    private final val CYAN_B = s"${CSI}46m"
+    private final val WHITE_B = s"${CSI}47m"
+
+    def ansi256Fg(color: Int) = if (isEnabled) s"[38;5;${color}m" else ""
+    def ansi256Bg(color: Int) = if (isEnabled) s"[48;5;${color}m" else ""
+    def ansi256Fg(fgColor: Int, s: Any): String = 
s"${ansi256Fg(fgColor)}${s.toString}$ansiReset"
+    def ansi256(fgColor: Int, bgColor: Int, s: Any): String = 
s"${ansi256Fg(fgColor)}${ansi256Bg(bgColor)}${s.toString}$ansiReset"
+
+    // Effects.
+    private final val BOLD = s"${CSI}1m"
+    private final val UNDERLINED = s"${CSI}4m"
+    private final val BLINK = s"${CSI}5m"
+    private final val REVERSED = s"${CSI}7m"
+    private final val INVISIBLE = s"${CSI}8m"
+
+    // Erase functions.
+    private final val CLEAR_SCREEN = s"${CSI}J"
+    private final val CLEAR_SCREEN_AFTER = s"${CSI}0J"
+    private final val CLEAR_SCREEN_BEFORE = s"${CSI}1J"
+    private final val CLEAR_LINE = s"${CSI}K"
+    private final val CLEAR_LINE_AFTER = s"${CSI}0K"
+    private final val CLEAR_LINE_BEFORE = s"${CSI}1K"
+
+    // Cursor moves.
+    private final val CURSOR_UP = s"${CSI}1A"
+    private final val CURSOR_DOWN = s"${CSI}1B"
+    private final val CURSOR_LEFT = s"${CSI}1D"
+    private final val CURSOR_RIGHT = s"${CSI}1C"
+    private final val CURSOR_POS_SAVE= s"${CSI}s"
+    private final val CURSOR_POS_RESTORE = s"${CSI}u"
+    private final val CURSOR_LINE_HOME = s"${CSI}0G"
+    private final val CURSOR_SCREEN_HOME = s"${CSI}H"
+    private final val CURSOR_HIDE = s"${CSI}?25l"
+    private final val CURSOR_SHOW = s"${CSI}?25h"
+
+    def isEnabled: Boolean = !NCUtils.isSysEnvTrue(PROP)
+
+
+    // Re-route to 8-bit colors.
+    def G: String = ansi256Fg(34)
+    def M: String = ansi256Fg(177)
+    def R: String = ansi256Fg(202)
+
+    def C: String = ansiCyanFg
+    def Y: String = ansiYellowFg
+    def W: String = ansi256Fg(231)
+    def B: String = ansiBlueFg
+    def K: String = ansiBlackFg
+
+    def GB: String = ansi256Bg(34)
+    def MB: String = ansi256Bg(177)
+    def RB: String = ansi256Bg(202)
+    def CB: String = ansiCyanBg
+    def YB: String = ansiYellowBg
+    def WB: String = ansiWhiteBg
+    def BB: String = ansiBlueBg
+    def KB: String = ansiBlackBg
+
+    def BO: String = ansiBold
+    def RST: String = ansiReset
+
+    def g(s: Any): String = s"$G${s.toString}$RST"
+    def m(s: Any): String = s"$M${s.toString}$RST"
+    def r(s: Any): String = s"$R${s.toString}$RST"
+    def c(s: Any): String = s"$C${s.toString}$RST"
+    def y(s: Any): String = s"$Y${s.toString}$RST"
+    def w(s: Any): String = s"$W${s.toString}$RST"
+    def b(s: Any): String = s"$B${s.toString}$RST"
+    def k(s: Any): String = s"$K${s.toString}$RST"
+
+    def green(s: Any): String = s"$G${s.toString}$RST"
+    def magenta(s: Any): String = s"$M${s.toString}$RST"
+    def red(s: Any): String = s"$R${s.toString}$RST"
+    def cyan(s: Any): String = s"$C${s.toString}$RST"
+    def yellow(s: Any): String = s"$Y${s.toString}$RST"
+    def white(s: Any): String = s"$W${s.toString}$RST"
+    def blue(s: Any): String = s"$B${s.toString}$RST"
+    def black(s: Any): String = s"$K${s.toString}$RST"
+    def gb(s: Any): String = s"$GB${s.toString}$RST"
+    def rb(s: Any): String = s"$RB${s.toString}$RST"
+    def cb(s: Any): String = s"$CB${s.toString}$RST"
+    def yb(s: Any): String = s"$YB${s.toString}$RST"
+    def wb(s: Any): String = s"$WB${s.toString}$RST"
+    def bb(s: Any): String = s"$BB${s.toString}$RST"
+    def kb(s: Any): String = s"$KB${s.toString}$RST"
+    def greenBg(s: Any): String = s"$GB${s.toString}$RST"
+    def magentaBg(s: Any): String = s"$MB${s.toString}$RST"
+    def redBg(s: Any): String = s"$RB${s.toString}$RST"
+    def cyanBg(s: Any): String = s"$CB${s.toString}$RST"
+    def yellowBg(s: Any): String = s"$YB${s.toString}$RST"
+    def whiteBg(s: Any): String = s"$WB${s.toString}$RST"
+    def blueBg(s: Any): String = s"$BB${s.toString}$RST"
+    def blackBg(s: Any): String = s"$KB${s.toString}$RST"
+
+    // Effect shortcuts...
+    def rv(s: Any): String = s"$ansiReversed${s.toString}$RST"
+    def bo(s: Any): String = s"$ansiBold${s.toString}$RST"
+    def reverse(s: Any): String = s"$ansiReversed${s.toString}$RST"
+    def bold(s: Any): String = s"$ansiBold${s.toString}$RST"
+
+    // Color functions.
+    def ansiBlackFg: String = if (isEnabled) BLACK else ""
+    def ansiBlackBg: String = if (isEnabled) BLACK_B else ""
+    def ansiRedFg: String = if (isEnabled) RED else ""
+    def ansiRedBg: String = if (isEnabled) RED_B else ""
+    def ansiGreenFg: String = if (isEnabled) GREEN else ""
+    def ansiGreenBg: String = if (isEnabled) GREEN_B else ""
+    def ansiYellowFg: String = if (isEnabled) YELLOW else ""
+    def ansiYellowBg: String = if (isEnabled) YELLOW_B else ""
+    def ansiBlueFg: String = if (isEnabled) BLUE else ""
+    def ansiBlueBg: String = if (isEnabled) BLUE_B else ""
+    def ansiMagentaFg: String = if (isEnabled) MAGENTA else ""
+    def ansiMagentaBg: String = if (isEnabled) MAGENTA_B else ""
+    def ansiCyanFg: String = if (isEnabled) CYAN else ""
+    def ansiCyanBg: String = if (isEnabled) CYAN_B else ""
+    def ansiWhiteFg: String = if (isEnabled) WHITE else ""
+    def ansiWhiteBg: String = if (isEnabled) WHITE_B else ""
+
+    // Effect functions.
+    def ansiBold: String = if (isEnabled) BOLD else ""
+    def ansiUnderlined: String = if (isEnabled) UNDERLINED else ""
+    def ansiReset: String = if (isEnabled) RESET else ""
+    def ansiReversed: String = if (isEnabled) REVERSED else ""
+    def ansiBlink: String = if (isEnabled) BLINK else ""
+    def ansiInvisible: String = if (isEnabled) INVISIBLE else ""
+
+    def ansiGreen(s: Any): String = s"$ansiGreenFg${s.toString}$ansiReset"
+    def ansiRed(s: Any): String = s"$ansiRedFg${s.toString}$ansiReset"
+    def ansiCyan(s: Any): String = s"$ansiCyanFg${s.toString}s$ansiReset"
+    def ansiYellow(s: Any): String = s"$ansiYellowFg${s.toString}$ansiReset"
+    def ansiBlack(s: Any): String = s"$ansiBlackFg${s.toString}s$ansiReset"
+    def ansiWhite(s: Any): String = s"$ansiWhiteFg${s.toString}$ansiReset"
+    def ansiBlue(s: Any): String = s"$ansiBlueFg${s.toString}$ansiReset"
+    def ansiMagenta(s: Any): String = s"$ansiMagentaFg${s.toString}$ansiReset"
+    def ansiBold(s: Any): String = s"$ansiBold${s.toString}$ansiReset"
+
+    // Erase functions.
+    def ansiClearScreen: String = if (isEnabled) CLEAR_SCREEN else ""
+    def ansiClearScreenAfter: String = if (isEnabled) CLEAR_SCREEN_AFTER else 
""
+    def ansiClearScreenBefore: String = if (isEnabled) CLEAR_SCREEN_BEFORE 
else ""
+    def ansiClearLine: String = if (isEnabled) CLEAR_LINE else ""
+    def ansiClearLineAfter: String = if (isEnabled) CLEAR_LINE_AFTER else ""
+    def ansiClearLineBefore: String = if (isEnabled) CLEAR_LINE_BEFORE else ""
+
+    // Cursor movement functions.
+    def ansiCursorUp: String = if (isEnabled) CURSOR_UP else ""
+    def ansiCursorDown: String = if (isEnabled) CURSOR_DOWN else ""
+    def ansiCursorLeft: String = if (isEnabled) CURSOR_LEFT else ""
+    def ansiCursorRight: String = if (isEnabled) CURSOR_RIGHT else ""
+    def ansiCursorLineHome: String = if (isEnabled) CURSOR_LINE_HOME else ""
+    def ansiCursorScreenHome: String = if (isEnabled) CURSOR_SCREEN_HOME else 
""
+    def ansiCursorPosSave: String = if (isEnabled) CURSOR_POS_SAVE else ""
+    def ansiCursorPosRestore: String = if (isEnabled) CURSOR_POS_RESTORE else 
""
+    def ansiCursorShow: String = if (isEnabled) CURSOR_SHOW else ""
+    def ansiCursorHide: String = if (isEnabled) CURSOR_HIDE else ""
+
+
+object NCAnsi extends NCAnsi:
+    // Enabled by default.
+    // NOTE: it's not static as it can be changed at runtime.
+    private final val PROP = "NLPCRAFT_ANSI_COLOR_DISABLED"
+
+    /**
+      *
+      * @param f
+      */
+    def setEnabled(f: Boolean): Unit = System.setProperty(PROP, (!f).toString)
+
+    /**
+      *
+      */
+    def ackStatus(): Unit =
+        if isEnabled then
+            logger.info(s"${NCUtils.bgRainbow4Bit("ANSI")} coloring is 
enabled. Use '-D${ansiCyanFg}NLPCRAFT_ANSI_COLOR_DISABLED${ansiReset}=true' to 
disable it.", 130, 147)
+
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala
new file mode 100644
index 0000000..7a6153e
--- /dev/null
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala
@@ -0,0 +1,281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nlpcraft.common.util
+
+import com.typesafe.scalalogging.LazyLogging
+import org.apache.nlpcraft.common.ansi.NCAnsi.*
+
+import java.util.Random
+import scala.sys.SystemProperties
+
+/**
+  *
+  */
+object NCUtils extends LazyLogging:
+    final val NL = System getProperty "line.separator"
+    private final val RND = new Random()
+    private val sysProps = new SystemProperties
+    private val ANSI_FG_8BIT_COLORS = for (i <- 16 to 255) yield ansi256Fg(i)
+    private val ANSI_BG_8BIT_COLORS = for (i <- 16 to 255) yield ansi256Bg(i)
+    private val ANSI_FG_4BIT_COLORS = Seq(
+        ansiRedFg,
+        ansiGreenFg,
+        ansiBlueFg,
+        ansiYellowFg,
+        ansiWhiteFg,
+        ansiBlackFg,
+        ansiCyanFg
+    )
+    private val ANSI_BG_4BIT_COLORS = Seq(
+        ansiRedBg,
+        ansiGreenBg,
+        ansiBlueBg,
+        ansiYellowBg,
+        ansiWhiteBg,
+        ansiBlackBg,
+        ansiCyanBg
+    )
+    private val ANSI_4BIT_COLORS = for (fg <- ANSI_FG_4BIT_COLORS; bg <- 
ANSI_BG_4BIT_COLORS) yield s"$fg$bg"
+
+    /**
+      * Gets system property, or environment variable (in that order), or 
`None` if none exists.
+      *
+      * @param s Name of the system property or environment variable.
+      */
+    def sysEnv(s: String): Option[String] = 
sysProps.get(s).orElse(sys.env.get(s))
+
+    /**
+      * Tests whether given system property of environment variable is set or 
not.
+      *
+      * @param s @param s Name of the system property or environment variable.
+      * @return
+      */
+    def isSysEnvSet(s: String): Boolean = sysProps.get(s).nonEmpty || 
sys.env.contains(s)
+
+    /**
+      * Returns `true` if given system property, or environment variable is 
provided and has value
+      * 'true'. In all other cases returns `false`.
+      *
+      * @param s Name of the system property or environment variable.
+      */
+    def isSysEnvTrue(s: String): Boolean = sysEnv(s) match
+        case None => false
+        case Some(v) => java.lang.Boolean.valueOf(v) == java.lang.Boolean.TRUE
+
+
+    /**
+      * Gets random value from given sequence.
+      *
+      * @param seq Sequence.
+      */
+    def getRandom[T](seq: Seq[T]): T = seq(RND.nextInt(seq.size))
+
+    /**
+      * Makes random filled sequence with given length from initial.
+      *
+      * @param seq Initial sequence.
+      * @param n Required sequence length.
+      */
+    def getRandomSeq[T](seq: Seq[T], n: Int): Seq[T] =
+        require(seq.lengthCompare(n) >= 0)
+
+        val src = scala.collection.mutable.ArrayBuffer.empty[T] ++ seq
+        val dest = scala.collection.mutable.ArrayBuffer.empty[T]
+
+        (0 until n).foreach(_ => dest += src.remove(RND.nextInt(src.size)))
+
+        dest.toSeq
+
+    /**
+      * Prints 4-bit ASCII-logo.
+      */
+    def asciiLogo4Bit(): String =
+        raw"$ansiBlueFg    _   ____     $ansiCyanFg ______           ______   
$ansiReset$NL" +
+        raw"$ansiBlueFg   / | / / /___  $ansiCyanFg/ ____/________ _/ __/ /_  
$ansiReset$NL" +
+        raw"$ansiBlueFg  /  |/ / / __ \$ansiCyanFg/ /   / ___/ __ `/ /_/ __/  
$ansiReset$NL" +
+        raw"$ansiBlueFg / /|  / / /_/ /$ansiCyanFg /___/ /  / /_/ / __/ /_    
$ansiReset$NL" +
+        raw"$ansiBold$ansiRedFg/_/ |_/_/ .___/$ansiRedFg\____/_/   \__,_/_/  
\__/      $ansiReset$NL" +
+        raw"$ansiBold$ansiRedFg       /_/                                      
        $ansiReset$NL"
+
+    /**
+      * Prints 8-bit ASCII-logo.
+      */
+    def asciiLogo8Bit1(): String =
+        fgRainbow4Bit(
+            raw"${ansi256Fg(28)}    _   ____      ______           ______   
$ansiReset$NL" +
+            raw"${ansi256Fg(64)}   / | / / /___  / ____/________ _/ __/ /_  
$ansiReset$NL" +
+            raw"${ansi256Fg(100)}  /  |/ / / __ \/ /   / ___/ __ `/ /_/ __/  
$ansiReset$NL" +
+            raw"${ansi256Fg(136)} / /|  / / /_/ / /___/ /  / /_/ / __/ /_    
$ansiReset$NL" +
+            raw"${ansi256Fg(172)}/_/ |_/_/ .___/\____/_/   \__,_/_/  \__/    
$ansiReset$NL" +
+            raw"${ansi256Fg(208)}       /_/                                  
$ansiReset$NL"
+        )
+
+    /**
+      * Prints 8-bit ASCII-logo.
+      */
+    def asciiLogo8Bit(): String =
+        val startColor = getRandom(Seq(16, 22, 28, 34, 40, 46))
+        val range = 6
+
+        (for (lineIdx <- Seq(
+            raw"    _   ____      ______           ______   $NL",
+            raw"   / | / / /___  / ____/________ _/ __/ /_  $NL",
+            raw"  /  |/ / / __ \/ /   / ___/ __ `/ /_/ __/  $NL",
+            raw" / /|  / / /_/ / /___/ /  / /_/ / __/ /_    $NL",
+            raw"/_/ |_/_/ .___/\____/_/   \__,_/_/  \__/    $NL",
+            raw"       /_/                                  $NL"
+        ).zipWithIndex) yield {
+            val line = lineIdx._1
+            val idx = lineIdx._2
+            val start = startColor + (36 * idx)
+            val end = start + range - 1
+
+            gradAnsi8BitFgLine(line, start, end)
+        })
+        .mkString("")
+
+    /**
+      *
+      * @param line
+      * @param startColor Inclusive.
+      * @param endColor Inclusive.
+      * @return
+      */
+    def gradAnsi8BitFgLine(line: String, startColor: Int, endColor: Int): 
String =
+        line.zipWithIndex.foldLeft(new StringBuilder())((buf, zip) => {
+            val ch = zip._1
+            val idx = zip._2
+            val color = startColor + idx % (endColor - startColor + 1)
+
+            buf ++= s"${ansi256Fg(color)}$ch"
+        })
+        .toString + ansiReset
+
+    /**
+      *
+      * @param line
+      * @param startColor Inclusive.
+      * @param endColor Inclusive.
+      * @return
+      */
+    def gradAnsi8BitBgLine(line: String, startColor: Int, endColor: Int): 
String =
+        line.zipWithIndex.foldLeft(new StringBuilder())((buf, zip) => {
+            val ch = zip._1
+            val idx = zip._2
+            val color = startColor + idx % (endColor - startColor + 1)
+
+            buf ++= s"${ansi256Bg(color)}$ch"
+        })
+        .toString + ansiReset
+
+    /**
+      *
+      * @param s
+      * @return
+      */
+    def fgRainbow4Bit(s: String, addOn: String = ""): String = rainbowImpl(s, 
ANSI_FG_4BIT_COLORS, addOn)
+
+    /**
+      *
+      * @param s
+      * @return
+      */
+    def fgRainbow8Bit(s: String, addOn: String = ""): String = rainbowImpl(s, 
ANSI_FG_8BIT_COLORS, addOn)
+
+    /**
+      *
+      * @param s
+      * @return
+      */
+    def bgRainbow4Bit(s: String, addOn: String = ""): String = rainbowImpl(s, 
ANSI_BG_4BIT_COLORS, addOn)
+
+    /**
+      *
+      * @param s
+      * @return
+      */
+    def bgRainbow8Bit(s: String, addOn: String = ""): String = rainbowImpl(s, 
ANSI_BG_8BIT_COLORS, addOn)
+
+    /**
+      *
+      * @param s
+      * @return
+      */
+    def rainbow4Bit(s: String, addOn: String = ""): String = 
randomRainbowImpl(s, ANSI_4BIT_COLORS, addOn)
+
+    /**
+      *
+      * @param s
+      * @param colors
+      * @param addOn
+      * @return
+      */
+    private def randomRainbowImpl(s: String, colors: Seq[String], addOn: 
String): String =
+        s.zipWithIndex.foldLeft(new StringBuilder())((buf, zip) => {
+            buf ++= s"${colors(RND.nextInt(colors.size))}$addOn${zip._1}"
+        })
+        .toString + ansiReset
+
+    /**
+      *
+      * @param s
+      * @param colors
+      * @param addOn
+      * @return
+      */
+    private def rainbowImpl(s: String, colors: Seq[String], addOn: String): 
String =
+        s.zipWithIndex.foldLeft(new StringBuilder())((buf, zip) => {
+            buf ++= s"${colors(zip._2 % colors.size)}$addOn${zip._1}"
+        })
+        .toString + ansiReset
+
+    /**
+      * ANSI color JSON string.
+      *
+      * @param json JSON string to color.
+      * @return
+      */
+    def colorJson(json: String): String =
+        val buf = new StringBuilder
+        var inQuotes = false
+        var isValue = false
+
+        for (ch <- json)
+            ch match
+                case ':' if !inQuotes => buf ++= r(":"); isValue = true
+                case '[' | ']' | '{' | '}' if !inQuotes => buf ++= y(s"$ch"); 
isValue = false
+                case ',' if !inQuotes => buf ++= ansi256Fg(213, s"$ch"); 
isValue = false
+                case '"' =>
+                    if inQuotes then
+                        buf ++= ansi256Fg(105, s"$ch")
+                    else
+                        buf ++= s"${ansi256Fg(105)}$ch"
+                        buf ++= (if isValue then G else ansiCyanFg)
+
+                    inQuotes = !inQuotes
+
+                case _ => buf ++= s"$ch"
+
+
+        buf.append(RST)
+        buf.toString()
+
+    /**
+      * Shortcut - current timestamp in milliseconds.
+      */
+    def now(): Long = System.currentTimeMillis()

Reply via email to