Move SSD status error helper to typed Kotlin

ober

87e65ccbb430a25a81b413dba0b59774c21d7e7d

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 303a7e1..f2bb357 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -439,7 +439,8 @@
 
     (typed-kotlin-file "com/sfb/ssdreview/UiTextHelpers.kt"
       (typed-library (com sfb ssdreview)
-        (export normalizeFiringArc normalizeLabel isGenericGuessLabel isSsdPdfName)
+        (export normalizeFiringArc normalizeLabel isGenericGuessLabel isSsdPdfName
+                isErrorStatus)
         (def (normalizeFiringArc (value : String)) : String
           (string-uppercase (string-trim value)))
         (def (normalizeLabel (value : String)) : String
@@ -458,7 +459,13 @@
         (def (isSsdPdfName (name : String)) : Bool
           (let ((lower (string-lowercase name)))
             (and (string-ends-with? lower ".pdf")
-                 (string-contains? lower "ssd"))))))
+                 (string-contains? lower "ssd"))))
+        (def (isErrorStatus (text : String)) : Bool
+          (let ((lower (string-lowercase text)))
+            (or (or (string-contains? lower "failed")
+                    (string-contains? lower "error"))
+                (or (string-contains? lower "exception")
+                    (string-contains? lower "rejected")))))))
 
     (kotlin-file-lines "com/sfb/ssdreview/BoxTypes.kt"
       (
@@ -2359,11 +2366,6 @@
        "            .put(\"stack\", if (stack.length <= CLIENT_LOG_STACK_CHARS) stack else stack.take(CLIENT_LOG_STACK_CHARS) + \"...[truncated]\")"
        "    }"
        ""
-       "    private fun isErrorStatus(text: String): Boolean {"
-       "        val lower = text.lowercase()"
-       "        return lower.contains(\"failed\") || lower.contains(\"error\") || lower.contains(\"exception\") || lower.contains(\"rejected\")"
-       "    }"
-       ""
        "    private fun setStatus(text: String) {"
        "        status.text = text"
        "        if (isErrorStatus(text)) {"