Move SSD bbox helper to typed Kotlin

ober

869bed56189efad90a670a676a7658e05f06c8ea

diff --git a/.build.yml b/.build.yml
index 7deaf2d..adf95d1 100644
--- a/.build.yml
+++ b/.build.yml
@@ -5,7 +5,7 @@ packages:
   - make=4.4.1-r4
 sources:
   # Build dependency: full immutable commit, mirrored in dependencies.lock.json.
-  - "https://git.sr.ht/~lisp/jerboa#ef86e0761a15de93a61c67d177b4cadaf882d529"
+  - "https://git.sr.ht/~lisp/jerboa#661325ac41bb37055534b73f9092233f87cfd0de"
   # The second source is the build subject selected by the SourceHut submitter.
   - https://git.sr.ht/~lisp/jerboa-android
 tasks:
@@ -14,6 +14,6 @@ tasks:
       test "$(apk info -v chez-scheme)" = chez-scheme-10.3.0-r2
       test "$(apk info -v git)" = git-2.54.0-r0
       test "$(apk info -v make)" = make-4.4.1-r4
-      test "$(git -C ../jerboa rev-parse HEAD)" = ef86e0761a15de93a61c67d177b4cadaf882d529
-      test "$(git -C ../jerboa rev-parse 'HEAD^{tree}')" = ca975cbb04f1ca057e3f9cb1404795622a79d6c4
+      test "$(git -C ../jerboa rev-parse HEAD)" = 661325ac41bb37055534b73f9092233f87cfd0de
+      test "$(git -C ../jerboa rev-parse 'HEAD^{tree}')" = e500993b3aac8f99b50087d0135e10a425798edc
       JERBOA="chez --libdirs .:../jerboa/lib --script" make test
diff --git a/dependencies.lock.json b/dependencies.lock.json
index dc4ff29..d3943d5 100644
--- a/dependencies.lock.json
+++ b/dependencies.lock.json
@@ -11,8 +11,8 @@
   "generator_runtime": {
     "name": "jerboa",
     "repository": "https://git.sr.ht/~lisp/jerboa",
-    "commit": "ef86e0761a15de93a61c67d177b4cadaf882d529",
-    "tree": "ca975cbb04f1ca057e3f9cb1404795622a79d6c4"
+    "commit": "661325ac41bb37055534b73f9092233f87cfd0de",
+    "tree": "e500993b3aac8f99b50087d0135e10a425798edc"
   },
   "assurance_tools": {
     "osv_scanner": {
diff --git a/scripts/verify-supply-chain.sh b/scripts/verify-supply-chain.sh
index bda6f5e..dd61cd8 100755
--- a/scripts/verify-supply-chain.sh
+++ b/scripts/verify-supply-chain.sh
@@ -3,8 +3,8 @@ set -eu
 
 repo=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd -P)
 lock="$repo/dependencies.lock.json"
-jerboa_commit=ef86e0761a15de93a61c67d177b4cadaf882d529 # gitsafe:ignore
-jerboa_tree=ca975cbb04f1ca057e3f9cb1404795622a79d6c4 # gitsafe:ignore
+jerboa_commit=661325ac41bb37055534b73f9092233f87cfd0de # gitsafe:ignore
+jerboa_tree=e500993b3aac8f99b50087d0135e10a425798edc # gitsafe:ignore
 gradle_sha=20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78
 jdk_macos_sha=8fa1eff40bb637a33613b2ccb8b12c70dc3661cc22cf8e784943715769a05336
 jdk_linux_sha=d8afc263758141a66e0e3aafc321e783f7016696f4eaea067d340a269037d331
diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 12a24fe..e99763b 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -32,7 +32,8 @@
                 SsdCell-h SsdCell-h-set!
                 SsdCell-detector
                 ssdCellCx ssdCellCy ssdCellRect
-                rectOverlapArea rectCenterInside iou adjacent)
+                rectOverlapArea rectCenterInside iou adjacent
+                bboxForCells)
         (type Float32)
         (type FloatArray)
         (type Int32)
@@ -159,7 +160,26 @@
                                  (float32
                                    (float32-round->int32
                                      (* minW (float32 0.35)))))))))
-                (or horizontal vertical)))))))
+                (or horizontal vertical)))))
+        (def (bboxForCells (cells : (List SsdCell))) : FloatArray
+          (if (= (list-size cells) (int32 0))
+            (float-array (float32 0.0) (float32 0.0) (float32 0.0) (float32 0.0))
+            (let ((first (list-ref cells (int32 0))))
+              (float-array
+                (for/fold ((x (SsdCell-x first)))
+                          ((i (in-range (int32 1) (list-size cells))))
+                  (minFloat32 x (SsdCell-x (list-ref cells i))))
+                (for/fold ((y (SsdCell-y first)))
+                          ((i (in-range (int32 1) (list-size cells))))
+                  (minFloat32 y (SsdCell-y (list-ref cells i))))
+                (for/fold ((x2 (+ (SsdCell-x first) (SsdCell-w first))))
+                          ((i (in-range (int32 1) (list-size cells))))
+                  (let ((cell (list-ref cells i)))
+                    (maxFloat32 x2 (+ (SsdCell-x cell) (SsdCell-w cell)))))
+                (for/fold ((y2 (+ (SsdCell-y first) (SsdCell-h first))))
+                          ((i (in-range (int32 1) (list-size cells))))
+                  (let ((cell (list-ref cells i)))
+                    (maxFloat32 y2 (+ (SsdCell-y cell) (SsdCell-h cell)))))))))))
 
     (typed-kotlin-file "com/sfb/ssdreview/Component.kt"
       (typed-library (com sfb ssdreview)
@@ -2937,16 +2957,6 @@
        "    return payload"
        "}"
        ""
-       "fun bboxForCells(cells: List<SsdCell>): FloatArray {"
-       "    if (cells.isEmpty()) return floatArrayOf(0f, 0f, 0f, 0f)"
-       "    return floatArrayOf("
-       "        cells.minOf { it.x },"
-       "        cells.minOf { it.y },"
-       "        cells.maxOf { it.x + it.w },"
-       "        cells.maxOf { it.y + it.h }"
-       "    )"
-       "}"
-       ""
 	       "fun floatArrayToJson(rect: FloatArray): JSONArray = JSONArray().apply {"
 	       "    rect.forEach { put(it.toDouble()) }"
 	       "}"