@phin-tech/dottie 0.0.0-stage → 0.2.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/LICENSE +202 -0
- package/PARITY.md +42 -0
- package/README.md +82 -2
- package/dist/compile.js +391 -0
- package/dist/dottie-compile.mjs +493 -0
- package/dist/dottie-loader.js +20 -0
- package/dist/dottie-player.js +3075 -0
- package/dist/dottie-player.min.js +63 -0
- package/dist/dottie.js +3018 -0
- package/dist/types/cli.d.ts +1 -0
- package/dist/types/compile.d.ts +19 -0
- package/dist/types/connector.d.ts +28 -0
- package/dist/types/dungeon.d.ts +19 -0
- package/dist/types/element.d.ts +22 -0
- package/dist/types/index.d.ts +21 -0
- package/dist/types/inspect.d.ts +7 -0
- package/dist/types/metrics.d.ts +11 -0
- package/dist/types/model.d.ts +181 -0
- package/dist/types/note.d.ts +47 -0
- package/dist/types/path.d.ts +76 -0
- package/dist/types/player-entry.d.ts +1 -0
- package/dist/types/player.d.ts +80 -0
- package/dist/types/rng.d.ts +17 -0
- package/dist/types/rough.d.ts +16 -0
- package/dist/types/shapes.d.ts +17 -0
- package/dist/types/svg-util.d.ts +3 -0
- package/dist/types/svg.d.ts +36 -0
- package/dist/types/text.d.ts +15 -0
- package/dist/types/theme.d.ts +10 -0
- package/dist/types/timeline.d.ts +36 -0
- package/package.json +73 -4
package/dist/compile.js
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
/*! dottie.js 0.2.0 | Apache-2.0 | https://github.com/phin-tech/dottie */
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
|
|
6
|
+
// src/model.ts
|
|
7
|
+
var SUPPORTED_VERSION = 2;
|
|
8
|
+
var KINDS = ["rectangle", "ellipse", "diamond", "text", "connector", "freehand", "path", "note", "image"];
|
|
9
|
+
var EASES = ["linear", "easeIn", "easeOut", "easeInOut", "hold"];
|
|
10
|
+
var KNOWN_FIELDS = {
|
|
11
|
+
file: ["version", "pages", "images"],
|
|
12
|
+
page: ["id", "name", "layers", "elements", "theme", "guidesX", "guidesY", "guidesLocked", "timeline"],
|
|
13
|
+
layer: ["id", "name", "visible", "locked"],
|
|
14
|
+
rgba: ["r", "g", "b", "a"],
|
|
15
|
+
style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "gridSize", "opacity"],
|
|
16
|
+
element: [
|
|
17
|
+
"id",
|
|
18
|
+
"kind",
|
|
19
|
+
"x",
|
|
20
|
+
"y",
|
|
21
|
+
"width",
|
|
22
|
+
"height",
|
|
23
|
+
"style",
|
|
24
|
+
"seed",
|
|
25
|
+
"layerID",
|
|
26
|
+
"text",
|
|
27
|
+
"connector",
|
|
28
|
+
"groupID",
|
|
29
|
+
"points",
|
|
30
|
+
"path",
|
|
31
|
+
"subpaths",
|
|
32
|
+
"evenOdd",
|
|
33
|
+
"rotation",
|
|
34
|
+
"link",
|
|
35
|
+
"anchor",
|
|
36
|
+
"image",
|
|
37
|
+
"reveal"
|
|
38
|
+
],
|
|
39
|
+
strokePoint: ["x", "y"],
|
|
40
|
+
subpath: ["closed", "coords"],
|
|
41
|
+
inlineImage: ["data", "format"],
|
|
42
|
+
endpoint: ["elementID", "port", "x", "y"],
|
|
43
|
+
connector: ["start", "end", "routing", "startHead", "endHead"],
|
|
44
|
+
timeline: ["fps", "duration", "boil", "settle", "poster", "tracks", "camera", "markers"],
|
|
45
|
+
track: ["element", "keys", "boil", "follow", "repeats"],
|
|
46
|
+
keyframe: ["t", "x", "y", "width", "height", "rotation", "strokeWidth", "stroke", "fill", "visible", "reveal", "opacity", "ease"],
|
|
47
|
+
follow: ["path", "start", "end", "ease", "reverse", "orient", "laps"],
|
|
48
|
+
repeat: ["start", "end", "count"],
|
|
49
|
+
cameraKey: ["t", "x", "y", "width", "height", "ease"],
|
|
50
|
+
marker: ["t", "name"]
|
|
51
|
+
};
|
|
52
|
+
var MAX_DURATION = 3600;
|
|
53
|
+
var black = { r: 0.12, g: 0.12, b: 0.13, a: 1 };
|
|
54
|
+
var clear = { r: 0, g: 0, b: 0, a: 0 };
|
|
55
|
+
var DottieFormatError = class extends Error {
|
|
56
|
+
};
|
|
57
|
+
var isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
58
|
+
var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
59
|
+
var str = (v) => typeof v === "string" ? v : void 0;
|
|
60
|
+
var bool = (v) => typeof v === "boolean" ? v : void 0;
|
|
61
|
+
var uuid = (v) => typeof v === "string" ? v.toUpperCase() : void 0;
|
|
62
|
+
function clampTime(t) {
|
|
63
|
+
if (!Number.isFinite(t)) return t === Infinity ? MAX_DURATION : 0;
|
|
64
|
+
return Math.min(Math.max(t, 0), MAX_DURATION);
|
|
65
|
+
}
|
|
66
|
+
function clampFPS(f) {
|
|
67
|
+
return Number.isFinite(f) ? Math.min(Math.max(f, 1), 60) : 12;
|
|
68
|
+
}
|
|
69
|
+
function rgba(v) {
|
|
70
|
+
if (!isObj(v)) return void 0;
|
|
71
|
+
const r = num(v.r), g = num(v.g), b = num(v.b);
|
|
72
|
+
if (r === void 0 || g === void 0 || b === void 0) return void 0;
|
|
73
|
+
return { r, g, b, a: num(v.a) ?? 1 };
|
|
74
|
+
}
|
|
75
|
+
var Reader = class {
|
|
76
|
+
constructor() {
|
|
77
|
+
__publicField(this, "warnings", []);
|
|
78
|
+
__publicField(this, "seen", /* @__PURE__ */ new Set());
|
|
79
|
+
}
|
|
80
|
+
warn(message) {
|
|
81
|
+
if (!this.seen.has(message)) {
|
|
82
|
+
this.seen.add(message);
|
|
83
|
+
this.warnings.push(message);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Reports fields this version doesn't read (they're ignored, as Dottie ignores them). */
|
|
87
|
+
fields(v, kind) {
|
|
88
|
+
const known = KNOWN_FIELDS[kind];
|
|
89
|
+
for (const k of Object.keys(v)) if (!known.includes(k)) this.warn(`Unknown field "${k}" on ${kind}, ignored`);
|
|
90
|
+
}
|
|
91
|
+
style(v) {
|
|
92
|
+
const s = isObj(v) ? v : {};
|
|
93
|
+
this.fields(s, "style");
|
|
94
|
+
const fillStyle = str(s.fillStyle) ?? "solid";
|
|
95
|
+
const dash = str(s.dash) ?? "solid";
|
|
96
|
+
if (!["solid", "hachure", "crossHatch", "grid"].includes(fillStyle)) this.warn(`Unknown fill style "${fillStyle}", drawn solid`);
|
|
97
|
+
if (!["solid", "dashed", "dotted"].includes(dash)) this.warn(`Unknown dash "${dash}", drawn solid`);
|
|
98
|
+
return {
|
|
99
|
+
stroke: rgba(s.stroke) ?? { ...black },
|
|
100
|
+
fill: rgba(s.fill) ?? { ...clear },
|
|
101
|
+
fillStyle: ["solid", "hachure", "crossHatch", "grid"].includes(fillStyle) ? fillStyle : "solid",
|
|
102
|
+
strokeWidth: num(s.strokeWidth) ?? 2,
|
|
103
|
+
dash: ["solid", "dashed", "dotted"].includes(dash) ? dash : "solid",
|
|
104
|
+
roughness: num(s.roughness) ?? 1,
|
|
105
|
+
bowing: num(s.bowing) ?? 1,
|
|
106
|
+
fontSize: num(s.fontSize) ?? 18,
|
|
107
|
+
gridSize: num(s.gridSize) ?? null,
|
|
108
|
+
opacity: num(s.opacity) ?? null
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
endpoint(v) {
|
|
112
|
+
const e = isObj(v) ? v : {};
|
|
113
|
+
const port = str(e.port);
|
|
114
|
+
return {
|
|
115
|
+
elementID: uuid(e.elementID) ?? null,
|
|
116
|
+
port: port && ["top", "right", "bottom", "left"].includes(port) ? port : null,
|
|
117
|
+
x: num(e.x) ?? 0,
|
|
118
|
+
y: num(e.y) ?? 0
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
connector(v) {
|
|
122
|
+
if (!isObj(v)) return null;
|
|
123
|
+
this.fields(v, "connector");
|
|
124
|
+
const head = (h, d) => {
|
|
125
|
+
const s = str(h);
|
|
126
|
+
return s && ["none", "arrow", "triangle", "dot", "bar"].includes(s) ? s : d;
|
|
127
|
+
};
|
|
128
|
+
const routing = str(v.routing);
|
|
129
|
+
return {
|
|
130
|
+
start: this.endpoint(v.start),
|
|
131
|
+
end: this.endpoint(v.end),
|
|
132
|
+
routing: routing && ["straight", "curved", "elbow"].includes(routing) ? routing : "straight",
|
|
133
|
+
startHead: head(v.startHead, "none"),
|
|
134
|
+
endHead: head(v.endHead, "arrow")
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
image(v, table) {
|
|
138
|
+
if (!isObj(v)) return null;
|
|
139
|
+
const ref = str(v.ref);
|
|
140
|
+
if (ref !== void 0) return table[ref] ?? { data: "", format: "png" };
|
|
141
|
+
const data = str(v.data);
|
|
142
|
+
return data === void 0 ? null : this.picture(data, str(v.format));
|
|
143
|
+
}
|
|
144
|
+
/** A picture's bytes, only if they really are base64: they go into an attribute of the drawn SVG. */
|
|
145
|
+
picture(data, format) {
|
|
146
|
+
if (!BASE64.test(data)) {
|
|
147
|
+
this.warn("Skipped a picture whose data isn't base64");
|
|
148
|
+
return { data: "", format: "png" };
|
|
149
|
+
}
|
|
150
|
+
return { data: data.replace(/\s+/g, ""), format: format === "jpeg" ? "jpeg" : "png" };
|
|
151
|
+
}
|
|
152
|
+
element(v, images) {
|
|
153
|
+
if (!isObj(v)) return null;
|
|
154
|
+
this.fields(v, "element");
|
|
155
|
+
const id = uuid(v.id), kind = str(v.kind), layerID = uuid(v.layerID);
|
|
156
|
+
if (!id || !kind || !layerID) {
|
|
157
|
+
this.warn("Skipped an element without an id, kind or layer");
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
if (!KINDS.includes(kind)) this.warn(`Unknown element kind "${kind}", drawn as a placeholder`);
|
|
161
|
+
const subpaths = Array.isArray(v.subpaths) ? v.subpaths.filter(isObj).map((s) => ({ closed: bool(s.closed) ?? false, coords: Array.isArray(s.coords) ? s.coords.filter((c) => typeof c === "number") : [] })) : null;
|
|
162
|
+
return {
|
|
163
|
+
id,
|
|
164
|
+
kind,
|
|
165
|
+
layerID,
|
|
166
|
+
x: num(v.x) ?? 0,
|
|
167
|
+
y: num(v.y) ?? 0,
|
|
168
|
+
width: num(v.width) ?? 0,
|
|
169
|
+
height: num(v.height) ?? 0,
|
|
170
|
+
style: this.style(v.style),
|
|
171
|
+
seed: (num(v.seed) ?? 1) >>> 0,
|
|
172
|
+
text: str(v.text) ?? null,
|
|
173
|
+
connector: this.connector(v.connector),
|
|
174
|
+
groupID: uuid(v.groupID) ?? null,
|
|
175
|
+
points: Array.isArray(v.points) ? v.points.filter(isObj).map((p) => ({ x: num(p.x) ?? 0, y: num(p.y) ?? 0 })) : null,
|
|
176
|
+
path: Array.isArray(v.path) ? v.path.filter((c) => typeof c === "number") : null,
|
|
177
|
+
subpaths,
|
|
178
|
+
evenOdd: bool(v.evenOdd) ?? null,
|
|
179
|
+
rotation: num(v.rotation) ?? null,
|
|
180
|
+
link: uuid(v.link) ?? null,
|
|
181
|
+
anchor: str(v.anchor) ?? null,
|
|
182
|
+
image: this.image(v.image, images),
|
|
183
|
+
reveal: num(v.reveal) ?? null
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
ease(v) {
|
|
187
|
+
const s = str(v);
|
|
188
|
+
if (s === void 0) return null;
|
|
189
|
+
if (!EASES.includes(s)) {
|
|
190
|
+
this.warn(`Unknown ease "${s}", played linear`);
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
return s;
|
|
194
|
+
}
|
|
195
|
+
keyframe(v) {
|
|
196
|
+
if (!isObj(v)) return null;
|
|
197
|
+
this.fields(v, "keyframe");
|
|
198
|
+
const t = num(v.t);
|
|
199
|
+
if (t === void 0) return null;
|
|
200
|
+
const k = { t };
|
|
201
|
+
for (const p of ["x", "y", "width", "height", "rotation", "strokeWidth", "reveal", "opacity"]) {
|
|
202
|
+
const n = num(v[p]);
|
|
203
|
+
if (n !== void 0) k[p] = n;
|
|
204
|
+
}
|
|
205
|
+
const stroke = rgba(v.stroke), fill = rgba(v.fill), visible = bool(v.visible), ease = this.ease(v.ease);
|
|
206
|
+
if (stroke) k.stroke = stroke;
|
|
207
|
+
if (fill) k.fill = fill;
|
|
208
|
+
if (visible !== void 0) k.visible = visible;
|
|
209
|
+
if (ease) k.ease = ease;
|
|
210
|
+
return k;
|
|
211
|
+
}
|
|
212
|
+
track(v) {
|
|
213
|
+
if (!isObj(v)) return null;
|
|
214
|
+
this.fields(v, "track");
|
|
215
|
+
const element = uuid(v.element);
|
|
216
|
+
if (!element) return null;
|
|
217
|
+
const keys = (Array.isArray(v.keys) ? v.keys : []).map((k) => this.keyframe(k)).filter((k) => k !== null && k.t >= 0 && k.t <= MAX_DURATION);
|
|
218
|
+
stableSortBy(keys, (k) => k.t);
|
|
219
|
+
const follow = Array.isArray(v.follow) ? v.follow.filter(isObj).flatMap((f) => {
|
|
220
|
+
const path = uuid(f.path), start = num(f.start), end = num(f.end);
|
|
221
|
+
if (!path || start === void 0 || end === void 0 || start < 0 || end > MAX_DURATION) return [];
|
|
222
|
+
return [{ path, start, end, ease: this.ease(f.ease), reverse: bool(f.reverse) ?? null, orient: bool(f.orient) ?? null, laps: num(f.laps) ?? null }];
|
|
223
|
+
}) : null;
|
|
224
|
+
const repeats = Array.isArray(v.repeats) ? v.repeats.filter(isObj).flatMap((r) => {
|
|
225
|
+
const start = num(r.start), end = num(r.end);
|
|
226
|
+
if (start === void 0 || end === void 0) return [];
|
|
227
|
+
const count = num(r.count);
|
|
228
|
+
const rep = { start, end, count: count === void 0 ? null : Math.trunc(count) };
|
|
229
|
+
return repeatIsValid(rep) ? [rep] : [];
|
|
230
|
+
}) : null;
|
|
231
|
+
return { element, keys, boil: bool(v.boil) ?? null, follow, repeats };
|
|
232
|
+
}
|
|
233
|
+
timeline(v) {
|
|
234
|
+
if (!isObj(v)) return null;
|
|
235
|
+
this.fields(v, "timeline");
|
|
236
|
+
const boil = num(v.boil);
|
|
237
|
+
const camera = Array.isArray(v.camera) ? v.camera.filter(isObj).flatMap((c) => {
|
|
238
|
+
const t = num(c.t), x = num(c.x), y = num(c.y), width = num(c.width), height = num(c.height);
|
|
239
|
+
if (t === void 0 || x === void 0 || y === void 0 || width === void 0 || height === void 0) return [];
|
|
240
|
+
if (!(width > 1 && height > 1 && t >= 0)) return [];
|
|
241
|
+
return [{ t, x, y, width, height, ease: this.ease(c.ease) }];
|
|
242
|
+
}) : null;
|
|
243
|
+
if (camera) stableSortBy(camera, (c) => c.t);
|
|
244
|
+
const markers = Array.isArray(v.markers) ? v.markers.filter(isObj).flatMap((m) => {
|
|
245
|
+
const t = num(m.t);
|
|
246
|
+
return t !== void 0 && t >= 0 ? [{ t, name: str(m.name) ?? "" }] : [];
|
|
247
|
+
}) : null;
|
|
248
|
+
if (markers) stableSortBy(markers, (m) => m.t);
|
|
249
|
+
const poster = num(v.poster);
|
|
250
|
+
return {
|
|
251
|
+
fps: clampFPS(num(v.fps) ?? 12),
|
|
252
|
+
duration: clampTime(num(v.duration) ?? 0),
|
|
253
|
+
boil: boil !== void 0 && Number.isInteger(boil) && boil > 0 ? Math.min(boil, 1e4) : null,
|
|
254
|
+
settle: bool(v.settle) ?? null,
|
|
255
|
+
poster: poster === void 0 ? null : clampTime(poster),
|
|
256
|
+
tracks: (Array.isArray(v.tracks) ? v.tracks : []).map((t) => this.track(t)).filter((t) => t !== null),
|
|
257
|
+
camera,
|
|
258
|
+
markers
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
page(v, images, n) {
|
|
262
|
+
if (!isObj(v)) throw new DottieFormatError(`Page ${n} is not an object`);
|
|
263
|
+
this.fields(v, "page");
|
|
264
|
+
const layers = (Array.isArray(v.layers) ? v.layers : []).filter(isObj).flatMap((l) => {
|
|
265
|
+
const id = uuid(l.id);
|
|
266
|
+
return id ? [{ id, name: str(l.name) ?? "", visible: bool(l.visible) ?? true, locked: bool(l.locked) ?? false }] : [];
|
|
267
|
+
});
|
|
268
|
+
if (layers.length === 0) {
|
|
269
|
+
this.warn(`Page ${n} has no layers`);
|
|
270
|
+
layers.push({ id: "LAYER", name: "Layer 1", visible: true, locked: false });
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
id: uuid(v.id) ?? `PAGE-${n}`,
|
|
274
|
+
name: str(v.name) ?? `Page ${n}`,
|
|
275
|
+
layers,
|
|
276
|
+
elements: (Array.isArray(v.elements) ? v.elements : []).map((e) => this.element(e, images)).filter((e) => e !== null),
|
|
277
|
+
theme: str(v.theme) ?? null,
|
|
278
|
+
timeline: this.timeline(v.timeline)
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
var BASE64 = /^[A-Za-z0-9+/=\s]*$/;
|
|
283
|
+
function repeatIsValid(r) {
|
|
284
|
+
return Number.isFinite(r.start) && Number.isFinite(r.end) && r.start >= 0 && r.end - r.start > 1e-3 && r.end <= MAX_DURATION && (r.count === null || r.count >= 1 && r.count <= 1e4);
|
|
285
|
+
}
|
|
286
|
+
function stableSortBy(a, key) {
|
|
287
|
+
const indexed = a.map((v, i) => [v, i]);
|
|
288
|
+
indexed.sort((p, q) => key(p[0]) - key(q[0]) || p[1] - q[1]);
|
|
289
|
+
for (let i = 0; i < a.length; i++) a[i] = indexed[i][0];
|
|
290
|
+
}
|
|
291
|
+
function parseDottie(source) {
|
|
292
|
+
let json = source;
|
|
293
|
+
if (typeof source === "string") {
|
|
294
|
+
try {
|
|
295
|
+
json = JSON.parse(source);
|
|
296
|
+
} catch (e) {
|
|
297
|
+
throw new DottieFormatError(`Not JSON: ${e.message}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (!isObj(json)) throw new DottieFormatError("Not a Dottie drawing");
|
|
301
|
+
const version = num(json.version);
|
|
302
|
+
if (version === void 0) throw new DottieFormatError("Not a Dottie drawing (no version)");
|
|
303
|
+
if (!Array.isArray(json.pages) || json.pages.length === 0) throw new DottieFormatError("A drawing needs at least one page");
|
|
304
|
+
const reader = new Reader();
|
|
305
|
+
reader.fields(json, "file");
|
|
306
|
+
if (version > SUPPORTED_VERSION) reader.warn(`File version ${version} is newer than this player knows (${SUPPORTED_VERSION}); some things may not show`);
|
|
307
|
+
const images = {};
|
|
308
|
+
if (isObj(json.images)) {
|
|
309
|
+
for (const [k, v] of Object.entries(json.images)) {
|
|
310
|
+
if (isObj(v) && typeof v.data === "string") images[k] = reader.picture(v.data, str(v.format));
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const pages = json.pages.map((p, i) => reader.page(p, images, i + 1));
|
|
314
|
+
if (new Set(pages.map((p) => p.id)).size !== pages.length) throw new DottieFormatError("Two pages share an id");
|
|
315
|
+
return { version, pages, warnings: reader.warnings };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/player.ts
|
|
319
|
+
function pageIndex(file, spec) {
|
|
320
|
+
const s = (spec ?? "").trim();
|
|
321
|
+
if (!s) return 0;
|
|
322
|
+
const byName = file.pages.findIndex((p) => p.name.toLowerCase() === s.toLowerCase());
|
|
323
|
+
if (byName >= 0) return byName;
|
|
324
|
+
const n = Number(s);
|
|
325
|
+
return Number.isInteger(n) && n >= 1 && n <= file.pages.length ? n - 1 : 0;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// src/compile.ts
|
|
329
|
+
var LOADER = `;(function () {
|
|
330
|
+
var data = DOTTIE_DATA, options = DOTTIE_OPTIONS;
|
|
331
|
+
var script = document.currentScript;
|
|
332
|
+
function attr(el, name, value) { el.setAttribute(name.replace(/[A-Z]/g, function (c) { return "-" + c.toLowerCase(); }), value); }
|
|
333
|
+
function mount() {
|
|
334
|
+
var player = document.createElement("dottie-player"), k;
|
|
335
|
+
for (k in options) attr(player, k, options[k]);
|
|
336
|
+
if (script) for (k in script.dataset) if (k !== "target") attr(player, k, script.dataset[k]);
|
|
337
|
+
var target = script && script.dataset.target ? document.querySelector(script.dataset.target) : null;
|
|
338
|
+
if (target) target.appendChild(player);
|
|
339
|
+
else if (script && script.parentNode && script.parentNode !== document.head) script.parentNode.insertBefore(player, script);
|
|
340
|
+
else document.body.appendChild(player);
|
|
341
|
+
player.setFile(window.Dottie.parseDottie(data));
|
|
342
|
+
}
|
|
343
|
+
if (document.readyState === "loading" && (!script || script.parentNode === document.head || script.dataset.target)) {
|
|
344
|
+
document.addEventListener("DOMContentLoaded", mount);
|
|
345
|
+
} else {
|
|
346
|
+
mount();
|
|
347
|
+
}
|
|
348
|
+
})();
|
|
349
|
+
`;
|
|
350
|
+
function scriptJSON(value) {
|
|
351
|
+
return JSON.stringify(value).replace(/<\//g, "<\\/").replace(/<!--/g, "<\\!--").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
352
|
+
}
|
|
353
|
+
function playerAttributes(options) {
|
|
354
|
+
const out = {};
|
|
355
|
+
if (options.at !== void 0) out.at = String(options.at);
|
|
356
|
+
if (options.clean) out.clean = "";
|
|
357
|
+
if (options.noControls) out["no-controls"] = "";
|
|
358
|
+
if (options.noAutoplay) out["no-autoplay"] = "";
|
|
359
|
+
if (options.noLoop) out["no-loop"] = "";
|
|
360
|
+
if (options.label !== void 0) out.label = options.label;
|
|
361
|
+
return out;
|
|
362
|
+
}
|
|
363
|
+
function compile(source, runtime, options = {}) {
|
|
364
|
+
let raw = source;
|
|
365
|
+
if (typeof source === "string") {
|
|
366
|
+
try {
|
|
367
|
+
raw = JSON.parse(source);
|
|
368
|
+
} catch (e) {
|
|
369
|
+
throw new DottieFormatError(`Not JSON: ${e.message}`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const file = parseDottie(raw);
|
|
373
|
+
const json = raw;
|
|
374
|
+
const i = pageIndex(file, options.page === void 0 ? null : String(options.page));
|
|
375
|
+
const page = json.pages[i];
|
|
376
|
+
const refs = /* @__PURE__ */ new Set();
|
|
377
|
+
JSON.stringify(page, (k, v) => {
|
|
378
|
+
if (k === "ref" && typeof v === "string") refs.add(v);
|
|
379
|
+
return v;
|
|
380
|
+
});
|
|
381
|
+
const images = Object.fromEntries(Object.entries(json.images ?? {}).filter(([k]) => refs.has(k)));
|
|
382
|
+
const data = { version: json.version, pages: [page] };
|
|
383
|
+
if (Object.keys(images).length) data.images = images;
|
|
384
|
+
return runtime.trimEnd() + "\n" + LOADER.replace("DOTTIE_DATA", () => scriptJSON(data)).replace("DOTTIE_OPTIONS", () => scriptJSON(playerAttributes(options)));
|
|
385
|
+
}
|
|
386
|
+
export {
|
|
387
|
+
LOADER,
|
|
388
|
+
compile,
|
|
389
|
+
playerAttributes,
|
|
390
|
+
scriptJSON
|
|
391
|
+
};
|