@livemira/target-rating 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,71 @@ follow [Semantic Versioning](https://semver.org/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.6.0] — 2026-11-06
9
+
10
+ The camera session learns to wait: a hidden page suspends the run instead of ending it, the videos of a run are kept
11
+ for the run, the wait for the camera permission no longer shows a made-up percentage, and the camera is released
12
+ where it used to be left on. The recognition and tracking algorithms are unchanged.
13
+
14
+ ### Added
15
+
16
+ - `suspend()`, `resume()` and `isSuspended` on the engine, for a hidden page: videos pause (no sound), recognition and
17
+ drawing idle, the camera track is switched off (`enabled = false`) and targets in view are reported lost with the new
18
+ reason `'suspended'` (`targetLost`). The camera, the compiled targets and the loaded videos stay. Idempotent; called
19
+ before the camera is open, it applies once the camera is; `stop()` ends it. The recognition Worker switches off the
20
+ track it owns and releases incoming frames unprocessed while suspended (new `suspend` message to the Worker).
21
+ - `media.selectTarget(targetId | null)` on the engine: optional exclusive playback. Until it is first called every
22
+ target in view plays its video, as before; after it only the selected target's video plays or is drawn, the others
23
+ stay paused with their source kept, and `setMuted` and `retry` act on the selected one.
24
+ - `suspend()` and `resume()` on the camera session (`@livemira/ui`), the `isSuspended` state field, and the same two
25
+ optional members on `ArSessionLike`. `suspend()` returns `false` when it cannot (no run, or an engine module without
26
+ `suspend`).
27
+ - A short hint at the top of the camera view, positioned to reduce overlap with the browser's own permission prompt, while the camera is not yet
28
+ open.
29
+
30
+ ### Changed
31
+
32
+ - Videos are kept per run. A photo's video is requested the first time the photo is recognised and kept until the run
33
+ ends: losing and finding the photo again, or switching between photos, never requests it twice, and other photos'
34
+ downloads are not interrupted. `stop()` (exit and `dispose()` too, also while a prompt, the preparation or a
35
+ download is pending) aborts every download, releases the videos and ignores late results.
36
+ - One video plays at a time: the session selects the recognised photo with `media.selectTarget`, so videos kept for
37
+ other photos stay paused. Without that engine member the UI falls back to the old behaviour.
38
+ - A hidden page, by default, suspends the run and resumes it when the page is visible again (`pageshow` too). An
39
+ engine module without `suspend` still gets the old behaviour (the run stops). `isStoppedWhenHidden` is now unset by
40
+ default: `true` stops the run as 0.5 did, `false` leaves it alone. **Behaviour change** for hosts that relied on the
41
+ hidden page ending the run without setting the option.
42
+ - `readiness` is the share of photos prepared (0..1) and `null` until the engine is loaded. Waiting for the camera
43
+ permission is no longer part of it and no longer sits at a made-up percentage: the loader card's ring fills only for
44
+ measured work (photos prepared) and turns for every other wait. The percentage text inside the ring is gone.
45
+ - Wording (both languages): the camera hint is "Allow camera access", the video status "Preparing video…" and "Loading
46
+ video N%", and the lost notice "Photo out of view". Hosts that match these texts (tests, `messages` overrides that
47
+ copy them) need to follow.
48
+ - The documentation set describes the target rating as an npm package (`@livemira/target-rating`) next to its offline
49
+ tarball.
50
+ - Release tooling: the integration guide and the release notes template live in `release-src/`, the changelog and
51
+ NOTICE at the repository root, the guides only in `documentation/`; the release builds the target rating into the
52
+ demo's folder too and checks every relative link of the finished release. The demo's sample media are read from the
53
+ 0.5.1 release directory (`DEMO_ASSETS` in `tools/bundle.ts`).
54
+
55
+ ### Fixed
56
+
57
+ - Camera privacy: a camera granted after the run had already been stopped (stopped while the permission prompt was
58
+ open) is released at once; before, the stream stayed open with nothing left to close it.
59
+ - Camera privacy: a hidden page no longer keeps the camera track live. Suspending switches off every track of the run,
60
+ including the one the recognition Worker owns, and frames that arrive meanwhile are dropped, not processed.
61
+ - A page that is already hidden when the camera view is mounted is suspended too (browsers fire no `visibilitychange`
62
+ for that initial state).
63
+ - A video that failed to load while its photo was out of view is reported when the photo is next found, and one photo's
64
+ video notice no longer shows on another.
65
+
66
+ ### Limits
67
+
68
+ - Suspending switches a track off; it does not close the camera. Whether a browser's camera indicator goes off with it
69
+ depends on the browser: call `stop()` to release the camera.
70
+ - The hidden-page and permission-wait behaviour is covered by unit and integration tests and was accepted on phones by
71
+ the publisher. No wider device matrix was run for this release; how browsers treat a disabled camera track differs.
72
+
8
73
  ## [0.5.1] — 2026-11-04
9
74
 
10
75
  The camera UI learns two things at runtime: a language button and a relocated sound button. The demo is now in
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @livemira/target-rating — target rating
2
2
 
3
- [English](https://github.com/andy-mira/livemira/blob/v0.5.1/release/0.5.1/documentation/target-rating.md) | [简体中文](https://github.com/andy-mira/livemira/blob/v0.5.1/release/0.5.1/documentation/target-rating.zh-CN.md)
3
+ [English](https://github.com/andy-mira/livemira/blob/v0.6.0/release/0.6.0/documentation/target-rating.md) | [简体中文](https://github.com/andy-mira/livemira/blob/v0.6.0/release/0.6.0/documentation/target-rating.zh-CN.md)
4
4
 
5
- > **Offline package**, not on npm: `npm install ./livemira-target-rating-0.5.1.tgz` from the [release](https://github.com/andy-mira/livemira/tree/v0.5.1/release/0.5.1).
5
+ > **npm:** `npm install @livemira/target-rating`. The files listed below as `files/livemira-target-rating*` are under `dist/` here (`import { rateTargetImage } from '@livemira/target-rating'`; the Worker file is `@livemira/target-rating/worker`). It needs no engine. The same package is in the [release](https://github.com/andy-mira/livemira/tree/v0.6.0/release/0.6.0) as an offline tarball.
6
6
 
7
7
  Rates a picture for scanning (0.5–5 stars), so a page where the user picks the target picture (an uploaded photo, or
8
8
  the first, last or any frame of a video) can suggest a better one.
@@ -14,13 +14,13 @@ target the engine would track.
14
14
 
15
15
  ## Files
16
16
 
17
- | File | Purpose |
18
- | -------------------------------------------- | -------------------------------------------------------------------------- |
19
- | `files/livemira-target-rating.min.mjs` | One ES module, Worker embedded (about 47 KB). |
20
- | `files/livemira-target-rating.mjs` | The same module, readable. |
21
- | `files/livemira-target-rating-worker.min.js` | The rating Worker script (classic), for pages whose CSP forbids `blob:`. |
22
- | `files/livemira-target-rating.d.ts` | Declarations. |
23
- | `npm/livemira-target-rating-*.tgz` | Offline package `@livemira/target-rating` (not on npm; `npm install` the file). |
17
+ | File | Purpose |
18
+ | -------------------------------------------- | ----------------------------------------------------------------------------- |
19
+ | `files/livemira-target-rating.min.mjs` | One ES module, Worker embedded (about 47 KB). |
20
+ | `files/livemira-target-rating.mjs` | The same module, readable. |
21
+ | `files/livemira-target-rating-worker.min.js` | The rating Worker script (classic), for pages whose CSP forbids `blob:`. |
22
+ | `files/livemira-target-rating.d.ts` | Declarations. |
23
+ | `npm/livemira-target-rating-*.tgz` | The npm package `@livemira/target-rating` as a tarball, for offline installs. |
24
24
 
25
25
  Importing the module creates nothing; the first rating starts its Worker, which closes after 4 s idle. One picture is
26
26
  rated at a time; the rest wait in order.
@@ -35,7 +35,8 @@ try {
35
35
  showStars(rating.stars); // 0.5…5 in halves
36
36
  if (rating.stars < 3) suggestAnotherFrame(rating.advice);
37
37
  } catch (error) {
38
- if (error instanceof RatingError && error.code === 'UNSUITABLE_TARGET') showCannotUse(); // the engine would refuse it
38
+ if (error instanceof RatingError && error.code === 'UNSUITABLE_TARGET')
39
+ showCannotUse(); // the engine would refuse it
39
40
  else if (error?.code !== 'ABORTED') throw error;
40
41
  }
41
42
  ```
@@ -59,8 +60,9 @@ Factors (0..1): `detail` (points found in at least 5 of the compiler's 14 views)
59
60
  picture: grid cells, evenness, the weakest quarter), `distinctiveness` (no look-alikes far apart), `recognition` (the
60
61
  detector on synthetic views, five tests from easy to hard: smaller, tilted, motion-blurred, dimmer, partly covered;
61
62
  each view tried twice and counted by its margin; per test in `metrics.tests`). Score = 100 × (0.15 detail + 0.4 spread
62
- + 0.05 distinctiveness + 0.4 recognition); stars = 0.5 + 4.5 × the score's place between 15 and 95, capped at
63
- 1 + 4 × min(spread, recognition)^0.4: detail crowded in one place, or hardly found in the views, cannot rate high.
63
+
64
+ - 0.05 distinctiveness + 0.4 recognition); stars = 0.5 + 4.5 × the score's place between 15 and 95, capped at
65
+ 1 + 4 × min(spread, recognition)^0.4: detail crowded in one place, or hardly found in the views, cannot rate high.
64
66
 
65
67
  `advice`, most important first: `HARD_TO_FIND`, `CONCENTRATED`, `WEAK_QUARTER` (`metrics.weakestQuarter`),
66
68
  `FEW_DETAILS`, `REPETITIVE`, and `FAILS_SMALL`, `FAILS_TILTED`, `FAILS_BLURRED`, `FAILS_DIM`, `FAILS_COVERED` (that
@@ -84,4 +86,4 @@ rating leaves the engine's files as they are. `RATING_VERSION` and `ratingBuildI
84
86
 
85
87
  ## License
86
88
 
87
- Apache-2.0. See [LICENSE](https://github.com/andy-mira/livemira/blob/v0.5.1/release/0.5.1/LICENSE) and [NOTICE](https://github.com/andy-mira/livemira/blob/v0.5.1/release/0.5.1/NOTICE).
89
+ Apache-2.0. See [LICENSE](https://github.com/andy-mira/livemira/blob/v0.6.0/release/0.6.0/LICENSE) and [NOTICE](https://github.com/andy-mira/livemira/blob/v0.6.0/release/0.6.0/NOTICE).
package/README.zh-CN.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @livemira/target-rating —— 目标图评分
2
2
 
3
- [English](https://github.com/andy-mira/livemira/blob/v0.5.1/release/0.5.1/documentation/target-rating.md) | [简体中文](https://github.com/andy-mira/livemira/blob/v0.5.1/release/0.5.1/documentation/target-rating.zh-CN.md)
3
+ [English](https://github.com/andy-mira/livemira/blob/v0.6.0/release/0.6.0/documentation/target-rating.md) | [简体中文](https://github.com/andy-mira/livemira/blob/v0.6.0/release/0.6.0/documentation/target-rating.zh-CN.md)
4
4
 
5
- > **离线包**,不在 npm 上:从[发布包](https://github.com/andy-mira/livemira/tree/v0.5.1/release/0.5.1)中 `npm install ./livemira-target-rating-0.5.1.tgz`。
5
+ > **npm:** `npm install @livemira/target-rating`。下文中 `files/livemira-target-rating*` 在本包的 `dist/` 下(`import { rateTargetImage } from '@livemira/target-rating'`,Worker 文件为 `@livemira/target-rating/worker`)。不需要引擎。同一个包也以离线 tarball 形式在[发布包](https://github.com/andy-mira/livemira/tree/v0.6.0/release/0.6.0)中。
6
6
 
7
7
  给扫描用的照片打分(0.5–5 星),在用户选目标图时(上传的图片,或视频的首帧、尾帧、任意一帧)提示他换一张更好的。
8
8
 
@@ -10,13 +10,13 @@
10
10
 
11
11
  ## 文件
12
12
 
13
- | 文件 | 用途 |
14
- | -------------------------------------------- | ---------------------------------------------------------------------- |
15
- | `files/livemira-target-rating.min.mjs` | 单个 ES 模块,Worker 已内嵌(约 47 KB)。 |
16
- | `files/livemira-target-rating.mjs` | 同一模块的可读版本。 |
17
- | `files/livemira-target-rating-worker.min.js` | 评分的 Worker 脚本(经典脚本),供 CSP 禁止 `blob:` Worker 的页面使用。 |
18
- | `files/livemira-target-rating.d.ts` | 类型声明。 |
19
- | `npm/livemira-target-rating-*.tgz` | 离线包 `@livemira/target-rating`(不在 npm 上,可 `npm install` 这个文件)。 |
13
+ | 文件 | 用途 |
14
+ | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
15
+ | `files/livemira-target-rating.min.mjs` | 单个 ES 模块,Worker 已内嵌(约 47 KB)。 |
16
+ | `files/livemira-target-rating.mjs` | 同一模块的可读版本。 |
17
+ | `files/livemira-target-rating-worker.min.js` | 评分的 Worker 脚本(经典脚本),供 CSP 禁止 `blob:` Worker 的页面使用。 |
18
+ | `files/livemira-target-rating.d.ts` | 类型声明。 |
19
+ | `npm/livemira-target-rating-*.tgz` | npm 包 `@livemira/target-rating` 的 tarball,用于离线安装(也可直接 `npm install @livemira/target-rating`)。 |
20
20
 
21
21
  导入模块不会创建任何东西;第一次评分时才启动 Worker,空闲 4 秒后关闭。同一时间只评一张,其余排队。
22
22
 
@@ -31,7 +31,8 @@ try {
31
31
  showStars(rating.stars); // 0.5…5,半星
32
32
  if (rating.stars < 3) suggestAnotherFrame(rating.advice);
33
33
  } catch (error) {
34
- if (error instanceof RatingError && error.code === 'UNSUITABLE_TARGET') showCannotUse(); // 引擎不会接受这张图
34
+ if (error instanceof RatingError && error.code === 'UNSUITABLE_TARGET')
35
+ showCannotUse(); // 引擎不会接受这张图
35
36
  else if (error?.code !== 'ABORTED') throw error;
36
37
  }
37
38
  ```
@@ -72,25 +73,25 @@ try {
72
73
 
73
74
  四项各 0..1:
74
75
 
75
- | 项目 | 含义 |
76
- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
77
- | `detail` 细节 | 编译器 14 个模拟视角中,至少 5 个都能检出的"稳定点"的数量(40 个以下为 0,250 个以上为满分) |
78
- | `spread` 分布 | 稳定点在画面网格(约 16 格,随长宽比)里铺开的程度:有足够点的格子占比、各格均匀度,再乘上最弱一角的系数(只要有一角几乎没有点,最多扣 40%) |
79
- | `distinctiveness` 独特性 | 稳定点中,在远处找不到相似描述子的比例;同一角点在旁边几个像素处的近亲不算 |
76
+ | 项目 | 含义 |
77
+ | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
78
+ | `detail` 细节 | 编译器 14 个模拟视角中,至少 5 个都能检出的"稳定点"的数量(40 个以下为 0,250 个以上为满分) |
79
+ | `spread` 分布 | 稳定点在画面网格(约 16 格,随长宽比)里铺开的程度:有足够点的格子占比、各格均匀度,再乘上最弱一角的系数(只要有一角几乎没有点,最多扣 40%) |
80
+ | `distinctiveness` 独特性 | 稳定点中,在远处找不到相似描述子的比例;同一角点在旁边几个像素处的近亲不算 |
80
81
  | `recognition` 实测识别 | 用引擎自己的检测器认 640 × 360 的合成画面,五项测试各由易到难:缩小(长边 160/120/90/70 px)、斜拍(45°/60°/70°)、晃动模糊(6/10/16 px)、暗光(对比降到 35%/20% 并加噪)、部分遮挡(遮住任一角或任一半);每个画面换两种握持各试一次,按内点数计余量(刚好认出只算一部分)。各项结果见 `metrics.tests` |
81
82
 
82
83
  分数 = 100 × (0.15 细节 + 0.4 分布 + 0.05 独特性 + 0.4 实测识别);星级 = 0.5 + 4.5 × (分数从 15 到 95 线性对应),并封顶于 1 + 4 × min(分布, 实测识别)^0.4,按半星取整。所以细节再多,只要挤在一处,或在合成画面里几乎认不出,也给不了高分。
83
84
 
84
85
  `advice` 按重要性列出原因:
85
86
 
86
- | 代码 | 含义 |
87
- | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
88
- | `HARD_TO_FIND` | 合成画面中多数认不出或很勉强 |
89
- | `CONCENTRATED` | 细节集中在画面的一部分 |
90
- | `WEAK_QUARTER` | 某一角几乎没有细节(`metrics.weakestQuarter`) |
91
- | `FEW_DETAILS` | 能从不同角度稳定认出的细节点偏少 |
92
- | `REPETITIVE` | 相似图案多(格子、砖墙、条纹等),容易认错位置 |
93
- | `FAILS_SMALL`、`FAILS_TILTED`、`FAILS_BLURRED`、`FAILS_DIM`、`FAILS_COVERED` | 缩小、斜拍、晃动模糊、暗光、部分遮挡这一项明显差于一般照片 |
87
+ | 代码 | 含义 |
88
+ | ---------------------------------------------------------------------------- | ---------------------------------------------------------- |
89
+ | `HARD_TO_FIND` | 合成画面中多数认不出或很勉强 |
90
+ | `CONCENTRATED` | 细节集中在画面的一部分 |
91
+ | `WEAK_QUARTER` | 某一角几乎没有细节(`metrics.weakestQuarter`) |
92
+ | `FEW_DETAILS` | 能从不同角度稳定认出的细节点偏少 |
93
+ | `REPETITIVE` | 相似图案多(格子、砖墙、条纹等),容易认错位置 |
94
+ | `FAILS_SMALL`、`FAILS_TILTED`、`FAILS_BLURRED`、`FAILS_DIM`、`FAILS_COVERED` | 缩小、斜拍、晃动模糊、暗光、部分遮挡这一项明显差于一般照片 |
94
95
 
95
96
  中文提示文字可参考示例 `demo/rate.js` 里的 `ADVICE`。`points` 是计入细节的点(目标像素坐标,`width` × `height`),可画在图上说明分布;`metrics.grid` 是各格的点数。
96
97
 
@@ -114,4 +115,4 @@ Worker、`createImageBitmap`;Worker 中的 `OffscreenCanvas` 2D 可用时在 W
114
115
 
115
116
  ## 许可
116
117
 
117
- Apache-2.0。见 [LICENSE](https://github.com/andy-mira/livemira/blob/v0.5.1/release/0.5.1/LICENSE) 与 [NOTICE](https://github.com/andy-mira/livemira/blob/v0.5.1/release/0.5.1/NOTICE)。
118
+ Apache-2.0。见 [LICENSE](https://github.com/andy-mira/livemira/blob/v0.6.0/release/0.6.0/LICENSE) 与 [NOTICE](https://github.com/andy-mira/livemira/blob/v0.6.0/release/0.6.0/NOTICE)。
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
- // LiveMira 0.5.1
2
+ // LiveMira 0.6.0
3
3
 
4
4
  /**
5
5
  * Why a picture rated as it did, most important first:
@@ -1 +1 @@
1
- var _=Object.defineProperty;var R=(n,t,e)=>t in n?_(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var o=(n,t,e)=>R(n,typeof t!="symbol"?t+"":t,e);var g="0.5.1",y=Object.freeze({version:g,buildId:"d07d146e702d07a629d46fa828db292b0a2909338e0bd671e05a59d54fa55f82",variant:"minified"});var c=class extends Error{constructor(e,r,i){super(r,i);o(this,"code");this.name="PictureError",this.code=e}};function w(n,t,e){let r=Math.min(1,e/Math.max(n,t));return[Math.max(1,Math.round(n*r)),Math.max(1,Math.round(t*r))]}function E(n,t,e){let r=new Uint8Array(t*e);for(let i=0;i<r.length;i++)r[i]=77*n[4*i]+150*n[4*i+1]+29*n[4*i+2]+128>>8;return r}async function h(n,t){let e;try{e=await createImageBitmap(n)}catch(I){throw new c("DECODE_FAILED","The picture cannot be decoded",{cause:I})}let[r,i]=w(e.width,e.height,t),s=document.createElement("canvas");s.width=r,s.height=i;let u=s.getContext("2d",{willReadFrequently:!0});u.imageSmoothingQuality="high",u.drawImage(e,0,0,r,i),e.close();let f=E(u.getImageData(0,0,r,i).data,r,i);return{width:r,height:i,data:f.buffer}}var a=class extends Error{constructor(e,r,i={}){super(r,i.cause===void 0?void 0:{cause:i.cause});o(this,"name","RatingError");o(this,"code");this.code=e}};var b=4e3,d=null;function T(){return d||(d=URL.createObjectURL(new Blob(['"use strict";(()=>{var le=Object.defineProperty;var Ae=(e,t,r)=>t in e?le(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var F=(e,t,r)=>Ae(e,typeof t!="symbol"?t+"":t,r);var X=class{constructor(){F(this,"rows",new Int32Array(0));F(this,"levels",[])}build(t,r,n=24){let o=[{...t,scale:1}];for(let l=1;l<r;l++){let c=o[l-1],s=c.width>>1,a=c.height>>1;if(s<n||a<n)break;this.rows.length<c.width*a&&(this.rows=new Int32Array(c.width*a));let i=this.levels[l]=this.levels[l]&&this.levels[l].length===s*a?this.levels[l]:new Uint8Array(s*a);me(c,s,a,this.rows,i),o.push({width:s,height:a,stride:s,data:i,scale:c.scale*2})}return{levels:o}}};function me(e,t,r,n,o){let l=e.width,c=e.height,s=e.data,a=e.stride;for(let i=0;i<r;i++){let A=2*i,u=Math.max(0,A-1)*a,m=A*a,h=Math.min(c-1,A+1)*a,g=Math.min(c-1,A+2)*a,y=i*l;for(let f=0;f<l;f++)n[y+f]=s[u+f]+3*s[m+f]+3*s[h+f]+s[g+f]}for(let i=0;i<r;i++){let A=i*l;for(let u=0;u<t;u++){let m=2*u,h=n[A+Math.max(0,m-1)],g=n[A+m],y=n[A+Math.min(l-1,m+1)],f=n[A+Math.min(l-1,m+2)];o[i*t+u]=h+3*g+3*y+f+32>>6}}}function Ct(e,t,r=24){return new X().build(e,t,r)}function tt(e,t,r){let n=t-.5,o=r-.5,l=Math.floor(n),c=Math.floor(o);if(l<0||c<0||l+1>=e.width||c+1>=e.height)return NaN;let s=n-l,a=o-c,i=e.data,A=c*e.stride+l,u=i[A]+s*(i[A+1]-i[A]),m=i[A+e.stride]+s*(i[A+e.stride+1]-i[A+e.stride]);return u+a*(m-u)}var Kt=Object.freeze({sha256:"d51fe1439175bb1343361385d7910036f36a63ed17a83311619a3b04cfa3e837",byteLength:4375,base64:"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"});function ue(e){let t=atob(e),r=new Uint8Array(t.length);for(let n=0;n<t.length;n++)r[n]=t.charCodeAt(n);return r}var et;function ut(){if(typeof WebAssembly>"u")return null;try{if(et===void 0){let e=ue(Kt.base64);et=WebAssembly.validate(e)?new WebAssembly.Module(e):null}return et?new WebAssembly.Instance(et,{}).exports:null}catch{return et=null,null}}var fe=[[0,-3],[1,-3],[2,-2],[3,-1],[3,0],[3,1],[2,2],[1,3],[0,3],[-1,3],[-2,2],[-3,1],[-3,0],[-3,-1],[-2,-2],[-1,-3]];function ye(e,t,r,n){let o=e[t],l=o+n,c=o-n,s=e[t+r[0]],a=e[t+r[8]];if(s<=l&&s>=c&&a<=l&&a>=c)return 0;let i=e[t+r[4]],A=e[t+r[12]];if(i<=l&&i>=c&&A<=l&&A>=c)return 0;let u=0,m=0,h=0,g=0;for(let y=0;y<16;y++){let f=e[t+r[y]];f>l?(u|=1<<y,h+=f-l):f<c&&(m|=1<<y,g+=c-f)}return qt(u)?h+1:qt(m)?g+1:0}function qt(e){if(!e)return!1;let t=(e|e<<16)>>>0,r=t;for(let n=1;n<9;n++)r&=t>>>n;return r!==0}var yt=class{constructor(){F(this,"backend","js");F(this,"map",new Uint16Array(0));F(this,"image",null);F(this,"offsets",new Int32Array(16))}begin(t){return this.map.length<t.width*t.height&&(this.map=new Uint16Array(t.width*t.height)),this.image=t,this.offsets=Int32Array.from(fe.map(([r,n])=>n*t.stride+r)),this.map}score(t,r,n,o,l,c){let{width:s,stride:a,data:i}=this.image;for(let A=r;A<o;A++)for(let u=t;u<n;u++){let m=ye(i,A*a+u,this.offsets,l);m>0&&(this.map[A*s+u]=m,c.push(A*s+u))}}},Qt=class{constructor(t){F(this,"backend","wasm-simd");F(this,"k");F(this,"capacity",0);F(this,"img",0);F(this,"scores",0);F(this,"found",0);F(this,"map",new Uint16Array(0));F(this,"image",null);this.k=t}begin(t){let r=t.stride*t.height;if(r>this.capacity){let n=this.k;if(n.reset_heap(),this.img=n.reserve(r+16),this.scores=n.reserve(2*r),this.found=n.reserve(4*r),!this.img||!this.scores||!this.found)throw new Error("fast9: out of memory");this.capacity=r,new Uint16Array(n.memory.buffer,this.scores,r).fill(0)}return new Uint8Array(this.k.memory.buffer,this.img,r).set(t.data.subarray(0,r)),this.map=new Uint16Array(this.k.memory.buffer,this.scores,t.width*t.height),this.image=t,this.map}score(t,r,n,o,l,c){let s=this.image,a=this.k.fast9(this.img,s.stride,t,r,n,o,l,this.scores,s.width,this.found),i=new Uint32Array(this.k.memory.buffer,this.found,a);for(let A=0;A<a;A++)c.push(i[A])}};function he(e){let n=new Uint8Array(2867),o=2654435769;for(let s=0;s<47;s++)for(let a=0;a<61;a++){o^=o<<13,o^=o>>>17,o^=o<<5;let i=(o>>>0)%64;n[s*61+a]=a<20?128:a<40?((a>>2)+(s>>2))%2?230-i:20+i:i*4}let l={width:61,height:47,stride:61,data:n},c=new yt;for(let s of[4,16,40]){let a=[],i=[],A=c.begin(l),u=e.begin(l);if(c.score(3,3,43,44,s,a),e.score(3,3,43,44,s,i),a.length!==i.length||a.some((m,h)=>m!==i[h]||A[m]!==u[m]))return!1;for(let m of a)A[m]=0;for(let m of i)u[m]=0;if(s===16&&a.length<10)return!1}return!0}var ft=null;function Yt(e=!0){if(!ft){let t=ut(),r=null;try{r=t?new Qt(t):null,r&&!he(r)&&(r=null)}catch{r=null}ft={wasm:r,js:new yt}}return e&&ft.wasm||ft.js}var _=15,ht=_+3,V=32,ge=(()=>{let e=625341585,t=()=>(e^=e<<13,e>>>=0,e^=e>>>17,e^=e<<5,e>>>=0,(e+.5)/4294967296),r=()=>Math.sqrt(-2*Math.log(t()))*Math.cos(2*Math.PI*t()),n=new Int8Array(1024);for(let o=0;o<256;){let l=[0,1,2,3].map(()=>Math.round(r()*8.5));Math.hypot(l[0],l[1])>15||Math.hypot(l[2],l[3])>15||Math.hypot(l[0]-l[2],l[1]-l[3])<2||(n.set(l,4*o),o++)}return n})(),dt=2;function de(e){return Array.from({length:V},(t,r)=>{let n=2*Math.PI*r/V,o=Math.cos(n),l=Math.sin(n),c=new Int8Array(1024);for(let s=0;s<512;s++){let a=e[2*s],i=e[2*s+1];c[2*s]=Math.round(o*a-l*i),c[2*s+1]=Math.round(l*a+o*i)}return c})}var _t=new WeakMap;function pe(e){let t=_t.get(e);if(!t){let r=e.length===1024;for(let n=0;n<512&&r;n++)r=Math.hypot(e[2*n],e[2*n+1])<=15;if(!r)throw new Error("BRIEF pattern: 256 tests with box centres within 15 px");t=de(e),_t.set(e,t)}return t}var Ie=(()=>{let e=new Int32Array(_+1);for(let t=0;t<=_;t++)e[t]=Math.floor(Math.sqrt(_*_-t*t)+.5);return e})(),gt=class{constructor(){F(this,"octaves",new X);F(this,"halfOctaves",new X);F(this,"horizontal",new Uint16Array(0));F(this,"blur",new Uint8Array(0));F(this,"half",new Uint8Array(0));F(this,"integral",new Int32Array(0))}},Jt=new gt;function be(e,t){let r=e.width,n=e.height,o=Math.floor(r/Math.SQRT2),l=Math.floor(n/Math.SQRT2),c=e.data;t.horizontal.length<r*n&&(t.horizontal=new Uint16Array(r*n),t.blur=new Uint8Array(r*n)),t.half.length!==o*l&&(t.half=new Uint8Array(o*l));let s=t.horizontal;for(let m=0;m<n;m++){let h=m*e.stride,g=m*r;s[g]=3*c[h]+c[h+1];for(let y=1;y<r-1;y++)s[g+y]=c[h+y-1]+2*c[h+y]+c[h+y+1];s[g+r-1]=c[h+r-2]+3*c[h+r-1]}let a=t.blur;for(let m=0;m<n;m++){let h=Math.max(0,m-1)*r,g=m*r,y=Math.min(n-1,m+1)*r;for(let f=0;f<r;f++)a[g+f]=s[h+f]+2*s[g+f]+s[y+f]+8>>4}let i=new Int32Array(o),A=new Float32Array(o);for(let m=0;m<o;m++){let h=(m+.5)*Math.SQRT2-.5;i[m]=Math.min(r-2,Math.max(0,Math.floor(h))),A[m]=h-i[m]}let u=t.half;for(let m=0;m<l;m++){let h=(m+.5)*Math.SQRT2-.5,g=Math.min(n-2,Math.max(0,Math.floor(h))),y=h-g,f=g*r,d=f+r;for(let p=0;p<o;p++){let x=i[p],b=A[p],M=a[f+x]+b*(a[f+x+1]-a[f+x]),I=a[d+x]+b*(a[d+x+1]-a[d+x]);u[m*o+p]=M+y*(I-M)+.5|0}}return{width:o,height:l,stride:o,data:u}}function we(e,t,r=new gt){let n=Math.ceil(t/2),o=r.octaves.build(e,n,24).levels,l=r.halfOctaves.build(be(e,r),n,24).levels,c=[];for(let s=0;s<n;s++)o[s]&&c.push({image:o[s],scale:2**s}),l[s]&&c.push({image:l[s],scale:Math.SQRT2*2**s});return c.slice(0,t)}function xe(e,t,r,n){let o=0,l=0,c=0;for(let s=-3;s<=3;s++)for(let a=-3;a<=3;a++){let i=(n+s)*t+r+a,A=e[i+1]-e[i-1],u=e[i+t]-e[i-t];o+=A*A,l+=u*u,c+=A*u}return o*l-c*c-.04*(o+l)**2}function Ee(e,t){let r=e.width+1;t.integral.length<r*(e.height+1)&&(t.integral=new Int32Array(r*(e.height+1)));let n=t.integral;n.fill(0,0,r);for(let o=0;o<e.height;o++){n[(o+1)*r]=0;let l=0;for(let c=0;c<e.width;c++)l+=e.data[o*e.stride+c],n[(o+1)*r+c+1]=n[o*r+c+1]+l}return n}function Me(e,t,r,n,o){let{width:l,height:c,stride:s,data:a}=e,i=r.cell,A=[],u=Math.max(ht,Math.floor(n.x0)),m=Math.max(ht,Math.floor(n.y0)),h=Math.min(l-ht,Math.ceil(n.x1)),g=Math.min(c-ht,Math.ceil(n.y1));if(h<=u||g<=m)return A;let y=o.begin(e),f=[];for(let d=m;d<g;d+=i)for(let p=u;p<h;p+=i){let x=Math.min(g,d+i),b=Math.min(h,p+i);f.length=0;let M=255,I=0;for(let E=d;E<x;E+=2)for(let B=p;B<b;B+=2){let C=a[E*s+B];C<M&&(M=C),C>I&&(I=C)}if(I-M<2*r.minFastThreshold)continue;for(let E=r.fastThreshold;o.score(p,d,b,x,E,f),!(f.length>=2||E===r.minFastThreshold);E=r.minFastThreshold){for(let B of f)y[B]=0;f.length=0}let w=[];for(let E of f){let B=y[E],C=!0;for(let P=-1;P<=1&&C;P++)for(let k=-1;k<=1;k++){if(!k&&!P)continue;let v=y[E+P*l+k];if(v>B||v===B&&(P<0||P===0&&k<0)){C=!1;break}}C&&w.push({i:E,s:B})}for(let E of f)y[E]=0;w.sort((E,B)=>B.s-E.s||E.i-B.i);let Q=[];for(let E of w.slice(0,8)){let B=E.i%l,C=(E.i-B)/l,P=xe(a,s,B,C);P>0&&Q.push({x:B,y:C,score:P})}Q.sort((E,B)=>B.score-E.score||E.y-B.y||E.x-B.x),A.push(...Q.slice(0,2))}return A.sort((d,p)=>p.score-d.score||d.y-p.y||d.x-p.x),A.slice(0,t)}function Be(e,t,r){let n=e.data,o=e.stride,l=0,c=0,s=r*o+t;for(let a=-_;a<=_;a++)c+=a*n[s+a];for(let a=1;a<=_;a++){let i=0,A=Ie[a];for(let u=-A;u<=A;u++){let m=n[s-a*o+u],h=n[s+a*o+u];i+=h-m,c+=u*(m+h)}l+=a*i}return Math.atan2(l,c)}function Ce(e){return(Math.round(e*V/(2*Math.PI))%V+V)%V}function Qe(e,t,r,n,o,l,c,s){let a=l[Ce(o)],i=(n-2)*t+(r-2),A=5*t;for(let u=0;u<32;u++){let m=0;for(let h=0;h<8;h++){let g=4*(8*u+h),y=i+a[g+1]*t+a[g],f=i+a[g+3]*t+a[g+2],d=e[y+A+5]-e[y+5]-e[y+A]+e[y],p=e[f+A+5]-e[f+5]-e[f+A]+e[f];d<p&&(m|=1<<h)}c[s+u]=m}}function rt(e,t={}){let r=t.budget??700,n=we(e,t.levels??6,Jt),o={fastThreshold:t.fastThreshold??16,minFastThreshold:t.minFastThreshold??4,cell:t.cell??24},l=Yt(t.wasm!==!1),c=pe(t.pattern??ge),s=n.reduce((d,p)=>d+p.image.width*p.image.height,0),a=t.roi??{x:0,y:0,width:e.width,height:e.height},i=[],A=[],u=[],m=[],h=[],g=[];n.forEach((d,p)=>{let x=Math.max(16,Math.round(r*d.image.width*d.image.height/s)),b=d.scale,M=Me(d.image,x,o,{x0:a.x/b,y0:a.y/b,x1:(a.x+a.width)/b,y1:(a.y+a.height)/b},l);if(!M.length)return;let I=Ee(d.image,Jt),w=new Uint8Array(32*M.length);M.forEach((Q,E)=>{let B=Be(d.image,Q.x,Q.y);Qe(I,d.image.width+1,Q.x,Q.y,B,c,w,32*E),i.push((Q.x+.5)*b),A.push((Q.y+.5)*b),u.push(p),m.push(B),h.push(Q.score)}),g.push(w)});let y=new Uint8Array(32*i.length),f=0;for(let d of g)y.set(d,f),f+=d.length;return{count:i.length,x:Float32Array.from(i),y:Float32Array.from(A),level:Uint8Array.from(u),angle:Float32Array.from(m),score:Float32Array.from(h),descriptors:y,descriptorBytes:32}}function Ue(e,t,r){let n=r*Math.PI/180,o=Math.cos(n),l=Math.sin(n),c=o*o/t+l*l,s=o*l/t-o*l,a=l*l/t+o*o,i=[[0,0],[e.width,0],[e.width,e.height],[0,e.height]].map(([I,w])=>[c*I+s*w,s*I+a*w]),A=Math.min(...i.map(I=>I[0])),u=Math.min(...i.map(I=>I[1])),m=Math.ceil(Math.max(...i.map(I=>I[0]))-A),h=Math.ceil(Math.max(...i.map(I=>I[1]))-u),g=[c,s,-A,s,a,-u],y=.8*Math.sqrt(Math.max(0,t*t-1)),f=y>.3?jt(e,y):e,d=c*a-s*s,p=a/d,x=-s/d,b=c/d,M=new Uint8Array(m*h).fill(128);for(let I=0;I<h;I++)for(let w=0;w<m;w++){let Q=w+.5-g[2],E=I+.5-g[5],B=p*Q+x*E-.5,C=x*Q+b*E-.5,P=Math.floor(B),k=Math.floor(C);if(P<0||k<0||P+1>=e.width||k+1>=e.height)continue;let v=B-P,T=C-k,D=k*f.stride+P,R=f.data,L=R[D]+v*(R[D+1]-R[D]),O=R[D+f.stride]+v*(R[D+f.stride+1]-R[D+f.stride]);M[I*m+w]=Math.round(L+T*(O-L))}return{image:{width:m,height:h,stride:m,data:M},A:g}}function jt(e,t){let r=Math.ceil(3*t),n=Array.from({length:2*r+1},(a,i)=>Math.exp(-((i-r)**2)/(2*t*t))),o=n.reduce((a,i)=>a+i,0),l=n.map(a=>a/o),c=new Float32Array(e.width*e.height);for(let a=0;a<e.height;a++)for(let i=0;i<e.width;i++){let A=0;for(let u=-r;u<=r;u++)A+=l[u+r]*e.data[a*e.stride+Math.min(e.width-1,Math.max(0,i+u))];c[a*e.width+i]=A}let s=new Uint8Array(e.width*e.height);for(let a=0;a<e.height;a++)for(let i=0;i<e.width;i++){let A=0;for(let u=-r;u<=r;u++)A+=l[u+r]*c[Math.min(e.height-1,Math.max(0,a+u))*e.width+i];s[a*e.width+i]=Math.round(A)}return{width:e.width,height:e.height,stride:e.width,data:s}}function Fe(e,t,r,n){let o=0;for(let l=0;l<32;l++){let c=e[t+l]^r[n+l];for(;c;)c&=c-1,o++}return o}function nt(e,t={}){let r=t.tilts??[1.4,2,2.8],n=t.longitudes??[0,45,90,135],o=[{image:e.image,A:[1,0,0,0,1,0]}];for(let d of r)for(let p of n)o.push(Ue(e.image,d,p));for(let d of t.blurs??[2.5])o.push({image:jt(e.image,d),A:[1,0,0,0,1,0]});let l=[],c=new Map,s=4,a=(d,p)=>Math.floor(p/s)*65536+Math.floor(d/s);o.forEach((d,p)=>{let x=rt(d.image,{budget:900,...t.orb}),[b,M,I,w,Q,E]=d.A,B=b*Q-M*w;for(let C=0;C<x.count;C++){let P=x.x[C]-I,k=x.y[C]-E,v=(Q*P-M*k)/B,T=(-w*P+b*k)/B;if(v<0||T<0||v>=e.info.width||T>=e.info.height)continue;let D=2+1.5*(2**(x.level[C]/2)-1),R=-1;for(let O=-1;O<=1&&R<0;O++)for(let N=-1;N<=1&&R<0;N++)for(let W of c.get(a(v+N*s,T+O*s))??[]){let S=l[W];if(Math.hypot(S.x-v,S.y-T)<=D){R=W;break}}let L=x.descriptors.slice(32*C,32*C+32);if(R<0){l.push({x:v,y:T,n:1,views:new Set([p]),score:x.score[C],desc:[L]});let O=a(v,T);c.set(O,[...c.get(O)??[],l.length-1])}else{let O=l[R];O.views.add(p),O.n++,O.score=Math.max(O.score,x.score[C]),O.desc.push(L)}}});let i=t.maxPoints??700,A=t.descriptorsPerPoint??3,u=l.map((d,p)=>({g:d,i:p})).sort((d,p)=>p.g.views.size-d.g.views.size||p.g.score-d.g.score||d.i-p.i).slice(0,i).map(d=>d.g),m=new Float32Array(2*u.length),h=new Uint8Array(u.length),g=[],y=[];u.forEach((d,p)=>{m[2*p]=d.x,m[2*p+1]=d.y,h[p]=d.views.size;let x=[];for(let b of d.desc){if(x.length>=A)break;x.every(M=>Fe(M,0,b,0)>24)&&x.push(b)}for(let b of x)g.push(b),y.push(p)});let f=new Uint8Array(32*g.length);return g.forEach((d,p)=>f.set(d,32*p)),{info:e.info,points:m,repeatability:h,descriptors:f,descriptorPoint:Uint32Array.from(y)}}function ot(e,t,r){let n=e[6]*t+e[7]*r+e[8];return Math.abs(n)<1e-12?[NaN,NaN]:[(e[0]*t+e[1]*r+e[2])/n,(e[3]*t+e[4]*r+e[5])/n]}function at(e,t,r){return[ot(e,0,0),ot(e,t,0),ot(e,t,r),ot(e,0,r)]}function pt(e,t,r){for(let n=0;n<r;n++){let o=n,l=Math.abs(e[n*r+n]);for(let s=n+1;s<r;s++){let a=Math.abs(e[s*r+n]);a>l&&(l=a,o=s)}if(l<1e-12)return!1;if(o!==n){for(let a=0;a<r;a++){let i=e[n*r+a];e[n*r+a]=e[o*r+a],e[o*r+a]=i}let s=t[n];t[n]=t[o],t[o]=s}let c=e[n*r+n];for(let s=n+1;s<r;s++){let a=e[s*r+n]/c;if(a!==0){for(let i=n;i<r;i++)e[s*r+i]-=a*e[n*r+i];t[s]-=a*t[n]}}}for(let n=r-1;n>=0;n--){let o=t[n];for(let l=n+1;l<r;l++)o-=e[n*r+l]*t[l];t[n]=o/e[n*r+n]}return t.every(Number.isFinite)}function Xt(e,t){let r=new Float64Array(e),n=new Float64Array(t*t);for(let o=0;o<t;o++)n[o*t+o]=1;for(let o=0;o<t;o++){let l=o;for(let s=o+1;s<t;s++)Math.abs(r[s*t+o])>Math.abs(r[l*t+o])&&(l=s);if(Math.abs(r[l*t+o])<1e-15)return null;if(l!==o)for(let s=0;s<t;s++){let a=r[o*t+s];r[o*t+s]=r[l*t+s],r[l*t+s]=a,a=n[o*t+s],n[o*t+s]=n[l*t+s],n[l*t+s]=a}let c=r[o*t+o];for(let s=0;s<t;s++)r[o*t+s]/=c,n[o*t+s]/=c;for(let s=0;s<t;s++){if(s===o)continue;let a=r[s*t+o];if(a!==0)for(let i=0;i<t;i++)r[s*t+i]-=a*r[o*t+i],n[s*t+i]-=a*n[o*t+i]}}return n}function zt(e,t){let r=new Float64Array(e),n=new Float64Array(t*t);for(let c=0;c<t;c++)n[c*t+c]=1;for(let c=0;c<50;c++){let s=0;for(let a=0;a<t;a++)for(let i=a+1;i<t;i++)s+=r[a*t+i]**2;if(s<1e-24)break;for(let a=0;a<t;a++)for(let i=a+1;i<t;i++){let A=r[a*t+i];if(Math.abs(A)<1e-300)continue;let u=(r[i*t+i]-r[a*t+a])/(2*A),m=Math.sign(u||1)/(Math.abs(u)+Math.sqrt(u*u+1)),h=1/Math.sqrt(m*m+1),g=m*h;for(let y=0;y<t;y++){let f=r[y*t+a],d=r[y*t+i];r[y*t+a]=h*f-g*d,r[y*t+i]=g*f+h*d}for(let y=0;y<t;y++){let f=r[a*t+y],d=r[i*t+y];r[a*t+y]=h*f-g*d,r[i*t+y]=g*f+h*d}for(let y=0;y<t;y++){let f=n[y*t+a],d=n[y*t+i];n[y*t+a]=h*f-g*d,n[y*t+i]=g*f+h*d}}}let o=0;for(let c=1;c<t;c++)r[c*t+c]<r[o*t+o]&&(o=c);let l=new Float64Array(t);for(let c=0;c<t;c++)l[c]=n[c*t+o];return l}function Ft(e,t){let r=new Float64Array(9);for(let n=0;n<3;n++)for(let o=0;o<3;o++)r[n*3+o]=e[n*3]*t[o]+e[n*3+1]*t[3+o]+e[n*3+2]*t[6+o];return r}function vt(e){let[t,r,n,o,l,c,s,a,i]=[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]],A=[l*i-c*a,n*a-r*i,r*c-n*l,c*s-o*i,t*i-n*s,n*o-t*c,o*a-l*s,r*s-t*a,t*l-r*o],u=t*A[0]+r*A[3]+n*A[6];return!Number.isFinite(u)||Math.abs(u)<1e-300?null:Float64Array.from(A,m=>m/u)}function Vt(e){let t=e[8];if(!Number.isFinite(t)||Math.abs(t)<1e-12)return null;for(let r=0;r<9;r++)e[r]/=t;return e.every(Number.isFinite)?e:null}function wt(e,t,r){let n=0,o=0;for(let c=0;c<r;c++){let s=t[c];n+=e[2*s],o+=e[2*s+1]}n/=r,o/=r;let l=0;for(let c=0;c<r;c++){let s=t[c];l+=Math.hypot(e[2*s]-n,e[2*s+1]-o)}return l/=r,l<1e-9?null:[Math.SQRT2/l,n,o]}function Zt(e,t,r){let[n,o,l]=t,[c,s,a]=r,i=[n,0,-n*o,0,n,-n*l,0,0,1],A=[1/c,0,s,0,1/c,a,0,0,1];return Vt(Ft(Ft(A,e),i))}function Pt(e,t,r,n,o){if(n<4)return null;let l=wt(e,r,n),c=wt(t,r,n);if(!l||!c)return null;let s=new Float64Array(81),a=new Float64Array(9);for(let i=0;i<n;i++){let A=r[i],u=o?o[A]:1;if(u<=0)continue;let m=l[0]*(e[2*A]-l[1]),h=l[0]*(e[2*A+1]-l[2]),g=c[0]*(t[2*A]-c[1]),y=c[0]*(t[2*A+1]-c[2]);for(let f=0;f<2;f++){f===0?a.set([m,h,1,0,0,0,-g*m,-g*h,-g]):a.set([0,0,0,m,h,1,-y*m,-y*h,-y]);for(let d=0;d<9;d++){let p=a[d]*u;if(p!==0)for(let x=d;x<9;x++)s[d*9+x]+=p*a[x]}}}for(let i=0;i<9;i++)for(let A=0;A<i;A++)s[i*9+A]=s[A*9+i];return Zt(zt(s,9),l,c)}var It=new Float64Array(64),bt=new Float64Array(8);function st(e,t,r){let n=wt(e,r,4),o=wt(t,r,4);if(!n||!o)return null;It.fill(0);for(let l=0;l<4;l++){let c=r[l],s=n[0]*(e[2*c]-n[1]),a=n[0]*(e[2*c+1]-n[2]),i=o[0]*(t[2*c]-o[1]),A=o[0]*(t[2*c+1]-o[2]);It.set([s,a,1,0,0,0,-i*s,-i*a],16*l),It.set([0,0,0,s,a,1,-A*s,-A*a],16*l+8),bt[2*l]=i,bt[2*l+1]=A}return pt(It,bt,8)?Zt([...bt,1],n,o):null}function $t(e,t,r,n){let o=e[6]*t+e[7]*r+e[8];return o>1e-12?(n[0]=(e[0]*t+e[1]*r+e[2])/o,n[1]=(e[3]*t+e[4]*r+e[5])/o,!0):!1}var J=new Float64Array(8),Ut=new Float64Array(2);function it(e,t,r,n=64,o=30){let l=[0,t,t,0],c=[0,0,r,r];for(let A=0;A<4;A++){if(!$t(e,l[A],c[A],Ut))return!1;J[2*A]=Ut[0],J[2*A+1]=Ut[1]}let s=0,a=1/0,i=0;for(let A=0;A<4;A++){let u=J[2*A],m=J[2*A+1],h=J[(2*A+2)%8],g=J[(2*A+3)%8],y=J[(2*A+4)%8],f=J[(2*A+5)%8];if((h-u)*(f-g)-(g-m)*(y-h)<=0)return!1;s+=u*g-h*m;let d=Math.hypot(h-u,g-m);a=Math.min(a,d),i=Math.max(i,d)}return s/2>=n&&i<=o*Math.max(a,1e-9)}function Tt(e,t,r){let n=[];for(let i=0;i<r;i++)(!t||t[i])&&n.push([e[2*i],e[2*i+1]]);if(n.length<3)return 0;n.sort((i,A)=>i[0]-A[0]||i[1]-A[1]);let o=(i,A,u)=>(A[0]-i[0])*(u[1]-i[1])-(A[1]-i[1])*(u[0]-i[0]),l=[];for(let i of n){for(;l.length>=2&&o(l.at(-2),l.at(-1),i)<=0;)l.pop();l.push(i)}let c=[];for(let i=n.length-1;i>=0;i--){let A=n[i];for(;c.length>=2&&o(c.at(-2),c.at(-1),A)<=0;)c.pop();c.push(A)}let s=[...l.slice(0,-1),...c.slice(0,-1)],a=0;for(let i=0;i<s.length;i++){let A=s[i],u=s[(i+1)%s.length];a+=A[0]*u[1]-u[0]*A[1]}return Math.abs(a)/2}var ve=(e,t)=>e<=t?1:t/e;function Rt(e,t,r,n,o,l={}){let c=l.iterations??8,s=l.huberPx??1.5,a=Float64Array.from(e.subarray(0,8)),i=.001,A=new Float64Array(64),u=new Float64Array(8),m=new Float64Array(8),h=new Float64Array(8),g=b=>{let M=0;for(let I=0;I<o;I++){if(!n[I])continue;let w=t[2*I],Q=t[2*I+1],E=b[6]*w+b[7]*Q+1;if(!(E>1e-12))return 1/0;let B=(b[0]*w+b[1]*Q+b[2])/E-r[2*I],C=(b[3]*w+b[4]*Q+b[5])/E-r[2*I+1],P=Math.hypot(B,C);M+=P<=s?P*P:2*s*P-s*s}return M},y=g(a);for(let b=0;b<c;b++){A.fill(0),u.fill(0);for(let I=0;I<o;I++){if(!n[I])continue;let w=t[2*I],Q=t[2*I+1],E=a[6]*w+a[7]*Q+1,B=(a[0]*w+a[1]*Q+a[2])/E,C=(a[3]*w+a[4]*Q+a[5])/E,P=B-r[2*I],k=C-r[2*I+1],v=ve(Math.hypot(P,k),s);m.set([w/E,Q/E,1/E,0,0,0,-B*w/E,-B*Q/E]),h.set([0,0,0,w/E,Q/E,1/E,-C*w/E,-C*Q/E]);for(let T=0;T<8;T++){u[T]+=v*(m[T]*P+h[T]*k);for(let D=T;D<8;D++)A[T*8+D]+=v*(m[T]*m[D]+h[T]*h[D])}}for(let I=0;I<8;I++)for(let w=0;w<I;w++)A[I*8+w]=A[w*8+I];let M=!1;for(let I=0;I<4&&!M;I++){let w=new Float64Array(A);for(let C=0;C<8;C++)w[C*9]*=1+i;let Q=Float64Array.from(u,C=>-C);if(!pt(w,Q,8)){i*=10;continue}let E=Float64Array.from(a,(C,P)=>C+Q[P]),B=g(E);B<y?(a=E,y=B,i=Math.max(1e-7,i/10),M=!0):i*=10}if(!M)break}let f=0,d=0;A.fill(0);for(let b=0;b<o;b++){if(!n[b])continue;let M=t[2*b],I=t[2*b+1],w=a[6]*M+a[7]*I+1,Q=(a[0]*M+a[1]*I+a[2])/w,E=(a[3]*M+a[4]*I+a[5])/w;d+=(Q-r[2*b])**2+(E-r[2*b+1])**2,f++,m.set([M/w,I/w,1/w,0,0,0,-Q*M/w,-Q*I/w]),h.set([0,0,0,M/w,I/w,1/w,-E*M/w,-E*I/w]);for(let B=0;B<8;B++)for(let C=0;C<8;C++)A[B*8+C]+=m[B]*m[C]+h[B]*h[C]}let p=f>4?d/(2*f-8):d,x=Xt(A,8);return{H:Float64Array.from([...a,1]),rmsPx:f?Math.sqrt(d/f):1/0,paramCovariance:x?x.map(b=>b*p):null}}function Pe(e){let t=e>>>0||625341585;return()=>(t^=t<<13,t>>>=0,t^=t>>>17,t^=t<<5,t>>>=0,t)}function Gt(e,t,r,n,o,l){let c=0,s=0;for(let a=0;a<n;a++){let i=t[2*a],A=t[2*a+1],u=e[6]*i+e[7]*A+e[8],m=o;if(u>1e-12){let g=(e[0]*i+e[1]*A+e[2])/u-r[2*a],y=(e[3]*i+e[4]*A+e[5])/u-r[2*a+1];m=Math.min(o,g*g+y*y)}let h=m<o;l[a]=h?1:0,h&&s++,c+=m}return{score:c,inliers:s}}function Te(e,t){let r=0;for(let o=0;o<t;o++)e[o]&&r++;let n=new Int32Array(r);for(let o=0,l=0;o<t;o++)e[o]&&(n[l++]=o);return n}function xt(e,t,r,n){let o=(e[2*r]-e[2*t])*(e[2*n+1]-e[2*t+1])-(e[2*r+1]-e[2*t+1])*(e[2*n]-e[2*t]);return Math.abs(o)<.001*(1+Math.abs(e[2*t])+Math.abs(e[2*r]))}function kt(e,t,r,n,o,l={}){let c=l.thresholdPx??3,s=c*c,a=l.confidence??.995,i=l.maxIterations??500,A=l.minInliers??12,u=l.minInlierRatio??.2,m=l.minCoverage??.08;if(r<Math.max(4,A))return{accepted:!1,reason:"INSUFFICIENT_MATCHES",iterations:0};let h=Pe(l.seed??12345),g=new Uint8Array(r),y=new Uint8Array(r),f=null,d=1/0,p=0,x=i,b=4,M=i;for(let v=0;v<4;v++)M*=(b-v)/(r-v);let I=1,w=new Int32Array(4),Q=0,E=v=>{if(!v||!it(v,n,o))return;let{score:T,inliers:D}=Gt(v,e,t,r,s,g);if(T>=d)return;f=v,d=T,p=D,y.set(g);for(let O=0;O<3&&p>=8;O++){let N=Pt(e,t,Te(y,r),p);if(!N||!it(N,n,o))break;let W=Gt(N,e,t,r,s,g);if(W.score>=d)break;f=N,d=W.score,p=W.inliers,y.set(g)}let R=p/r,L=Math.log(1-a)/Math.log(Math.max(1e-12,1-R**4));x=Math.min(i,Math.max(16,Math.ceil(L)))};for(;Q<x;){if(Q++,Q>=I&&b<r){let W=M*(b+1)/(b+1-4);b++,I+=Math.ceil(W-M),M=W}let v=I>Q?b-1:b,T=0;I>Q&&(w[T++]=b-1);let D=0;for(;T<4&&D++<64;){let W=h()%v,S=!1;for(let U=0;U<T;U++)w[U]===W&&(S=!0);S||(w[T++]=W)}if(T<4)continue;let[R,L,O,N]=[w[0],w[1],w[2],w[3]];xt(e,R,L,O)||xt(e,R,L,N)||xt(e,R,O,N)||xt(e,L,O,N)||E(st(e,t,w))}if(!f||p<A)return{accepted:!1,reason:"NO_MODEL",iterations:Q};let B=f,C=Rt(B,e,t,y,r,{huberPx:c/2});for(let v=0;v<2;v++){if(!it(C.H,n,o))return{accepted:!1,reason:"IMPLAUSIBLE_MODEL",iterations:Q};B=C.H,p=Gt(B,e,t,r,s,y).inliers,v===0&&(C=Rt(B,e,t,y,r,{huberPx:c/2}))}let P=p/r;if(p<A||P<u)return{accepted:!1,reason:"LOW_INLIER_SUPPORT",iterations:Q};let k=Tt(e,y,r)/(n*o);return k<m?{accepted:!1,reason:"LOW_SPATIAL_COVERAGE",iterations:Q}:{accepted:!0,H:B,mask:y,inliers:p,ratio:P,rmsPx:C.rmsPx,coverage:k,paramCovariance:C.paramCovariance,iterations:Q}}var te=844385612;function Re(e,t,r){if(e.width===t&&e.height===r)return e;let n=new Uint8Array(t*r),o=e.width/t,l=e.height/r;for(let c=0;c<r;c++){let s=Math.min(e.height-1.001,Math.max(0,(c+.5)*l-.5)),a=Math.floor(s),i=s-a;for(let A=0;A<t;A++){let u=Math.min(e.width-1.001,Math.max(0,(A+.5)*o-.5)),m=Math.floor(u),h=u-m,g=a*e.stride+m,y=e.data,f=y[g]+h*(y[g+1]-y[g]),d=y[g+e.stride]+h*(y[g+e.stride+1]-y[g+e.stride]);n[c*t+A]=Math.round(f+i*(d-f))}}return{width:t,height:r,stride:t,data:n}}function Ge(e,t){let r=Math.max(e.width,e.height)/t;if(r<=1)return e;let n=Math.round(e.width/r),o=Math.round(e.height/r),l=new Uint8Array(n*o);for(let c=0;c<o;c++)for(let s=0;s<n;s++){let a=Math.floor(s*r),i=Math.max(a+1,Math.floor((s+1)*r)),A=Math.floor(c*r),u=Math.max(A+1,Math.floor((c+1)*r)),m=0;for(let h=A;h<u;h++)for(let g=a;g<i;g++)m+=e.data[h*e.stride+g];l[c*n+s]=Math.round(m/((i-a)*(u-A)))}return{width:n,height:o,stride:n,data:l}}async function ct(e,t,r={}){let n=Ge(t,r.templateMaxEdge??480),o=new TextEncoder().encode(e.info.id),l=e.points.length/2,c=e.descriptorPoint.length,s=10+o.length+8+8+8*l+l+4*c+32*c+4+n.width*n.height,a=new Uint8Array(s+32),i=new DataView(a.buffer),A=0;i.setUint32(A,te,!0),i.setUint16(A+4,2,!0),i.setUint16(A+6,dt,!0),A+=8,i.setUint16(A,o.length,!0),a.set(o,A+2),A+=2+o.length,i.setUint16(A,e.info.width,!0),i.setUint16(A+2,e.info.height,!0),i.setFloat32(A+4,e.info.physicalWidthMeters??NaN,!0),A+=8,i.setUint32(A,l,!0),i.setUint32(A+4,c,!0),A+=8;for(let m=0;m<2*l;m++,A+=4)i.setFloat32(A,e.points[m],!0);a.set(e.repeatability,A),A+=l;for(let m=0;m<c;m++,A+=4)i.setUint32(A,e.descriptorPoint[m],!0);a.set(e.descriptors,A),A+=32*c,i.setUint16(A,n.width,!0),i.setUint16(A+2,n.height,!0),A+=4;for(let m=0;m<n.height;m++)a.set(n.data.subarray(m*n.stride,m*n.stride+n.width),A+m*n.width);A+=n.width*n.height;let u=new Uint8Array(await crypto.subtle.digest("SHA-256",a.subarray(0,A)));return a.set(u,A),a}async function Z(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=M=>{throw new Error(`Invalid target asset: ${M}`)};(e.length<64||t.getUint32(0,!0)!==te||t.getUint16(4,!0)!==2)&&r("header");let n=t.getUint16(6,!0)&255;n!==dt&&r(`descriptor pattern v${n}, this engine uses v${dt}; recompile the target`);let o=e.subarray(0,e.length-32);new Uint8Array(await crypto.subtle.digest("SHA-256",new Uint8Array(o))).every((M,I)=>M===e[e.length-32+I])||r("checksum");let c=8,s=t.getUint16(c,!0),a=new TextDecoder().decode(e.subarray(c+2,c+2+s));c+=2+s;let i=t.getUint16(c,!0),A=t.getUint16(c+2,!0),u=t.getFloat32(c+4,!0);c+=8;let m=t.getUint32(c,!0),h=t.getUint32(c+4,!0);c+=8;let g=new Float32Array(2*m);for(let M=0;M<2*m;M++,c+=4)g[M]=t.getFloat32(c,!0);let y=e.slice(c,c+m);c+=m;let f=new Uint32Array(h);for(let M=0;M<h;M++,c+=4)f[M]=t.getUint32(c,!0);let d=e.slice(c,c+32*h);c+=32*h;let p=t.getUint16(c,!0),x=t.getUint16(c+2,!0);c+=4;let b={width:p,height:x,stride:p,data:e.slice(c,c+p*x)};return{compiled:{info:{id:a,width:i,height:A,physicalWidthMeters:Number.isNaN(u)?null:u},points:g,repeatability:y,descriptors:d,descriptorPoint:f},template:Re(b,i,A)}}function Ot(e,t){let r=e.length/32,n=t.length/32,o=new Uint32Array(3*r),l=new Uint32Array(e.buffer,e.byteOffset,e.length/4),c=new Uint32Array(t.buffer,t.byteOffset,t.length/4);for(let s=0;s<r;s++){let a=257,i=257,A=4294967295,u=8*s;for(let m=0;m<n;m++){let h=8*m,g=0;for(let y=0;y<8;y++){let f=(l[u+y]^c[h+y])>>>0;f-=f>>>1&1431655765,f=(f&858993459)+(f>>>2&858993459),g+=(f+(f>>>4)&252645135)*16843009>>>24}g<a?(i=a,a=g,A=m):g<i&&(i=g)}o[3*s]=A,o[3*s+1]=a,o[3*s+2]=i}return o}function Dt(e,t,r){let n=e.length/32,o=t.length/32,l=new Uint32Array(3*n),c=new Uint32Array(e.buffer,e.byteOffset,e.length/4),s=new Uint32Array(t.buffer,t.byteOffset,t.length/4);for(let a=0;a<n;a++){let i=257,A=4294967295,u=257,m=4294967295,h=8*a;for(let g=0;g<o;g++){let y=8*g,f=0;for(let p=0;p<8;p++){let x=(c[h+p]^s[y+p])>>>0;x-=x>>>1&1431655765,x=(x&858993459)+(x>>>2&858993459),f+=(x+(x>>>4)&252645135)*16843009>>>24}let d=r[g];d===A?f<i&&(i=f,m=g):f<i?(u=i,i=f,A=d,m=g):f<u&&(u=f)}l[3*a]=m,l[3*a+1]=i,l[3*a+2]=u}return l}var Et=class e{constructor(t){F(this,"backend");F(this,"kernel");this.kernel=t,this.backend=t?"wasm-simd":"js"}static create(t={}){let r=t.allowWasm===!1?null:ut();if(!r)return new e(null);try{let n=new e(r);return n.selfTest()?n:new e(null)}catch{return new e(null)}}selfTest(){let t=19088743,r=A=>Uint8Array.from({length:A},()=>(t^=t<<13,t^=t>>>17,t^=t<<5,t&255)),n=r(1184),o=new Uint8Array(352);o.set(r(320)),o.set(n.subarray(160,192),320);let l=Ot(o,n),c=this.nearest2(o,n),s=Uint32Array.from({length:37},(A,u)=>u>>1),a=Dt(o,n,s),i=this.nearest2Grouped(o,n,s);return c.length===l.length&&c.every((A,u)=>A===l[u])&&i.length===a.length&&i.every((A,u)=>A===a[u])}nearest2(t,r){let n=this.kernel;if(!n)return Ot(t,r);let o=t.length/32,l=r.length/32;n.reset_heap();let c=n.reserve(t.length),s=n.reserve(r.length),a=n.reserve(12*o);return!c||!s||!a?Ot(t,r):(new Uint8Array(n.memory.buffer).set(t,c),new Uint8Array(n.memory.buffer).set(r,s),n.nearest2(c,o,s,l,a),new Uint32Array(n.memory.buffer.slice(a,a+12*o)))}nearest2Grouped(t,r,n){let o=this.kernel;if(!o)return Dt(t,r,n);let l=t.length/32;o.reset_heap();let c=o.reserve(t.length),s=o.reserve(r.length),a=o.reserve(n.byteLength),i=o.reserve(12*l);if(!c||!s||!a||!i)return Dt(t,r,n);let A=o.memory.buffer;return new Uint8Array(A).set(t,c),new Uint8Array(A).set(r,s),new Uint8Array(A).set(new Uint8Array(n.buffer,n.byteOffset,n.byteLength),a),o.nearest2_grouped(c,l,s,a,r.length/32,i),new Uint32Array(o.memory.buffer.slice(i,i+12*l))}};var ke=e=>Math.max(700,Math.round(700*e.width*e.height/(640*360))),Oe=36e4;function De(e,t,r,n){let o=Math.min(r,3,Math.sqrt(Oe/(t.width*t.height)));if(o<1.2)return null;let l=Math.round(t.width*o),c=Math.round(t.height*o),s=new Uint8Array(l*c),a=e.width-1.001,i=e.height-1.001;for(let u=0;u<c;u++){let m=Math.min(i,Math.max(.5,t.y+(u+.5)/o));for(let h=0;h<l;h++)s[u*l+h]=Math.round(tt(e,Math.min(a,Math.max(.5,t.x+(h+.5)/o)),m))}let A=rt({width:l,height:c,stride:l,data:s},{budget:500,...n});return{...A,x:A.x.map(u=>t.x+(u+.5)/o-.5),y:A.y.map(u=>t.y+(u+.5)/o-.5)}}var lt=class{constructor(t={}){F(this,"info",{id:"C1.orb-views",layer:"L2",route:"light",determinism:"bit-exact",requires:[]});F(this,"options");F(this,"matcher");F(this,"targets",[]);this.options=t,this.matcher=Et.create(t.allowWasm===!1?{allowWasm:!1}:{})}get backend(){return this.matcher.backend}probe(t){return{isAvailable:!0}}async load(t){let r=[];this.targets=[];for(let n of t){let o=performance.now(),l=nt(n,this.options.compile),c=await ct(l,n.image,{templateMaxEdge:this.options.templateMaxEdge??480}),s=await Z(c);this.targets.push(s.compiled),r.push({id:n.info.id,compileUs:(performance.now()-o)*1e3,serialized:c,template:s.template})}return{targets:r}}async loadEncoded(t){let r=[];this.targets=[];for(let n of t){let o=performance.now(),l=await Z(n);this.targets.push(l.compiled),r.push({id:l.compiled.info.id,compileUs:(performance.now()-o)*1e3,serialized:n,template:l.template,info:l.compiled.info})}return{targets:r}}async detect(t,r={}){if(t.image.kind!=="cpu-gray")throw new Error("OrbDetector needs cpu-gray frames");let n=r.roi??null,o=(n&&(r.upscale??1)>1?De(t.image.image,n,r.upscale,this.options.orb??{}):null)??rt(t.image.image,{budget:n?500:ke(t.image.image),...this.options.orb,roi:n});if(o.count<8)return[];let l=this.options.ratio??.85,c=this.options.maxDistance??80,s=[];for(let a of this.targets){let i=this.matcher.nearest2Grouped(o.descriptors,a.descriptors,a.descriptorPoint),A=new Map;for(let y=0;y<o.count;y++){let f=i[3*y+1],d=i[3*y+2];if(f>c||l<1&&f>=l*d)continue;let p=a.descriptorPoint[i[3*y]],x=f/Math.max(1,d),b=A.get(p);(!b||x<b.r)&&A.set(p,{q:y,r:x})}let u=[...A].sort((y,f)=>y[1].r-f[1].r||y[0]-f[0]);if(u.length<12)continue;let m=new Float64Array(2*u.length),h=new Float64Array(2*u.length);u.forEach(([y,{q:f}],d)=>{m[2*d]=a.points[2*y],m[2*d+1]=a.points[2*y+1],h[2*d]=o.x[f],h[2*d+1]=o.y[f]});let g=kt(m,h,u.length,a.info.width,a.info.height,{thresholdPx:this.options.thresholdPx??4,maxIterations:1e3,minInliers:12,minInlierRatio:.1,minCoverage:.05});g.accepted&&s.push({inliers:g.inliers,pose:{targetId:a.info.id,frameId:t.frameId,timeUs:t.time.captureUs,H_imageFromTarget:g.H,corners:at(g.H,a.info.width,a.info.height),covariance:null,quality:{support:g.inliers,ratio:g.ratio,residual:g.rmsPx,residualKind:"px",coverage:g.coverage},origin:"detector"}})}return s.sort((a,i)=>i.inliers-a.inliers||a.pose.targetId.localeCompare(i.pose.targetId)),s.length>1&&s[1].inliers>=.85*s[0].inliers?[]:s.map(a=>a.pose)}};var Se=48,Le=64,z=class extends Error{constructor(r,n,o){super(n,o);F(this,"code");this.name="PictureError",this.code=r}};function Ne(e,t,r){let n=Math.min(1,r/Math.max(e,t));return[Math.max(1,Math.round(e*n)),Math.max(1,Math.round(t*n))]}function He(e,t,r){let n=new Uint8Array(t*r);for(let o=0;o<n.length;o++)n[o]=77*e[4*o]+150*e[4*o+1]+29*e[4*o+2]+128>>8;return n}function ee(){try{return typeof OffscreenCanvas=="function"&&!!new OffscreenCanvas(1,1).getContext("2d")}catch{return!1}}async function re(e,t){let r;try{r=await createImageBitmap(e,{imageOrientation:"from-image"})}catch{try{r=await createImageBitmap(e)}catch(n){throw new z("DECODE_FAILED",`The picture cannot be decoded: ${String(n)}`,{cause:n})}}try{let[n,o]=Ne(r.width,r.height,t),l=r,c=r.width,s=r.height;for(;c>2*n&&s>2*o;){let u=new OffscreenCanvas(Math.ceil(c/2),Math.ceil(s/2)),m=u.getContext("2d");m.imageSmoothingQuality="high",m.drawImage(l,0,0,u.width,u.height),l=u,c=u.width,s=u.height}let i=new OffscreenCanvas(n,o).getContext("2d",{willReadFrequently:!0});i.imageSmoothingQuality="high",i.drawImage(l,0,0,n,o);let A=i.getImageData(0,0,n,o).data;return{width:n,height:o,stride:n,data:He(A,n,o)}}finally{r.close()}}async function ne(e,t){if(Math.min(t.width,t.height)<Le)throw new z("UNSUITABLE_TARGET",`The picture is too small (${t.width}×${t.height} px)`);let r=nt({info:{id:e,width:t.width,height:t.height,physicalWidthMeters:null},image:t}),n=r.points.length/2;if(n<Se)throw new z("UNSUITABLE_TARGET",`The picture has too little detail (${n} recognition points)`);return{bytes:await ct(r,t),pointCount:n}}var We=5,Ke=24,qe=.08,Mt={detail:.15,spread:.4,distinctiveness:.05,recognition:.4},Ye=[.1,.7],_e=[15,95],Je=.4,At={size:.08,tilt:.15,blur:.33,dim:.6,covered:.6},j=(e,t,r)=>e<=t?0:e>=r?1:(e-t)/(r-t),q=640,mt=360,St=500,Lt=118,je=[...[160,120,90,70].map(e=>({name:`size-${e}`,test:"size",longPx:e})),...[45,60,70].map(e=>({name:`tilt-${e}`,test:"tilt",longPx:240,tiltDeg:e})),...[6,10,16].map(e=>({name:`blur-${e}`,test:"blur",longPx:240,blurPx:e})),...[.35,.2].map(e=>({name:`dim-${e}`,test:"dim",longPx:240,gain:e})),...[[0],[1],[2],[3],[0,2],[1,3],[0,1],[2,3]].map(e=>({name:`covered-${e.join("")}`,test:"covered",longPx:240,covered:e}))].flatMap(e=>[{...e,rollDeg:8,offset:[24,12]},{...e,rollDeg:-12,offset:[-30,-8]}]),oe=[12,40],Nt={size:.25,tilt:.2,blur:.2,dim:.15,covered:.2};function Xe(e,t,r){let n=e.longPx/Math.max(t,r),o=t*n,l=r*n,c=q/2+e.offset[0],s=mt/2+e.offset[1],a=[[c-o/2,s-l/2],[c+o/2,s-l/2],[c+o/2,s+l/2],[c-o/2,s+l/2]];if(e.tiltDeg){let m=e.tiltDeg*Math.PI/180;a=a.map(([h,g])=>{let y=St+(g-s)*Math.sin(m);return[c+(h-c)*St/y,s+(g-s)*Math.cos(m)*St/y]})}let i=e.rollDeg*Math.PI/180;a=a.map(([m,h])=>[c+(m-c)*Math.cos(i)-(h-s)*Math.sin(i),s+(m-c)*Math.sin(i)+(h-s)*Math.cos(i)]);let A=Float64Array.from([0,0,t,0,t,r,0,r]),u=Float64Array.from(a.flat());return st(A,u,[0,1,2,3])}function ze(e,t,r){let n=e.levels[0],o=t.longPx/Math.max(n.width,n.height),l=Math.max(0,Math.min(e.levels.length-1,Math.floor(Math.log2(1/o)))),c=e.levels[l],s=2**l,a=vt(r),i=new Uint8Array(q*mt),A=12345,u=n.width/2,m=n.height/2;for(let h=0;h<mt;h++)for(let g=0;g<q;g++){A=A*1103515245+12345>>>0;let y=Lt+(A>>>16)%9-4,f=g+.5,d=h+.5,p=a[6]*f+a[7]*d+a[8],x=(a[0]*f+a[1]*d+a[2])/p,b=(a[3]*f+a[4]*d+a[5])/p;if(x>=0&&b>=0&&x<n.width&&b<n.height){let M=(b<m?0:2)+(x<u?0:1);if(!t.covered?.includes(M)){let I=tt(c,Math.min(c.width-.51,Math.max(.5,x/s)),Math.min(c.height-.51,Math.max(.5,b/s)));Number.isNaN(I)||(y=I)}}t.gain!==void 0&&(A=A*1103515245+12345>>>0,y=Lt+(y-Lt)*t.gain+(A>>>16)%13-6),i[h*q+g]=Math.max(0,Math.min(255,Math.round(y)))}if(t.blurPx){let h=Math.floor(t.blurPx/2),g=new Float64Array(q+1);for(let y=0;y<mt;y++){for(let f=0;f<q;f++)g[f+1]=g[f]+i[y*q+f];for(let f=0;f<q;f++){let d=Math.max(0,f-h),p=Math.min(q,f-h+t.blurPx);i[y*q+f]=Math.round((g[p]-g[d])/(p-d))}}}return{width:q,height:mt,stride:q,data:i}}async function ae(e){let t=await Z(e),{compiled:r,template:n}=t,{width:o,height:l}=r.info,c=r.points.length/2,s=[];for(let U=0;U<c;U++)r.repeatability[U]>=We&&s.push(U);let a=new Float32Array(2*s.length);s.forEach((U,G)=>{a[2*G]=r.points[2*U],a[2*G+1]=r.points[2*U+1]});let i=j(s.length,40,250),A=o/l,u=Math.max(2,Math.round(4*Math.sqrt(A))),m=Math.max(2,Math.round(4/Math.sqrt(A))),h=new Array(u*m).fill(0),g=[0,0,0,0];for(let U=0;U<s.length;U++){let G=a[2*U],K=a[2*U+1];h[Math.min(m-1,Math.floor(K/l*m))*u+Math.min(u-1,Math.floor(G/o*u))]++,g[(K<l/2?0:2)+(G<o/2?0:1)]++}let y=Math.max(1,s.length),f=u*m,d=h.filter(U=>U>=Math.max(3,.3*y/f)).length,p=h.reduce((U,G)=>U+(G/y)**2,0),x=s.length?1/p/f:0,b=g.indexOf(Math.min(...g)),M=g[b]/y,I=(.5*j(d/f,.3,.85)+.5*j(x,.25,.65))*(.6+.4*j(M,.03,.15)),w=new Uint32Array(r.descriptors.buffer,r.descriptors.byteOffset,r.descriptors.length/4),Q=Array.from({length:c},()=>[]);r.descriptorPoint.forEach((U,G)=>Q[U].push(G));let E=(qe*Math.hypot(o,l))**2,B=(U,G)=>{let K=0;for(let H=0;H<8;H++){let Y=(w[8*U+H]^w[8*G+H])>>>0;Y-=Y>>>1&1431655765,Y=(Y&858993459)+(Y>>>2&858993459),K+=(Y+(Y>>>4)&252645135)*16843009>>>24}return K},C=U=>{let G=r.points[2*U],K=r.points[2*U+1];for(let H=0;H<c;H++)if(!((r.points[2*H]-G)**2+(r.points[2*H+1]-K)**2<E)){for(let Y of Q[U])for(let $ of Q[H])if(B(Y,$)<=Ke)return!0}return!1},P=s.length?s.filter(U=>!C(U)).length/s.length:0,k=j(P,.35,.7),v=new lt;await v.loadEncoded([e]);let T=Ct(n,6,16),D=[];for(let[U,G]of je.entries()){let K=Xe(G,o,l),H=at(K,o,l),$=(await v.detect({sessionId:"rate",frameId:U+1,time:{captureUs:U,receiveUs:U,source:"replay"},image:{kind:"cpu-gray",image:ze(T,G,K)}})).find(ie=>ie.corners.reduce((ce,Ht,Wt)=>ce+Math.hypot(Ht[0]-H[Wt][0],Ht[1]-H[Wt][1]),0)/4<.08*G.longPx);D.push({name:G.name,test:G.test,found:!!$,margin:$?j($.quality.support,oe[0],oe[1]):0})}let R=Object.fromEntries(Object.keys(Nt).map(U=>{let G=D.filter(K=>K.test===U);return[U,G.reduce((K,H)=>K+H.margin,0)/G.length]})),L=j(Object.keys(Nt).reduce((U,G)=>U+Nt[G]*R[G],0),...Ye),O=100*(Mt.detail*i+Mt.spread*I+Mt.distinctiveness*k+Mt.recognition*L),N=Math.min(.5+4.5*j(O,..._e),1+4*Math.min(I,L)**Je),W=Math.min(5,Math.max(.5,Math.round(N*2)/2)),S=[];return L<.4&&S.push("HARD_TO_FIND"),I<.6&&(d/f<.6||x<.45)&&S.push("CONCENTRATED"),M<.08&&S.push("WEAK_QUARTER"),i<.5&&S.push("FEW_DETAILS"),k<.4&&S.push("REPETITIVE"),R.size<At.size&&S.push("FAILS_SMALL"),R.tilt<At.tilt&&S.push("FAILS_TILTED"),R.blur<At.blur&&S.push("FAILS_BLURRED"),R.dim<At.dim&&S.push("FAILS_DIM"),R.covered<At.covered&&S.push("FAILS_COVERED"),{stars:W,score:Math.round(20*N),factors:{detail:i,spread:I,distinctiveness:k,recognition:L},metrics:{robustPoints:s.length,grid:{columns:u,rows:m,counts:h},populatedCells:d,evenness:x,weakestQuarter:{index:b,share:M},distinctShare:P,tests:R,views:D},advice:S,points:a,width:o,height:l}}var Bt=class extends Error{constructor(r,n){super(n);F(this,"code");this.code=r}};async function Ve(e){if(e.bytes)return new Uint8Array(e.bytes);let t;if(e.gray)t={width:e.gray.width,height:e.gray.height,stride:e.gray.width,data:new Uint8Array(e.gray.data)};else if(ee())t=await re(e.image,e.maxEdgePx);else return null;return(await ne("rated",t)).bytes}function se(e){let t=Promise.resolve();e.addEventListener("message",r=>{let n=r.data;n.type==="rate"&&(t=t.then(async()=>{try{let o=await Ve(n);if(!o){e.postMessage({type:"need-gray",id:n.id});return}let l;try{l=await ae(o)}catch(c){throw n.bytes?new Bt("INVALID_TARGET",c instanceof Error?c.message:String(c)):c}e.postMessage({type:"rated",id:n.id,rating:l},[l.points.buffer])}catch(o){e.postMessage({type:"failed",id:n.id,code:o instanceof z||o instanceof Bt?o.code:"WORKER_FAILED",message:o instanceof Error?o.message:String(o)})}}))})}se(globalThis);})();\n'],{type:"text/javascript"})),d)}var l=class{constructor(t){o(this,"worker",null);o(this,"queue",[]);o(this,"current",null);o(this,"nextId",1);o(this,"idleTimer",null);o(this,"workerUrl");this.workerUrl=t}run(t,e){return new Promise((r,i)=>{if(e?.aborted)return i(new a("ABORTED","Rating aborted"));let s={id:this.nextId++,request:t,resolve:r,reject:i};e?.addEventListener("abort",()=>{let u=this.queue.indexOf(s);u>=0&&this.queue.splice(u,1),this.current===s&&(this.current=null,this.pump()),i(new a("ABORTED","Rating aborted"))},{once:!0}),this.queue.push(s),this.pump()})}pump(){if(this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.current)return;let t=this.queue.shift();if(!t){this.idleTimer=setTimeout(()=>this.close(),b);return}try{this.worker??=this.spawn()}catch(e){for(let r of[t,...this.queue.splice(0)])r.reject(e instanceof a?e:new a("WORKER_FAILED",String(e)));return}this.current=t,this.worker.postMessage({...t.request,id:t.id})}spawn(){let t;try{t=new Worker(this.workerUrl??T(),{name:"LiveMira rating"})}catch(e){throw e instanceof a?e:new a("WORKER_FAILED","Cannot start the rating Worker (a CSP may forbid blob: Workers)",{cause:e})}return t.onmessage=e=>{this.answer(e.data)},t.onerror=e=>{e.preventDefault(),t.terminate(),this.worker===t&&(this.worker=null);let r=this.current;this.current=null,r?.reject(new a("WORKER_FAILED",`The rating Worker failed: ${e.message}`)),this.pump()},t}async answer(t){let e=this.current;if(!(!e||e.id!==t.id)){if(t.type==="need-gray"){try{let r=await h(e.request.image,e.request.maxEdgePx);if(this.current!==e)return;this.worker.postMessage({...e.request,id:e.id,image:null,gray:r},[r.data])}catch(r){this.current=null,e.reject(r instanceof c?new a(r.code,r.message,{cause:r.cause}):new a("DECODE_FAILED",String(r))),this.pump()}return}this.current=null,t.type==="rated"?e.resolve(Object.freeze(t.rating)):e.reject(new a(t.code,t.message)),this.pump()}}close(){this.idleTimer=null,this.worker?.terminate(),this.worker=null}},m=new Map,p=n=>{let t=n?String(n):"",e=m.get(t);return e||m.set(t,e=new l(n)),e};function A(n,t={}){if(!(typeof Blob<"u"&&n instanceof Blob))return Promise.reject(new a("INVALID_INPUT","rateTargetImage needs a Blob or File"));let e=t.maxEdgePx??640;return!Number.isInteger(e)||e<64||e>2048?Promise.reject(new a("INVALID_INPUT","maxEdgePx must be an integer 64..2048")):n.size===0?Promise.reject(new a("DECODE_FAILED","The picture file is empty")):p(t.workerUrl).run({type:"rate",maxEdgePx:e,image:n,gray:null,bytes:null},t.signal)}function x(n,t={}){let e=n instanceof Uint8Array?n:n?.bytes;return e instanceof Uint8Array?p(t.workerUrl).run({type:"rate",maxEdgePx:640,image:null,gray:null,bytes:e.slice().buffer},t.signal):Promise.reject(new a("INVALID_INPUT","rateTarget needs a target bundle or its bytes"))}export{g as RATING_VERSION,a as RatingError,x as rateTarget,A as rateTargetImage,y as ratingBuildInfo};
1
+ var _=Object.defineProperty;var R=(n,t,e)=>t in n?_(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var o=(n,t,e)=>R(n,typeof t!="symbol"?t+"":t,e);var g="0.6.0",y=Object.freeze({version:g,buildId:"147b918dc0232a92a4232661db7ed083bbeca340b9cdb721c17ad1337a014eff",variant:"minified"});var c=class extends Error{constructor(e,r,i){super(r,i);o(this,"code");this.name="PictureError",this.code=e}};function w(n,t,e){let r=Math.min(1,e/Math.max(n,t));return[Math.max(1,Math.round(n*r)),Math.max(1,Math.round(t*r))]}function E(n,t,e){let r=new Uint8Array(t*e);for(let i=0;i<r.length;i++)r[i]=77*n[4*i]+150*n[4*i+1]+29*n[4*i+2]+128>>8;return r}async function h(n,t){let e;try{e=await createImageBitmap(n)}catch(I){throw new c("DECODE_FAILED","The picture cannot be decoded",{cause:I})}let[r,i]=w(e.width,e.height,t),s=document.createElement("canvas");s.width=r,s.height=i;let u=s.getContext("2d",{willReadFrequently:!0});u.imageSmoothingQuality="high",u.drawImage(e,0,0,r,i),e.close();let f=E(u.getImageData(0,0,r,i).data,r,i);return{width:r,height:i,data:f.buffer}}var a=class extends Error{constructor(e,r,i={}){super(r,i.cause===void 0?void 0:{cause:i.cause});o(this,"name","RatingError");o(this,"code");this.code=e}};var b=4e3,d=null;function T(){return d||(d=URL.createObjectURL(new Blob(['"use strict";(()=>{var le=Object.defineProperty;var Ae=(e,t,r)=>t in e?le(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var F=(e,t,r)=>Ae(e,typeof t!="symbol"?t+"":t,r);var X=class{constructor(){F(this,"rows",new Int32Array(0));F(this,"levels",[])}build(t,r,n=24){let o=[{...t,scale:1}];for(let l=1;l<r;l++){let c=o[l-1],s=c.width>>1,a=c.height>>1;if(s<n||a<n)break;this.rows.length<c.width*a&&(this.rows=new Int32Array(c.width*a));let i=this.levels[l]=this.levels[l]&&this.levels[l].length===s*a?this.levels[l]:new Uint8Array(s*a);me(c,s,a,this.rows,i),o.push({width:s,height:a,stride:s,data:i,scale:c.scale*2})}return{levels:o}}};function me(e,t,r,n,o){let l=e.width,c=e.height,s=e.data,a=e.stride;for(let i=0;i<r;i++){let A=2*i,u=Math.max(0,A-1)*a,m=A*a,h=Math.min(c-1,A+1)*a,g=Math.min(c-1,A+2)*a,y=i*l;for(let f=0;f<l;f++)n[y+f]=s[u+f]+3*s[m+f]+3*s[h+f]+s[g+f]}for(let i=0;i<r;i++){let A=i*l;for(let u=0;u<t;u++){let m=2*u,h=n[A+Math.max(0,m-1)],g=n[A+m],y=n[A+Math.min(l-1,m+1)],f=n[A+Math.min(l-1,m+2)];o[i*t+u]=h+3*g+3*y+f+32>>6}}}function Ct(e,t,r=24){return new X().build(e,t,r)}function tt(e,t,r){let n=t-.5,o=r-.5,l=Math.floor(n),c=Math.floor(o);if(l<0||c<0||l+1>=e.width||c+1>=e.height)return NaN;let s=n-l,a=o-c,i=e.data,A=c*e.stride+l,u=i[A]+s*(i[A+1]-i[A]),m=i[A+e.stride]+s*(i[A+e.stride+1]-i[A+e.stride]);return u+a*(m-u)}var Kt=Object.freeze({sha256:"d51fe1439175bb1343361385d7910036f36a63ed17a83311619a3b04cfa3e837",byteLength:4375,base64:"AGFzbQEAAAABKAVgCn9/f39/f39/f38Bf2AFf39/f38AYAZ/f39/f38AYAF/AX9gAAADBgUAAQIDBAUDAQARBhkDfwFBgIDAAAt/AEGQgMAAC38AQYSAwAALB2IIBm1lbW9yeQIABWZhc3Q5AAAIbmVhcmVzdDIAARBuZWFyZXN0Ml9ncm91cGVkAAIHcmVzZXJ2ZQADC19faGVhcF9iYXNlAwEKcmVzZXRfaGVhcAAECl9fZGF0YV9lbmQDAgr5HQW/EAwIfwF7BX8EewF/DXsBfwJ7AX8HewF/FXsjgICAgABBwAJrIgokgICAgABBACELAkAgAyAFTw0AIAIgBE8NAEF9IAFrIQwgAUEDbCENQQMgAWshDiABQX1sIQ9BACABQQF0IhBrIREgBkH/ASAGQf8BSRv9DyESQQAhCwNAIAMgCGwhEyAAIAMgAWxqIRQgAiEVA0ACQEH//wNBfyAEIBVrIgZ0QX9zQf//A3EgBkEPSxsiFiAUIBVqIgYgDWoiF/0AAAAiGCAG/QAAACIZIBL9cyIa/SYiGyAGIA9qIhz9AAAAIh0gGv0mIh79UCAGQX1q/QAAACIfIBr9JiIgIAb9AAADIiEgGv0mIiL9UP1OIBggGSAS/XAiGf0oIiMgHSAZ/SgiJP1QICEgGf0oIiUgHyAZ/SgiJv1Q/U79UP1kcUUNACAWICIgBiAOav0AAAAiJyAa/SYiKP1OIikgBiAQaiIqQQJq/QAAACIrIBr9JiIsIAYgAWoiLUEDav0AAAAiLiAa/SYiL/1OIjD9TiIxIB4gHEF/av0AAAAiMiAa/SYiM/1OIjQgBiARaiI1QQJq/QAAACI2IBr9JiI3IBxBAWr9AAAAIjggGv0mIjn9TiI6/U4iO/1OIBdBAWr9AAAAIjwgGv0mIj39TiAsICggN/1OIj4gLyAi/U4iP/1OIkAgMyA1QX5q/QAAACJBIBr9JiJC/U4iQyA5IB79TiJE/U4iRf1O/U4gOiAp/U4iRiBCIAYgDGr9AAAAIikgGv0mIjr9TiJHIDT9TiJI/U4gL/1OICIgPiBE/U4iPiBDIDogIP1OIi/9TiJD/U79TiA7ICAgLUF9av0AAAAiIiAa/SYiNP1OIkQgR/1OIkf9TiAo/U4gNyBFIDQgKkF+av0AAAAiKCAa/SYiO/1OIkkgL/1OIkr9Tv1OIEggOyAXQX9q/QAAACIvIBr9JiI3/U4iRSBE/U4iRP1OIDn9TiAeIEMgSSA3IBv9TiI5/U4iSP1O/U4gMyBH/U4gRSAbID39TiIe/U4iM/1OIEIgSiA9ICz9TiIsIDn9TiI5/U79TiA6IET9TiAwIB79TiIe/U4gICBIICwgP/1OIiz9Tv1OIDQgMf1OIDP9TiA7IDkgQP1O/U4gNyBG/U4gHv1OIBsgLCA+/U79Tv1Q/VD9UP1Q/VD9UP1Q/VD9UP1Q/VD9UP1Q/VD9UP1kICUgJyAZ/SgiG/1OIkIgKyAZ/SgiHiAuIBn9KCIg/U4iOv1OIjQgJCAyIBn9KCIs/U4iOyA2IBn9KCIzIDggGf0oIjf9TiIw/U4iMf1OIDwgGf0oIjn9TiAeIBsgM/1OIj4gICAl/U4iP/1OIkAgLCBBIBn9KCI9/U4iQyA3ICT9TiJE/U4iRf1O/U4gMCBC/U4iMCA9ICkgGf0oIkL9TiJGIDv9TiI7/U4gIP1OICUgPiBE/U4iPiBDIEIgJv1OIkT9TiJD/U79TiAxICYgIiAZ/SgiIP1OIkcgRv1OIkb9TiAb/U4gMyBFICAgKCAZ/SgiG/1OIjEgRP1OIkT9Tv1OIDsgGyAvIBn9KCIl/U4iMyBH/U4iRf1OIDf9TiAkIEMgMSAlICP9TiI3/U4iO/1O/U4gLCBG/U4gMyAjIDn9TiIk/U4iLP1OID0gRCA5IB79TiIeIDf9TiIz/U79TiBCIEX9TiA6ICT9TiIk/U4gJiA7IB4gP/1OIh79Tv1OICAgNP1OICz9TiAbIDMgQP1O/U4gJSAw/U4gJP1OICMgHiA+/U79Tv1Q/VD9UP1Q/VD9UP1Q/VD9UP1Q/VD9UP1Q/VD9UP1kIhxycSIGRQ0AIAogMiAZ/XP9CwTwASAKIEEgGf1z/QsE4AEgCiApIBn9c/0LBNABIAogHyAZ/XP9CwTAASAKICIgGf1z/QsEsAEgCiAoIBn9c/0LBKABIAogLyAZ/XP9CwSQASAKIBggGf1z/QsEgAEgCiA8IBn9c/0LBHAgCiArIBn9c/0LBGAgCiAuIBn9c/0LBFAgCiAhIBn9c/0LBEAgCiAnIBn9c/0LBDAgCiA2IBn9c/0LBCAgCiA4IBn9c/0LBBAgCiAdIBn9c/0LBABBACEX/QwAAAAAAAAAAAAAAAAAAAAAIhkhGwNAIBsgCiAXav0ABAAiHv2KAf2OASEbIBkgHv2JAf2OASEZIBdBEGoiF0GAAkcNAAsgCiAaIDL9c/0LBPABIAogGiBB/XP9CwTgASAKIBogKf1z/QsE0AEgCiAaIB/9c/0LBMABIAogGiAi/XP9CwSwASAKIBogKP1z/QsEoAEgCiAaIC/9c/0LBJABIAogGiAY/XP9CwSAASAKIBogPP1z/QsEcCAKIBogK/1z/QsEYCAKIBogLv1z/QsEUCAKIBogIf1z/QsEQCAKIBogJ/1z/QsEMCAKIBogNv1z/QsEICAKIBogOP1z/QsEECAKIBogHf1z/QsEAEEAIRf9DAAAAAAAAAAAAAAAAAAAAAAiHiEaA0AgGiAKIBdq/QAEACIg/YoB/Y4BIRogHiAg/YkB/Y4BIR4gF0EQaiIXQYACRw0ACyAKIBv9CwSQAiAKIBn9CwSAAiAKIBr9CwSwAiAKIB79CwSgAiAcIBZxISogFSATaiEtIAkgC0ECdGohFwNAIAcgLSAGaCIcaiIWQQF0aiAKQYACaiAKQaACaiAqIBx2QQFxGyAcQQF0ai8BAEEBajsBACAXIBY2AgAgF0EEaiEXIAtBAWohCyAGQX9qIAZxIgYNAAsLIBVBEGoiFSAESQ0ACyADQQFqIgMgBUcNAAsLIApBwAJqJICAgIAAIAsL/wUGAn8CewR/AXsCfwF+AkAgAUUNAAJAIANFDQBBACEFA0AgACAFQQV0aiIG/QAAECEHIAb9AAAAIQhBfyEJQYECIQYgAiEKQQAhC0GBAiEMA0AgBiAKQRBq/QAAACAH/VH9YiAK/QAAACAI/VH9Yv1u/X39fyIN/RsAIA39GwFqIA39GwJqIA39GwNqIg4gDCAOIAxJGyAOIAZJIg8bIQwgCyAJIA8bIQkgCkEgaiEKIA4gBiAPGyIOIQYgAyALQQFqIgtHDQALIAQgBUEMbGoiBiAJNgIAIAZBCGogDDYCACAGQQRqIA42AgAgBUEBaiIFIAFHDQAMAgsLQQAhDwJAIAFBGEkNAEEAIQ8gBEEEaiIGIAFBf2qtQgx+IhCnIgpqIAZJDQAgBEEIaiIGIApqIAZJDQAgEEIgiKdBAEcNAP0MAAAAAAEAAAACAAAAAwAAACEHIAFBfHEiDyELA0AgBCAH/QwMAAAADAAAAAwAAAAMAAAA/bUBIg39GwBqIgZBfzYCACAEIA39GwFqIgpBfzYCACAEIA39GwJqIg5BfzYCACAEIA39GwNqIgxBfzYCACAGQQRqQYECNgIAIApBBGpBgQI2AgAgDkEEakGBAjYCACAMQQRqQYECNgIAIAZBCGpBgQI2AgAgCkEIakGBAjYCACAOQQhqQYECNgIAIAxBCGpBgQI2AgAgB/0MBAAAAAQAAAAEAAAABAAAAP2uASEHIAtBfGoiCw0ACyABIA9GDQELIA8hDgJAIAFBA3EiCkUNACAPIApqIQ4gBCAPQQxsaiEGA0AgBkL/////nyA3AgAgBkEIakGBAjYCACAGQQxqIQYgCkF/aiIKDQALCyAPIAFrQXxLDQAgASAOayEKIAQgDkEMbGohBgNAIAb9DP////8BAQAAAQEAAP/////9CwIAIAZBIGr9DAEBAAD/////AQEAAAEBAAD9CwIAIAZBEGr9DAEBAAABAQAA/////wEBAAD9CwIAIAZBMGohBiAKQXxqIgoNAAsLC7kGBgJ/AnsGfwF7An8BfgJAIAFFDQACQCAERQ0AQQAhBgNAIAAgBkEFdGoiB/0AABAhCCAH/QAAACEJQX8hCkGBAiELIAIhByADIQxBACENQYECIQ5BfyEPA0AgB0EQav0AAAAgCP1R/WIgB/0AAAAgCf1R/WL9bv19/X8iEP0bACAQ/RsBaiAQ/RsCaiAQ/RsDaiERAkACQCAMKAIAIhIgCkYNAAJAIBEgC08NACANIQ8gCyEOIBIhCiARIQsMAgsgESAOIBEgDkkbIQ4MAQsgESALIBEgC0kiEhshCyANIA8gEhshDwsgB0EgaiEHIAxBBGohDCAEIA1BAWoiDUcNAAsgBSAGQQxsaiIHIA82AgAgB0EIaiAONgIAIAdBBGogCzYCACAGQQFqIgYgAUcNAAwCCwtBACEPAkAgAUEYSQ0AQQAhDyAFQQRqIgcgAUF/aq1CDH4iE6ciEWogB0kNACAFQQhqIgcgEWogB0kNACATQiCIp0EARw0A/QwAAAAAAQAAAAIAAAADAAAAIQggAUF8cSIPIQsDQCAFIAj9DAwAAAAMAAAADAAAAAwAAAD9tQEiEP0bAGoiB0F/NgIAIAUgEP0bAWoiEUF/NgIAIAUgEP0bAmoiDEF/NgIAIAUgEP0bA2oiDUF/NgIAIAdBBGpBgQI2AgAgEUEEakGBAjYCACAMQQRqQYECNgIAIA1BBGpBgQI2AgAgB0EIakGBAjYCACARQQhqQYECNgIAIAxBCGpBgQI2AgAgDUEIakGBAjYCACAI/QwEAAAABAAAAAQAAAAEAAAA/a4BIQggC0F8aiILDQALIAEgD0YNAQsgDyEMAkAgAUEDcSIRRQ0AIA8gEWohDCAFIA9BDGxqIQcDQCAHQv////+fIDcCACAHQQhqQYECNgIAIAdBDGohByARQX9qIhENAAsLIA8gAWtBfEsNACABIAxrIREgBSAMQQxsaiEHA0AgB/0M/////wEBAAABAQAA//////0LAgAgB0Egav0MAQEAAP////8BAQAAAQEAAP0LAgAgB0EQav0MAQEAAAEBAAD/////AQEAAP0LAgAgB0EwaiEHIBFBfGoiEQ0ACwsLZQEDfwJAQQAoAoCAwIAAIgENAEEAQZ+AwIAAQXBxIgE2AoCAwIAACwJAIAAgAWpBD2pBcHEiAEH//wNqQRB2IgI/ACIDTQ0AIAIgA2tAAEF/Rw0AQQAPC0EAIAA2AoCAwIAAIAELFABBAEGfgMCAAEFwcTYCgIDAgAALAGwEbmFtZQAWFWxpdmVtaXJhX2tlcm5lbHMud2FzbQE5BQAFZmFzdDkBCG5lYXJlc3QyAhBuZWFyZXN0Ml9ncm91cGVkAwdyZXNlcnZlBApyZXNldF9oZWFwBxIBAA9fX3N0YWNrX3BvaW50ZXIATQlwcm9kdWNlcnMCCGxhbmd1YWdlAQRSdXN0AAxwcm9jZXNzZWQtYnkBBXJ1c3RjHTEuOTUuMCAoNTk4MDc2MTZlIDIwMjYtMDQtMTQpAJ0BD3RhcmdldF9mZWF0dXJlcwkrC2J1bGstbWVtb3J5Kw9idWxrLW1lbW9yeS1vcHQrFmNhbGwtaW5kaXJlY3Qtb3ZlcmxvbmcrCm11bHRpdmFsdWUrD211dGFibGUtZ2xvYmFscysTbm9udHJhcHBpbmctZnB0b2ludCsPcmVmZXJlbmNlLXR5cGVzKwhzaWduLWV4dCsHc2ltZDEyOA=="});function ue(e){let t=atob(e),r=new Uint8Array(t.length);for(let n=0;n<t.length;n++)r[n]=t.charCodeAt(n);return r}var et;function ut(){if(typeof WebAssembly>"u")return null;try{if(et===void 0){let e=ue(Kt.base64);et=WebAssembly.validate(e)?new WebAssembly.Module(e):null}return et?new WebAssembly.Instance(et,{}).exports:null}catch{return et=null,null}}var fe=[[0,-3],[1,-3],[2,-2],[3,-1],[3,0],[3,1],[2,2],[1,3],[0,3],[-1,3],[-2,2],[-3,1],[-3,0],[-3,-1],[-2,-2],[-1,-3]];function ye(e,t,r,n){let o=e[t],l=o+n,c=o-n,s=e[t+r[0]],a=e[t+r[8]];if(s<=l&&s>=c&&a<=l&&a>=c)return 0;let i=e[t+r[4]],A=e[t+r[12]];if(i<=l&&i>=c&&A<=l&&A>=c)return 0;let u=0,m=0,h=0,g=0;for(let y=0;y<16;y++){let f=e[t+r[y]];f>l?(u|=1<<y,h+=f-l):f<c&&(m|=1<<y,g+=c-f)}return qt(u)?h+1:qt(m)?g+1:0}function qt(e){if(!e)return!1;let t=(e|e<<16)>>>0,r=t;for(let n=1;n<9;n++)r&=t>>>n;return r!==0}var yt=class{constructor(){F(this,"backend","js");F(this,"map",new Uint16Array(0));F(this,"image",null);F(this,"offsets",new Int32Array(16))}begin(t){return this.map.length<t.width*t.height&&(this.map=new Uint16Array(t.width*t.height)),this.image=t,this.offsets=Int32Array.from(fe.map(([r,n])=>n*t.stride+r)),this.map}score(t,r,n,o,l,c){let{width:s,stride:a,data:i}=this.image;for(let A=r;A<o;A++)for(let u=t;u<n;u++){let m=ye(i,A*a+u,this.offsets,l);m>0&&(this.map[A*s+u]=m,c.push(A*s+u))}}},Qt=class{constructor(t){F(this,"backend","wasm-simd");F(this,"k");F(this,"capacity",0);F(this,"img",0);F(this,"scores",0);F(this,"found",0);F(this,"map",new Uint16Array(0));F(this,"image",null);this.k=t}begin(t){let r=t.stride*t.height;if(r>this.capacity){let n=this.k;if(n.reset_heap(),this.img=n.reserve(r+16),this.scores=n.reserve(2*r),this.found=n.reserve(4*r),!this.img||!this.scores||!this.found)throw new Error("fast9: out of memory");this.capacity=r,new Uint16Array(n.memory.buffer,this.scores,r).fill(0)}return new Uint8Array(this.k.memory.buffer,this.img,r).set(t.data.subarray(0,r)),this.map=new Uint16Array(this.k.memory.buffer,this.scores,t.width*t.height),this.image=t,this.map}score(t,r,n,o,l,c){let s=this.image,a=this.k.fast9(this.img,s.stride,t,r,n,o,l,this.scores,s.width,this.found),i=new Uint32Array(this.k.memory.buffer,this.found,a);for(let A=0;A<a;A++)c.push(i[A])}};function he(e){let n=new Uint8Array(2867),o=2654435769;for(let s=0;s<47;s++)for(let a=0;a<61;a++){o^=o<<13,o^=o>>>17,o^=o<<5;let i=(o>>>0)%64;n[s*61+a]=a<20?128:a<40?((a>>2)+(s>>2))%2?230-i:20+i:i*4}let l={width:61,height:47,stride:61,data:n},c=new yt;for(let s of[4,16,40]){let a=[],i=[],A=c.begin(l),u=e.begin(l);if(c.score(3,3,43,44,s,a),e.score(3,3,43,44,s,i),a.length!==i.length||a.some((m,h)=>m!==i[h]||A[m]!==u[m]))return!1;for(let m of a)A[m]=0;for(let m of i)u[m]=0;if(s===16&&a.length<10)return!1}return!0}var ft=null;function Yt(e=!0){if(!ft){let t=ut(),r=null;try{r=t?new Qt(t):null,r&&!he(r)&&(r=null)}catch{r=null}ft={wasm:r,js:new yt}}return e&&ft.wasm||ft.js}var _=15,ht=_+3,V=32,ge=(()=>{let e=625341585,t=()=>(e^=e<<13,e>>>=0,e^=e>>>17,e^=e<<5,e>>>=0,(e+.5)/4294967296),r=()=>Math.sqrt(-2*Math.log(t()))*Math.cos(2*Math.PI*t()),n=new Int8Array(1024);for(let o=0;o<256;){let l=[0,1,2,3].map(()=>Math.round(r()*8.5));Math.hypot(l[0],l[1])>15||Math.hypot(l[2],l[3])>15||Math.hypot(l[0]-l[2],l[1]-l[3])<2||(n.set(l,4*o),o++)}return n})(),dt=2;function de(e){return Array.from({length:V},(t,r)=>{let n=2*Math.PI*r/V,o=Math.cos(n),l=Math.sin(n),c=new Int8Array(1024);for(let s=0;s<512;s++){let a=e[2*s],i=e[2*s+1];c[2*s]=Math.round(o*a-l*i),c[2*s+1]=Math.round(l*a+o*i)}return c})}var _t=new WeakMap;function pe(e){let t=_t.get(e);if(!t){let r=e.length===1024;for(let n=0;n<512&&r;n++)r=Math.hypot(e[2*n],e[2*n+1])<=15;if(!r)throw new Error("BRIEF pattern: 256 tests with box centres within 15 px");t=de(e),_t.set(e,t)}return t}var Ie=(()=>{let e=new Int32Array(_+1);for(let t=0;t<=_;t++)e[t]=Math.floor(Math.sqrt(_*_-t*t)+.5);return e})(),gt=class{constructor(){F(this,"octaves",new X);F(this,"halfOctaves",new X);F(this,"horizontal",new Uint16Array(0));F(this,"blur",new Uint8Array(0));F(this,"half",new Uint8Array(0));F(this,"integral",new Int32Array(0))}},Jt=new gt;function be(e,t){let r=e.width,n=e.height,o=Math.floor(r/Math.SQRT2),l=Math.floor(n/Math.SQRT2),c=e.data;t.horizontal.length<r*n&&(t.horizontal=new Uint16Array(r*n),t.blur=new Uint8Array(r*n)),t.half.length!==o*l&&(t.half=new Uint8Array(o*l));let s=t.horizontal;for(let m=0;m<n;m++){let h=m*e.stride,g=m*r;s[g]=3*c[h]+c[h+1];for(let y=1;y<r-1;y++)s[g+y]=c[h+y-1]+2*c[h+y]+c[h+y+1];s[g+r-1]=c[h+r-2]+3*c[h+r-1]}let a=t.blur;for(let m=0;m<n;m++){let h=Math.max(0,m-1)*r,g=m*r,y=Math.min(n-1,m+1)*r;for(let f=0;f<r;f++)a[g+f]=s[h+f]+2*s[g+f]+s[y+f]+8>>4}let i=new Int32Array(o),A=new Float32Array(o);for(let m=0;m<o;m++){let h=(m+.5)*Math.SQRT2-.5;i[m]=Math.min(r-2,Math.max(0,Math.floor(h))),A[m]=h-i[m]}let u=t.half;for(let m=0;m<l;m++){let h=(m+.5)*Math.SQRT2-.5,g=Math.min(n-2,Math.max(0,Math.floor(h))),y=h-g,f=g*r,d=f+r;for(let p=0;p<o;p++){let x=i[p],b=A[p],M=a[f+x]+b*(a[f+x+1]-a[f+x]),I=a[d+x]+b*(a[d+x+1]-a[d+x]);u[m*o+p]=M+y*(I-M)+.5|0}}return{width:o,height:l,stride:o,data:u}}function we(e,t,r=new gt){let n=Math.ceil(t/2),o=r.octaves.build(e,n,24).levels,l=r.halfOctaves.build(be(e,r),n,24).levels,c=[];for(let s=0;s<n;s++)o[s]&&c.push({image:o[s],scale:2**s}),l[s]&&c.push({image:l[s],scale:Math.SQRT2*2**s});return c.slice(0,t)}function xe(e,t,r,n){let o=0,l=0,c=0;for(let s=-3;s<=3;s++)for(let a=-3;a<=3;a++){let i=(n+s)*t+r+a,A=e[i+1]-e[i-1],u=e[i+t]-e[i-t];o+=A*A,l+=u*u,c+=A*u}return o*l-c*c-.04*(o+l)**2}function Ee(e,t){let r=e.width+1;t.integral.length<r*(e.height+1)&&(t.integral=new Int32Array(r*(e.height+1)));let n=t.integral;n.fill(0,0,r);for(let o=0;o<e.height;o++){n[(o+1)*r]=0;let l=0;for(let c=0;c<e.width;c++)l+=e.data[o*e.stride+c],n[(o+1)*r+c+1]=n[o*r+c+1]+l}return n}function Me(e,t,r,n,o){let{width:l,height:c,stride:s,data:a}=e,i=r.cell,A=[],u=Math.max(ht,Math.floor(n.x0)),m=Math.max(ht,Math.floor(n.y0)),h=Math.min(l-ht,Math.ceil(n.x1)),g=Math.min(c-ht,Math.ceil(n.y1));if(h<=u||g<=m)return A;let y=o.begin(e),f=[];for(let d=m;d<g;d+=i)for(let p=u;p<h;p+=i){let x=Math.min(g,d+i),b=Math.min(h,p+i);f.length=0;let M=255,I=0;for(let E=d;E<x;E+=2)for(let B=p;B<b;B+=2){let C=a[E*s+B];C<M&&(M=C),C>I&&(I=C)}if(I-M<2*r.minFastThreshold)continue;for(let E=r.fastThreshold;o.score(p,d,b,x,E,f),!(f.length>=2||E===r.minFastThreshold);E=r.minFastThreshold){for(let B of f)y[B]=0;f.length=0}let w=[];for(let E of f){let B=y[E],C=!0;for(let P=-1;P<=1&&C;P++)for(let k=-1;k<=1;k++){if(!k&&!P)continue;let v=y[E+P*l+k];if(v>B||v===B&&(P<0||P===0&&k<0)){C=!1;break}}C&&w.push({i:E,s:B})}for(let E of f)y[E]=0;w.sort((E,B)=>B.s-E.s||E.i-B.i);let Q=[];for(let E of w.slice(0,8)){let B=E.i%l,C=(E.i-B)/l,P=xe(a,s,B,C);P>0&&Q.push({x:B,y:C,score:P})}Q.sort((E,B)=>B.score-E.score||E.y-B.y||E.x-B.x),A.push(...Q.slice(0,2))}return A.sort((d,p)=>p.score-d.score||d.y-p.y||d.x-p.x),A.slice(0,t)}function Be(e,t,r){let n=e.data,o=e.stride,l=0,c=0,s=r*o+t;for(let a=-_;a<=_;a++)c+=a*n[s+a];for(let a=1;a<=_;a++){let i=0,A=Ie[a];for(let u=-A;u<=A;u++){let m=n[s-a*o+u],h=n[s+a*o+u];i+=h-m,c+=u*(m+h)}l+=a*i}return Math.atan2(l,c)}function Ce(e){return(Math.round(e*V/(2*Math.PI))%V+V)%V}function Qe(e,t,r,n,o,l,c,s){let a=l[Ce(o)],i=(n-2)*t+(r-2),A=5*t;for(let u=0;u<32;u++){let m=0;for(let h=0;h<8;h++){let g=4*(8*u+h),y=i+a[g+1]*t+a[g],f=i+a[g+3]*t+a[g+2],d=e[y+A+5]-e[y+5]-e[y+A]+e[y],p=e[f+A+5]-e[f+5]-e[f+A]+e[f];d<p&&(m|=1<<h)}c[s+u]=m}}function rt(e,t={}){let r=t.budget??700,n=we(e,t.levels??6,Jt),o={fastThreshold:t.fastThreshold??16,minFastThreshold:t.minFastThreshold??4,cell:t.cell??24},l=Yt(t.wasm!==!1),c=pe(t.pattern??ge),s=n.reduce((d,p)=>d+p.image.width*p.image.height,0),a=t.roi??{x:0,y:0,width:e.width,height:e.height},i=[],A=[],u=[],m=[],h=[],g=[];n.forEach((d,p)=>{let x=Math.max(16,Math.round(r*d.image.width*d.image.height/s)),b=d.scale,M=Me(d.image,x,o,{x0:a.x/b,y0:a.y/b,x1:(a.x+a.width)/b,y1:(a.y+a.height)/b},l);if(!M.length)return;let I=Ee(d.image,Jt),w=new Uint8Array(32*M.length);M.forEach((Q,E)=>{let B=Be(d.image,Q.x,Q.y);Qe(I,d.image.width+1,Q.x,Q.y,B,c,w,32*E),i.push((Q.x+.5)*b),A.push((Q.y+.5)*b),u.push(p),m.push(B),h.push(Q.score)}),g.push(w)});let y=new Uint8Array(32*i.length),f=0;for(let d of g)y.set(d,f),f+=d.length;return{count:i.length,x:Float32Array.from(i),y:Float32Array.from(A),level:Uint8Array.from(u),angle:Float32Array.from(m),score:Float32Array.from(h),descriptors:y,descriptorBytes:32}}function Ue(e,t,r){let n=r*Math.PI/180,o=Math.cos(n),l=Math.sin(n),c=o*o/t+l*l,s=o*l/t-o*l,a=l*l/t+o*o,i=[[0,0],[e.width,0],[e.width,e.height],[0,e.height]].map(([I,w])=>[c*I+s*w,s*I+a*w]),A=Math.min(...i.map(I=>I[0])),u=Math.min(...i.map(I=>I[1])),m=Math.ceil(Math.max(...i.map(I=>I[0]))-A),h=Math.ceil(Math.max(...i.map(I=>I[1]))-u),g=[c,s,-A,s,a,-u],y=.8*Math.sqrt(Math.max(0,t*t-1)),f=y>.3?jt(e,y):e,d=c*a-s*s,p=a/d,x=-s/d,b=c/d,M=new Uint8Array(m*h).fill(128);for(let I=0;I<h;I++)for(let w=0;w<m;w++){let Q=w+.5-g[2],E=I+.5-g[5],B=p*Q+x*E-.5,C=x*Q+b*E-.5,P=Math.floor(B),k=Math.floor(C);if(P<0||k<0||P+1>=e.width||k+1>=e.height)continue;let v=B-P,T=C-k,D=k*f.stride+P,R=f.data,L=R[D]+v*(R[D+1]-R[D]),O=R[D+f.stride]+v*(R[D+f.stride+1]-R[D+f.stride]);M[I*m+w]=Math.round(L+T*(O-L))}return{image:{width:m,height:h,stride:m,data:M},A:g}}function jt(e,t){let r=Math.ceil(3*t),n=Array.from({length:2*r+1},(a,i)=>Math.exp(-((i-r)**2)/(2*t*t))),o=n.reduce((a,i)=>a+i,0),l=n.map(a=>a/o),c=new Float32Array(e.width*e.height);for(let a=0;a<e.height;a++)for(let i=0;i<e.width;i++){let A=0;for(let u=-r;u<=r;u++)A+=l[u+r]*e.data[a*e.stride+Math.min(e.width-1,Math.max(0,i+u))];c[a*e.width+i]=A}let s=new Uint8Array(e.width*e.height);for(let a=0;a<e.height;a++)for(let i=0;i<e.width;i++){let A=0;for(let u=-r;u<=r;u++)A+=l[u+r]*c[Math.min(e.height-1,Math.max(0,a+u))*e.width+i];s[a*e.width+i]=Math.round(A)}return{width:e.width,height:e.height,stride:e.width,data:s}}function Fe(e,t,r,n){let o=0;for(let l=0;l<32;l++){let c=e[t+l]^r[n+l];for(;c;)c&=c-1,o++}return o}function nt(e,t={}){let r=t.tilts??[1.4,2,2.8],n=t.longitudes??[0,45,90,135],o=[{image:e.image,A:[1,0,0,0,1,0]}];for(let d of r)for(let p of n)o.push(Ue(e.image,d,p));for(let d of t.blurs??[2.5])o.push({image:jt(e.image,d),A:[1,0,0,0,1,0]});let l=[],c=new Map,s=4,a=(d,p)=>Math.floor(p/s)*65536+Math.floor(d/s);o.forEach((d,p)=>{let x=rt(d.image,{budget:900,...t.orb}),[b,M,I,w,Q,E]=d.A,B=b*Q-M*w;for(let C=0;C<x.count;C++){let P=x.x[C]-I,k=x.y[C]-E,v=(Q*P-M*k)/B,T=(-w*P+b*k)/B;if(v<0||T<0||v>=e.info.width||T>=e.info.height)continue;let D=2+1.5*(2**(x.level[C]/2)-1),R=-1;for(let O=-1;O<=1&&R<0;O++)for(let N=-1;N<=1&&R<0;N++)for(let W of c.get(a(v+N*s,T+O*s))??[]){let S=l[W];if(Math.hypot(S.x-v,S.y-T)<=D){R=W;break}}let L=x.descriptors.slice(32*C,32*C+32);if(R<0){l.push({x:v,y:T,n:1,views:new Set([p]),score:x.score[C],desc:[L]});let O=a(v,T);c.set(O,[...c.get(O)??[],l.length-1])}else{let O=l[R];O.views.add(p),O.n++,O.score=Math.max(O.score,x.score[C]),O.desc.push(L)}}});let i=t.maxPoints??700,A=t.descriptorsPerPoint??3,u=l.map((d,p)=>({g:d,i:p})).sort((d,p)=>p.g.views.size-d.g.views.size||p.g.score-d.g.score||d.i-p.i).slice(0,i).map(d=>d.g),m=new Float32Array(2*u.length),h=new Uint8Array(u.length),g=[],y=[];u.forEach((d,p)=>{m[2*p]=d.x,m[2*p+1]=d.y,h[p]=d.views.size;let x=[];for(let b of d.desc){if(x.length>=A)break;x.every(M=>Fe(M,0,b,0)>24)&&x.push(b)}for(let b of x)g.push(b),y.push(p)});let f=new Uint8Array(32*g.length);return g.forEach((d,p)=>f.set(d,32*p)),{info:e.info,points:m,repeatability:h,descriptors:f,descriptorPoint:Uint32Array.from(y)}}function ot(e,t,r){let n=e[6]*t+e[7]*r+e[8];return Math.abs(n)<1e-12?[NaN,NaN]:[(e[0]*t+e[1]*r+e[2])/n,(e[3]*t+e[4]*r+e[5])/n]}function at(e,t,r){return[ot(e,0,0),ot(e,t,0),ot(e,t,r),ot(e,0,r)]}function pt(e,t,r){for(let n=0;n<r;n++){let o=n,l=Math.abs(e[n*r+n]);for(let s=n+1;s<r;s++){let a=Math.abs(e[s*r+n]);a>l&&(l=a,o=s)}if(l<1e-12)return!1;if(o!==n){for(let a=0;a<r;a++){let i=e[n*r+a];e[n*r+a]=e[o*r+a],e[o*r+a]=i}let s=t[n];t[n]=t[o],t[o]=s}let c=e[n*r+n];for(let s=n+1;s<r;s++){let a=e[s*r+n]/c;if(a!==0){for(let i=n;i<r;i++)e[s*r+i]-=a*e[n*r+i];t[s]-=a*t[n]}}}for(let n=r-1;n>=0;n--){let o=t[n];for(let l=n+1;l<r;l++)o-=e[n*r+l]*t[l];t[n]=o/e[n*r+n]}return t.every(Number.isFinite)}function Xt(e,t){let r=new Float64Array(e),n=new Float64Array(t*t);for(let o=0;o<t;o++)n[o*t+o]=1;for(let o=0;o<t;o++){let l=o;for(let s=o+1;s<t;s++)Math.abs(r[s*t+o])>Math.abs(r[l*t+o])&&(l=s);if(Math.abs(r[l*t+o])<1e-15)return null;if(l!==o)for(let s=0;s<t;s++){let a=r[o*t+s];r[o*t+s]=r[l*t+s],r[l*t+s]=a,a=n[o*t+s],n[o*t+s]=n[l*t+s],n[l*t+s]=a}let c=r[o*t+o];for(let s=0;s<t;s++)r[o*t+s]/=c,n[o*t+s]/=c;for(let s=0;s<t;s++){if(s===o)continue;let a=r[s*t+o];if(a!==0)for(let i=0;i<t;i++)r[s*t+i]-=a*r[o*t+i],n[s*t+i]-=a*n[o*t+i]}}return n}function zt(e,t){let r=new Float64Array(e),n=new Float64Array(t*t);for(let c=0;c<t;c++)n[c*t+c]=1;for(let c=0;c<50;c++){let s=0;for(let a=0;a<t;a++)for(let i=a+1;i<t;i++)s+=r[a*t+i]**2;if(s<1e-24)break;for(let a=0;a<t;a++)for(let i=a+1;i<t;i++){let A=r[a*t+i];if(Math.abs(A)<1e-300)continue;let u=(r[i*t+i]-r[a*t+a])/(2*A),m=Math.sign(u||1)/(Math.abs(u)+Math.sqrt(u*u+1)),h=1/Math.sqrt(m*m+1),g=m*h;for(let y=0;y<t;y++){let f=r[y*t+a],d=r[y*t+i];r[y*t+a]=h*f-g*d,r[y*t+i]=g*f+h*d}for(let y=0;y<t;y++){let f=r[a*t+y],d=r[i*t+y];r[a*t+y]=h*f-g*d,r[i*t+y]=g*f+h*d}for(let y=0;y<t;y++){let f=n[y*t+a],d=n[y*t+i];n[y*t+a]=h*f-g*d,n[y*t+i]=g*f+h*d}}}let o=0;for(let c=1;c<t;c++)r[c*t+c]<r[o*t+o]&&(o=c);let l=new Float64Array(t);for(let c=0;c<t;c++)l[c]=n[c*t+o];return l}function Ft(e,t){let r=new Float64Array(9);for(let n=0;n<3;n++)for(let o=0;o<3;o++)r[n*3+o]=e[n*3]*t[o]+e[n*3+1]*t[3+o]+e[n*3+2]*t[6+o];return r}function vt(e){let[t,r,n,o,l,c,s,a,i]=[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]],A=[l*i-c*a,n*a-r*i,r*c-n*l,c*s-o*i,t*i-n*s,n*o-t*c,o*a-l*s,r*s-t*a,t*l-r*o],u=t*A[0]+r*A[3]+n*A[6];return!Number.isFinite(u)||Math.abs(u)<1e-300?null:Float64Array.from(A,m=>m/u)}function Vt(e){let t=e[8];if(!Number.isFinite(t)||Math.abs(t)<1e-12)return null;for(let r=0;r<9;r++)e[r]/=t;return e.every(Number.isFinite)?e:null}function wt(e,t,r){let n=0,o=0;for(let c=0;c<r;c++){let s=t[c];n+=e[2*s],o+=e[2*s+1]}n/=r,o/=r;let l=0;for(let c=0;c<r;c++){let s=t[c];l+=Math.hypot(e[2*s]-n,e[2*s+1]-o)}return l/=r,l<1e-9?null:[Math.SQRT2/l,n,o]}function Zt(e,t,r){let[n,o,l]=t,[c,s,a]=r,i=[n,0,-n*o,0,n,-n*l,0,0,1],A=[1/c,0,s,0,1/c,a,0,0,1];return Vt(Ft(Ft(A,e),i))}function Pt(e,t,r,n,o){if(n<4)return null;let l=wt(e,r,n),c=wt(t,r,n);if(!l||!c)return null;let s=new Float64Array(81),a=new Float64Array(9);for(let i=0;i<n;i++){let A=r[i],u=o?o[A]:1;if(u<=0)continue;let m=l[0]*(e[2*A]-l[1]),h=l[0]*(e[2*A+1]-l[2]),g=c[0]*(t[2*A]-c[1]),y=c[0]*(t[2*A+1]-c[2]);for(let f=0;f<2;f++){f===0?a.set([m,h,1,0,0,0,-g*m,-g*h,-g]):a.set([0,0,0,m,h,1,-y*m,-y*h,-y]);for(let d=0;d<9;d++){let p=a[d]*u;if(p!==0)for(let x=d;x<9;x++)s[d*9+x]+=p*a[x]}}}for(let i=0;i<9;i++)for(let A=0;A<i;A++)s[i*9+A]=s[A*9+i];return Zt(zt(s,9),l,c)}var It=new Float64Array(64),bt=new Float64Array(8);function st(e,t,r){let n=wt(e,r,4),o=wt(t,r,4);if(!n||!o)return null;It.fill(0);for(let l=0;l<4;l++){let c=r[l],s=n[0]*(e[2*c]-n[1]),a=n[0]*(e[2*c+1]-n[2]),i=o[0]*(t[2*c]-o[1]),A=o[0]*(t[2*c+1]-o[2]);It.set([s,a,1,0,0,0,-i*s,-i*a],16*l),It.set([0,0,0,s,a,1,-A*s,-A*a],16*l+8),bt[2*l]=i,bt[2*l+1]=A}return pt(It,bt,8)?Zt([...bt,1],n,o):null}function $t(e,t,r,n){let o=e[6]*t+e[7]*r+e[8];return o>1e-12?(n[0]=(e[0]*t+e[1]*r+e[2])/o,n[1]=(e[3]*t+e[4]*r+e[5])/o,!0):!1}var J=new Float64Array(8),Ut=new Float64Array(2);function it(e,t,r,n=64,o=30){let l=[0,t,t,0],c=[0,0,r,r];for(let A=0;A<4;A++){if(!$t(e,l[A],c[A],Ut))return!1;J[2*A]=Ut[0],J[2*A+1]=Ut[1]}let s=0,a=1/0,i=0;for(let A=0;A<4;A++){let u=J[2*A],m=J[2*A+1],h=J[(2*A+2)%8],g=J[(2*A+3)%8],y=J[(2*A+4)%8],f=J[(2*A+5)%8];if((h-u)*(f-g)-(g-m)*(y-h)<=0)return!1;s+=u*g-h*m;let d=Math.hypot(h-u,g-m);a=Math.min(a,d),i=Math.max(i,d)}return s/2>=n&&i<=o*Math.max(a,1e-9)}function Tt(e,t,r){let n=[];for(let i=0;i<r;i++)(!t||t[i])&&n.push([e[2*i],e[2*i+1]]);if(n.length<3)return 0;n.sort((i,A)=>i[0]-A[0]||i[1]-A[1]);let o=(i,A,u)=>(A[0]-i[0])*(u[1]-i[1])-(A[1]-i[1])*(u[0]-i[0]),l=[];for(let i of n){for(;l.length>=2&&o(l.at(-2),l.at(-1),i)<=0;)l.pop();l.push(i)}let c=[];for(let i=n.length-1;i>=0;i--){let A=n[i];for(;c.length>=2&&o(c.at(-2),c.at(-1),A)<=0;)c.pop();c.push(A)}let s=[...l.slice(0,-1),...c.slice(0,-1)],a=0;for(let i=0;i<s.length;i++){let A=s[i],u=s[(i+1)%s.length];a+=A[0]*u[1]-u[0]*A[1]}return Math.abs(a)/2}var ve=(e,t)=>e<=t?1:t/e;function Rt(e,t,r,n,o,l={}){let c=l.iterations??8,s=l.huberPx??1.5,a=Float64Array.from(e.subarray(0,8)),i=.001,A=new Float64Array(64),u=new Float64Array(8),m=new Float64Array(8),h=new Float64Array(8),g=b=>{let M=0;for(let I=0;I<o;I++){if(!n[I])continue;let w=t[2*I],Q=t[2*I+1],E=b[6]*w+b[7]*Q+1;if(!(E>1e-12))return 1/0;let B=(b[0]*w+b[1]*Q+b[2])/E-r[2*I],C=(b[3]*w+b[4]*Q+b[5])/E-r[2*I+1],P=Math.hypot(B,C);M+=P<=s?P*P:2*s*P-s*s}return M},y=g(a);for(let b=0;b<c;b++){A.fill(0),u.fill(0);for(let I=0;I<o;I++){if(!n[I])continue;let w=t[2*I],Q=t[2*I+1],E=a[6]*w+a[7]*Q+1,B=(a[0]*w+a[1]*Q+a[2])/E,C=(a[3]*w+a[4]*Q+a[5])/E,P=B-r[2*I],k=C-r[2*I+1],v=ve(Math.hypot(P,k),s);m.set([w/E,Q/E,1/E,0,0,0,-B*w/E,-B*Q/E]),h.set([0,0,0,w/E,Q/E,1/E,-C*w/E,-C*Q/E]);for(let T=0;T<8;T++){u[T]+=v*(m[T]*P+h[T]*k);for(let D=T;D<8;D++)A[T*8+D]+=v*(m[T]*m[D]+h[T]*h[D])}}for(let I=0;I<8;I++)for(let w=0;w<I;w++)A[I*8+w]=A[w*8+I];let M=!1;for(let I=0;I<4&&!M;I++){let w=new Float64Array(A);for(let C=0;C<8;C++)w[C*9]*=1+i;let Q=Float64Array.from(u,C=>-C);if(!pt(w,Q,8)){i*=10;continue}let E=Float64Array.from(a,(C,P)=>C+Q[P]),B=g(E);B<y?(a=E,y=B,i=Math.max(1e-7,i/10),M=!0):i*=10}if(!M)break}let f=0,d=0;A.fill(0);for(let b=0;b<o;b++){if(!n[b])continue;let M=t[2*b],I=t[2*b+1],w=a[6]*M+a[7]*I+1,Q=(a[0]*M+a[1]*I+a[2])/w,E=(a[3]*M+a[4]*I+a[5])/w;d+=(Q-r[2*b])**2+(E-r[2*b+1])**2,f++,m.set([M/w,I/w,1/w,0,0,0,-Q*M/w,-Q*I/w]),h.set([0,0,0,M/w,I/w,1/w,-E*M/w,-E*I/w]);for(let B=0;B<8;B++)for(let C=0;C<8;C++)A[B*8+C]+=m[B]*m[C]+h[B]*h[C]}let p=f>4?d/(2*f-8):d,x=Xt(A,8);return{H:Float64Array.from([...a,1]),rmsPx:f?Math.sqrt(d/f):1/0,paramCovariance:x?x.map(b=>b*p):null}}function Pe(e){let t=e>>>0||625341585;return()=>(t^=t<<13,t>>>=0,t^=t>>>17,t^=t<<5,t>>>=0,t)}function Gt(e,t,r,n,o,l){let c=0,s=0;for(let a=0;a<n;a++){let i=t[2*a],A=t[2*a+1],u=e[6]*i+e[7]*A+e[8],m=o;if(u>1e-12){let g=(e[0]*i+e[1]*A+e[2])/u-r[2*a],y=(e[3]*i+e[4]*A+e[5])/u-r[2*a+1];m=Math.min(o,g*g+y*y)}let h=m<o;l[a]=h?1:0,h&&s++,c+=m}return{score:c,inliers:s}}function Te(e,t){let r=0;for(let o=0;o<t;o++)e[o]&&r++;let n=new Int32Array(r);for(let o=0,l=0;o<t;o++)e[o]&&(n[l++]=o);return n}function xt(e,t,r,n){let o=(e[2*r]-e[2*t])*(e[2*n+1]-e[2*t+1])-(e[2*r+1]-e[2*t+1])*(e[2*n]-e[2*t]);return Math.abs(o)<.001*(1+Math.abs(e[2*t])+Math.abs(e[2*r]))}function kt(e,t,r,n,o,l={}){let c=l.thresholdPx??3,s=c*c,a=l.confidence??.995,i=l.maxIterations??500,A=l.minInliers??12,u=l.minInlierRatio??.2,m=l.minCoverage??.08;if(r<Math.max(4,A))return{accepted:!1,reason:"INSUFFICIENT_MATCHES",iterations:0};let h=Pe(l.seed??12345),g=new Uint8Array(r),y=new Uint8Array(r),f=null,d=1/0,p=0,x=i,b=4,M=i;for(let v=0;v<4;v++)M*=(b-v)/(r-v);let I=1,w=new Int32Array(4),Q=0,E=v=>{if(!v||!it(v,n,o))return;let{score:T,inliers:D}=Gt(v,e,t,r,s,g);if(T>=d)return;f=v,d=T,p=D,y.set(g);for(let O=0;O<3&&p>=8;O++){let N=Pt(e,t,Te(y,r),p);if(!N||!it(N,n,o))break;let W=Gt(N,e,t,r,s,g);if(W.score>=d)break;f=N,d=W.score,p=W.inliers,y.set(g)}let R=p/r,L=Math.log(1-a)/Math.log(Math.max(1e-12,1-R**4));x=Math.min(i,Math.max(16,Math.ceil(L)))};for(;Q<x;){if(Q++,Q>=I&&b<r){let W=M*(b+1)/(b+1-4);b++,I+=Math.ceil(W-M),M=W}let v=I>Q?b-1:b,T=0;I>Q&&(w[T++]=b-1);let D=0;for(;T<4&&D++<64;){let W=h()%v,S=!1;for(let U=0;U<T;U++)w[U]===W&&(S=!0);S||(w[T++]=W)}if(T<4)continue;let[R,L,O,N]=[w[0],w[1],w[2],w[3]];xt(e,R,L,O)||xt(e,R,L,N)||xt(e,R,O,N)||xt(e,L,O,N)||E(st(e,t,w))}if(!f||p<A)return{accepted:!1,reason:"NO_MODEL",iterations:Q};let B=f,C=Rt(B,e,t,y,r,{huberPx:c/2});for(let v=0;v<2;v++){if(!it(C.H,n,o))return{accepted:!1,reason:"IMPLAUSIBLE_MODEL",iterations:Q};B=C.H,p=Gt(B,e,t,r,s,y).inliers,v===0&&(C=Rt(B,e,t,y,r,{huberPx:c/2}))}let P=p/r;if(p<A||P<u)return{accepted:!1,reason:"LOW_INLIER_SUPPORT",iterations:Q};let k=Tt(e,y,r)/(n*o);return k<m?{accepted:!1,reason:"LOW_SPATIAL_COVERAGE",iterations:Q}:{accepted:!0,H:B,mask:y,inliers:p,ratio:P,rmsPx:C.rmsPx,coverage:k,paramCovariance:C.paramCovariance,iterations:Q}}var te=844385612;function Re(e,t,r){if(e.width===t&&e.height===r)return e;let n=new Uint8Array(t*r),o=e.width/t,l=e.height/r;for(let c=0;c<r;c++){let s=Math.min(e.height-1.001,Math.max(0,(c+.5)*l-.5)),a=Math.floor(s),i=s-a;for(let A=0;A<t;A++){let u=Math.min(e.width-1.001,Math.max(0,(A+.5)*o-.5)),m=Math.floor(u),h=u-m,g=a*e.stride+m,y=e.data,f=y[g]+h*(y[g+1]-y[g]),d=y[g+e.stride]+h*(y[g+e.stride+1]-y[g+e.stride]);n[c*t+A]=Math.round(f+i*(d-f))}}return{width:t,height:r,stride:t,data:n}}function Ge(e,t){let r=Math.max(e.width,e.height)/t;if(r<=1)return e;let n=Math.round(e.width/r),o=Math.round(e.height/r),l=new Uint8Array(n*o);for(let c=0;c<o;c++)for(let s=0;s<n;s++){let a=Math.floor(s*r),i=Math.max(a+1,Math.floor((s+1)*r)),A=Math.floor(c*r),u=Math.max(A+1,Math.floor((c+1)*r)),m=0;for(let h=A;h<u;h++)for(let g=a;g<i;g++)m+=e.data[h*e.stride+g];l[c*n+s]=Math.round(m/((i-a)*(u-A)))}return{width:n,height:o,stride:n,data:l}}async function ct(e,t,r={}){let n=Ge(t,r.templateMaxEdge??480),o=new TextEncoder().encode(e.info.id),l=e.points.length/2,c=e.descriptorPoint.length,s=10+o.length+8+8+8*l+l+4*c+32*c+4+n.width*n.height,a=new Uint8Array(s+32),i=new DataView(a.buffer),A=0;i.setUint32(A,te,!0),i.setUint16(A+4,2,!0),i.setUint16(A+6,dt,!0),A+=8,i.setUint16(A,o.length,!0),a.set(o,A+2),A+=2+o.length,i.setUint16(A,e.info.width,!0),i.setUint16(A+2,e.info.height,!0),i.setFloat32(A+4,e.info.physicalWidthMeters??NaN,!0),A+=8,i.setUint32(A,l,!0),i.setUint32(A+4,c,!0),A+=8;for(let m=0;m<2*l;m++,A+=4)i.setFloat32(A,e.points[m],!0);a.set(e.repeatability,A),A+=l;for(let m=0;m<c;m++,A+=4)i.setUint32(A,e.descriptorPoint[m],!0);a.set(e.descriptors,A),A+=32*c,i.setUint16(A,n.width,!0),i.setUint16(A+2,n.height,!0),A+=4;for(let m=0;m<n.height;m++)a.set(n.data.subarray(m*n.stride,m*n.stride+n.width),A+m*n.width);A+=n.width*n.height;let u=new Uint8Array(await crypto.subtle.digest("SHA-256",a.subarray(0,A)));return a.set(u,A),a}async function Z(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=M=>{throw new Error(`Invalid target asset: ${M}`)};(e.length<64||t.getUint32(0,!0)!==te||t.getUint16(4,!0)!==2)&&r("header");let n=t.getUint16(6,!0)&255;n!==dt&&r(`descriptor pattern v${n}, this engine uses v${dt}; recompile the target`);let o=e.subarray(0,e.length-32);new Uint8Array(await crypto.subtle.digest("SHA-256",new Uint8Array(o))).every((M,I)=>M===e[e.length-32+I])||r("checksum");let c=8,s=t.getUint16(c,!0),a=new TextDecoder().decode(e.subarray(c+2,c+2+s));c+=2+s;let i=t.getUint16(c,!0),A=t.getUint16(c+2,!0),u=t.getFloat32(c+4,!0);c+=8;let m=t.getUint32(c,!0),h=t.getUint32(c+4,!0);c+=8;let g=new Float32Array(2*m);for(let M=0;M<2*m;M++,c+=4)g[M]=t.getFloat32(c,!0);let y=e.slice(c,c+m);c+=m;let f=new Uint32Array(h);for(let M=0;M<h;M++,c+=4)f[M]=t.getUint32(c,!0);let d=e.slice(c,c+32*h);c+=32*h;let p=t.getUint16(c,!0),x=t.getUint16(c+2,!0);c+=4;let b={width:p,height:x,stride:p,data:e.slice(c,c+p*x)};return{compiled:{info:{id:a,width:i,height:A,physicalWidthMeters:Number.isNaN(u)?null:u},points:g,repeatability:y,descriptors:d,descriptorPoint:f},template:Re(b,i,A)}}function Ot(e,t){let r=e.length/32,n=t.length/32,o=new Uint32Array(3*r),l=new Uint32Array(e.buffer,e.byteOffset,e.length/4),c=new Uint32Array(t.buffer,t.byteOffset,t.length/4);for(let s=0;s<r;s++){let a=257,i=257,A=4294967295,u=8*s;for(let m=0;m<n;m++){let h=8*m,g=0;for(let y=0;y<8;y++){let f=(l[u+y]^c[h+y])>>>0;f-=f>>>1&1431655765,f=(f&858993459)+(f>>>2&858993459),g+=(f+(f>>>4)&252645135)*16843009>>>24}g<a?(i=a,a=g,A=m):g<i&&(i=g)}o[3*s]=A,o[3*s+1]=a,o[3*s+2]=i}return o}function Dt(e,t,r){let n=e.length/32,o=t.length/32,l=new Uint32Array(3*n),c=new Uint32Array(e.buffer,e.byteOffset,e.length/4),s=new Uint32Array(t.buffer,t.byteOffset,t.length/4);for(let a=0;a<n;a++){let i=257,A=4294967295,u=257,m=4294967295,h=8*a;for(let g=0;g<o;g++){let y=8*g,f=0;for(let p=0;p<8;p++){let x=(c[h+p]^s[y+p])>>>0;x-=x>>>1&1431655765,x=(x&858993459)+(x>>>2&858993459),f+=(x+(x>>>4)&252645135)*16843009>>>24}let d=r[g];d===A?f<i&&(i=f,m=g):f<i?(u=i,i=f,A=d,m=g):f<u&&(u=f)}l[3*a]=m,l[3*a+1]=i,l[3*a+2]=u}return l}var Et=class e{constructor(t){F(this,"backend");F(this,"kernel");this.kernel=t,this.backend=t?"wasm-simd":"js"}static create(t={}){let r=t.allowWasm===!1?null:ut();if(!r)return new e(null);try{let n=new e(r);return n.selfTest()?n:new e(null)}catch{return new e(null)}}selfTest(){let t=19088743,r=A=>Uint8Array.from({length:A},()=>(t^=t<<13,t^=t>>>17,t^=t<<5,t&255)),n=r(1184),o=new Uint8Array(352);o.set(r(320)),o.set(n.subarray(160,192),320);let l=Ot(o,n),c=this.nearest2(o,n),s=Uint32Array.from({length:37},(A,u)=>u>>1),a=Dt(o,n,s),i=this.nearest2Grouped(o,n,s);return c.length===l.length&&c.every((A,u)=>A===l[u])&&i.length===a.length&&i.every((A,u)=>A===a[u])}nearest2(t,r){let n=this.kernel;if(!n)return Ot(t,r);let o=t.length/32,l=r.length/32;n.reset_heap();let c=n.reserve(t.length),s=n.reserve(r.length),a=n.reserve(12*o);return!c||!s||!a?Ot(t,r):(new Uint8Array(n.memory.buffer).set(t,c),new Uint8Array(n.memory.buffer).set(r,s),n.nearest2(c,o,s,l,a),new Uint32Array(n.memory.buffer.slice(a,a+12*o)))}nearest2Grouped(t,r,n){let o=this.kernel;if(!o)return Dt(t,r,n);let l=t.length/32;o.reset_heap();let c=o.reserve(t.length),s=o.reserve(r.length),a=o.reserve(n.byteLength),i=o.reserve(12*l);if(!c||!s||!a||!i)return Dt(t,r,n);let A=o.memory.buffer;return new Uint8Array(A).set(t,c),new Uint8Array(A).set(r,s),new Uint8Array(A).set(new Uint8Array(n.buffer,n.byteOffset,n.byteLength),a),o.nearest2_grouped(c,l,s,a,r.length/32,i),new Uint32Array(o.memory.buffer.slice(i,i+12*l))}};var ke=e=>Math.max(700,Math.round(700*e.width*e.height/(640*360))),Oe=36e4;function De(e,t,r,n){let o=Math.min(r,3,Math.sqrt(Oe/(t.width*t.height)));if(o<1.2)return null;let l=Math.round(t.width*o),c=Math.round(t.height*o),s=new Uint8Array(l*c),a=e.width-1.001,i=e.height-1.001;for(let u=0;u<c;u++){let m=Math.min(i,Math.max(.5,t.y+(u+.5)/o));for(let h=0;h<l;h++)s[u*l+h]=Math.round(tt(e,Math.min(a,Math.max(.5,t.x+(h+.5)/o)),m))}let A=rt({width:l,height:c,stride:l,data:s},{budget:500,...n});return{...A,x:A.x.map(u=>t.x+(u+.5)/o-.5),y:A.y.map(u=>t.y+(u+.5)/o-.5)}}var lt=class{constructor(t={}){F(this,"info",{id:"C1.orb-views",layer:"L2",route:"light",determinism:"bit-exact",requires:[]});F(this,"options");F(this,"matcher");F(this,"targets",[]);this.options=t,this.matcher=Et.create(t.allowWasm===!1?{allowWasm:!1}:{})}get backend(){return this.matcher.backend}probe(t){return{isAvailable:!0}}async load(t){let r=[];this.targets=[];for(let n of t){let o=performance.now(),l=nt(n,this.options.compile),c=await ct(l,n.image,{templateMaxEdge:this.options.templateMaxEdge??480}),s=await Z(c);this.targets.push(s.compiled),r.push({id:n.info.id,compileUs:(performance.now()-o)*1e3,serialized:c,template:s.template})}return{targets:r}}async loadEncoded(t){let r=[];this.targets=[];for(let n of t){let o=performance.now(),l=await Z(n);this.targets.push(l.compiled),r.push({id:l.compiled.info.id,compileUs:(performance.now()-o)*1e3,serialized:n,template:l.template,info:l.compiled.info})}return{targets:r}}async detect(t,r={}){if(t.image.kind!=="cpu-gray")throw new Error("OrbDetector needs cpu-gray frames");let n=r.roi??null,o=(n&&(r.upscale??1)>1?De(t.image.image,n,r.upscale,this.options.orb??{}):null)??rt(t.image.image,{budget:n?500:ke(t.image.image),...this.options.orb,roi:n});if(o.count<8)return[];let l=this.options.ratio??.85,c=this.options.maxDistance??80,s=[];for(let a of this.targets){let i=this.matcher.nearest2Grouped(o.descriptors,a.descriptors,a.descriptorPoint),A=new Map;for(let y=0;y<o.count;y++){let f=i[3*y+1],d=i[3*y+2];if(f>c||l<1&&f>=l*d)continue;let p=a.descriptorPoint[i[3*y]],x=f/Math.max(1,d),b=A.get(p);(!b||x<b.r)&&A.set(p,{q:y,r:x})}let u=[...A].sort((y,f)=>y[1].r-f[1].r||y[0]-f[0]);if(u.length<12)continue;let m=new Float64Array(2*u.length),h=new Float64Array(2*u.length);u.forEach(([y,{q:f}],d)=>{m[2*d]=a.points[2*y],m[2*d+1]=a.points[2*y+1],h[2*d]=o.x[f],h[2*d+1]=o.y[f]});let g=kt(m,h,u.length,a.info.width,a.info.height,{thresholdPx:this.options.thresholdPx??4,maxIterations:1e3,minInliers:12,minInlierRatio:.1,minCoverage:.05});g.accepted&&s.push({inliers:g.inliers,pose:{targetId:a.info.id,frameId:t.frameId,timeUs:t.time.captureUs,H_imageFromTarget:g.H,corners:at(g.H,a.info.width,a.info.height),covariance:null,quality:{support:g.inliers,ratio:g.ratio,residual:g.rmsPx,residualKind:"px",coverage:g.coverage},origin:"detector"}})}return s.sort((a,i)=>i.inliers-a.inliers||a.pose.targetId.localeCompare(i.pose.targetId)),s.length>1&&s[1].inliers>=.85*s[0].inliers?[]:s.map(a=>a.pose)}};var Se=48,Le=64,z=class extends Error{constructor(r,n,o){super(n,o);F(this,"code");this.name="PictureError",this.code=r}};function Ne(e,t,r){let n=Math.min(1,r/Math.max(e,t));return[Math.max(1,Math.round(e*n)),Math.max(1,Math.round(t*n))]}function He(e,t,r){let n=new Uint8Array(t*r);for(let o=0;o<n.length;o++)n[o]=77*e[4*o]+150*e[4*o+1]+29*e[4*o+2]+128>>8;return n}function ee(){try{return typeof OffscreenCanvas=="function"&&!!new OffscreenCanvas(1,1).getContext("2d")}catch{return!1}}async function re(e,t){let r;try{r=await createImageBitmap(e,{imageOrientation:"from-image"})}catch{try{r=await createImageBitmap(e)}catch(n){throw new z("DECODE_FAILED",`The picture cannot be decoded: ${String(n)}`,{cause:n})}}try{let[n,o]=Ne(r.width,r.height,t),l=r,c=r.width,s=r.height;for(;c>2*n&&s>2*o;){let u=new OffscreenCanvas(Math.ceil(c/2),Math.ceil(s/2)),m=u.getContext("2d");m.imageSmoothingQuality="high",m.drawImage(l,0,0,u.width,u.height),l=u,c=u.width,s=u.height}let i=new OffscreenCanvas(n,o).getContext("2d",{willReadFrequently:!0});i.imageSmoothingQuality="high",i.drawImage(l,0,0,n,o);let A=i.getImageData(0,0,n,o).data;return{width:n,height:o,stride:n,data:He(A,n,o)}}finally{r.close()}}async function ne(e,t){if(Math.min(t.width,t.height)<Le)throw new z("UNSUITABLE_TARGET",`The picture is too small (${t.width}×${t.height} px)`);let r=nt({info:{id:e,width:t.width,height:t.height,physicalWidthMeters:null},image:t}),n=r.points.length/2;if(n<Se)throw new z("UNSUITABLE_TARGET",`The picture has too little detail (${n} recognition points)`);return{bytes:await ct(r,t),pointCount:n}}var We=5,Ke=24,qe=.08,Mt={detail:.15,spread:.4,distinctiveness:.05,recognition:.4},Ye=[.1,.7],_e=[15,95],Je=.4,At={size:.08,tilt:.15,blur:.33,dim:.6,covered:.6},j=(e,t,r)=>e<=t?0:e>=r?1:(e-t)/(r-t),q=640,mt=360,St=500,Lt=118,je=[...[160,120,90,70].map(e=>({name:`size-${e}`,test:"size",longPx:e})),...[45,60,70].map(e=>({name:`tilt-${e}`,test:"tilt",longPx:240,tiltDeg:e})),...[6,10,16].map(e=>({name:`blur-${e}`,test:"blur",longPx:240,blurPx:e})),...[.35,.2].map(e=>({name:`dim-${e}`,test:"dim",longPx:240,gain:e})),...[[0],[1],[2],[3],[0,2],[1,3],[0,1],[2,3]].map(e=>({name:`covered-${e.join("")}`,test:"covered",longPx:240,covered:e}))].flatMap(e=>[{...e,rollDeg:8,offset:[24,12]},{...e,rollDeg:-12,offset:[-30,-8]}]),oe=[12,40],Nt={size:.25,tilt:.2,blur:.2,dim:.15,covered:.2};function Xe(e,t,r){let n=e.longPx/Math.max(t,r),o=t*n,l=r*n,c=q/2+e.offset[0],s=mt/2+e.offset[1],a=[[c-o/2,s-l/2],[c+o/2,s-l/2],[c+o/2,s+l/2],[c-o/2,s+l/2]];if(e.tiltDeg){let m=e.tiltDeg*Math.PI/180;a=a.map(([h,g])=>{let y=St+(g-s)*Math.sin(m);return[c+(h-c)*St/y,s+(g-s)*Math.cos(m)*St/y]})}let i=e.rollDeg*Math.PI/180;a=a.map(([m,h])=>[c+(m-c)*Math.cos(i)-(h-s)*Math.sin(i),s+(m-c)*Math.sin(i)+(h-s)*Math.cos(i)]);let A=Float64Array.from([0,0,t,0,t,r,0,r]),u=Float64Array.from(a.flat());return st(A,u,[0,1,2,3])}function ze(e,t,r){let n=e.levels[0],o=t.longPx/Math.max(n.width,n.height),l=Math.max(0,Math.min(e.levels.length-1,Math.floor(Math.log2(1/o)))),c=e.levels[l],s=2**l,a=vt(r),i=new Uint8Array(q*mt),A=12345,u=n.width/2,m=n.height/2;for(let h=0;h<mt;h++)for(let g=0;g<q;g++){A=A*1103515245+12345>>>0;let y=Lt+(A>>>16)%9-4,f=g+.5,d=h+.5,p=a[6]*f+a[7]*d+a[8],x=(a[0]*f+a[1]*d+a[2])/p,b=(a[3]*f+a[4]*d+a[5])/p;if(x>=0&&b>=0&&x<n.width&&b<n.height){let M=(b<m?0:2)+(x<u?0:1);if(!t.covered?.includes(M)){let I=tt(c,Math.min(c.width-.51,Math.max(.5,x/s)),Math.min(c.height-.51,Math.max(.5,b/s)));Number.isNaN(I)||(y=I)}}t.gain!==void 0&&(A=A*1103515245+12345>>>0,y=Lt+(y-Lt)*t.gain+(A>>>16)%13-6),i[h*q+g]=Math.max(0,Math.min(255,Math.round(y)))}if(t.blurPx){let h=Math.floor(t.blurPx/2),g=new Float64Array(q+1);for(let y=0;y<mt;y++){for(let f=0;f<q;f++)g[f+1]=g[f]+i[y*q+f];for(let f=0;f<q;f++){let d=Math.max(0,f-h),p=Math.min(q,f-h+t.blurPx);i[y*q+f]=Math.round((g[p]-g[d])/(p-d))}}}return{width:q,height:mt,stride:q,data:i}}async function ae(e){let t=await Z(e),{compiled:r,template:n}=t,{width:o,height:l}=r.info,c=r.points.length/2,s=[];for(let U=0;U<c;U++)r.repeatability[U]>=We&&s.push(U);let a=new Float32Array(2*s.length);s.forEach((U,G)=>{a[2*G]=r.points[2*U],a[2*G+1]=r.points[2*U+1]});let i=j(s.length,40,250),A=o/l,u=Math.max(2,Math.round(4*Math.sqrt(A))),m=Math.max(2,Math.round(4/Math.sqrt(A))),h=new Array(u*m).fill(0),g=[0,0,0,0];for(let U=0;U<s.length;U++){let G=a[2*U],K=a[2*U+1];h[Math.min(m-1,Math.floor(K/l*m))*u+Math.min(u-1,Math.floor(G/o*u))]++,g[(K<l/2?0:2)+(G<o/2?0:1)]++}let y=Math.max(1,s.length),f=u*m,d=h.filter(U=>U>=Math.max(3,.3*y/f)).length,p=h.reduce((U,G)=>U+(G/y)**2,0),x=s.length?1/p/f:0,b=g.indexOf(Math.min(...g)),M=g[b]/y,I=(.5*j(d/f,.3,.85)+.5*j(x,.25,.65))*(.6+.4*j(M,.03,.15)),w=new Uint32Array(r.descriptors.buffer,r.descriptors.byteOffset,r.descriptors.length/4),Q=Array.from({length:c},()=>[]);r.descriptorPoint.forEach((U,G)=>Q[U].push(G));let E=(qe*Math.hypot(o,l))**2,B=(U,G)=>{let K=0;for(let H=0;H<8;H++){let Y=(w[8*U+H]^w[8*G+H])>>>0;Y-=Y>>>1&1431655765,Y=(Y&858993459)+(Y>>>2&858993459),K+=(Y+(Y>>>4)&252645135)*16843009>>>24}return K},C=U=>{let G=r.points[2*U],K=r.points[2*U+1];for(let H=0;H<c;H++)if(!((r.points[2*H]-G)**2+(r.points[2*H+1]-K)**2<E)){for(let Y of Q[U])for(let $ of Q[H])if(B(Y,$)<=Ke)return!0}return!1},P=s.length?s.filter(U=>!C(U)).length/s.length:0,k=j(P,.35,.7),v=new lt;await v.loadEncoded([e]);let T=Ct(n,6,16),D=[];for(let[U,G]of je.entries()){let K=Xe(G,o,l),H=at(K,o,l),$=(await v.detect({sessionId:"rate",frameId:U+1,time:{captureUs:U,receiveUs:U,source:"replay"},image:{kind:"cpu-gray",image:ze(T,G,K)}})).find(ie=>ie.corners.reduce((ce,Ht,Wt)=>ce+Math.hypot(Ht[0]-H[Wt][0],Ht[1]-H[Wt][1]),0)/4<.08*G.longPx);D.push({name:G.name,test:G.test,found:!!$,margin:$?j($.quality.support,oe[0],oe[1]):0})}let R=Object.fromEntries(Object.keys(Nt).map(U=>{let G=D.filter(K=>K.test===U);return[U,G.reduce((K,H)=>K+H.margin,0)/G.length]})),L=j(Object.keys(Nt).reduce((U,G)=>U+Nt[G]*R[G],0),...Ye),O=100*(Mt.detail*i+Mt.spread*I+Mt.distinctiveness*k+Mt.recognition*L),N=Math.min(.5+4.5*j(O,..._e),1+4*Math.min(I,L)**Je),W=Math.min(5,Math.max(.5,Math.round(N*2)/2)),S=[];return L<.4&&S.push("HARD_TO_FIND"),I<.6&&(d/f<.6||x<.45)&&S.push("CONCENTRATED"),M<.08&&S.push("WEAK_QUARTER"),i<.5&&S.push("FEW_DETAILS"),k<.4&&S.push("REPETITIVE"),R.size<At.size&&S.push("FAILS_SMALL"),R.tilt<At.tilt&&S.push("FAILS_TILTED"),R.blur<At.blur&&S.push("FAILS_BLURRED"),R.dim<At.dim&&S.push("FAILS_DIM"),R.covered<At.covered&&S.push("FAILS_COVERED"),{stars:W,score:Math.round(20*N),factors:{detail:i,spread:I,distinctiveness:k,recognition:L},metrics:{robustPoints:s.length,grid:{columns:u,rows:m,counts:h},populatedCells:d,evenness:x,weakestQuarter:{index:b,share:M},distinctShare:P,tests:R,views:D},advice:S,points:a,width:o,height:l}}var Bt=class extends Error{constructor(r,n){super(n);F(this,"code");this.code=r}};async function Ve(e){if(e.bytes)return new Uint8Array(e.bytes);let t;if(e.gray)t={width:e.gray.width,height:e.gray.height,stride:e.gray.width,data:new Uint8Array(e.gray.data)};else if(ee())t=await re(e.image,e.maxEdgePx);else return null;return(await ne("rated",t)).bytes}function se(e){let t=Promise.resolve();e.addEventListener("message",r=>{let n=r.data;n.type==="rate"&&(t=t.then(async()=>{try{let o=await Ve(n);if(!o){e.postMessage({type:"need-gray",id:n.id});return}let l;try{l=await ae(o)}catch(c){throw n.bytes?new Bt("INVALID_TARGET",c instanceof Error?c.message:String(c)):c}e.postMessage({type:"rated",id:n.id,rating:l},[l.points.buffer])}catch(o){e.postMessage({type:"failed",id:n.id,code:o instanceof z||o instanceof Bt?o.code:"WORKER_FAILED",message:o instanceof Error?o.message:String(o)})}}))})}se(globalThis);})();\n'],{type:"text/javascript"})),d)}var l=class{constructor(t){o(this,"worker",null);o(this,"queue",[]);o(this,"current",null);o(this,"nextId",1);o(this,"idleTimer",null);o(this,"workerUrl");this.workerUrl=t}run(t,e){return new Promise((r,i)=>{if(e?.aborted)return i(new a("ABORTED","Rating aborted"));let s={id:this.nextId++,request:t,resolve:r,reject:i};e?.addEventListener("abort",()=>{let u=this.queue.indexOf(s);u>=0&&this.queue.splice(u,1),this.current===s&&(this.current=null,this.pump()),i(new a("ABORTED","Rating aborted"))},{once:!0}),this.queue.push(s),this.pump()})}pump(){if(this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.current)return;let t=this.queue.shift();if(!t){this.idleTimer=setTimeout(()=>this.close(),b);return}try{this.worker??=this.spawn()}catch(e){for(let r of[t,...this.queue.splice(0)])r.reject(e instanceof a?e:new a("WORKER_FAILED",String(e)));return}this.current=t,this.worker.postMessage({...t.request,id:t.id})}spawn(){let t;try{t=new Worker(this.workerUrl??T(),{name:"LiveMira rating"})}catch(e){throw e instanceof a?e:new a("WORKER_FAILED","Cannot start the rating Worker (a CSP may forbid blob: Workers)",{cause:e})}return t.onmessage=e=>{this.answer(e.data)},t.onerror=e=>{e.preventDefault(),t.terminate(),this.worker===t&&(this.worker=null);let r=this.current;this.current=null,r?.reject(new a("WORKER_FAILED",`The rating Worker failed: ${e.message}`)),this.pump()},t}async answer(t){let e=this.current;if(!(!e||e.id!==t.id)){if(t.type==="need-gray"){try{let r=await h(e.request.image,e.request.maxEdgePx);if(this.current!==e)return;this.worker.postMessage({...e.request,id:e.id,image:null,gray:r},[r.data])}catch(r){this.current=null,e.reject(r instanceof c?new a(r.code,r.message,{cause:r.cause}):new a("DECODE_FAILED",String(r))),this.pump()}return}this.current=null,t.type==="rated"?e.resolve(Object.freeze(t.rating)):e.reject(new a(t.code,t.message)),this.pump()}}close(){this.idleTimer=null,this.worker?.terminate(),this.worker=null}},m=new Map,p=n=>{let t=n?String(n):"",e=m.get(t);return e||m.set(t,e=new l(n)),e};function A(n,t={}){if(!(typeof Blob<"u"&&n instanceof Blob))return Promise.reject(new a("INVALID_INPUT","rateTargetImage needs a Blob or File"));let e=t.maxEdgePx??640;return!Number.isInteger(e)||e<64||e>2048?Promise.reject(new a("INVALID_INPUT","maxEdgePx must be an integer 64..2048")):n.size===0?Promise.reject(new a("DECODE_FAILED","The picture file is empty")):p(t.workerUrl).run({type:"rate",maxEdgePx:e,image:n,gray:null,bytes:null},t.signal)}function x(n,t={}){let e=n instanceof Uint8Array?n:n?.bytes;return e instanceof Uint8Array?p(t.workerUrl).run({type:"rate",maxEdgePx:640,image:null,gray:null,bytes:e.slice().buffer},t.signal):Promise.reject(new a("INVALID_INPUT","rateTarget needs a target bundle or its bytes"))}export{g as RATING_VERSION,a as RatingError,x as rateTarget,A as rateTargetImage,y as ratingBuildInfo};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livemira/target-rating",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,