pixi-effects 0.40.0 → 0.42.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 +17 -0
- package/README.md +5 -5
- package/ai/chat-template.html +3 -3
- package/ai/tools/check.mjs +19 -2
- package/dist/Composition-N6BOROJ2.cjs +16 -0
- package/dist/{Composition-C3UEVHQG.cjs.map → Composition-N6BOROJ2.cjs.map} +1 -1
- package/dist/Composition-YGBQX3HZ.js +7 -0
- package/dist/{Composition-KRWH72MA.js.map → Composition-YGBQX3HZ.js.map} +1 -1
- package/dist/Controller.d.cts +1 -1
- package/dist/Controller.d.ts +1 -1
- package/dist/{Movie-CMq4KFmc.d.cts → Movie-BHGhg-fJ.d.cts} +88 -1
- package/dist/{Movie-CG6Jy1tx.d.ts → Movie-CBVFZ1kg.d.ts} +88 -1
- package/dist/{Spans-TWO4VN5H.js → Spans-6L2ZVECX.js} +4 -4
- package/dist/{Spans-TWO4VN5H.js.map → Spans-6L2ZVECX.js.map} +1 -1
- package/dist/{Spans-APNJHCYO.cjs → Spans-XTIWYSNO.cjs} +9 -9
- package/dist/{Spans-APNJHCYO.cjs.map → Spans-XTIWYSNO.cjs.map} +1 -1
- package/dist/{chunk-27PYJ4JY.cjs → chunk-3HZV3UHU.cjs} +67 -63
- package/dist/chunk-3HZV3UHU.cjs.map +1 -0
- package/dist/{chunk-LMWXR5OC.js → chunk-4QVQ5UJJ.js} +4 -4
- package/dist/{chunk-LMWXR5OC.js.map → chunk-4QVQ5UJJ.js.map} +1 -1
- package/dist/{chunk-26Z544SH.js → chunk-ICI6ACHY.js} +7 -3
- package/dist/chunk-ICI6ACHY.js.map +1 -0
- package/dist/{chunk-CT5CZVT5.js → chunk-NFJKBWYO.js} +243 -4
- package/dist/chunk-NFJKBWYO.js.map +1 -0
- package/dist/{chunk-LEL7UNYQ.cjs → chunk-WVZLAIKK.cjs} +278 -39
- package/dist/chunk-WVZLAIKK.cjs.map +1 -0
- package/dist/{chunk-7EI2N7WO.cjs → chunk-X62H3RBG.cjs} +4 -4
- package/dist/{chunk-7EI2N7WO.cjs.map → chunk-X62H3RBG.cjs.map} +1 -1
- package/dist/index.cjs +33 -33
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/loader.css +1 -1
- package/dist/present.cjs +3 -3
- package/dist/present.d.cts +1 -1
- package/dist/present.d.ts +1 -1
- package/dist/present.js +3 -3
- package/dist/three.cjs +86 -7
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +27 -1
- package/dist/three.d.ts +27 -1
- package/dist/three.js +83 -4
- package/dist/three.js.map +1 -1
- package/docs/api.md +37 -0
- package/docs/dsl.md +1 -1
- package/llms-full.txt +173 -3
- package/package.json +1 -1
- package/skills/pixi-effects/SKILL.md +3 -2
- package/skills/pixi-effects/reference/cheatsheet.md +3 -0
- package/skills/pixi-effects/reference/recipes.md +129 -0
- package/skills/pixi-effects/template.html +6 -6
- package/dist/Composition-C3UEVHQG.cjs +0 -16
- package/dist/Composition-KRWH72MA.js +0 -7
- package/dist/chunk-26Z544SH.js.map +0 -1
- package/dist/chunk-27PYJ4JY.cjs.map +0 -1
- package/dist/chunk-CT5CZVT5.js.map +0 -1
- package/dist/chunk-LEL7UNYQ.cjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CompositionSequence, maskSourceOf } from './chunk-
|
|
2
|
-
import { EXPRESSION_NAMES, createTimeline, lengthen, ensureFilterLibrary, checkEase, parseEase, homeDistance, DEFAULT_FOV, random, noise, flattenSvgPath, trimPolylines, rand, DEG, timeRemapOf, contentLength, resolveAt, parseSpring, springDuration, spansMeta } from './chunk-
|
|
1
|
+
import { CompositionSequence, maskSourceOf } from './chunk-ICI6ACHY.js';
|
|
2
|
+
import { EXPRESSION_NAMES, createTimeline, lengthen, ensureFilterLibrary, checkEase, parseEase, homeDistance, DEFAULT_FOV, random, noise, flattenSvgPath, trimPolylines, rand, DEG, timeRemapOf, contentLength, resolveAt, parseSpring, springDuration, spansMeta } from './chunk-4QVQ5UJJ.js';
|
|
3
3
|
import { analyzeAudio, fft, resampleThrough, playSpan } from './chunk-UHNSL2KJ.js';
|
|
4
4
|
import { usesAdvancedBlend, enableAdvancedBlend } from './chunk-VNP7QCJE.js';
|
|
5
5
|
import { describeLayer } from './chunk-32MMNDDN.js';
|
|
@@ -1729,6 +1729,202 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1729
1729
|
return { frame, time, canvas, summary: { layers: layers.length, visible: layers.filter((l) => l.visible).length }, issues, layers: listed };
|
|
1730
1730
|
}
|
|
1731
1731
|
|
|
1732
|
+
// src/core/pick.ts
|
|
1733
|
+
var scratch;
|
|
1734
|
+
var saidBlind = /* @__PURE__ */ new Set();
|
|
1735
|
+
var readResourceAlpha = (resource, x, y) => {
|
|
1736
|
+
try {
|
|
1737
|
+
if (scratch === void 0) {
|
|
1738
|
+
const c = document.createElement("canvas");
|
|
1739
|
+
c.width = c.height = 1;
|
|
1740
|
+
scratch = c.getContext("2d", { willReadFrequently: true });
|
|
1741
|
+
}
|
|
1742
|
+
if (!scratch) return null;
|
|
1743
|
+
scratch.clearRect(0, 0, 1, 1);
|
|
1744
|
+
scratch.drawImage(resource, x, y, 1, 1, 0, 0, 1, 1);
|
|
1745
|
+
return scratch.getImageData(0, 0, 1, 1).data[3] / 255;
|
|
1746
|
+
} catch {
|
|
1747
|
+
return null;
|
|
1748
|
+
}
|
|
1749
|
+
};
|
|
1750
|
+
function pointInQuad(q, x, y) {
|
|
1751
|
+
let pos = 0, neg = 0;
|
|
1752
|
+
for (let i = 0; i < 4; i++) {
|
|
1753
|
+
const ax = q[i * 2], ay = q[i * 2 + 1], bx = q[(i + 1) % 4 * 2], by = q[(i + 1) % 4 * 2 + 1];
|
|
1754
|
+
const cross = (bx - ax) * (y - ay) - (by - ay) * (x - ax);
|
|
1755
|
+
if (cross > 0) pos++;
|
|
1756
|
+
else if (cross < 0) neg++;
|
|
1757
|
+
}
|
|
1758
|
+
return pos === 0 || neg === 0;
|
|
1759
|
+
}
|
|
1760
|
+
function orderOf(node) {
|
|
1761
|
+
const key = [];
|
|
1762
|
+
for (let n = node; n && n.parent; n = n.parent) {
|
|
1763
|
+
key.unshift([n.zIndex ?? 0, Math.max(0, n.parent.children?.indexOf(n) ?? 0)]);
|
|
1764
|
+
}
|
|
1765
|
+
return key;
|
|
1766
|
+
}
|
|
1767
|
+
var above = (a, b) => {
|
|
1768
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) {
|
|
1769
|
+
if (a[i][0] !== b[i][0]) return b[i][0] - a[i][0];
|
|
1770
|
+
if (a[i][1] !== b[i][1]) return b[i][1] - a[i][1];
|
|
1771
|
+
}
|
|
1772
|
+
return b.length - a.length;
|
|
1773
|
+
};
|
|
1774
|
+
function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
1775
|
+
if (opts.alpha !== void 0 && !(opts.alpha >= 0 && opts.alpha <= 1)) throw new Error(`pixi-effects: pick: alpha must be a number from 0 to 1 (a pixel at or below it is not a hit), got ${opts.alpha}`);
|
|
1776
|
+
const readAlpha = deps.readAlpha ?? readResourceAlpha;
|
|
1777
|
+
const found = [];
|
|
1778
|
+
const names = (list, name, path) => list.some((e) => e === path || name !== void 0 && e === name || path.startsWith(e + "/") || path.split("/").slice(0, -1).includes(e));
|
|
1779
|
+
const wanted = (name, path) => {
|
|
1780
|
+
if (opts.ignore && names(opts.ignore, name, path)) return false;
|
|
1781
|
+
if (opts.only && !names(opts.only, name, path)) return false;
|
|
1782
|
+
return true;
|
|
1783
|
+
};
|
|
1784
|
+
const inside = (b, p) => p.x >= b.x && p.x <= b.x + b.width && p.y >= b.y && p.y <= b.y + b.height;
|
|
1785
|
+
const walk2 = (comp, prefix, parentVisible) => {
|
|
1786
|
+
comp.layers().forEach(({ seq, display, threeD, carriers, quad }, i) => {
|
|
1787
|
+
const d = display;
|
|
1788
|
+
if (!d) return;
|
|
1789
|
+
const t = seq.target;
|
|
1790
|
+
const name = seq.spec.name;
|
|
1791
|
+
const path = prefix + (name ?? `${seq.spec.type}#${i}`);
|
|
1792
|
+
const alpha = (t?.alpha ?? 1) * carriers.reduce((a, c) => a * (c.target?.alpha ?? 1), 1);
|
|
1793
|
+
const alive = (threeD ? d.visible : t?.renderable ?? true) && carriers.every((c) => c.target?.renderable ?? true);
|
|
1794
|
+
const visible = parentVisible && alive && alpha > 0;
|
|
1795
|
+
if (!visible) return;
|
|
1796
|
+
const isComposition = seq instanceof CompositionSequence;
|
|
1797
|
+
if (isComposition && !threeD) {
|
|
1798
|
+
walk2(seq, path + "/", visible);
|
|
1799
|
+
return;
|
|
1800
|
+
}
|
|
1801
|
+
if (!wanted(name, path)) return;
|
|
1802
|
+
const point = { x, y };
|
|
1803
|
+
let hit = null;
|
|
1804
|
+
if (threeD) {
|
|
1805
|
+
if (quad && pointInQuad(quad, d.toLocal(point).x, d.toLocal(point).y)) hit = { name, path, type: seq.spec.type, kind: "card", point };
|
|
1806
|
+
} else {
|
|
1807
|
+
const local = d.toLocal(point);
|
|
1808
|
+
const lb = d.getLocalBounds();
|
|
1809
|
+
if (inside(lb, local)) {
|
|
1810
|
+
const three = typeof seq.pickAt === "function" ? seq.pickAt((local.x - lb.x) / lb.width, (local.y - lb.y) / lb.height) : void 0;
|
|
1811
|
+
if (three) {
|
|
1812
|
+
const planeOf = seq.dragPlane;
|
|
1813
|
+
if (planeOf) {
|
|
1814
|
+
three.grab = (plane = "screen") => {
|
|
1815
|
+
const along = planeOf.call(seq, three.point, plane);
|
|
1816
|
+
return { move: (cx, cy) => {
|
|
1817
|
+
const lp = d.toLocal({ x: cx, y: cy });
|
|
1818
|
+
const b = d.getLocalBounds();
|
|
1819
|
+
return along((lp.x - b.x) / b.width, (lp.y - b.y) / b.height);
|
|
1820
|
+
} };
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
hit = { name, path, type: seq.spec.type, kind: "three", point, three };
|
|
1824
|
+
} else if (three === void 0 && (typeof d.containsPoint !== "function" || d.containsPoint(local))) {
|
|
1825
|
+
let opaque = true;
|
|
1826
|
+
const tex = opts.alpha !== void 0 && seq.spec.type !== "shader" ? d.texture : void 0;
|
|
1827
|
+
if (tex?.source?.resource) {
|
|
1828
|
+
const res = tex.source.resolution ?? 1;
|
|
1829
|
+
const a = readAlpha(tex.source.resource, (tex.frame.x + (local.x - lb.x) / lb.width * tex.frame.width) * res, (tex.frame.y + (local.y - lb.y) / lb.height * tex.frame.height) * res);
|
|
1830
|
+
if (a === null) {
|
|
1831
|
+
if (!saidBlind.has(path)) {
|
|
1832
|
+
saidBlind.add(path);
|
|
1833
|
+
console.warn(`pixi-effects: pick: the picture of layer "${path}" cannot be read for { alpha } (a picture from another origin: load it with crossorigin="anonymous" or from the same site), so the box counts as the picture`);
|
|
1834
|
+
}
|
|
1835
|
+
} else opaque = a > opts.alpha;
|
|
1836
|
+
}
|
|
1837
|
+
if (opaque) hit = { name, path, type: seq.spec.type, kind: "flat", point, local: { x: local.x - lb.x, y: local.y - lb.y } };
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
if (!hit) return;
|
|
1842
|
+
const maskTarget = seq.maskSequence?.target;
|
|
1843
|
+
const maskSrc = maskSourceOf(seq.spec.mask);
|
|
1844
|
+
if (maskTarget && !(maskSrc.kind === "inline" && maskSrc.invert) && !inside(maskTarget.getBounds(), point)) return;
|
|
1845
|
+
found.push({ hit, order: orderOf(d) });
|
|
1846
|
+
});
|
|
1847
|
+
};
|
|
1848
|
+
walk2(root, "", true);
|
|
1849
|
+
return found.sort((a, b) => above(a.order, b.order)).map((f) => f.hit);
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
// src/core/hover.ts
|
|
1853
|
+
var keyOf = (h) => h ? `${h.path}${h.three ? `#${h.three.object}` : ""}` : null;
|
|
1854
|
+
function startHover(host, opts = {}) {
|
|
1855
|
+
const { canvas } = host;
|
|
1856
|
+
const request = host.requestFrame ?? ((fn) => requestAnimationFrame(fn));
|
|
1857
|
+
const cancel = host.cancelFrame ?? ((id) => cancelAnimationFrame(id));
|
|
1858
|
+
const cursor = opts.cursor === true ? "pointer" : opts.cursor || "";
|
|
1859
|
+
const pickOpts = {};
|
|
1860
|
+
if (opts.only) pickOpts.only = opts.only;
|
|
1861
|
+
if (opts.ignore) pickOpts.ignore = opts.ignore;
|
|
1862
|
+
let current = null;
|
|
1863
|
+
let last = null;
|
|
1864
|
+
let loop = null;
|
|
1865
|
+
let said = false;
|
|
1866
|
+
const call = (fn, hit) => {
|
|
1867
|
+
if (!fn) return;
|
|
1868
|
+
try {
|
|
1869
|
+
fn(hit);
|
|
1870
|
+
} catch (err) {
|
|
1871
|
+
if (!said) {
|
|
1872
|
+
said = true;
|
|
1873
|
+
console.warn("pixi-effects: movie.hover: a handler threw (said once) \u2014", err);
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
};
|
|
1877
|
+
const setCursor = (on) => {
|
|
1878
|
+
if (cursor) canvas.style.cursor = on ? cursor : "";
|
|
1879
|
+
};
|
|
1880
|
+
const evaluate = () => {
|
|
1881
|
+
if (!last) return;
|
|
1882
|
+
const [x, y] = host.point(last);
|
|
1883
|
+
const hit = host.pick(x, y, pickOpts);
|
|
1884
|
+
if (keyOf(hit) === keyOf(current)) {
|
|
1885
|
+
current = hit ?? current;
|
|
1886
|
+
return;
|
|
1887
|
+
}
|
|
1888
|
+
const was = current;
|
|
1889
|
+
current = hit;
|
|
1890
|
+
if (was) call(opts.onLeave, was);
|
|
1891
|
+
if (hit) call(opts.onEnter, hit);
|
|
1892
|
+
setCursor(!!hit);
|
|
1893
|
+
};
|
|
1894
|
+
const tick = () => {
|
|
1895
|
+
loop = null;
|
|
1896
|
+
if (last) {
|
|
1897
|
+
evaluate();
|
|
1898
|
+
loop = request(tick);
|
|
1899
|
+
}
|
|
1900
|
+
};
|
|
1901
|
+
const onMove = (event) => {
|
|
1902
|
+
last = event;
|
|
1903
|
+
evaluate();
|
|
1904
|
+
if (loop === null) loop = request(tick);
|
|
1905
|
+
};
|
|
1906
|
+
const onLeave = () => {
|
|
1907
|
+
last = null;
|
|
1908
|
+
if (loop !== null) {
|
|
1909
|
+
cancel(loop);
|
|
1910
|
+
loop = null;
|
|
1911
|
+
}
|
|
1912
|
+
const was = current;
|
|
1913
|
+
current = null;
|
|
1914
|
+
if (was) call(opts.onLeave, was);
|
|
1915
|
+
setCursor(false);
|
|
1916
|
+
};
|
|
1917
|
+
canvas.addEventListener("pointermove", onMove);
|
|
1918
|
+
canvas.addEventListener("pointerdown", onMove);
|
|
1919
|
+
canvas.addEventListener("pointerleave", onLeave);
|
|
1920
|
+
return () => {
|
|
1921
|
+
canvas.removeEventListener("pointermove", onMove);
|
|
1922
|
+
canvas.removeEventListener("pointerdown", onMove);
|
|
1923
|
+
canvas.removeEventListener("pointerleave", onLeave);
|
|
1924
|
+
onLeave();
|
|
1925
|
+
};
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1732
1928
|
// src/core/timelineChart.ts
|
|
1733
1929
|
var GROUP_MIN = 4;
|
|
1734
1930
|
var MAX_KEYS = 200;
|
|
@@ -2783,6 +2979,14 @@ var Movie = class {
|
|
|
2783
2979
|
await this._goto(frame);
|
|
2784
2980
|
this.emit("seeked", { frame: this.currentFrame, totalFrames: this.totalFrames });
|
|
2785
2981
|
}
|
|
2982
|
+
/**
|
|
2983
|
+
* Draw the frame on screen again, quietly (no `seeking` / `seeked`). For a paused movie when something outside it that a layer reads has changed: a `three` layer whose `update` reads the page's own
|
|
2984
|
+
* state (a dragged object's place) shows it after `await movie.redraw()`. A playing movie needs no call: the next frame draws it.
|
|
2985
|
+
*/
|
|
2986
|
+
async redraw() {
|
|
2987
|
+
this._requireReady("redraw");
|
|
2988
|
+
await this._quietly(() => this.gotoFrame(this.currentFrame, true));
|
|
2989
|
+
}
|
|
2786
2990
|
/** Run `fn` with `seeking` / `seeked` silenced: the movie is moving its own playhead, not answering a seek. */
|
|
2787
2991
|
async _quietly(fn) {
|
|
2788
2992
|
this._quiet++;
|
|
@@ -2986,6 +3190,41 @@ var Movie = class {
|
|
|
2986
3190
|
* Where every layer is drawn at `frame` (canvas pixels, visibility) plus `issues` — text that is off
|
|
2987
3191
|
* the canvas, cut by an edge, empty, or overlapping other text. Seeks there and stays there.
|
|
2988
3192
|
*/
|
|
3193
|
+
/**
|
|
3194
|
+
* What is under the canvas point (x, y) (canvas pixels: the movie's own `width` x `height`; `canvasPoint(event)` makes them from a pointer event) at the frame on screen: the layer on
|
|
3195
|
+
* top, or null. A flat layer is hit by its own shape, a `threeD` card by its projected quad, a `three` layer by a ray through its camera (`hit.three` has the object). It reads the
|
|
3196
|
+
* frame as the last draw left it, so after `await movie.snapshot(frame)` or any seek it answers for that frame. `opts.only` / `opts.ignore`: layer names or paths.
|
|
3197
|
+
*/
|
|
3198
|
+
pick(x, y, opts = {}) {
|
|
3199
|
+
return this.pickAll(x, y, opts)[0] ?? null;
|
|
3200
|
+
}
|
|
3201
|
+
/** Every layer under the canvas point, the one on top first (see `pick`). */
|
|
3202
|
+
pickAll(x, y, opts = {}) {
|
|
3203
|
+
warnUnknownOptions("movie.pick()", opts, ["only", "ignore", "alpha"]);
|
|
3204
|
+
this._requireReady("pick");
|
|
3205
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) throw new Error(`pixi-effects: movie.pick(x, y) needs two numbers (canvas pixels), got ${x}, ${y}. For a pointer event: movie.pick(...movie.canvasPoint(event))`);
|
|
3206
|
+
return pickScene(this._rootSequence, x, y, opts);
|
|
3207
|
+
}
|
|
3208
|
+
/**
|
|
3209
|
+
* Which layer the pointer is over, as callbacks: `onEnter(hit)` when the layer (or, in a `three` layer, the object) under the pointer changes to another, `onLeave(hit)` for the one it
|
|
3210
|
+
* left (also when the pointer leaves the picture). While the pointer rests inside, it is asked again on every frame, so a picture that moves under a still pointer is followed.
|
|
3211
|
+
* `{ only, ignore }` as for `pick`; `cursor: true` (or a CSS cursor) shows it while something is hovered. Returns the function that stops it. A page-side tool: an exported video has no pointer.
|
|
3212
|
+
*/
|
|
3213
|
+
hover(opts = {}) {
|
|
3214
|
+
warnUnknownOptions("movie.hover()", opts, ["onEnter", "onLeave", "cursor", "only", "ignore"]);
|
|
3215
|
+
this._requireReady("hover");
|
|
3216
|
+
const canvas = this.app?.canvas;
|
|
3217
|
+
if (!canvas) throw new Error("pixi-effects: movie.hover needs the movie's canvas");
|
|
3218
|
+
return startHover({ canvas, pick: (x, y, o) => this.pick(x, y, o), point: (e) => this.canvasPoint(e) }, opts);
|
|
3219
|
+
}
|
|
3220
|
+
/** A pointer event's place in canvas pixels (the canvas may be shown larger or smaller than its own size): `movie.pick(...movie.canvasPoint(event))`. */
|
|
3221
|
+
canvasPoint(event) {
|
|
3222
|
+
this._requireReady("canvasPoint");
|
|
3223
|
+
const canvas = this.app?.canvas;
|
|
3224
|
+
if (!canvas) throw new Error("pixi-effects: movie.canvasPoint needs the movie's canvas");
|
|
3225
|
+
const r = canvas.getBoundingClientRect();
|
|
3226
|
+
return [(event.clientX - r.left) * this.width / (r.width || this.width), (event.clientY - r.top) * this.height / (r.height || this.height)];
|
|
3227
|
+
}
|
|
2989
3228
|
async inspect(frame = this.currentFrame, opts = { layers: "visible" }) {
|
|
2990
3229
|
warnUnknownOptions("movie.inspect()", opts, ["layers"]);
|
|
2991
3230
|
this._requireReady("inspect");
|
|
@@ -4485,5 +4724,5 @@ function withFade(spec, opts) {
|
|
|
4485
4724
|
}
|
|
4486
4725
|
|
|
4487
4726
|
export { Movie, animateText, audioEnvelope, bpmEnvelope, cameraPath, computeEnvelope, dismissLoader, failLoader, followPath, kenBurns, measureText, musicBuffer, musicEnvelope, musicEvents, orbit, parseEase2 as parseEase, particles, react, resolveLoader, samplePath, splitText, stagger, wiggle, withFade };
|
|
4488
|
-
//# sourceMappingURL=chunk-
|
|
4489
|
-
//# sourceMappingURL=chunk-
|
|
4727
|
+
//# sourceMappingURL=chunk-NFJKBWYO.js.map
|
|
4728
|
+
//# sourceMappingURL=chunk-NFJKBWYO.js.map
|