@motionscript/geography 0.1.0-alpha.7 → 0.1.0-alpha.9

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.
Files changed (61) hide show
  1. package/CHANGELOG.md +104 -1
  2. package/CREDITS.md +8 -8
  3. package/LICENSE +201 -201
  4. package/NOTICE +49 -48
  5. package/README.md +149 -85
  6. package/dist/border/format.d.ts +73 -0
  7. package/dist/border/format.d.ts.map +1 -0
  8. package/dist/border/format.js +68 -0
  9. package/dist/border/format.js.map +1 -0
  10. package/dist/border/geo-border.d.ts +103 -0
  11. package/dist/border/geo-border.d.ts.map +1 -0
  12. package/dist/border/geo-border.js +203 -0
  13. package/dist/border/geo-border.js.map +1 -0
  14. package/dist/border/geometry.d.ts +40 -0
  15. package/dist/border/geometry.d.ts.map +1 -0
  16. package/dist/border/geometry.js +382 -0
  17. package/dist/border/geometry.js.map +1 -0
  18. package/dist/border/index.d.ts +15 -0
  19. package/dist/border/index.d.ts.map +1 -0
  20. package/dist/border/index.js +15 -0
  21. package/dist/border/index.js.map +1 -0
  22. package/dist/border/loader.d.ts +31 -0
  23. package/dist/border/loader.d.ts.map +1 -0
  24. package/dist/border/loader.js +87 -0
  25. package/dist/border/loader.js.map +1 -0
  26. package/dist/border/registry.d.ts +64 -0
  27. package/dist/border/registry.d.ts.map +1 -0
  28. package/dist/border/registry.js +163 -0
  29. package/dist/border/registry.js.map +1 -0
  30. package/dist/border/selection.d.ts +21 -0
  31. package/dist/border/selection.d.ts.map +1 -0
  32. package/dist/border/selection.js +86 -0
  33. package/dist/border/selection.js.map +1 -0
  34. package/dist/border/simplify.d.ts +12 -0
  35. package/dist/border/simplify.d.ts.map +1 -0
  36. package/dist/border/simplify.js +116 -0
  37. package/dist/border/simplify.js.map +1 -0
  38. package/dist/browser/THIRD_PARTY_LICENSES.txt +58 -0
  39. package/dist/browser/index.js +2 -0
  40. package/dist/browser/index.js.map +7 -0
  41. package/dist/browser/manifest.json +23 -0
  42. package/dist/index.d.ts +3 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +3 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/nodes.d.ts +15 -0
  47. package/dist/nodes.d.ts.map +1 -0
  48. package/dist/nodes.js +16 -0
  49. package/dist/nodes.js.map +1 -0
  50. package/package.json +46 -8
  51. package/registry.json +16 -0
  52. package/src/border/format.ts +147 -0
  53. package/src/border/geo-border.ts +268 -0
  54. package/src/border/geometry.ts +463 -0
  55. package/src/border/index.ts +14 -0
  56. package/src/border/loader.ts +97 -0
  57. package/src/border/registry.ts +201 -0
  58. package/src/border/selection.ts +95 -0
  59. package/src/border/simplify.ts +110 -0
  60. package/src/index.ts +2 -0
  61. package/src/nodes.ts +16 -0
package/NOTICE CHANGED
@@ -1,48 +1,49 @@
1
- Motionscript
2
- Copyright 2026 Motionscript LLC
3
-
4
- This product includes the third-party code below, each part under the MIT
5
- License reproduced at the end of this file.
6
-
7
- - packages/skia-render/src/fills/fractal-noise.ts: `hash2` is "Hash without
8
- Sine" by David Hoskins (https://www.shadertoy.com/view/4djSRW).
9
- Copyright (c) 2014 David Hoskins.
10
-
11
- - packages/skia-render/src/fills/fractal-noise.ts: `simplexNoise` follows
12
- "Noise - simplex - 2D" by Inigo Quilez (https://www.shadertoy.com/view/Msf3WH).
13
- Copyright (c) 2013 Inigo Quilez.
14
-
15
- The project website, which is in the source repository only and in no npm
16
- package, also includes MIT code: its landing-page background
17
- (packages/site/components/landing/GradientBackground.tsx) uses 3D simplex
18
- noise from webgl-noise by Ian McEwan, Ashima Arts
19
- (https://github.com/ashima/webgl-noise). Copyright (C) 2011 by Ashima Arts.
20
-
21
- @motionscript/canvaskit is a build of Skia's CanvasKit (BSD-3-Clause,
22
- Copyright (c) 2011 Google Inc.) and carries FreeType, HarfBuzz, ICU, zlib,
23
- libpng, Brotli, WOFF2, Emscripten and musl; their notices are in
24
- packages/canvaskit/THIRD_PARTY_NOTICES.txt.
25
-
26
- The browser builds under dist/browser/ bundle each package's npm dependencies;
27
- dist/browser/THIRD_PARTY_LICENSES.txt in each package lists them with their
28
- licences.
29
-
30
- MIT License
31
-
32
- Permission is hereby granted, free of charge, to any person obtaining a copy
33
- of this software and associated documentation files (the "Software"), to deal
34
- in the Software without restriction, including without limitation the rights
35
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
- copies of the Software, and to permit persons to whom the Software is
37
- furnished to do so, subject to the following conditions:
38
-
39
- The above copyright notice and this permission notice shall be included in all
40
- copies or substantial portions of the Software.
41
-
42
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
48
- SOFTWARE.
1
+ Motionscript
2
+ Copyright 2026 Motionscript LLC
3
+
4
+ This product includes the third-party code below, each part under the MIT
5
+ License reproduced at the end of this file.
6
+
7
+ - packages/renderer/crates/renderer/src/shaders/prim.wgsl (`fn_hash2`):
8
+ "Hash without Sine" by David Hoskins (https://www.shadertoy.com/view/4djSRW).
9
+ Copyright (c) 2014 David Hoskins.
10
+
11
+ - packages/renderer/crates/renderer/src/shaders/prim.wgsl (`simplex_noise`): "Noise - simplex - 2D" by Inigo Quilez
12
+ (https://www.shadertoy.com/view/Msf3WH). Copyright (c) 2013 Inigo Quilez.
13
+
14
+ - packages/renderer/crates/render3d (in @motionscript/renderer's WebAssembly):
15
+ its shaders (src/shaders/mesh.wgsl) port three.js r185's mesh programs and
16
+ src/geometry.rs its primitive generators (https://threejs.org).
17
+ Copyright (c) 2010-2026 three.js authors.
18
+
19
+ @motionscript/renderer's WebAssembly (dist/ms_renderer_bg.wasm) compiles in
20
+ Rust crates under MIT, Apache-2.0, Zlib and Unicode-3.0 terms (wgpu, naga,
21
+ harfrust, read-fonts, kurbo, wasm-bindgen and others); their notices are in
22
+ packages/renderer/THIRD_PARTY_NOTICES.txt.
23
+
24
+ MP3 export loads @mediabunny/mp3-encoder (MPL-2.0), a WebAssembly build of
25
+ the LAME MP3 encoder (LGPL, https://lame.sourceforge.io), on first use.
26
+
27
+ The browser builds under dist/browser/ bundle each package's npm dependencies;
28
+ dist/browser/THIRD_PARTY_LICENSES.txt in each package lists them with their
29
+ licences.
30
+
31
+ MIT License
32
+
33
+ Permission is hereby granted, free of charge, to any person obtaining a copy
34
+ of this software and associated documentation files (the "Software"), to deal
35
+ in the Software without restriction, including without limitation the rights
36
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
37
+ copies of the Software, and to permit persons to whom the Software is
38
+ furnished to do so, subject to the following conditions:
39
+
40
+ The above copyright notice and this permission notice shall be included in all
41
+ copies or substantial portions of the Software.
42
+
43
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
46
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
48
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
49
+ SOFTWARE.
package/README.md CHANGED
@@ -1,85 +1,149 @@
1
- # @motionscript/geography
2
-
3
- Country and first-level subdivision outlines for Motion Script's `GeoBorder`
4
- ([`@motionscript/geo`](https://github.com/motionscript-dev/motionscript/tree/main/packages/components/geo)), as small JSON files keyed by ISO 3166
5
- code. Derived from [Natural Earth](https://www.naturalearthdata.com/) v5.1.2
6
- (public domain); see `CREDITS.md`.
7
-
8
- The package has no JavaScript entry point. Its `exports` are `./package.json` and
9
- `./data/*`, read by path from `node_modules` or served from a static host. The geo
10
- kit does not depend on it: the two meet only at the file format.
11
-
12
- ## Install
13
-
14
- ```bash
15
- npm install @motionscript/geography
16
- ```
17
-
18
- Or serve `data/` from a static host. Registering it as `GeoBorder`'s data source:
19
- [motionscript.dev/docs](https://motionscript.dev/docs).
20
-
21
- ## The data is generated, never edited
22
-
23
- `data/` and `.cache/` are gitignored. `scripts/generate.mjs` removes `data/v1/`
24
- and writes it whole, from three Natural Earth GeoJSON files pinned in
25
- `sources.lock.json` (tag, URL, sha256, size). A downloaded or cached file that
26
- does not match the lock is refused, and a file is cached only after it matches.
27
- The lock changes only through `--update-lock`. To change what a code draws, change
28
- the generator or its tables (`scripts/lib/*.mjs`) and regenerate.
29
-
30
- ```bash
31
- pnpm --filter @motionscript/geography generate # network on first run, ~8 GB heap
32
- pnpm --filter @motionscript/geography verify # checks data/v1/
33
- pnpm --filter @motionscript/geography test # node --test over scripts/tests
34
- node scripts/fixture.mjs <out-dir> # cut the geo kit's test fixture from data/
35
- node --max-old-space-size=8192 scripts/generate.mjs --update-lock # re-pin sources
36
- ```
37
-
38
- `prepack` (before `npm pack` and `publish`) generates `data/` when it is missing,
39
- then runs `verify`; the package has no `build`, `lint` or `typecheck`. The geo kit's
40
- committed fixture is `components/geo/src/border/tests/fixtures/v1/`.
41
-
42
- ## Layout and keys
43
-
44
- ```
45
- data/v1/index.json every listed region: [code, name, nameNl, parent|null, first 0|1]
46
- data/v1/countries/<ISO2>.json one country per file
47
- data/v1/states/<prefix>.json every subdivision whose code starts with <prefix> (US-CA is in states/US)
48
- ```
49
-
50
- - **Countries** are ISO 3166-1 alpha-2 codes from Natural Earth's de facto
51
- worldview, plus `XK` (Kosovo) and two user-assigned codes: `XS` Somaliland and
52
- `XN` Northern Cyprus. Territories the default file folds into a parent (`GF`,
53
- `RE`, `SJ`, ...) are countries of their own while the parent keeps its geometry.
54
- - **Subdivisions** are ISO 3166-2 codes (`US-CA`, `FR-IDF`, `GB-ENG`), filed by the
55
- code's prefix, never by `adm0_a3` (which files Crimea under Russia and Puerto
56
- Rico outside the US). First-level regions of FR, GB, IT, ES and PH are built from
57
- Natural Earth's second-level units.
58
- - **Unlisted features** (placeholders such as `SY-X01`, codeless `-99` units) are in
59
- the files so a state map has no holes, and absent from `index.json`.
60
- - **A feature** has `code`, `name`, `nameNl`, `parent`, `first`, `listed`, optional
61
- `remote`, `area` (steradians), `mainland` (polygon indices, or `null` when all),
62
- `areas` and `polygons` (rings of arc references; `~i` is arc `i` reversed).
63
-
64
- ## Invariants
65
-
66
- - **One topology.** Every country and subdivision is stitched and quantised
67
- together (1e6 steps, one `transform` for every file), so a border two regions
68
- share is one arc with one global id (`arcIds`) in every file that uses it, and
69
- simplifies identically on both sides. The renderer relies on it to stroke the
70
- border once.
71
- - **Simplification is stored, not applied.** Each arc point is a triple
72
- `x, y, bucket` (the first `x`, `y` absolute, the rest deltas). The bucket is
73
- `clamp(round(-2 * log2(weight)), 1, 254)` of the point's spherical triangle area,
74
- 0 for an arc's first and last point (so no detail setting can open a ring), and
75
- 255 for a non-positive weight. `GeoBorder`'s `detail` is a draw-time threshold
76
- over the bucket, so one set of files serves every detail.
77
- - **No file is over 1.5 MiB**, so any one can be fetched alone (`verify`).
78
- - **The format is in the path.** A change in meaning or removal of a field is a new
79
- `data/v<N>/`, with `FORMAT` in `scripts/generate.mjs` and `scripts/verify.mjs` and
80
- `GEO_DATA_FORMAT` in the geo kit's `src/border/format.ts` moving together; adding
81
- a field is compatible with the kit's decoder, which ignores unknown ones.
82
- - **`verify` checks structure and coverage, not provenance**: arc and index
83
- integrity, endpoints, size, and minimum counts (249 countries, the 50 US states
84
- and DC, FR, GB, IT, ES, CA, DE and AU first-level regions). It does not compare
85
- the data with the lock or the generator.
1
+ # @motionscript/geography
2
+
3
+ Geography for [Motion Script](https://motionscript.dev): `GeoBorder`, country and
4
+ state outlines by ISO 3166 code. Hand `NODES` to the engine through your
5
+ project entry, and a document can name `geoBorder`:
6
+
7
+ ```ts
8
+ // src/project.ts
9
+ import { NODES } from '@motionscript/geography';
10
+
11
+ export const nodes = NODES;
12
+ ```
13
+
14
+ `GeoBorder` draws nothing until a data source is registered; see
15
+ [its docs page](https://motionscript.dev/docs/components/geography/geo-border).
16
+
17
+ This package is written against [`@motionscript/sdk`](https://github.com/motionscript-dev/motionscript/tree/main/packages/sdk), which it
18
+ takes as a peer dependency.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ npm install @motionscript/geography @motionscript/sdk
24
+ ```
25
+
26
+ ## GeoBorder
27
+
28
+ - **`start` and `end` trim the fill and the overlay as well as the outline.**
29
+ Each path is cut to the part of `[start, end]` that falls inside it, so a
30
+ filled border drawn on with `end` from 0 to 1 grows as partial polygons, each
31
+ closed by a straight chord, and a stroke-only one grows as a line. There is no
32
+ way to trim the stroke alone.
33
+ - **Fill and stroke are separate geometry.** The fill is each kept polygon; the
34
+ stroke draws each arc once, so a border two selected regions share is stroked
35
+ once, and `stroke.align` is forced to the centre. `clipSelf` is the layout box,
36
+ not the outline.
37
+ - **`detail` never refits.** The files store a simplification bucket per point,
38
+ `detail` is a draw-time threshold over it, and the projection is fitted at full
39
+ detail and cached apart from it, so tweening `detail` does not move the drawing.
40
+ - **`iso` is a list of codes**, as an array or text split on spaces, commas and
41
+ semicolons, upper-cased. A code is `AB` or `AB-XYZ`; one that is not, or that no
42
+ loaded file has, draws nothing and warns once. A bare country code draws the
43
+ country, or at `level: "state"` its first-level subdivisions (minus `remote`
44
+ ones when `frame` is `"mainland"`); a subdivision code is always itself.
45
+ - **Drawing never throws.** A node declares each file it needs as the asset
46
+ `geo:<key>` (gate `render`: layout does not wait for it, but an export loads the
47
+ files before the frame that needs them); a missing or failed file draws nothing.
48
+
49
+ ### Data sources
50
+
51
+ The files are this package's own `data/` (see [The data](#the-data)); the kit
52
+ reads them only through their format
53
+ (`v1/index`, `v1/countries/<ISO2>`, `v1/states/<ISO2>`, where `v1/states/US`
54
+ holds every `US-…` unit). The registry is process-wide, shared by every engine,
55
+ session and node:
56
+
57
+ ```ts
58
+ import { geoRegistry, geoUrlSource } from '@motionscript/geography';
59
+
60
+ geoRegistry.use(geoUrlSource('/geo')); // serves the *contents of* @motionscript/geography/data
61
+ geoRegistry.define({ 'XX-ATLANTIS': { shape: geojsonPolygon, name: 'Atlantis' } });
62
+ ```
63
+
64
+ - **Sources are asked in registration order; the first non-null answer wins.**
65
+ `null` means "not here" and a throw means "could not tell"; neither is cached
66
+ for good, and `loadGeoFile` never rejects. `geoUrlSource` treats HTTP 404 and 400
67
+ as absent. `geoLoaderSource(load)` wraps text, bytes or parsed JSON (for example
68
+ `fs.readFile`). With no source registered nothing loads and `GeoBorder` draws
69
+ nothing.
70
+ - **A defined shape wins over every source** and needs none. It is GeoJSON in
71
+ lon/lat, wound either way round, and is simplified by `detail` like any other.
72
+ - **Decoded files are never freed** while the process lives (`clearGeoFiles`
73
+ exists for tests), and `geoLoader(key)` returns one function per key, so any
74
+ number of nodes declare the same loader.
75
+
76
+ ## The data
77
+
78
+ The package also ships the outlines `GeoBorder` draws: country and first-level
79
+ subdivision outlines keyed by ISO 3166 code, as small JSON files derived from
80
+ [Natural Earth](https://www.naturalearthdata.com/) v5.1.2 (public domain; see
81
+ `CREDITS.md`). They are in `data/` and exported as `./data/*`, read by path from
82
+ `node_modules` or served from a static host. The kit's code does not import
83
+ them.
84
+
85
+ ### The data is generated, never edited
86
+
87
+ `data/` and `.cache/` are gitignored. `scripts/generate.mjs` removes `data/v1/`
88
+ and writes it whole, from three Natural Earth GeoJSON files pinned in
89
+ `sources.lock.json` (tag, URL, sha256, size). A downloaded or cached file that
90
+ does not match the lock is refused, and a file is cached only after it matches.
91
+ The lock changes only through `--update-lock`. To change what a code draws, change
92
+ the generator or its tables (`scripts/lib/*.mjs`) and regenerate.
93
+
94
+ ```bash
95
+ pnpm --filter @motionscript/geography generate # network on first run, ~8 GB heap
96
+ pnpm --filter @motionscript/geography verify # checks data/v1/
97
+ pnpm --filter @motionscript/geography test # node --test over scripts/tests
98
+ node scripts/fixture.mjs <out-dir> # cut the geo kit's test fixture from data/
99
+ node --max-old-space-size=8192 scripts/generate.mjs --update-lock # re-pin sources
100
+ ```
101
+
102
+ `prepack` (before `npm pack` and `publish`) generates `data/` when it is missing,
103
+ then runs `verify`; the package has no `build`, `lint` or `typecheck`. The geo kit's
104
+ committed fixture is `components/geography/src/border/tests/fixtures/v1/`.
105
+
106
+ ### Layout and keys
107
+
108
+ ```
109
+ data/v1/index.json every listed region: [code, name, nameNl, parent|null, first 0|1]
110
+ data/v1/countries/<ISO2>.json one country per file
111
+ data/v1/states/<prefix>.json every subdivision whose code starts with <prefix> (US-CA is in states/US)
112
+ ```
113
+
114
+ - **Countries** are ISO 3166-1 alpha-2 codes from Natural Earth's de facto
115
+ worldview, plus `XK` (Kosovo) and two user-assigned codes: `XS` Somaliland and
116
+ `XN` Northern Cyprus. Territories the default file folds into a parent (`GF`,
117
+ `RE`, `SJ`, ...) are countries of their own while the parent keeps its geometry.
118
+ - **Subdivisions** are ISO 3166-2 codes (`US-CA`, `FR-IDF`, `GB-ENG`), filed by the
119
+ code's prefix, never by `adm0_a3` (which files Crimea under Russia and Puerto
120
+ Rico outside the US). First-level regions of FR, GB, IT, ES and PH are built from
121
+ Natural Earth's second-level units.
122
+ - **Unlisted features** (placeholders such as `SY-X01`, codeless `-99` units) are in
123
+ the files so a state map has no holes, and absent from `index.json`.
124
+ - **A feature** has `code`, `name`, `nameNl`, `parent`, `first`, `listed`, optional
125
+ `remote`, `area` (steradians), `mainland` (polygon indices, or `null` when all),
126
+ `areas` and `polygons` (rings of arc references; `~i` is arc `i` reversed).
127
+
128
+ ### Invariants
129
+
130
+ - **One topology.** Every country and subdivision is stitched and quantised
131
+ together (1e6 steps, one `transform` for every file), so a border two regions
132
+ share is one arc with one global id (`arcIds`) in every file that uses it, and
133
+ simplifies identically on both sides. The renderer relies on it to stroke the
134
+ border once.
135
+ - **Simplification is stored, not applied.** Each arc point is a triple
136
+ `x, y, bucket` (the first `x`, `y` absolute, the rest deltas). The bucket is
137
+ `clamp(round(-2 * log2(weight)), 1, 254)` of the point's spherical triangle area,
138
+ 0 for an arc's first and last point (so no detail setting can open a ring), and
139
+ 255 for a non-positive weight. `GeoBorder`'s `detail` is a draw-time threshold
140
+ over the bucket, so one set of files serves every detail.
141
+ - **No file is over 1.5 MiB**, so any one can be fetched alone (`verify`).
142
+ - **The format is in the path.** A change in meaning or removal of a field is a new
143
+ `data/v<N>/`, with `FORMAT` in `scripts/generate.mjs` and `scripts/verify.mjs` and
144
+ `GEO_DATA_FORMAT` in the geo kit's `src/border/format.ts` moving together; adding
145
+ a field is compatible with the kit's decoder, which ignores unknown ones.
146
+ - **`verify` checks structure and coverage, not provenance**: arc and index
147
+ integrity, endpoints, size, and minimum counts (249 countries, the 50 US states
148
+ and DC, FR, GB, IT, ES, CA, DE and AU first-level regions). It does not compare
149
+ the data with the lock or the generator.
@@ -0,0 +1,73 @@
1
+ /** The on-disk shape `@motionscript/geography` writes; see its `generate.mjs`. */
2
+ export declare const GEO_DATA_FORMAT = 1;
3
+ export interface GeoFileData {
4
+ format: number;
5
+ source?: string;
6
+ transform: {
7
+ scale: [number, number];
8
+ translate: [number, number];
9
+ };
10
+ /** Global arc id per local arc — identical across files for a shared border. */
11
+ arcIds: number[];
12
+ /** Per arc, flat `[x0, y0, w0, dx, dy, w, …]`: delta-encoded quantized lon/lat and a weight bucket. */
13
+ arcs: number[][];
14
+ features: GeoFeatureData[];
15
+ }
16
+ export interface GeoFeatureData {
17
+ code: string;
18
+ name: string;
19
+ nameNl?: string;
20
+ parent: string | null;
21
+ first: boolean;
22
+ listed: boolean;
23
+ remote?: boolean;
24
+ area: number;
25
+ mainland: number[] | null;
26
+ areas: number[];
27
+ /** Polygons → rings → arc refs (`~i` is arc `i` reversed). */
28
+ polygons: number[][][];
29
+ }
30
+ /** `[code, name, nameNl, parent, first]` per listed region. */
31
+ export type GeoIndexEntry = [string, string, string, string | null, 0 | 1];
32
+ export interface GeoIndex {
33
+ format: number;
34
+ source?: string;
35
+ regions: GeoIndexEntry[];
36
+ }
37
+ export interface GeoArc {
38
+ /** Identity for de-duplicating a border drawn by two regions, across files. */
39
+ key: number | string;
40
+ /** Interleaved lon/lat, in degrees. */
41
+ points: Float64Array;
42
+ /** Per point: 0 always survives, higher buckets are less significant; see `thresholdBucket`. */
43
+ buckets: Uint8Array;
44
+ }
45
+ export interface GeoRingRef {
46
+ arc: GeoArc;
47
+ reversed: boolean;
48
+ }
49
+ export interface GeoPolygon {
50
+ rings: GeoRingRef[][];
51
+ /** Per ring, in steradians — exterior first, then holes. */
52
+ ringAreas: number[];
53
+ area: number;
54
+ mainland: boolean;
55
+ }
56
+ export interface GeoFeature {
57
+ code: string;
58
+ name: string;
59
+ nameNl: string;
60
+ parent: string | null;
61
+ first: boolean;
62
+ listed: boolean;
63
+ remote: boolean;
64
+ polygons: GeoPolygon[];
65
+ }
66
+ export interface DecodedGeoFile {
67
+ features: Map<string, GeoFeature>;
68
+ }
69
+ export declare function ringCoordinates(ring: readonly GeoRingRef[]): [number, number][];
70
+ /** A ring's area in steradians, whichever way it winds. */
71
+ export declare function ringArea(ring: readonly GeoRingRef[]): number;
72
+ export declare function decodeGeoFile(data: GeoFileData): DecodedGeoFile;
73
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/border/format.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,eAAO,MAAM,eAAe,IAAI,CAAA;AAEhC,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE;QAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;IACnE,gFAAgF;IAChF,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,uGAAuG;IACvG,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;IAChB,QAAQ,EAAE,cAAc,EAAE,CAAA;CAC7B;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACzB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;CACzB;AAED,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;AAE1E,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,aAAa,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,MAAM;IACnB,+EAA+E;IAC/E,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,uCAAuC;IACvC,MAAM,EAAE,YAAY,CAAA;IACpB,gGAAgG;IAChG,OAAO,EAAE,UAAU,CAAA;CACtB;AAED,MAAM,WAAW,UAAU;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,UAAU,EAAE,EAAE,CAAA;IACrB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,UAAU,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CACpC;AAkBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAU/E;AAED,2DAA2D;AAC3D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAK5D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,cAAc,CAiC/D"}
@@ -0,0 +1,68 @@
1
+ import { geoArea } from "d3-geo";
2
+ /** The on-disk shape `@motionscript/geography` writes; see its `generate.mjs`. */
3
+ export const GEO_DATA_FORMAT = 1;
4
+ function decodeArc(encoded, key, [kx, ky], [tx, ty]) {
5
+ const count = encoded.length / 3;
6
+ const points = new Float64Array(count * 2);
7
+ const buckets = new Uint8Array(count);
8
+ let x = 0;
9
+ let y = 0;
10
+ for (let i = 0; i < count; i++) {
11
+ x += encoded[i * 3];
12
+ y += encoded[i * 3 + 1];
13
+ points[i * 2] = x * kx + tx;
14
+ points[i * 2 + 1] = y * ky + ty;
15
+ buckets[i] = encoded[i * 3 + 2];
16
+ }
17
+ return { key, points, buckets };
18
+ }
19
+ export function ringCoordinates(ring) {
20
+ const out = [];
21
+ for (const { arc, reversed } of ring) {
22
+ const n = arc.buckets.length;
23
+ for (let j = out.length === 0 ? 0 : 1; j < n; j++) {
24
+ const i = reversed ? n - 1 - j : j;
25
+ out.push([arc.points[i * 2], arc.points[i * 2 + 1]]);
26
+ }
27
+ }
28
+ return out;
29
+ }
30
+ /** A ring's area in steradians, whichever way it winds. */
31
+ export function ringArea(ring) {
32
+ const coordinates = ringCoordinates(ring);
33
+ if (coordinates.length < 4)
34
+ return 0;
35
+ const area = geoArea({ type: "Polygon", coordinates: [coordinates] });
36
+ return area > 2 * Math.PI ? 4 * Math.PI - area : area;
37
+ }
38
+ export function decodeGeoFile(data) {
39
+ if (data.format !== GEO_DATA_FORMAT) {
40
+ throw new Error(`geo data format ${data.format} is not supported (expected ${GEO_DATA_FORMAT})`);
41
+ }
42
+ const arcs = data.arcs.map((encoded, i) => decodeArc(encoded, data.arcIds[i], data.transform.scale, data.transform.translate));
43
+ const ref = (index) => index < 0 ? { arc: arcs[~index], reversed: true } : { arc: arcs[index], reversed: false };
44
+ const features = new Map();
45
+ for (const f of data.features) {
46
+ const mainland = f.mainland ? new Set(f.mainland) : null;
47
+ features.set(f.code, {
48
+ code: f.code,
49
+ name: f.name,
50
+ nameNl: f.nameNl ?? f.name,
51
+ parent: f.parent,
52
+ first: f.first,
53
+ listed: f.listed,
54
+ remote: f.remote === true,
55
+ polygons: f.polygons.map((rings, i) => {
56
+ const resolved = rings.map((ring) => ring.map(ref));
57
+ return {
58
+ rings: resolved,
59
+ ringAreas: resolved.map((ring, r) => (r === 0 ? f.areas[i] : ringArea(ring))),
60
+ area: f.areas[i],
61
+ mainland: mainland === null || mainland.has(i),
62
+ };
63
+ }),
64
+ });
65
+ }
66
+ return { features };
67
+ }
68
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/border/format.ts"],"names":[],"mappings":"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","sourcesContent":["import { geoArea } from \"d3-geo\"\n\n/** The on-disk shape `@motionscript/geography` writes; see its `generate.mjs`. */\nexport const GEO_DATA_FORMAT = 1\n\nexport interface GeoFileData {\n format: number\n source?: string\n transform: { scale: [number, number]; translate: [number, number] }\n /** Global arc id per local arc — identical across files for a shared border. */\n arcIds: number[]\n /** Per arc, flat `[x0, y0, w0, dx, dy, w, …]`: delta-encoded quantized lon/lat and a weight bucket. */\n arcs: number[][]\n features: GeoFeatureData[]\n}\n\nexport interface GeoFeatureData {\n code: string\n name: string\n nameNl?: string\n parent: string | null\n first: boolean\n listed: boolean\n remote?: boolean\n area: number\n mainland: number[] | null\n areas: number[]\n /** Polygons → rings → arc refs (`~i` is arc `i` reversed). */\n polygons: number[][][]\n}\n\n/** `[code, name, nameNl, parent, first]` per listed region. */\nexport type GeoIndexEntry = [string, string, string, string | null, 0 | 1]\n\nexport interface GeoIndex {\n format: number\n source?: string\n regions: GeoIndexEntry[]\n}\n\nexport interface GeoArc {\n /** Identity for de-duplicating a border drawn by two regions, across files. */\n key: number | string\n /** Interleaved lon/lat, in degrees. */\n points: Float64Array\n /** Per point: 0 always survives, higher buckets are less significant; see `thresholdBucket`. */\n buckets: Uint8Array\n}\n\nexport interface GeoRingRef {\n arc: GeoArc\n reversed: boolean\n}\n\nexport interface GeoPolygon {\n rings: GeoRingRef[][]\n /** Per ring, in steradians — exterior first, then holes. */\n ringAreas: number[]\n area: number\n mainland: boolean\n}\n\nexport interface GeoFeature {\n code: string\n name: string\n nameNl: string\n parent: string | null\n first: boolean\n listed: boolean\n remote: boolean\n polygons: GeoPolygon[]\n}\n\nexport interface DecodedGeoFile {\n features: Map<string, GeoFeature>\n}\n\nfunction decodeArc(encoded: number[], key: number, [kx, ky]: [number, number], [tx, ty]: [number, number]): GeoArc {\n const count = encoded.length / 3\n const points = new Float64Array(count * 2)\n const buckets = new Uint8Array(count)\n let x = 0\n let y = 0\n for (let i = 0; i < count; i++) {\n x += encoded[i * 3]\n y += encoded[i * 3 + 1]\n points[i * 2] = x * kx + tx\n points[i * 2 + 1] = y * ky + ty\n buckets[i] = encoded[i * 3 + 2]\n }\n return { key, points, buckets }\n}\n\nexport function ringCoordinates(ring: readonly GeoRingRef[]): [number, number][] {\n const out: [number, number][] = []\n for (const { arc, reversed } of ring) {\n const n = arc.buckets.length\n for (let j = out.length === 0 ? 0 : 1; j < n; j++) {\n const i = reversed ? n - 1 - j : j\n out.push([arc.points[i * 2], arc.points[i * 2 + 1]])\n }\n }\n return out\n}\n\n/** A ring's area in steradians, whichever way it winds. */\nexport function ringArea(ring: readonly GeoRingRef[]): number {\n const coordinates = ringCoordinates(ring)\n if (coordinates.length < 4) return 0\n const area = geoArea({ type: \"Polygon\", coordinates: [coordinates] })\n return area > 2 * Math.PI ? 4 * Math.PI - area : area\n}\n\nexport function decodeGeoFile(data: GeoFileData): DecodedGeoFile {\n if (data.format !== GEO_DATA_FORMAT) {\n throw new Error(`geo data format ${data.format} is not supported (expected ${GEO_DATA_FORMAT})`)\n }\n const arcs = data.arcs.map((encoded, i) =>\n decodeArc(encoded, data.arcIds[i], data.transform.scale, data.transform.translate)\n )\n const ref = (index: number): GeoRingRef =>\n index < 0 ? { arc: arcs[~index], reversed: true } : { arc: arcs[index], reversed: false }\n\n const features = new Map<string, GeoFeature>()\n for (const f of data.features) {\n const mainland = f.mainland ? new Set(f.mainland) : null\n features.set(f.code, {\n code: f.code,\n name: f.name,\n nameNl: f.nameNl ?? f.name,\n parent: f.parent,\n first: f.first,\n listed: f.listed,\n remote: f.remote === true,\n polygons: f.polygons.map((rings, i) => {\n const resolved = rings.map((ring) => ring.map(ref))\n return {\n rings: resolved,\n ringAreas: resolved.map((ring, r) => (r === 0 ? f.areas[i] : ringArea(ring))),\n area: f.areas[i],\n mainland: mainland === null || mainland.has(i),\n }\n }),\n })\n }\n return { features }\n}\n"]}
@@ -0,0 +1,103 @@
1
+ import { type FillResolved, type NodeOf, type Alignment as _Alignment, type Fill as _Fill, type FlowMode as _FlowMode, type FlowResolved as _FlowResolved, type GapSize as _GapSize, type Node2D as _Node2D, type Node2DProps as _Node2DProps, type Shadow as _Shadow, type Stroke as _Stroke, type Vector2 as _Vector2, type ShadowResolved, type ShapeProps, type StrokeResolved, type Type } from "@motionscript/sdk";
2
+ import { type GeoBorders, type GeoProjectionKind } from "./geometry.js";
3
+ import { type GeoFrame, type GeoLevel } from "./selection.js";
4
+ export interface GeoBorderProps extends ShapeProps {
5
+ /** ISO 3166-1 alpha-2 (`"FR"`) or ISO 3166-2 (`"US-CA"`) codes. */
6
+ iso: string | readonly string[];
7
+ level: GeoLevel;
8
+ /** 0–1: 1 is full resolution, lower is a more stylised outline. */
9
+ detail: number;
10
+ projection: GeoProjectionKind;
11
+ frame: GeoFrame;
12
+ borders: GeoBorders;
13
+ }
14
+ /**
15
+ * Country and subdivision outlines by ISO 3166 code, fitted into the node's box.
16
+ *
17
+ * <GeoBorder iso={["FR", "DE"]} detail={0.4} stroke={{ weight: 2, fill: "white" }} />
18
+ *
19
+ * Geometry comes from whatever `geoRegistry` has been given — a URL, a loader,
20
+ * or shapes defined by hand — and loads as a declared asset, so a frame never
21
+ * draws half a country. Fill and stroke are separate geometry: the fill is each
22
+ * region's polygons, the stroke is every border once, which is why a border two
23
+ * selected regions share is not drawn twice and why `stroke.align` does not
24
+ * apply.
25
+ */
26
+ export declare const GeoBorder: import("@motionscript/sdk").Component<"geoBorder", import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
27
+ readonly iso: Type<string | readonly string[], string[], false>;
28
+ readonly level: Type<"country" | "state", "country" | "state", false>;
29
+ readonly detail: Type<number, number, false>;
30
+ readonly projection: Type<"conic" | "mercator" | "equirectangular" | "orthographic", "conic" | "mercator" | "equirectangular" | "orthographic", false>;
31
+ readonly frame: Type<"mainland" | "all", "mainland" | "all", false>;
32
+ readonly borders: Type<"all" | "outline", "all" | "outline", false>;
33
+ readonly flow: Type<_FlowMode, _FlowResolved, false>;
34
+ readonly gap: Type<_GapSize, _GapSize, false>;
35
+ readonly wrap: boolean;
36
+ readonly crossGap: Type<number | undefined, number | undefined, false>;
37
+ readonly columns: Type<number, number, false>;
38
+ readonly align: import("@motionscript/sdk").Attribute<_Alignment, _Vector2>;
39
+ readonly fill: import("@motionscript/sdk").Attribute<_Fill, FillResolved[]>;
40
+ readonly stroke: import("@motionscript/sdk").Attribute<_Stroke, StrokeResolved[]>;
41
+ readonly shadow: import("@motionscript/sdk").Attribute<_Shadow, ShadowResolved[]>;
42
+ readonly overlay: import("@motionscript/sdk").Attribute<_Fill, FillResolved[]>;
43
+ readonly start: Type<number, number, false>;
44
+ readonly end: Type<number, number, false>;
45
+ }>, {
46
+ readonly fillTo: readonly ["fill"];
47
+ readonly strokeTo: readonly ["stroke"];
48
+ readonly shadowTo: readonly ["shadow"];
49
+ readonly overlayTo: readonly ["overlay"];
50
+ readonly progressTo: readonly ["start", "end"];
51
+ readonly flash: {
52
+ readonly portion: Type<number, number, false>;
53
+ };
54
+ }, null, _Node2D<_Node2DProps>, import("@motionscript/sdk").CallProps<import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
55
+ readonly iso: Type<string | readonly string[], string[], false>;
56
+ readonly level: Type<"country" | "state", "country" | "state", false>;
57
+ readonly detail: Type<number, number, false>;
58
+ readonly projection: Type<"conic" | "mercator" | "equirectangular" | "orthographic", "conic" | "mercator" | "equirectangular" | "orthographic", false>;
59
+ readonly frame: Type<"mainland" | "all", "mainland" | "all", false>;
60
+ readonly borders: Type<"all" | "outline", "all" | "outline", false>;
61
+ readonly flow: Type<_FlowMode, _FlowResolved, false>;
62
+ readonly gap: Type<_GapSize, _GapSize, false>;
63
+ readonly wrap: boolean;
64
+ readonly crossGap: Type<number | undefined, number | undefined, false>;
65
+ readonly columns: Type<number, number, false>;
66
+ readonly align: import("@motionscript/sdk").Attribute<_Alignment, _Vector2>;
67
+ readonly fill: import("@motionscript/sdk").Attribute<_Fill, FillResolved[]>;
68
+ readonly stroke: import("@motionscript/sdk").Attribute<_Stroke, StrokeResolved[]>;
69
+ readonly shadow: import("@motionscript/sdk").Attribute<_Shadow, ShadowResolved[]>;
70
+ readonly overlay: import("@motionscript/sdk").Attribute<_Fill, FillResolved[]>;
71
+ readonly start: Type<number, number, false>;
72
+ readonly end: Type<number, number, false>;
73
+ }>, null, import("@motionscript/sdk").BuiltNode<import("@motionscript/sdk").Merge<import("@motionscript/sdk").Box2DState, {
74
+ readonly iso: Type<string | readonly string[], string[], false>;
75
+ readonly level: Type<"country" | "state", "country" | "state", false>;
76
+ readonly detail: Type<number, number, false>;
77
+ readonly projection: Type<"conic" | "mercator" | "equirectangular" | "orthographic", "conic" | "mercator" | "equirectangular" | "orthographic", false>;
78
+ readonly frame: Type<"mainland" | "all", "mainland" | "all", false>;
79
+ readonly borders: Type<"all" | "outline", "all" | "outline", false>;
80
+ readonly flow: Type<_FlowMode, _FlowResolved, false>;
81
+ readonly gap: Type<_GapSize, _GapSize, false>;
82
+ readonly wrap: boolean;
83
+ readonly crossGap: Type<number | undefined, number | undefined, false>;
84
+ readonly columns: Type<number, number, false>;
85
+ readonly align: import("@motionscript/sdk").Attribute<_Alignment, _Vector2>;
86
+ readonly fill: import("@motionscript/sdk").Attribute<_Fill, FillResolved[]>;
87
+ readonly stroke: import("@motionscript/sdk").Attribute<_Stroke, StrokeResolved[]>;
88
+ readonly shadow: import("@motionscript/sdk").Attribute<_Shadow, ShadowResolved[]>;
89
+ readonly overlay: import("@motionscript/sdk").Attribute<_Fill, FillResolved[]>;
90
+ readonly start: Type<number, number, false>;
91
+ readonly end: Type<number, number, false>;
92
+ }>, {
93
+ readonly fillTo: readonly ["fill"];
94
+ readonly strokeTo: readonly ["stroke"];
95
+ readonly shadowTo: readonly ["shadow"];
96
+ readonly overlayTo: readonly ["overlay"];
97
+ readonly progressTo: readonly ["start", "end"];
98
+ readonly flash: {
99
+ readonly portion: Type<number, number, false>;
100
+ };
101
+ }, _Node2D<_Node2DProps>>>>;
102
+ export type GeoBorder = NodeOf<typeof GeoBorder>;
103
+ //# sourceMappingURL=geo-border.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geo-border.d.ts","sourceRoot":"","sources":["../../src/border/geo-border.ts"],"names":[],"mappings":"AAAA,OAAO,EAQH,KAAK,YAAY,EACjB,KAAK,MAAM,EAEX,KAAK,SAAS,IAAI,UAAU,EAC5B,KAAK,IAAI,IAAI,KAAK,EAClB,KAAK,QAAQ,IAAI,SAAS,EAC1B,KAAK,YAAY,IAAI,aAAa,EAClC,KAAK,OAAO,IAAI,QAAQ,EACxB,KAAK,MAAM,IAAI,OAAO,EACtB,KAAK,WAAW,IAAI,YAAY,EAChC,KAAK,MAAM,IAAI,OAAO,EACtB,KAAK,MAAM,IAAI,OAAO,EACtB,KAAK,OAAO,IAAI,QAAQ,EAExB,KAAK,cAAc,EACnB,KAAK,UAAU,EAEf,KAAK,cAAc,EACnB,KAAK,IAAI,EACZ,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAe,KAAK,UAAU,EAAqC,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGpH,OAAO,EAAgD,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAA;AAExG,MAAM,WAAW,cAAe,SAAQ,UAAU;IAC9C,mEAAmE;IACnE,GAAG,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;IAC/B,KAAK,EAAE,QAAQ,CAAA;IACf,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,iBAAiB,CAAA;IAC7B,KAAK,EAAE,QAAQ,CAAA;IACf,OAAO,EAAE,UAAU,CAAA;CACtB;AA4ID;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAqEpB,CAAA;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,SAAS,CAAC,CAAA"}