@fxi/zartigl 0.4.2 → 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/README.md +117 -11
- package/dist/GeoVideoScalarSource-DoQAnyTy.js +38 -0
- package/dist/catalog.d.ts +40 -2
- package/dist/catalog.js +111 -62
- package/dist/engine.d.ts +616 -0
- package/dist/engine.js +29 -0
- package/dist/geovideo-index-CD5wflJT.js +833 -0
- package/dist/land-50m-BX3pQS4x.js +15 -0
- package/dist/projversor.d.ts +919 -0
- package/dist/projversor.js +2374 -0
- package/dist/scalar-color-domain-PEK8Hxg1.js +12 -0
- package/dist/story.d.ts +398 -0
- package/dist/story.js +561 -0
- package/dist/zartigl.d.ts +356 -34
- package/dist/zartigl.js +3606 -2637
- package/package.json +49 -7
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
const I = { label: "Thermal", tags: ["sequential", "temperature"], colors: ["#042333", "#2c3395", "#744796", "#b15f82", "#eb7958", "#fbb43d", "#e8fa5b"] }, N = { label: "Haline", tags: ["sequential", "salinity"], colors: ["#2a186c", "#17568b", "#1a7e8f", "#22a785", "#55c666", "#aadc32", "#fde333"] }, L = { label: "Solar", tags: ["sequential", "irradiance"], colors: ["#330f0b", "#6b2313", "#a83c12", "#d6621a", "#f3951e", "#f7c741", "#f9f871"] }, V = { label: "Ice", tags: ["sequential"], colors: ["#040d1a", "#123365", "#1c5f9e", "#2b8ece", "#62bde3", "#aaddf2", "#f2faff"] }, B = { label: "Deep", tags: ["sequential", "depth"], colors: ["#fdfecc", "#c8e59b", "#74c8a3", "#3194b0", "#2a5b8e", "#281a5e", "#0c0820"] }, k = { label: "RdYlBu", tags: ["diverging"], colors: ["#3288bd", "#66c2a5", "#abdda4", "#e6f598", "#fee08b", "#fdae61", "#f46d43", "#d53e4f"] }, X = { label: "Dense", tags: ["sequential"], colors: ["#e6f1f1", "#92c4ca", "#44929a", "#20627a", "#1a3c6a", "#211a50", "#0d0621"] }, C = { label: "Algae", tags: ["sequential", "biology", "log"], colors: ["#d7f9d0", "#a2d595", "#64b463", "#129450", "#126e45", "#1a482f", "#122414"] }, O = { label: "Oxygen", tags: ["sequential", "biology", "hypoxia"], colors: ["#09060f", "#5b1028", "#d43d2f", "#f39b3d", "#f3e7b3", "#79cbd1", "#176b9c"] }, q = { label: "Matter", tags: ["sequential", "biology"], colors: ["#fdfecc", "#f2c98a", "#e07c4e", "#bc3754", "#8d1a6d", "#51156b", "#1c0c3f"] }, g = { label: "Viridis", tags: ["sequential", "perceptual"], colors: ["#440154", "#443983", "#31688e", "#21918c", "#35b779", "#90d743", "#fde725"] }, W = { label: "Plasma", tags: ["sequential", "perceptual"], colors: ["#0d0887", "#5e01a6", "#9c179e", "#cc4778", "#ed7953", "#fdb42f", "#f0f921"] }, $ = { label: "Cyclic", tags: ["cyclic", "direction"], colors: ["#2e22ea", "#b541fb", "#fc93c0", "#f1ee35", "#77c80d", "#458776", "#2c24e9"] }, H = { label: "Tempo", tags: ["sequential"], colors: ["#fff6f4", "#c2d1b9", "#7db390", "#2a937f", "#156d73", "#1c455b", "#151d44"] }, j = { label: "Turbid", tags: ["sequential", "biology", "log"], colors: ["#e9f5a0", "#c8c86e", "#a09845", "#786031", "#533324", "#341423", "#150d17"] }, Y = { label: "Speed", tags: ["sequential", "velocity"], colors: ["#fcfea4", "#d5e429", "#94c63e", "#52a657", "#2d8169", "#1d5b6d", "#0d3361"] }, z = { label: "Amp", tags: ["sequential"], colors: ["#f2f2f2", "#c0b8db", "#9180b6", "#6c4e9e", "#4e2e83", "#32185d", "#110a35"] }, K = { label: "Balance", tags: ["diverging"], colors: ["#181c43", "#3066af", "#9bbcdd", "#f2f2f2", "#e07d53", "#b13626", "#2c0b0e"] }, J = { label: "Delta", tags: ["diverging"], colors: ["#0e3f31", "#20877b", "#99d4c1", "#f2f2f2", "#a1b0d4", "#3c5b9e", "#0d1938"] }, Q = { label: "Curl", tags: ["diverging"], colors: ["#152237", "#2471b3", "#8dbac4", "#f2f2f2", "#c79f84", "#a63827", "#270b17"] }, Z = { label: "Gray", tags: ["sequential"], colors: ["#000000", "#252525", "#4d4d4d", "#7a7a7a", "#a8a8a8", "#d4d4d4", "#ffffff"] }, G = {
|
|
2
|
+
thermal: I,
|
|
3
|
+
"thermal-alt": { label: "Thermal Alt", tags: ["sequential", "temperature"], colors: ["#176b9c", "#79cbd1", "#f3e7b3", "#f39b3d", "#d43d2f", "#5b1028", "#09060f"] },
|
|
4
|
+
haline: N,
|
|
5
|
+
solar: L,
|
|
6
|
+
ice: V,
|
|
7
|
+
deep: B,
|
|
8
|
+
rdylbu: k,
|
|
9
|
+
dense: X,
|
|
10
|
+
algae: C,
|
|
11
|
+
oxygen: O,
|
|
12
|
+
matter: q,
|
|
13
|
+
viridis: g,
|
|
14
|
+
plasma: W,
|
|
15
|
+
cyclic: $,
|
|
16
|
+
tempo: H,
|
|
17
|
+
turbid: j,
|
|
18
|
+
speed: Y,
|
|
19
|
+
amp: z,
|
|
20
|
+
balance: K,
|
|
21
|
+
delta: J,
|
|
22
|
+
curl: Q,
|
|
23
|
+
"mono-black": { label: "Black", tags: ["monochrome", "particles"], colors: ["#000000", "#000000"] },
|
|
24
|
+
"mono-white": { label: "White", tags: ["monochrome", "particles"], colors: ["#ffffff", "#ffffff"] },
|
|
25
|
+
"mono-pink": { label: "Pink", tags: ["monochrome", "particles"], colors: ["#ff2aa1", "#ff2aa1"] },
|
|
26
|
+
gray: Z
|
|
27
|
+
};
|
|
28
|
+
function A(e) {
|
|
29
|
+
const t = {}, r = e.length - 1;
|
|
30
|
+
return e.forEach((n, a) => {
|
|
31
|
+
t[r === 0 ? 0 : a / r] = n;
|
|
32
|
+
}), t;
|
|
33
|
+
}
|
|
34
|
+
function ee(e, t) {
|
|
35
|
+
const r = G;
|
|
36
|
+
if (typeof e == "string") {
|
|
37
|
+
const n = r[e];
|
|
38
|
+
if (!n)
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Palette "${e}" not found. Available palettes: ${Object.keys(
|
|
41
|
+
r
|
|
42
|
+
).join(", ")}`
|
|
43
|
+
);
|
|
44
|
+
const a = t?.reverse ? [...n.colors].reverse() : n.colors;
|
|
45
|
+
return A(a);
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(e)) {
|
|
48
|
+
const n = t?.reverse ? [...e].reverse() : e;
|
|
49
|
+
return A(n);
|
|
50
|
+
}
|
|
51
|
+
return e;
|
|
52
|
+
}
|
|
53
|
+
function we() {
|
|
54
|
+
return Object.entries(G).map(([t, r]) => ({ id: t, ...r }));
|
|
55
|
+
}
|
|
56
|
+
function x(e, t, r) {
|
|
57
|
+
const n = e.createShader(t);
|
|
58
|
+
if (!n)
|
|
59
|
+
throw new Error("Failed to create shader");
|
|
60
|
+
if (e.shaderSource(n, r), e.compileShader(n), !e.getShaderParameter(n, e.COMPILE_STATUS)) {
|
|
61
|
+
const a = e.getShaderInfoLog(n);
|
|
62
|
+
throw e.deleteShader(n), new Error(`Shader compile error: ${a}`);
|
|
63
|
+
}
|
|
64
|
+
return n;
|
|
65
|
+
}
|
|
66
|
+
function Fe(e, t, r) {
|
|
67
|
+
const n = e.createProgram();
|
|
68
|
+
if (!n)
|
|
69
|
+
throw new Error("Failed to create program");
|
|
70
|
+
const a = x(e, e.VERTEX_SHADER, t), i = x(e, e.FRAGMENT_SHADER, r);
|
|
71
|
+
if (e.attachShader(n, a), e.attachShader(n, i), e.linkProgram(n), !e.getProgramParameter(n, e.LINK_STATUS)) {
|
|
72
|
+
const s = e.getProgramInfoLog(n);
|
|
73
|
+
throw e.deleteProgram(n), new Error(`Program link error: ${s}`);
|
|
74
|
+
}
|
|
75
|
+
return e.deleteShader(a), e.deleteShader(i), n;
|
|
76
|
+
}
|
|
77
|
+
function Ae(e, t, r, n, a) {
|
|
78
|
+
const i = e.createTexture();
|
|
79
|
+
if (!i)
|
|
80
|
+
throw new Error("Failed to create texture");
|
|
81
|
+
return e.bindTexture(e.TEXTURE_2D, i), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, t), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, t), e.texImage2D(
|
|
82
|
+
e.TEXTURE_2D,
|
|
83
|
+
0,
|
|
84
|
+
e.RGBA,
|
|
85
|
+
n,
|
|
86
|
+
a,
|
|
87
|
+
0,
|
|
88
|
+
e.RGBA,
|
|
89
|
+
e.UNSIGNED_BYTE,
|
|
90
|
+
r
|
|
91
|
+
), e.bindTexture(e.TEXTURE_2D, null), i;
|
|
92
|
+
}
|
|
93
|
+
function te(e, t, r) {
|
|
94
|
+
const n = e.getParameter(
|
|
95
|
+
e.TEXTURE_BINDING_2D
|
|
96
|
+
), a = e.getParameter(
|
|
97
|
+
e.FRAMEBUFFER_BINDING
|
|
98
|
+
), i = e.createTexture(), s = e.createFramebuffer();
|
|
99
|
+
if (!i || !s)
|
|
100
|
+
return i && e.deleteTexture(i), s && e.deleteFramebuffer(s), e.bindTexture(e.TEXTURE_2D, n), e.bindFramebuffer(e.FRAMEBUFFER, a), !1;
|
|
101
|
+
let o = !1;
|
|
102
|
+
try {
|
|
103
|
+
e.bindTexture(e.TEXTURE_2D, i), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.NEAREST), e.texImage2D(
|
|
104
|
+
e.TEXTURE_2D,
|
|
105
|
+
0,
|
|
106
|
+
t,
|
|
107
|
+
1,
|
|
108
|
+
1,
|
|
109
|
+
0,
|
|
110
|
+
e.RGBA,
|
|
111
|
+
r,
|
|
112
|
+
null
|
|
113
|
+
), e.bindFramebuffer(e.FRAMEBUFFER, s), e.framebufferTexture2D(
|
|
114
|
+
e.FRAMEBUFFER,
|
|
115
|
+
e.COLOR_ATTACHMENT0,
|
|
116
|
+
e.TEXTURE_2D,
|
|
117
|
+
i,
|
|
118
|
+
0
|
|
119
|
+
), o = e.checkFramebufferStatus(e.FRAMEBUFFER) === e.FRAMEBUFFER_COMPLETE;
|
|
120
|
+
} finally {
|
|
121
|
+
e.bindFramebuffer(e.FRAMEBUFFER, a), e.bindTexture(e.TEXTURE_2D, n), e.deleteFramebuffer(s), e.deleteTexture(i);
|
|
122
|
+
}
|
|
123
|
+
return o;
|
|
124
|
+
}
|
|
125
|
+
function re(e) {
|
|
126
|
+
return {
|
|
127
|
+
kind: "rgba8-packed",
|
|
128
|
+
internalFormat: e.RGBA,
|
|
129
|
+
type: e.UNSIGNED_BYTE
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function xe(e) {
|
|
133
|
+
if (typeof WebGL2RenderingContext > "u" || !(e instanceof WebGL2RenderingContext))
|
|
134
|
+
throw new Error("zartigl requires WebGL2");
|
|
135
|
+
return e;
|
|
136
|
+
}
|
|
137
|
+
function De(e) {
|
|
138
|
+
const t = [];
|
|
139
|
+
e.getExtension("EXT_color_buffer_float") ? t.push(
|
|
140
|
+
{ kind: "float32", internalFormat: e.RGBA32F, type: e.FLOAT },
|
|
141
|
+
{ kind: "float16", internalFormat: e.RGBA16F, type: e.HALF_FLOAT }
|
|
142
|
+
) : e.getExtension("EXT_color_buffer_half_float") && t.push({
|
|
143
|
+
kind: "float16",
|
|
144
|
+
internalFormat: e.RGBA16F,
|
|
145
|
+
type: e.HALF_FLOAT
|
|
146
|
+
});
|
|
147
|
+
for (const r of t)
|
|
148
|
+
if (te(
|
|
149
|
+
e,
|
|
150
|
+
r.internalFormat,
|
|
151
|
+
r.type
|
|
152
|
+
))
|
|
153
|
+
return r;
|
|
154
|
+
return re(e);
|
|
155
|
+
}
|
|
156
|
+
function Ue(e, t, r, n, a, i, s) {
|
|
157
|
+
const o = e.createTexture();
|
|
158
|
+
if (!o)
|
|
159
|
+
throw new Error("Failed to create texture");
|
|
160
|
+
return e.bindTexture(e.TEXTURE_2D, o), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, t), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, t), e.texImage2D(
|
|
161
|
+
e.TEXTURE_2D,
|
|
162
|
+
0,
|
|
163
|
+
i,
|
|
164
|
+
n,
|
|
165
|
+
a,
|
|
166
|
+
0,
|
|
167
|
+
e.RGBA,
|
|
168
|
+
s,
|
|
169
|
+
r
|
|
170
|
+
), e.bindTexture(e.TEXTURE_2D, null), o;
|
|
171
|
+
}
|
|
172
|
+
function ve(e, t, r) {
|
|
173
|
+
e.activeTexture(e.TEXTURE0 + r), e.bindTexture(e.TEXTURE_2D, t);
|
|
174
|
+
}
|
|
175
|
+
function Me(e, t) {
|
|
176
|
+
const r = e.createFramebuffer();
|
|
177
|
+
if (!r)
|
|
178
|
+
throw new Error("Failed to create framebuffer");
|
|
179
|
+
return e.bindFramebuffer(e.FRAMEBUFFER, r), e.framebufferTexture2D(
|
|
180
|
+
e.FRAMEBUFFER,
|
|
181
|
+
e.COLOR_ATTACHMENT0,
|
|
182
|
+
e.TEXTURE_2D,
|
|
183
|
+
t,
|
|
184
|
+
0
|
|
185
|
+
), e.bindFramebuffer(e.FRAMEBUFFER, null), r;
|
|
186
|
+
}
|
|
187
|
+
function ye(e) {
|
|
188
|
+
const t = e.createBuffer();
|
|
189
|
+
if (!t)
|
|
190
|
+
throw new Error("Failed to create buffer");
|
|
191
|
+
return e.bindBuffer(e.ARRAY_BUFFER, t), e.bufferData(
|
|
192
|
+
e.ARRAY_BUFFER,
|
|
193
|
+
new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),
|
|
194
|
+
e.STATIC_DRAW
|
|
195
|
+
), t;
|
|
196
|
+
}
|
|
197
|
+
const ae = {
|
|
198
|
+
0: "#3288bd",
|
|
199
|
+
0.1: "#66c2a5",
|
|
200
|
+
0.2: "#abdda4",
|
|
201
|
+
0.3: "#e6f598",
|
|
202
|
+
0.4: "#fee08b",
|
|
203
|
+
0.5: "#fdae61",
|
|
204
|
+
0.6: "#f46d43",
|
|
205
|
+
1: "#d53e4f"
|
|
206
|
+
};
|
|
207
|
+
function Ge(e, t) {
|
|
208
|
+
const r = t != null ? ee(t) : ae, n = document.createElement("canvas");
|
|
209
|
+
n.width = 256, n.height = 1;
|
|
210
|
+
const a = n.getContext("2d"), i = a.createLinearGradient(0, 0, 256, 0);
|
|
211
|
+
for (const [o, d] of Object.entries(r))
|
|
212
|
+
i.addColorStop(Number(o), d);
|
|
213
|
+
a.fillStyle = i, a.fillRect(0, 0, 256, 1);
|
|
214
|
+
const s = e.createTexture();
|
|
215
|
+
if (!s)
|
|
216
|
+
throw new Error("Failed to create color ramp texture");
|
|
217
|
+
return e.bindTexture(e.TEXTURE_2D, s), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, e.RGBA, e.UNSIGNED_BYTE, n), e.bindTexture(e.TEXTURE_2D, null), s;
|
|
218
|
+
}
|
|
219
|
+
function Se(e) {
|
|
220
|
+
const t = e.getExtension("WEBGL_debug_renderer_info");
|
|
221
|
+
return {
|
|
222
|
+
vendor: String(e.getParameter(e.VENDOR) ?? ""),
|
|
223
|
+
renderer: String(e.getParameter(e.RENDERER) ?? ""),
|
|
224
|
+
unmaskedVendor: t ? String(e.getParameter(t.UNMASKED_VENDOR_WEBGL) ?? "") : void 0,
|
|
225
|
+
unmaskedRenderer: t ? String(e.getParameter(t.UNMASKED_RENDERER_WEBGL) ?? "") : void 0,
|
|
226
|
+
version: String(e.getParameter(e.VERSION) ?? "")
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function Pe(e) {
|
|
230
|
+
return {
|
|
231
|
+
program: e.getParameter(e.CURRENT_PROGRAM),
|
|
232
|
+
activeTexture: e.getParameter(e.ACTIVE_TEXTURE),
|
|
233
|
+
arrayBuffer: e.getParameter(e.ARRAY_BUFFER_BINDING),
|
|
234
|
+
elementBuffer: e.getParameter(e.ELEMENT_ARRAY_BUFFER_BINDING),
|
|
235
|
+
framebuffer: e.getParameter(e.FRAMEBUFFER_BINDING),
|
|
236
|
+
blend: e.isEnabled(e.BLEND),
|
|
237
|
+
depthTest: e.isEnabled(e.DEPTH_TEST),
|
|
238
|
+
stencilTest: e.isEnabled(e.STENCIL_TEST),
|
|
239
|
+
viewport: e.getParameter(e.VIEWPORT),
|
|
240
|
+
blendFunc: [
|
|
241
|
+
e.getParameter(e.BLEND_SRC_RGB),
|
|
242
|
+
e.getParameter(e.BLEND_DST_RGB)
|
|
243
|
+
]
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function Ie(e, t) {
|
|
247
|
+
e.useProgram(t.program), e.activeTexture(t.activeTexture), e.bindBuffer(e.ARRAY_BUFFER, t.arrayBuffer), e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, t.elementBuffer), e.bindFramebuffer(e.FRAMEBUFFER, t.framebuffer), t.blend ? e.enable(e.BLEND) : e.disable(e.BLEND), t.depthTest ? e.enable(e.DEPTH_TEST) : e.disable(e.DEPTH_TEST), t.stencilTest ? e.enable(e.STENCIL_TEST) : e.disable(e.STENCIL_TEST), e.viewport(t.viewport[0], t.viewport[1], t.viewport[2], t.viewport[3]), e.blendFunc(t.blendFunc[0], t.blendFunc[1]);
|
|
248
|
+
}
|
|
249
|
+
const D = 20, ne = 600;
|
|
250
|
+
function ie(e) {
|
|
251
|
+
const t = Math.max(0, Math.min(1, e));
|
|
252
|
+
return D * Math.pow(ne / D, t);
|
|
253
|
+
}
|
|
254
|
+
function Ne(e) {
|
|
255
|
+
return Math.exp(-1 / ie(e));
|
|
256
|
+
}
|
|
257
|
+
const oe = 0.8, se = 120, de = 300;
|
|
258
|
+
class Le {
|
|
259
|
+
constructor(t) {
|
|
260
|
+
this.base = t, this.moving = !1, this.start = 0, this.duration = 0, this.from = t, this.to = t;
|
|
261
|
+
}
|
|
262
|
+
/** Configured opacity, applied at once unless the camera moves. */
|
|
263
|
+
setBase(t) {
|
|
264
|
+
this.base = t, this.moving || (this.from = t, this.to = t, this.duration = 0);
|
|
265
|
+
}
|
|
266
|
+
setMoving(t, r) {
|
|
267
|
+
t !== this.moving && (this.from = this.value(r), this.moving = t, this.to = t ? oe : this.base, this.start = r, this.duration = t ? se : de);
|
|
268
|
+
}
|
|
269
|
+
value(t) {
|
|
270
|
+
if (this.duration === 0)
|
|
271
|
+
return this.to;
|
|
272
|
+
const r = Math.min(1, Math.max(0, (t - this.start) / this.duration));
|
|
273
|
+
return r === 1 ? (this.duration = 0, this.from = this.to, this.to) : this.from + (this.to - this.from) * r * r * (3 - 2 * r);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const S = {
|
|
277
|
+
exposure: 0.8,
|
|
278
|
+
contrast: 0.6,
|
|
279
|
+
saturation: 0.4,
|
|
280
|
+
highlights: 0.6
|
|
281
|
+
}, ce = Object.freeze({
|
|
282
|
+
enabled: !1,
|
|
283
|
+
...S
|
|
284
|
+
}), fe = Object.freeze({
|
|
285
|
+
enabled: !0,
|
|
286
|
+
...S
|
|
287
|
+
}), U = {
|
|
288
|
+
exposure: [0, 4],
|
|
289
|
+
contrast: [0, 1],
|
|
290
|
+
saturation: [-1, 1],
|
|
291
|
+
highlights: [0, 1]
|
|
292
|
+
};
|
|
293
|
+
function Ve(e) {
|
|
294
|
+
if (!e)
|
|
295
|
+
return { ...ce };
|
|
296
|
+
const t = {
|
|
297
|
+
...fe,
|
|
298
|
+
enabled: e.enabled ?? !0
|
|
299
|
+
};
|
|
300
|
+
for (const r of Object.keys(U)) {
|
|
301
|
+
const n = e[r];
|
|
302
|
+
if (typeof n == "number" && Number.isFinite(n)) {
|
|
303
|
+
const [a, i] = U[r];
|
|
304
|
+
t[r] = Math.min(i, Math.max(a, n));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return t;
|
|
308
|
+
}
|
|
309
|
+
function Be(e) {
|
|
310
|
+
return [e.exposure, e.contrast, e.saturation, e.highlights];
|
|
311
|
+
}
|
|
312
|
+
function h(e, t) {
|
|
313
|
+
if (typeof e != "number" || !Number.isFinite(e))
|
|
314
|
+
throw new Error(`Invalid GeoVideo manifest ${t}`);
|
|
315
|
+
return e;
|
|
316
|
+
}
|
|
317
|
+
function b(e, t) {
|
|
318
|
+
if (typeof e != "string")
|
|
319
|
+
throw new Error(`Invalid GeoVideo manifest ${t}`);
|
|
320
|
+
const r = new Date(e).getTime();
|
|
321
|
+
if (!Number.isFinite(r))
|
|
322
|
+
throw new Error(`Invalid GeoVideo manifest ${t}`);
|
|
323
|
+
return r;
|
|
324
|
+
}
|
|
325
|
+
function R(e) {
|
|
326
|
+
return typeof e == "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(
|
|
327
|
+
e
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
function v(e) {
|
|
331
|
+
if (!e || typeof e != "object")
|
|
332
|
+
throw new Error("Invalid GeoVideo manifest");
|
|
333
|
+
const t = e;
|
|
334
|
+
if (t.schemaVersion !== 3 || t.type !== "geovideo")
|
|
335
|
+
throw new Error("Unsupported GeoVideo manifest version or type");
|
|
336
|
+
if (t.projection !== "equirectangular")
|
|
337
|
+
throw new Error(
|
|
338
|
+
`Unsupported GeoVideo projection: ${String(t.projection)}`
|
|
339
|
+
);
|
|
340
|
+
if (!Array.isArray(t.bounds) || t.bounds.length !== 4)
|
|
341
|
+
throw new Error("Invalid GeoVideo manifest bounds");
|
|
342
|
+
const [r, n, a, i] = t.bounds.map(
|
|
343
|
+
(u, m) => h(u, `bounds[${m}]`)
|
|
344
|
+
);
|
|
345
|
+
if (n < -90 || i > 90 || n >= i || r === a)
|
|
346
|
+
throw new Error("Invalid GeoVideo geographic bounds");
|
|
347
|
+
const s = t.media;
|
|
348
|
+
if (!s || typeof s.url != "string" || !s.url)
|
|
349
|
+
throw new Error("Invalid GeoVideo media");
|
|
350
|
+
for (const u of ["width", "height", "fps", "durationSeconds"])
|
|
351
|
+
if (h(s[u], `media.${u}`) <= 0)
|
|
352
|
+
throw new Error(`Invalid GeoVideo media.${u}`);
|
|
353
|
+
const o = t.encoding;
|
|
354
|
+
if (!o || o.bits !== 8 || o.colorSpace !== "bt709" || o.colorRange !== "limited" && o.colorRange !== "full")
|
|
355
|
+
throw new Error("Invalid GeoVideo encoding");
|
|
356
|
+
const d = h(o.codeMin, "encoding.codeMin"), c = h(o.codeMax, "encoding.codeMax");
|
|
357
|
+
if (d < 0 || c > 255 || d >= c)
|
|
358
|
+
throw new Error("Invalid GeoVideo code range");
|
|
359
|
+
let f = s.height;
|
|
360
|
+
if (o.kind === "scalar-luma") {
|
|
361
|
+
if (o.transfer !== "linear" || h(o.valueMin, "encoding.valueMin") >= h(o.valueMax, "encoding.valueMax"))
|
|
362
|
+
throw new Error("Invalid GeoVideo scalar-luma encoding");
|
|
363
|
+
} else if (o.kind === "vector-luma") {
|
|
364
|
+
if (o.transfer !== "linear" && o.transfer !== "sqrt" || o.layout !== "stacked-uv" || h(o.valueDomain, "encoding.valueDomain") <= 0 || s.height % 2 !== 0)
|
|
365
|
+
throw new Error("Invalid GeoVideo vector-luma encoding");
|
|
366
|
+
f = s.height / 2;
|
|
367
|
+
} else
|
|
368
|
+
throw new Error("Unsupported GeoVideo encoding");
|
|
369
|
+
const l = t.mask;
|
|
370
|
+
if (!l || l.kind !== "static-validity" || typeof l.url != "string" || !l.url || h(l.width, "mask.width") !== s.width || h(l.height, "mask.height") !== f || h(l.threshold, "mask.threshold") < 0 || l.threshold > 1)
|
|
371
|
+
throw new Error("Invalid GeoVideo static mask");
|
|
372
|
+
if (t.timeline?.kind === "range") {
|
|
373
|
+
const u = b(t.timeline.dateStart, "timeline.dateStart");
|
|
374
|
+
if (b(t.timeline.dateEnd, "timeline.dateEnd") <= u)
|
|
375
|
+
throw new Error("GeoVideo timeline end must follow start");
|
|
376
|
+
if (t.timeline.interpolation !== "linear" && t.timeline.interpolation !== "nearest")
|
|
377
|
+
throw new Error("Invalid GeoVideo interpolation");
|
|
378
|
+
} else if (t.timeline?.kind === "snapshot-loop")
|
|
379
|
+
b(t.timeline.date, "timeline.date");
|
|
380
|
+
else if (t.timeline?.kind === "sample-sequence") {
|
|
381
|
+
if (!Array.isArray(t.timeline.values) || t.timeline.values.length === 0)
|
|
382
|
+
throw new Error("GeoVideo sample sequence must contain values");
|
|
383
|
+
const u = t.timeline.values.map(
|
|
384
|
+
(m, T) => b(m, `timeline.values[${T}]`)
|
|
385
|
+
);
|
|
386
|
+
if (u.some((m, T) => T > 0 && m <= u[T - 1]))
|
|
387
|
+
throw new Error(
|
|
388
|
+
"GeoVideo sample sequence values must be strictly increasing"
|
|
389
|
+
);
|
|
390
|
+
} else
|
|
391
|
+
throw new Error("Invalid GeoVideo timeline");
|
|
392
|
+
const E = t.style?.colorDomain;
|
|
393
|
+
if (!Array.isArray(E) || E.length !== 2 || !E.every(Number.isFinite) || E[0] >= E[1])
|
|
394
|
+
throw new Error("Invalid GeoVideo color domain");
|
|
395
|
+
if (!R(t.id) || !t.provenance || !R(t.provenance.catalogEntryId) || !R(t.provenance.inputSourceId) || !Array.isArray(t.provenance.variables) || t.provenance.variables.length === 0)
|
|
396
|
+
throw new Error("Invalid GeoVideo provenance");
|
|
397
|
+
return { ...t, bounds: [r, n, a, i] };
|
|
398
|
+
}
|
|
399
|
+
async function ke(e, t) {
|
|
400
|
+
if (typeof e != "string")
|
|
401
|
+
return v(e);
|
|
402
|
+
const r = await fetch(e, { signal: t });
|
|
403
|
+
if (!r.ok)
|
|
404
|
+
throw new Error(
|
|
405
|
+
`GeoVideo manifest request failed (${r.status}): ${e}`
|
|
406
|
+
);
|
|
407
|
+
const n = await r.json(), a = v(n), i = typeof document < "u" ? new URL(e, document.baseURI).href : e;
|
|
408
|
+
return {
|
|
409
|
+
...a,
|
|
410
|
+
media: { ...a.media, url: new URL(a.media.url, i).href },
|
|
411
|
+
mask: { ...a.mask, url: new URL(a.mask.url, i).href }
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function F(e) {
|
|
415
|
+
if (e.timeline.kind === "snapshot-loop")
|
|
416
|
+
return [new Date(e.timeline.date).getTime()];
|
|
417
|
+
if (e.timeline.kind === "sample-sequence")
|
|
418
|
+
return e.timeline.values.map((a) => new Date(a).getTime());
|
|
419
|
+
const t = new Date(e.timeline.dateStart).getTime(), r = new Date(e.timeline.dateEnd).getTime(), n = Math.max(
|
|
420
|
+
2,
|
|
421
|
+
Math.round(e.media.durationSeconds * e.media.fps)
|
|
422
|
+
);
|
|
423
|
+
return Array.from(
|
|
424
|
+
{ length: n },
|
|
425
|
+
(a, i) => t + (r - t) * i / (n - 1)
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
function ue(e) {
|
|
429
|
+
return e.timeline.kind === "sample-sequence" ? e.timeline.values.length / e.media.durationSeconds : e.media.fps;
|
|
430
|
+
}
|
|
431
|
+
function Xe(e, t) {
|
|
432
|
+
return t / ue(e);
|
|
433
|
+
}
|
|
434
|
+
function he(e, t) {
|
|
435
|
+
if (e.timeline.kind === "snapshot-loop")
|
|
436
|
+
return 0;
|
|
437
|
+
if (e.timeline.kind === "sample-sequence") {
|
|
438
|
+
const i = F(e);
|
|
439
|
+
let s = 0;
|
|
440
|
+
for (let d = 1; d < i.length; d += 1)
|
|
441
|
+
Math.abs(i[d] - t) < Math.abs(i[s] - t) && (s = d);
|
|
442
|
+
const o = e.media.durationSeconds / i.length;
|
|
443
|
+
return s * o + Math.min(o / 2, 0.5 / e.media.fps);
|
|
444
|
+
}
|
|
445
|
+
const r = new Date(e.timeline.dateStart).getTime(), n = new Date(e.timeline.dateEnd).getTime();
|
|
446
|
+
return Math.max(0, Math.min(1, (t - r) / (n - r))) * P(e);
|
|
447
|
+
}
|
|
448
|
+
function Ce(e, t) {
|
|
449
|
+
if (e.timeline.kind === "snapshot-loop")
|
|
450
|
+
return new Date(e.timeline.date).getTime();
|
|
451
|
+
if (e.timeline.kind === "sample-sequence") {
|
|
452
|
+
const s = F(e), o = e.media.durationSeconds / s.length, d = Math.floor((t + 0.25 / e.media.fps) / o);
|
|
453
|
+
return s[Math.max(0, Math.min(s.length - 1, d))];
|
|
454
|
+
}
|
|
455
|
+
const r = new Date(e.timeline.dateStart).getTime(), n = new Date(e.timeline.dateEnd).getTime(), a = P(e), i = a > 0 ? Math.max(0, Math.min(1, t / a)) : 0;
|
|
456
|
+
return r + (n - r) * i;
|
|
457
|
+
}
|
|
458
|
+
function P(e) {
|
|
459
|
+
return Math.max(0, e.media.durationSeconds - 1 / e.media.fps);
|
|
460
|
+
}
|
|
461
|
+
function le(e, t) {
|
|
462
|
+
const r = new Uint8Array(e.length / 4);
|
|
463
|
+
for (let n = 0; n < r.length; n++) {
|
|
464
|
+
const a = e[n * 4];
|
|
465
|
+
r[n] = t === "limited" ? Math.round(a * 219 / 255 + 16) : a;
|
|
466
|
+
}
|
|
467
|
+
return r;
|
|
468
|
+
}
|
|
469
|
+
class me {
|
|
470
|
+
constructor() {
|
|
471
|
+
this.gl = null, this.texture = null, this.framebuffer = null;
|
|
472
|
+
}
|
|
473
|
+
read(t, r, n) {
|
|
474
|
+
const a = this.context();
|
|
475
|
+
a.bindTexture(a.TEXTURE_2D, this.texture), a.pixelStorei(a.UNPACK_FLIP_Y_WEBGL, !1), a.pixelStorei(a.UNPACK_PREMULTIPLY_ALPHA_WEBGL, !1), a.pixelStorei(a.UNPACK_COLORSPACE_CONVERSION_WEBGL, a.NONE), a.texParameteri(a.TEXTURE_2D, a.TEXTURE_MIN_FILTER, a.NEAREST), a.texParameteri(a.TEXTURE_2D, a.TEXTURE_MAG_FILTER, a.NEAREST), a.texParameteri(a.TEXTURE_2D, a.TEXTURE_WRAP_S, a.CLAMP_TO_EDGE), a.texParameteri(a.TEXTURE_2D, a.TEXTURE_WRAP_T, a.CLAMP_TO_EDGE), a.texImage2D(a.TEXTURE_2D, 0, a.RGBA, a.RGBA, a.UNSIGNED_BYTE, t), a.bindFramebuffer(a.FRAMEBUFFER, this.framebuffer), a.framebufferTexture2D(
|
|
476
|
+
a.FRAMEBUFFER,
|
|
477
|
+
a.COLOR_ATTACHMENT0,
|
|
478
|
+
a.TEXTURE_2D,
|
|
479
|
+
this.texture,
|
|
480
|
+
0
|
|
481
|
+
);
|
|
482
|
+
const i = new Uint8Array(r * n * 4);
|
|
483
|
+
return a.readPixels(0, 0, r, n, a.RGBA, a.UNSIGNED_BYTE, i), a.bindFramebuffer(a.FRAMEBUFFER, null), i;
|
|
484
|
+
}
|
|
485
|
+
release() {
|
|
486
|
+
this.gl?.getExtension("WEBGL_lose_context")?.loseContext(), this.gl = null, this.texture = null, this.framebuffer = null;
|
|
487
|
+
}
|
|
488
|
+
context() {
|
|
489
|
+
if (this.gl)
|
|
490
|
+
return this.gl;
|
|
491
|
+
const t = document.createElement("canvas"), r = {
|
|
492
|
+
premultipliedAlpha: !1,
|
|
493
|
+
antialias: !1
|
|
494
|
+
}, n = t.getContext("webgl2", r);
|
|
495
|
+
if (!n)
|
|
496
|
+
throw new Error("WebGL2 is required to decode GeoVideo frames");
|
|
497
|
+
return this.gl = n, this.texture = n.createTexture(), this.framebuffer = n.createFramebuffer(), n;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
function M(e) {
|
|
501
|
+
const t = Math.max(4, Math.floor(e.length / 4 / 997) * 4);
|
|
502
|
+
for (let r = 3; r < e.length; r += t)
|
|
503
|
+
if (e[r] !== 0)
|
|
504
|
+
return !1;
|
|
505
|
+
return !0;
|
|
506
|
+
}
|
|
507
|
+
function p() {
|
|
508
|
+
return new DOMException("GeoVideo frame request was cancelled", "AbortError");
|
|
509
|
+
}
|
|
510
|
+
function _(e, t) {
|
|
511
|
+
return new Promise(
|
|
512
|
+
(r) => e.addEventListener(t, () => r(), { once: !0 })
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
const Ee = 250;
|
|
516
|
+
function Te(e) {
|
|
517
|
+
return "requestVideoFrameCallback" in e ? Promise.race([
|
|
518
|
+
new Promise(
|
|
519
|
+
(t) => e.requestVideoFrameCallback(() => t())
|
|
520
|
+
),
|
|
521
|
+
new Promise((t) => setTimeout(t, Ee))
|
|
522
|
+
]) : Promise.resolve();
|
|
523
|
+
}
|
|
524
|
+
class be {
|
|
525
|
+
constructor(t, r, n = {}) {
|
|
526
|
+
this.reader = new me(), this.video = null, this.mask = null, this.initPromise = null, this.presented = !1, this.primed = !1, this.queue = Promise.resolve(), this.epoch = 0, this.frames = /* @__PURE__ */ new Map(), this.manifest = t, this.planes = r, this.cacheSize = Math.max(1, n.cacheSize ?? 3), this.width = t.media.width, this.height = t.media.height / r, this.times = Float64Array.from(F(t));
|
|
527
|
+
}
|
|
528
|
+
init() {
|
|
529
|
+
return this.initPromise ??= this.load().catch((t) => {
|
|
530
|
+
throw this.initPromise = null, t;
|
|
531
|
+
}), this.initPromise;
|
|
532
|
+
}
|
|
533
|
+
/** Abort queued frame decodes; frames already decoded stay cached. */
|
|
534
|
+
cancelAll() {
|
|
535
|
+
this.epoch++;
|
|
536
|
+
for (const [t, r] of this.frames)
|
|
537
|
+
r.catch(() => this.frames.delete(t));
|
|
538
|
+
}
|
|
539
|
+
/** Release the video element and GL context; a later init() reloads them. */
|
|
540
|
+
release() {
|
|
541
|
+
this.cancelAll(), this.frames.clear(), this.video && (this.video.removeAttribute("src"), this.video.load()), this.video = null, this.mask = null, this.presented = !1, this.primed = !1, this.initPromise = null, this.reader.release();
|
|
542
|
+
}
|
|
543
|
+
/** One decode per time step, cached. */
|
|
544
|
+
frame(t) {
|
|
545
|
+
const r = this.frames.get(t);
|
|
546
|
+
if (r)
|
|
547
|
+
return this.frames.delete(t), this.frames.set(t, r), r;
|
|
548
|
+
const n = this.epoch, a = this.queue.then(() => this.decode(t, n));
|
|
549
|
+
for (this.queue = a.catch(() => {
|
|
550
|
+
}), this.frames.set(t, a), a.catch(() => {
|
|
551
|
+
this.frames.get(t) === a && this.frames.delete(t);
|
|
552
|
+
}); this.frames.size > this.cacheSize; )
|
|
553
|
+
this.frames.delete(this.frames.keys().next().value);
|
|
554
|
+
return a;
|
|
555
|
+
}
|
|
556
|
+
async load() {
|
|
557
|
+
const [t] = await Promise.all([this.loadMask(), this.loadVideo()]);
|
|
558
|
+
this.mask = t;
|
|
559
|
+
}
|
|
560
|
+
async loadMask() {
|
|
561
|
+
const { url: t, width: r, height: n } = this.manifest.mask, a = new Image();
|
|
562
|
+
a.crossOrigin = "anonymous", a.src = t;
|
|
563
|
+
try {
|
|
564
|
+
await a.decode();
|
|
565
|
+
} catch {
|
|
566
|
+
throw new Error(`Failed to load GeoVideo mask: ${t}`);
|
|
567
|
+
}
|
|
568
|
+
if (a.naturalWidth !== r || a.naturalHeight !== n)
|
|
569
|
+
throw new Error(
|
|
570
|
+
`GeoVideo mask dimensions ${a.naturalWidth}x${a.naturalHeight} do not match manifest ${r}x${n}`
|
|
571
|
+
);
|
|
572
|
+
const i = this.reader.read(a, r, n), s = new Uint8Array(r * n);
|
|
573
|
+
for (let o = 0; o < s.length; o++)
|
|
574
|
+
s[o] = i[o * 4];
|
|
575
|
+
return s;
|
|
576
|
+
}
|
|
577
|
+
async loadVideo() {
|
|
578
|
+
const t = document.createElement("video");
|
|
579
|
+
t.crossOrigin = "anonymous", t.muted = !0, t.playsInline = !0, t.preload = "metadata", t.src = this.manifest.media.url, this.video = t, await new Promise((r, n) => {
|
|
580
|
+
t.addEventListener("loadedmetadata", () => r(), {
|
|
581
|
+
once: !0
|
|
582
|
+
}), t.addEventListener(
|
|
583
|
+
"error",
|
|
584
|
+
() => n(
|
|
585
|
+
new Error(
|
|
586
|
+
`Failed to load GeoVideo media: ${this.manifest.media.url}`
|
|
587
|
+
)
|
|
588
|
+
),
|
|
589
|
+
{ once: !0 }
|
|
590
|
+
);
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
/** Seek to a frame and wait until it is presented. */
|
|
594
|
+
async presentFrame(t, r) {
|
|
595
|
+
if (this.presented && Math.abs(t.currentTime - r) <= 1e-3 && !t.seeking)
|
|
596
|
+
return;
|
|
597
|
+
const n = Te(t), a = _(t, "seeked");
|
|
598
|
+
t.currentTime = r, await a, t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA && await Promise.race([_(t, "loadeddata"), _(t, "canplay")]), await n, this.presented = !0;
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Some mobile browsers expose no decoded pixels to WebGL until playback
|
|
602
|
+
* started once. A muted play/pause primes the decoder, only when needed:
|
|
603
|
+
* playback would otherwise buffer far beyond the requested frame.
|
|
604
|
+
*/
|
|
605
|
+
async primeDecoder(t) {
|
|
606
|
+
this.primed = !0;
|
|
607
|
+
try {
|
|
608
|
+
await t.play();
|
|
609
|
+
} catch {
|
|
610
|
+
}
|
|
611
|
+
t.pause(), this.presented = !1;
|
|
612
|
+
}
|
|
613
|
+
async decode(t, r) {
|
|
614
|
+
await this.init();
|
|
615
|
+
const n = this.video, a = this.mask;
|
|
616
|
+
if (r !== this.epoch || !n || !a)
|
|
617
|
+
throw p();
|
|
618
|
+
const i = he(this.manifest, this.times[t]);
|
|
619
|
+
if (await this.presentFrame(n, i), r !== this.epoch || n !== this.video)
|
|
620
|
+
throw p();
|
|
621
|
+
const s = this.height * this.planes;
|
|
622
|
+
let o = this.reader.read(n, this.width, s);
|
|
623
|
+
if (M(o) && !this.primed) {
|
|
624
|
+
if (await this.primeDecoder(n), await this.presentFrame(n, i), r !== this.epoch || n !== this.video)
|
|
625
|
+
throw p();
|
|
626
|
+
o = this.reader.read(n, this.width, s);
|
|
627
|
+
}
|
|
628
|
+
if (M(o))
|
|
629
|
+
throw new Error("GeoVideo frame could not be read back from the decoder");
|
|
630
|
+
const d = le(o, this.manifest.encoding.colorRange);
|
|
631
|
+
return this.decodeCodes(d, a, this.manifest.mask.threshold);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
function Re(e, t) {
|
|
635
|
+
let r = (e - t.codeMin) / (t.codeMax - t.codeMin) * 2 - 1;
|
|
636
|
+
return r = Math.max(-1, Math.min(1, r)), t.transfer === "sqrt" && (r = Math.sign(r) * r * r), r * t.valueDomain;
|
|
637
|
+
}
|
|
638
|
+
function pe(e, t, r, n) {
|
|
639
|
+
const a = t.length;
|
|
640
|
+
if (e.length !== 2 * a)
|
|
641
|
+
throw new Error(
|
|
642
|
+
`GeoVideo vector frame has ${e.length} codes, expected ${2 * a}`
|
|
643
|
+
);
|
|
644
|
+
const i = new Float32Array(256);
|
|
645
|
+
for (let c = 0; c < 256; c++)
|
|
646
|
+
i[c] = Re(c, n);
|
|
647
|
+
const s = r * 255, o = new Float32Array(a), d = new Float32Array(a);
|
|
648
|
+
for (let c = 0; c < a; c++) {
|
|
649
|
+
const f = t[c] >= s;
|
|
650
|
+
o[c] = f ? i[e[c]] : NaN, d[c] = f ? i[e[a + c]] : NaN;
|
|
651
|
+
}
|
|
652
|
+
return { u: o, v: d };
|
|
653
|
+
}
|
|
654
|
+
class Oe extends be {
|
|
655
|
+
constructor(t, r = {}) {
|
|
656
|
+
if (t.encoding.kind !== "vector-luma")
|
|
657
|
+
throw new Error("GeoVideoVectorSource requires a vector-luma manifest");
|
|
658
|
+
super(t, 2, r), this.encoding = t.encoding;
|
|
659
|
+
const [n, a, i, s] = t.bounds, o = (i - n) / this.width, d = (s - a) / this.height;
|
|
660
|
+
this.coords = {
|
|
661
|
+
time: this.times,
|
|
662
|
+
vertical: new Float32Array([0]),
|
|
663
|
+
latitude: Float32Array.from(
|
|
664
|
+
{ length: this.height },
|
|
665
|
+
(c, f) => s - (f + 0.5) * d
|
|
666
|
+
),
|
|
667
|
+
longitude: Float32Array.from(
|
|
668
|
+
{ length: this.width },
|
|
669
|
+
(c, f) => n + (f + 0.5) * o
|
|
670
|
+
)
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
getValueDomain() {
|
|
674
|
+
return this.encoding.valueDomain;
|
|
675
|
+
}
|
|
676
|
+
getCoords() {
|
|
677
|
+
return this.coords;
|
|
678
|
+
}
|
|
679
|
+
getDimensions() {
|
|
680
|
+
return ["time", "latitude", "longitude"];
|
|
681
|
+
}
|
|
682
|
+
getChunkShape() {
|
|
683
|
+
return [1, this.height, this.width];
|
|
684
|
+
}
|
|
685
|
+
findDepthIndex() {
|
|
686
|
+
return 0;
|
|
687
|
+
}
|
|
688
|
+
findTimeIndex(t) {
|
|
689
|
+
const r = typeof t == "number" ? t : new Date(t).getTime(), n = this.coords.time;
|
|
690
|
+
let a = 0;
|
|
691
|
+
for (let i = 1; i < n.length; i++)
|
|
692
|
+
Math.abs(n[i] - r) < Math.abs(n[a] - r) && (a = i);
|
|
693
|
+
return a;
|
|
694
|
+
}
|
|
695
|
+
getChunksForBounds(t, r, n) {
|
|
696
|
+
const { latitude: a, longitude: i } = this.coords;
|
|
697
|
+
return [
|
|
698
|
+
{
|
|
699
|
+
timeIdx: r,
|
|
700
|
+
depthIdx: n,
|
|
701
|
+
latIdx: 0,
|
|
702
|
+
lonIdx: 0,
|
|
703
|
+
latRange: [a[0], a[this.height - 1]],
|
|
704
|
+
lonRange: [i[0], i[this.width - 1]],
|
|
705
|
+
latSize: this.height,
|
|
706
|
+
lonSize: this.width
|
|
707
|
+
}
|
|
708
|
+
];
|
|
709
|
+
}
|
|
710
|
+
async fetchSpatialChunkResult(t, r) {
|
|
711
|
+
const n = await this.frame(r.timeIndex);
|
|
712
|
+
return {
|
|
713
|
+
data: t === "v" ? n.v : n.u,
|
|
714
|
+
missing: !1,
|
|
715
|
+
url: this.manifest.media.url
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
decodeCodes(t, r, n) {
|
|
719
|
+
return pe(t, r, n, this.encoding);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
function w(e) {
|
|
723
|
+
const { start: t, end: r } = e.temporal ?? {};
|
|
724
|
+
return [Date.parse(t ?? ""), Date.parse(r ?? t ?? "")];
|
|
725
|
+
}
|
|
726
|
+
function qe(e, t, r = {}) {
|
|
727
|
+
const [n, a] = r.range ?? [-1 / 0, 1 / 0], i = e.filter((d) => d.id === t.id && d.temporal?.start != null).map((d) => {
|
|
728
|
+
const [c, f] = w(d);
|
|
729
|
+
return { source: d, start: c, end: f };
|
|
730
|
+
}).sort((d, c) => d.start - c.start), s = Date.parse(t.temporal?.end ?? ""), o = i.find(
|
|
731
|
+
(d) => d.start > s && d.start <= a
|
|
732
|
+
) ?? (r.loop ? i.find(
|
|
733
|
+
(d) => d.end >= n && d.start <= a
|
|
734
|
+
) : void 0);
|
|
735
|
+
return o ? { source: o.source, time: Math.max(o.start, n) } : null;
|
|
736
|
+
}
|
|
737
|
+
function ge(e, t) {
|
|
738
|
+
const [r, n] = w(e);
|
|
739
|
+
let a = null, i = -1 / 0;
|
|
740
|
+
for (const s of t) {
|
|
741
|
+
const [o, d] = w(s), c = Math.min(n, d) - Math.max(r, o);
|
|
742
|
+
Number.isFinite(c) && c >= 0 && c > i && (a = s, i = c);
|
|
743
|
+
}
|
|
744
|
+
return a;
|
|
745
|
+
}
|
|
746
|
+
function We(e) {
|
|
747
|
+
return e.type === "geovideo" && typeof e.indexUrl == "string";
|
|
748
|
+
}
|
|
749
|
+
function $e(e, t) {
|
|
750
|
+
return e.id === t.id && (e.type !== "geovideo" || t.type !== "geovideo" || e.manifestUrl === t.manifestUrl);
|
|
751
|
+
}
|
|
752
|
+
function y(e) {
|
|
753
|
+
return typeof e == "string" && Number.isFinite(Date.parse(e));
|
|
754
|
+
}
|
|
755
|
+
function _e(e) {
|
|
756
|
+
const t = e;
|
|
757
|
+
if (!t || t.schemaVersion !== 1 || t.type !== "geovideo-index" || !Array.isArray(t.chunks))
|
|
758
|
+
throw new Error("Unsupported GeoVideo index");
|
|
759
|
+
for (const r of t.chunks)
|
|
760
|
+
if (!y(r?.start) || !y(r.end) || Date.parse(r.end) < Date.parse(r.start) || typeof r.manifestUrl != "string")
|
|
761
|
+
throw new Error("Invalid GeoVideo index chunk");
|
|
762
|
+
return t;
|
|
763
|
+
}
|
|
764
|
+
async function He(e, t) {
|
|
765
|
+
const r = await fetch(e, { signal: t });
|
|
766
|
+
if (!r.ok)
|
|
767
|
+
throw new Error(
|
|
768
|
+
`GeoVideo index request failed (${r.status}): ${e}`
|
|
769
|
+
);
|
|
770
|
+
return _e(await r.json());
|
|
771
|
+
}
|
|
772
|
+
function je(e, t, r) {
|
|
773
|
+
if (t.sourceId !== e.id || t.catalogEntryId !== r.id)
|
|
774
|
+
throw new Error(
|
|
775
|
+
`GeoVideo index identity does not match catalog entry/source: ${e.id}`
|
|
776
|
+
);
|
|
777
|
+
const n = typeof document < "u" ? new URL(e.indexUrl, document.baseURI).href : e.indexUrl;
|
|
778
|
+
return t.chunks.map(
|
|
779
|
+
(a) => ({
|
|
780
|
+
id: e.id,
|
|
781
|
+
type: "geovideo",
|
|
782
|
+
title: e.title,
|
|
783
|
+
provenance: e.provenance,
|
|
784
|
+
temporal: {
|
|
785
|
+
mode: "fixed",
|
|
786
|
+
cadence: e.temporal?.cadence,
|
|
787
|
+
start: a.start,
|
|
788
|
+
end: a.end
|
|
789
|
+
},
|
|
790
|
+
manifestUrl: new URL(a.manifestUrl, n).href
|
|
791
|
+
})
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
export {
|
|
795
|
+
ve as A,
|
|
796
|
+
xe as B,
|
|
797
|
+
ce as C,
|
|
798
|
+
Pe as D,
|
|
799
|
+
Ie as E,
|
|
800
|
+
he as F,
|
|
801
|
+
be as G,
|
|
802
|
+
Ce as H,
|
|
803
|
+
$e as I,
|
|
804
|
+
Xe as J,
|
|
805
|
+
ue as K,
|
|
806
|
+
Le as T,
|
|
807
|
+
fe as a,
|
|
808
|
+
Oe as b,
|
|
809
|
+
Be as c,
|
|
810
|
+
Ge as d,
|
|
811
|
+
Fe as e,
|
|
812
|
+
ie as f,
|
|
813
|
+
Ne as g,
|
|
814
|
+
je as h,
|
|
815
|
+
F as i,
|
|
816
|
+
we as j,
|
|
817
|
+
We as k,
|
|
818
|
+
He as l,
|
|
819
|
+
ke as m,
|
|
820
|
+
qe as n,
|
|
821
|
+
ee as o,
|
|
822
|
+
ge as p,
|
|
823
|
+
v as q,
|
|
824
|
+
Ve as r,
|
|
825
|
+
Se as s,
|
|
826
|
+
re as t,
|
|
827
|
+
De as u,
|
|
828
|
+
_e as v,
|
|
829
|
+
ye as w,
|
|
830
|
+
Ue as x,
|
|
831
|
+
Me as y,
|
|
832
|
+
Ae as z
|
|
833
|
+
};
|