@kieransimkin/dancemoves 3.0.2
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 +338 -0
- package/README.md +893 -0
- package/RUDIMENTS-API.md +394 -0
- package/docs/README.md +73 -0
- package/docs/api/adapters.md +400 -0
- package/docs/api/downloads.md +158 -0
- package/docs/api/effects.md +463 -0
- package/docs/api/javascript.md +500 -0
- package/docs/api/paper-planes.md +167 -0
- package/docs/api/styling.md +292 -0
- package/docs/api/surface.json +446 -0
- package/docs/api/wordpress.md +365 -0
- package/docs/clay-transform-validation.md +84 -0
- package/docs/development.md +254 -0
- package/docs/guide.md +288 -0
- package/docs/javascript-api.md +292 -0
- package/docs/javascript-server.md +150 -0
- package/docs/react-next.md +185 -0
- package/docs/releasing-shared.md +162 -0
- package/docs/rudiments-source-integrity.md +80 -0
- package/docs/shared-feature-coverage.md +34 -0
- package/docs/shared-runtime-migration.md +111 -0
- package/docs/source-audit.md +120 -0
- package/docs/validation-setup.md +102 -0
- package/docs/wordpress-examples.md +206 -0
- package/docs/wordpress-shared-runtime.md +133 -0
- package/lib/admin.min.js +1 -0
- package/lib/assets/DanceRudiments-LICENSE +21 -0
- package/lib/assets/DanceRudiments-build-manifest.json +21 -0
- package/lib/assets/paper-dreams-plane-atlas.png +0 -0
- package/lib/build-manifest.json +117 -0
- package/lib/dancemoves.css +9 -0
- package/lib/dancemoves.min.js +5 -0
- package/lib/index.cjs +4802 -0
- package/lib/index.d.ts +71 -0
- package/lib/index.mjs +4780 -0
- package/lib/react.cjs +154 -0
- package/lib/react.d.ts +12 -0
- package/lib/react.mjs +135 -0
- package/lib/rudiments.d.ts +124 -0
- package/lib/server.cjs +411 -0
- package/lib/server.d.ts +11 -0
- package/lib/server.mjs +367 -0
- package/lib/styles/clay-stars-effects.css +1 -0
- package/lib/styles/clay-stars-rudiments.css +1 -0
- package/lib/styles/dance-moves-core.css +1 -0
- package/lib/styles/ks-epk-device-orientation.css +1 -0
- package/lib/styles/paper-dreams-flight.css +1 -0
- package/lib/wordpress.js +5 -0
- package/package.json +101 -0
package/lib/server.mjs
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
// .build/modules/server.mjs
|
|
2
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
3
|
+
import { realpath, open } from "node:fs/promises";
|
|
4
|
+
import { constants as fsConstants } from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { Readable } from "node:stream";
|
|
7
|
+
|
|
8
|
+
// .build/modules/config.mjs
|
|
9
|
+
var PAGE_META_KEYS = Object.freeze({
|
|
10
|
+
bpm: "_dance_moves_bpm",
|
|
11
|
+
lyric: "_dance_moves_lyric_timing_id",
|
|
12
|
+
cue: "_dance_moves_cue_timing_id",
|
|
13
|
+
popups: "_dance_moves_lyric_popups_enabled",
|
|
14
|
+
duration: "_dance_moves_master_duration_ms",
|
|
15
|
+
effect: "_dance_moves_effect"
|
|
16
|
+
});
|
|
17
|
+
var object = (value) => value && typeof value === "object" && !Array.isArray(value);
|
|
18
|
+
function finite(value, name, min, max) {
|
|
19
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < min || value > max)
|
|
20
|
+
throw new RangeError(`${name} must be a finite number in [${min}, ${max}]`);
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function url(value, name) {
|
|
24
|
+
if (value === void 0 || value === "") return "";
|
|
25
|
+
if (typeof value !== "string" || value.length > 4096 || /[\u0000-\u001f]/.test(value)) throw new TypeError(`Invalid ${name}`);
|
|
26
|
+
const parsed = new URL(value, "https://dancemoves.invalid/");
|
|
27
|
+
if (!["http:", "https:"].includes(parsed.protocol) || parsed.username || parsed.password)
|
|
28
|
+
throw new TypeError(`${name} must be an HTTP(S) or relative URL`);
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
function validatePageConfig(input = {}) {
|
|
32
|
+
if (!object(input)) throw new TypeError("Page configuration must be an object");
|
|
33
|
+
const explicit = input.bpm !== void 0 && input.bpm !== null && input.bpm !== "";
|
|
34
|
+
const bpm = explicit ? Math.round(finite(input.bpm, "bpm", 20, 400) * 1e3) / 1e3 : 120;
|
|
35
|
+
const effect = input.effect ?? "";
|
|
36
|
+
if (!["", "paper-planes"].includes(effect)) throw new RangeError("effect must be empty or paper-planes");
|
|
37
|
+
if (input.lyricPopupsEnabled !== void 0 && typeof input.lyricPopupsEnabled !== "boolean") throw new TypeError("lyricPopupsEnabled must be boolean");
|
|
38
|
+
const duration = finite(input.masterDurationMilliseconds ?? 0, "masterDurationMilliseconds", 0, 864e5);
|
|
39
|
+
const ticks = finite(input.sharedControlTicks ?? 0, "sharedControlTicks", 0, 65536);
|
|
40
|
+
const disclosure = finite(input.lyricDisclosureTicks ?? 6, "lyricDisclosureTicks", 1, 65536);
|
|
41
|
+
const pageId = input.pageId ?? 0;
|
|
42
|
+
if (!Number.isSafeInteger(pageId) || pageId < 0) throw new RangeError("pageId must be a non-negative safe integer");
|
|
43
|
+
return Object.freeze({
|
|
44
|
+
pageId,
|
|
45
|
+
bpm,
|
|
46
|
+
bpmSource: explicit && input.bpmSource !== "fallback" ? "explicit" : "fallback",
|
|
47
|
+
fallbackBpm: 120,
|
|
48
|
+
ticksPerBeat: 16,
|
|
49
|
+
tickDefinition: "sixteenth-of-beat",
|
|
50
|
+
longDurationQuantumTicks: 16,
|
|
51
|
+
cueTimingUrl: url(input.cueTimingUrl, "cueTimingUrl"),
|
|
52
|
+
lyricTimingUrl: url(input.lyricTimingUrl, "lyricTimingUrl"),
|
|
53
|
+
lyricPopupsEnabled: input.lyricPopupsEnabled === true,
|
|
54
|
+
masterDurationMilliseconds: Math.round(duration * 1e3) / 1e3,
|
|
55
|
+
sharedControlTicks: ticks,
|
|
56
|
+
lyricDisclosureTicks: disclosure,
|
|
57
|
+
effect,
|
|
58
|
+
diagnostics: input.diagnostics === true
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
async function fromWordPressMeta(meta, resolveAttachment) {
|
|
62
|
+
if (!object(meta)) throw new TypeError("meta must be an object");
|
|
63
|
+
const numeric2 = (value) => value !== "" && value !== null && value !== void 0 && Number.isFinite(Number(value));
|
|
64
|
+
const b = meta[PAGE_META_KEYS.bpm];
|
|
65
|
+
const bpm = numeric2(b) && Number(b) >= 20 && Number(b) <= 400 ? Number(b) : void 0;
|
|
66
|
+
const resolve = async (key) => {
|
|
67
|
+
const value = Number(meta[key] || 0);
|
|
68
|
+
if (!Number.isSafeInteger(value)) throw new RangeError("Attachment ID must be a safe integer");
|
|
69
|
+
const id = Math.abs(value);
|
|
70
|
+
if (!id) return "";
|
|
71
|
+
if (typeof resolveAttachment !== "function") throw new TypeError("An attachment URL resolver is required for nonzero IDs");
|
|
72
|
+
return await resolveAttachment(id) || "";
|
|
73
|
+
};
|
|
74
|
+
const duration = Number(meta[PAGE_META_KEYS.duration]);
|
|
75
|
+
return validatePageConfig({
|
|
76
|
+
bpm,
|
|
77
|
+
lyricTimingUrl: await resolve(PAGE_META_KEYS.lyric),
|
|
78
|
+
cueTimingUrl: await resolve(PAGE_META_KEYS.cue),
|
|
79
|
+
lyricPopupsEnabled: meta[PAGE_META_KEYS.popups] === true || String(meta[PAGE_META_KEYS.popups]) === "1",
|
|
80
|
+
masterDurationMilliseconds: Number.isFinite(duration) && duration > 0 && duration <= 864e5 ? duration : 0,
|
|
81
|
+
effect: meta[PAGE_META_KEYS.effect] === "paper-planes" ? "paper-planes" : ""
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function createMemoryPageStore({ maxPages = 100, maxRevisions = 20 } = {}) {
|
|
85
|
+
for (const [name, value] of Object.entries({ maxPages, maxRevisions })) if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(name);
|
|
86
|
+
const pages = /* @__PURE__ */ new Map();
|
|
87
|
+
const key = (id) => {
|
|
88
|
+
if (typeof id !== "string" || !id.trim() || id.length > 160) throw new TypeError("Invalid page id");
|
|
89
|
+
return id;
|
|
90
|
+
};
|
|
91
|
+
const clone = (value) => value ? structuredClone(value) : null;
|
|
92
|
+
return Object.freeze({
|
|
93
|
+
read(id) {
|
|
94
|
+
return clone(pages.get(key(id))?.at(-1) || null);
|
|
95
|
+
},
|
|
96
|
+
revisions(id) {
|
|
97
|
+
return clone(pages.get(key(id)) || []);
|
|
98
|
+
},
|
|
99
|
+
save(id, input, { expectedRevision } = {}) {
|
|
100
|
+
key(id);
|
|
101
|
+
const config = validatePageConfig(input);
|
|
102
|
+
const history = pages.get(id) || [];
|
|
103
|
+
const current = history.at(-1)?.revision || 0;
|
|
104
|
+
if (expectedRevision !== void 0 && expectedRevision !== current) throw new Error("Revision conflict");
|
|
105
|
+
if (!pages.has(id) && pages.size >= maxPages) throw new Error("Page store capacity reached");
|
|
106
|
+
const record = { revision: current + 1, config, savedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
107
|
+
pages.set(id, [...history, record].slice(-maxRevisions));
|
|
108
|
+
return clone(record);
|
|
109
|
+
},
|
|
110
|
+
restore(id, revision, options) {
|
|
111
|
+
const record = (pages.get(key(id)) || []).find((item) => item.revision === revision);
|
|
112
|
+
if (!record) throw new RangeError("Revision not found");
|
|
113
|
+
return this.save(id, record.config, options);
|
|
114
|
+
},
|
|
115
|
+
delete(id) {
|
|
116
|
+
return pages.delete(key(id));
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// .build/modules/server.mjs
|
|
122
|
+
var ValidationError = class extends Error {
|
|
123
|
+
constructor(code, message, status = 400) {
|
|
124
|
+
super(message);
|
|
125
|
+
this.name = "ValidationError";
|
|
126
|
+
this.code = code;
|
|
127
|
+
this.status = status;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
var fail = (code, message, status) => {
|
|
131
|
+
throw new ValidationError(code, message, status);
|
|
132
|
+
};
|
|
133
|
+
function validateTimingFile(input, { kind = "cue", filename, maxBytes = 1048576 } = {}) {
|
|
134
|
+
if (!["cue", "lyric"].includes(kind)) throw new TypeError("kind must be cue or lyric");
|
|
135
|
+
if (filename) {
|
|
136
|
+
const ext = path.extname(filename).toLowerCase();
|
|
137
|
+
if (!(kind === "lyric" ? [".lrc"] : [".lrc", ".cue"]).includes(ext)) fail("timing_extension", "Incorrect timing-file extension");
|
|
138
|
+
}
|
|
139
|
+
if (typeof input !== "string" && !(input instanceof Uint8Array)) throw new TypeError("Timing input must be text or bytes");
|
|
140
|
+
const bytes = typeof input === "string" ? Buffer.from(input, "utf8") : input;
|
|
141
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes < 1 || bytes.byteLength > maxBytes) fail("timing_size", "Timing file exceeds the byte limit", 413);
|
|
142
|
+
let text;
|
|
143
|
+
try {
|
|
144
|
+
text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
145
|
+
} catch {
|
|
146
|
+
fail("timing_utf8", "Timing file is not valid UTF-8");
|
|
147
|
+
}
|
|
148
|
+
if (/[\u0000\uFFFD]/.test(text)) fail("timing_utf8", "Timing file contains a null or replacement character");
|
|
149
|
+
const stamps = [...text.matchAll(/\[(\d{1,3}):(\d{2})(?:[\.:](\d{1,3}))?\]/g)];
|
|
150
|
+
if (!stamps.length) fail("timing_timestamps", "Timing file must contain at least one bracketed timestamp");
|
|
151
|
+
let previous = -1;
|
|
152
|
+
for (const stamp of stamps) {
|
|
153
|
+
const time = Number(stamp[1]) * 60 + Number(stamp[2]) + (stamp[3] ? Number("0." + stamp[3]) : 0);
|
|
154
|
+
if (time < previous) fail("timing_order", "Timing timestamps must be monotonic");
|
|
155
|
+
previous = time;
|
|
156
|
+
}
|
|
157
|
+
return Object.freeze({ text, kind, bytes: bytes.byteLength, timestamps: stamps.length });
|
|
158
|
+
}
|
|
159
|
+
function normalizeDownloadPath(value) {
|
|
160
|
+
if (typeof value !== "string" || value.length > 4096) return "";
|
|
161
|
+
let result;
|
|
162
|
+
try {
|
|
163
|
+
result = decodeURIComponent(value.trim().replaceAll("\\", "/"));
|
|
164
|
+
} catch {
|
|
165
|
+
return "";
|
|
166
|
+
}
|
|
167
|
+
if (!result || result.startsWith("/") || /[:\u0000-\u001f\u007f\\]/.test(result) || !/\.mp3$/i.test(result)) return "";
|
|
168
|
+
if (result.split("/").some((part) => !part || part === "." || part === "..")) return "";
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
function asOrigin(value) {
|
|
172
|
+
const u = new URL(value);
|
|
173
|
+
if (!["https:", "http:"].includes(u.protocol) || u.username || u.password) throw new TypeError("Invalid HTTP origin");
|
|
174
|
+
return u.origin;
|
|
175
|
+
}
|
|
176
|
+
function privateHeaders() {
|
|
177
|
+
return { "Cache-Control": "private, no-store, max-age=0", "X-Content-Type-Options": "nosniff", "X-Robots-Tag": "noindex, nofollow" };
|
|
178
|
+
}
|
|
179
|
+
function json(body, status = 200, extra = {}) {
|
|
180
|
+
return new Response(JSON.stringify(body), { status, headers: { ...privateHeaders(), "Content-Type": "application/json; charset=utf-8", ...extra } });
|
|
181
|
+
}
|
|
182
|
+
function createDownloadService({ rootDirectory, secret, origin, route = "/api/download" } = {}) {
|
|
183
|
+
if (typeof rootDirectory !== "string" || !path.isAbsolute(rootDirectory)) throw new TypeError("rootDirectory must be an absolute local directory");
|
|
184
|
+
if (!(typeof secret === "string" || secret instanceof Uint8Array) || Buffer.byteLength(secret) < 32) throw new TypeError("Use a server-only secret of at least 32 bytes");
|
|
185
|
+
const baseOrigin = asOrigin(origin);
|
|
186
|
+
if (typeof route !== "string" || !route.startsWith("/") || route.startsWith("//")) throw new TypeError("route must be a same-origin absolute path");
|
|
187
|
+
const routeURL = new URL(route, baseOrigin);
|
|
188
|
+
if (routeURL.origin !== baseOrigin || routeURL.search || routeURL.hash) throw new TypeError("route must not include an origin, query or fragment");
|
|
189
|
+
const digest = (relative) => createHmac("sha256", secret).update(relative).digest("hex");
|
|
190
|
+
function sign(relative) {
|
|
191
|
+
const normal = normalizeDownloadPath(relative);
|
|
192
|
+
if (!normal) throw new ValidationError("download_path", "A safe relative MP3 path is required");
|
|
193
|
+
const url2 = new URL(routeURL);
|
|
194
|
+
url2.searchParams.set("path", normal);
|
|
195
|
+
url2.searchParams.set("signature", digest(normal));
|
|
196
|
+
return url2.href;
|
|
197
|
+
}
|
|
198
|
+
async function handle(request) {
|
|
199
|
+
let input;
|
|
200
|
+
try {
|
|
201
|
+
input = new URL(request.url);
|
|
202
|
+
} catch {
|
|
203
|
+
return new Response(null, { status: 404, headers: privateHeaders() });
|
|
204
|
+
}
|
|
205
|
+
if (input.pathname !== routeURL.pathname) return new Response(null, { status: 404, headers: privateHeaders() });
|
|
206
|
+
const relative = normalizeDownloadPath(input.searchParams.get("path"));
|
|
207
|
+
const signature = input.searchParams.get("signature") || "";
|
|
208
|
+
if (!relative || !/^[0-9a-f]{64}$/i.test(signature) || !timingSafeEqual(Buffer.from(signature, "hex"), Buffer.from(digest(relative), "hex")))
|
|
209
|
+
return new Response(null, { status: 404, headers: privateHeaders() });
|
|
210
|
+
if (!["GET", "HEAD"].includes(request.method)) return new Response(null, { status: 405, headers: { ...privateHeaders(), Allow: "GET, HEAD" } });
|
|
211
|
+
let file;
|
|
212
|
+
try {
|
|
213
|
+
const base = await realpath(rootDirectory);
|
|
214
|
+
const resolved = await realpath(path.join(base, ...relative.split("/")));
|
|
215
|
+
const rel = path.relative(base, resolved);
|
|
216
|
+
if (!rel || rel === ".." || rel.startsWith(".." + path.sep) || path.isAbsolute(rel) || path.extname(resolved).toLowerCase() !== ".mp3") return new Response(null, { status: 404, headers: privateHeaders() });
|
|
217
|
+
file = await open(resolved, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW || 0));
|
|
218
|
+
const stat = await file.stat();
|
|
219
|
+
if (!stat.isFile()) {
|
|
220
|
+
await file.close();
|
|
221
|
+
return new Response(null, { status: 404, headers: privateHeaders() });
|
|
222
|
+
}
|
|
223
|
+
const filename = path.basename(resolved);
|
|
224
|
+
const ascii = filename.replace(/[^\x20-\x7e]/g, "_").replace(/["\\]/g, "_") || "audio.mp3";
|
|
225
|
+
const encoded = encodeURIComponent(filename).replace(/['()*]/g, (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase());
|
|
226
|
+
const headers = {
|
|
227
|
+
...privateHeaders(),
|
|
228
|
+
"Content-Type": "audio/mpeg",
|
|
229
|
+
"Content-Length": String(stat.size),
|
|
230
|
+
"Content-Disposition": `attachment; filename="${ascii}"; filename*=UTF-8''${encoded}`
|
|
231
|
+
};
|
|
232
|
+
if (request.method === "HEAD") {
|
|
233
|
+
await file.close();
|
|
234
|
+
return new Response(null, { status: 200, headers });
|
|
235
|
+
}
|
|
236
|
+
const stream = file.createReadStream({ autoClose: true });
|
|
237
|
+
return new Response(Readable.toWeb(stream), { status: 200, headers });
|
|
238
|
+
} catch {
|
|
239
|
+
if (file) await file.close().catch(() => {
|
|
240
|
+
});
|
|
241
|
+
return new Response(null, { status: 404, headers: privateHeaders() });
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return Object.freeze({ sign, handle });
|
|
245
|
+
}
|
|
246
|
+
var numeric = (v, min, max) => typeof v === "number" && Number.isFinite(v) && v >= min && v <= max;
|
|
247
|
+
function boundedText(value, max = 500) {
|
|
248
|
+
return String(value ?? "").replace(/[\u0000-\u001f\u007f]/g, "").slice(0, max);
|
|
249
|
+
}
|
|
250
|
+
function validateMotionCapture(payload) {
|
|
251
|
+
if (!payload || payload.schema !== "ks-epk-motion-recording/v1") fail("ks_motion_schema", "Unsupported capture schema");
|
|
252
|
+
if (!Array.isArray(payload.samples) || payload.samples.length < 1 || payload.samples.length > 500) fail("ks_motion_samples", "A capture must contain 1..500 samples");
|
|
253
|
+
const samples = payload.samples.map((sample) => {
|
|
254
|
+
if (!sample || !numeric(sample.milliseconds, 0, 12e4) || !numeric(sample.beta, -180, 180) || !numeric(sample.gamma, -90, 90)) fail("ks_motion_invalid_samples", "Invalid motion sample");
|
|
255
|
+
return {
|
|
256
|
+
milliseconds: sample.milliseconds,
|
|
257
|
+
beta: sample.beta,
|
|
258
|
+
gamma: sample.gamma,
|
|
259
|
+
alpha: sample.alpha === null || sample.alpha === void 0 ? null : numeric(sample.alpha, 0, 360) ? sample.alpha : null,
|
|
260
|
+
screenAngle: numeric(sample.screenAngle ?? 0, -360, 360) ? sample.screenAngle || 0 : null,
|
|
261
|
+
...Object.fromEntries(["absolute", "nativeTrusted", "simulatedTrusted", "fieldParity", "dispatchParity", "mapperParity"].map((k) => [k, !!sample[k]]))
|
|
262
|
+
};
|
|
263
|
+
});
|
|
264
|
+
const clean = {
|
|
265
|
+
schema: payload.schema,
|
|
266
|
+
capturedAt: boundedText(payload.capturedAt, 100),
|
|
267
|
+
userAgent: boundedText(payload.userAgent),
|
|
268
|
+
samples,
|
|
269
|
+
screenAngle: numeric(payload.screenAngle ?? 0, -360, 360) ? payload.screenAngle || 0 : null,
|
|
270
|
+
storedSampleCount: samples.length,
|
|
271
|
+
sampleStrategy: boundedText(payload.sampleStrategy || "legacy", 80).toLowerCase().replace(/[^a-z0-9_-]/g, ""),
|
|
272
|
+
fullWindowObserved: !!payload.fullWindowObserved,
|
|
273
|
+
expectedDifference: boundedText(payload.expectedDifference),
|
|
274
|
+
passed: !!payload.passed,
|
|
275
|
+
failures: (Array.isArray(payload.failures) ? payload.failures : []).slice(0, 100).filter((v) => v && typeof v === "object").map((v) => ({
|
|
276
|
+
type: boundedText(v.type || "unknown", 80).toLowerCase().replace(/[^a-z0-9_-]/g, ""),
|
|
277
|
+
sample: Number.isFinite(Number(v.sample)) ? Math.abs(Math.trunc(Number(v.sample))) : null,
|
|
278
|
+
validPairs: Number.isFinite(Number(v.validPairs)) ? Math.abs(Math.trunc(Number(v.validPairs))) : null
|
|
279
|
+
}))
|
|
280
|
+
};
|
|
281
|
+
for (const key of ["targetDurationMilliseconds", "captureDurationMilliseconds", "sampledDurationMilliseconds", "storageIntervalMilliseconds"]) clean[key] = numeric(payload[key] ?? 0, 0, 12e4) ? payload[key] || 0 : null;
|
|
282
|
+
for (const key of ["processedPairCount", "failureCount"]) clean[key] = Math.min(1e5, Math.abs(Math.trunc(Number(payload[key]) || (key === "processedPairCount" ? samples.length : clean.failures.length))));
|
|
283
|
+
if (Buffer.byteLength(JSON.stringify(clean)) > 262144) fail("ks_motion_size", "Capture too large", 413);
|
|
284
|
+
return clean;
|
|
285
|
+
}
|
|
286
|
+
function createMemoryRateLimiter({ limit = 8, windowMilliseconds = 6e5, maxKeys = 1e4, now = Date.now } = {}) {
|
|
287
|
+
for (const [key, value] of Object.entries({ limit, windowMilliseconds, maxKeys })) if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(key);
|
|
288
|
+
const records = /* @__PURE__ */ new Map();
|
|
289
|
+
return Object.freeze({ consume(key) {
|
|
290
|
+
if (typeof key !== "string" || !key || key.length > 512) return false;
|
|
291
|
+
const time = now();
|
|
292
|
+
for (const [id, r2] of records) if (r2.until <= time) records.delete(id);
|
|
293
|
+
if (!records.has(key) && records.size >= maxKeys) return false;
|
|
294
|
+
const r = records.get(key) || { until: time + windowMilliseconds, count: 0 };
|
|
295
|
+
records.set(key, r);
|
|
296
|
+
return ++r.count <= limit;
|
|
297
|
+
} });
|
|
298
|
+
}
|
|
299
|
+
async function boundedBody(request, maxBytes) {
|
|
300
|
+
const length = request.headers.get("content-length");
|
|
301
|
+
if (length && (!/^\d+$/.test(length) || Number(length) > maxBytes)) fail("ks_motion_size", "Capture too large", 413);
|
|
302
|
+
if (!request.body) fail("ks_motion_schema", "Missing JSON body");
|
|
303
|
+
const reader = request.body.getReader();
|
|
304
|
+
const chunks = [];
|
|
305
|
+
let size = 0;
|
|
306
|
+
try {
|
|
307
|
+
while (true) {
|
|
308
|
+
const { done, value } = await reader.read();
|
|
309
|
+
if (done) break;
|
|
310
|
+
size += value.byteLength;
|
|
311
|
+
if (size > maxBytes) {
|
|
312
|
+
await reader.cancel();
|
|
313
|
+
fail("ks_motion_size", "Capture too large", 413);
|
|
314
|
+
}
|
|
315
|
+
chunks.push(value);
|
|
316
|
+
}
|
|
317
|
+
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks)));
|
|
318
|
+
} catch (error) {
|
|
319
|
+
if (error instanceof ValidationError) throw error;
|
|
320
|
+
fail("ks_motion_schema", "Invalid UTF-8 JSON");
|
|
321
|
+
} finally {
|
|
322
|
+
reader.releaseLock();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function createCaptureHandler({ authorize, store, rateLimit, allowedOrigin, maxBytes = 262144 } = {}) {
|
|
326
|
+
for (const [key, fn] of Object.entries({ authorize, store, rateLimit })) if (typeof fn !== "function") throw new TypeError(`${key} callback is required`);
|
|
327
|
+
const origin = asOrigin(allowedOrigin);
|
|
328
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes < 1 || maxBytes > 262144) throw new RangeError("maxBytes must be 1..262144");
|
|
329
|
+
return async (request) => {
|
|
330
|
+
if (request.method !== "POST") return json({ code: "method_not_allowed" }, 405, { Allow: "POST" });
|
|
331
|
+
try {
|
|
332
|
+
const source = request.headers.get("origin");
|
|
333
|
+
if (source) {
|
|
334
|
+
let sourceOrigin;
|
|
335
|
+
try {
|
|
336
|
+
sourceOrigin = asOrigin(source);
|
|
337
|
+
} catch {
|
|
338
|
+
return json({ code: "ks_motion_origin" }, 403);
|
|
339
|
+
}
|
|
340
|
+
if (sourceOrigin !== origin) return json({ code: "ks_motion_origin" }, 403);
|
|
341
|
+
}
|
|
342
|
+
if (!await authorize(request)) return json({ code: "ks_motion_forbidden" }, 403);
|
|
343
|
+
if (!await rateLimit(request)) return json({ code: "ks_motion_rate" }, 429, { "Retry-After": "600" });
|
|
344
|
+
if (!/^application\/json(?:\s*;|$)/i.test(request.headers.get("content-type") || "")) return json({ code: "ks_motion_content_type" }, 415);
|
|
345
|
+
const capture = validateMotionCapture(await boundedBody(request, maxBytes));
|
|
346
|
+
const stored = await store(capture, { visibility: "private", request });
|
|
347
|
+
if (!stored || !stored.captureId || stored.storedPrivately !== true) throw new Error("Storage did not confirm private persistence");
|
|
348
|
+
return json({ captureId: stored.captureId, sampleCount: capture.samples.length, storedPrivately: true });
|
|
349
|
+
} catch (error) {
|
|
350
|
+
if (error instanceof ValidationError) return json({ code: error.code, message: error.message }, error.status);
|
|
351
|
+
return json({ code: "ks_motion_server", message: "Capture could not be stored" }, 500);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
export {
|
|
356
|
+
PAGE_META_KEYS,
|
|
357
|
+
ValidationError,
|
|
358
|
+
createCaptureHandler,
|
|
359
|
+
createDownloadService,
|
|
360
|
+
createMemoryPageStore,
|
|
361
|
+
createMemoryRateLimiter,
|
|
362
|
+
fromWordPressMeta,
|
|
363
|
+
normalizeDownloadPath,
|
|
364
|
+
validateMotionCapture,
|
|
365
|
+
validatePageConfig,
|
|
366
|
+
validateTimingFile
|
|
367
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ks-clay-stars-v2{--ks-master-bpm: 90;--ks-master-beat: var(--dance-moves-beat, .666666667s);--ks-master-intensity: 1;--ks-particle-release-duration: var(--dance-moves-32t, 1.034482758s)}.ks-clay-stars-v2 .epk-actions>p:empty,.ks-clay-stars-v2 .ks-clay-stars-chapters>br,.ks-clay-stars-v2 .epk-cosmology-head>p:empty,.ks-clay-stars-v2 .epk-artwork>p:empty,.ks-clay-stars-v2 .epk-footer>br{display:none!important}.ks-clay-stars-v2 .epk-cover-wrap{--ks-bloom-x: 0px;--ks-bloom-y: 0px;--ks-flare-x: 0px;--ks-flare-y: 0px;--ks-spec-x: 0px;--ks-spec-y: 0px}.ks-clay-stars-v2 .ks-cloud-field{position:absolute;z-index:-1;inset:0;overflow:hidden;pointer-events:none;user-select:none;contain:paint}.ks-clay-stars-v2 .ks-cloud-field:before,.ks-clay-stars-v2 .ks-cloud-field:after{content:"";position:absolute;inset:-22%;display:block;background-repeat:no-repeat;mix-blend-mode:screen;will-change:transform}.ks-clay-stars-v2 .ks-cloud-field:before{background:radial-gradient(ellipse at 18% 28%,rgba(51,64,108,.3) 0 12%,transparent 42%),radial-gradient(ellipse at 72% 24%,rgba(163,101,76,.16) 0 10%,transparent 38%),radial-gradient(ellipse at 48% 68%,rgba(23,27,55,.44) 0 16%,transparent 50%);filter:blur(58px) saturate(.88);opacity:.52;animation:ks-cloud-drift-a var(--dance-moves-1584t, 51.206896552s) ease-in-out infinite alternate}.ks-clay-stars-v2 .ks-cloud-field:after{background:radial-gradient(ellipse at 82% 62%,rgba(138,60,37,.18) 0 10%,transparent 42%),radial-gradient(ellipse at 30% 78%,rgba(51,64,108,.24) 0 14%,transparent 46%),radial-gradient(ellipse at 58% 36%,rgba(196,153,134,.09) 0 7%,transparent 34%);filter:blur(72px) saturate(.82);opacity:.42;animation:ks-cloud-drift-b var(--dance-moves-2208t, 71.379310345s) ease-in-out infinite alternate-reverse}.ks-clay-stars-v2 .epk-atmosphere:after{transform-origin:50% 45%;animation:ks-particle-dance var(--dance-moves-128t, 4.137931034s) linear infinite;will-change:transform,opacity}.ks-clay-stars-v2 .epk-heading,.ks-clay-stars-v2 .ks-clay-stars-player-copy,.ks-clay-stars-v2 .epk-cosmology-head,.ks-clay-stars-v2 .epk-artwork>div,.ks-clay-stars-v2 .ks-epk-lyrics>div:first-child{position:relative}.ks-clay-stars-v2 .epk-heading:before,.ks-clay-stars-v2 .ks-clay-stars-player-copy:before,.ks-clay-stars-v2 .epk-cosmology-head:before,.ks-clay-stars-v2 .epk-artwork>div:before,.ks-clay-stars-v2 .ks-epk-lyrics>div:first-child:before{content:"";position:absolute;z-index:2;top:-34px;left:0;width:100%;pointer-events:none;color:#d4af37;background:linear-gradient(180deg,#ffe28a,#d4af37 28%,#8c650f 63%,#e8c348);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;font:400 clamp(20px,2vw,29px)/1 "Segoe UI Historic","Noto Sans Cuneiform",serif;letter-spacing:.2em;text-align:center;text-shadow:0 1px 0 #5A3B06,0 0 2px rgba(255,226,138,.7),0 0 9px rgba(212,175,55,.48);opacity:.92;transform-origin:center;animation:ks-gold-sparkle var(--dance-moves-192t, 6.206896552s) ease-in-out infinite alternate}.ks-clay-stars-v2 .epk-heading:before{content:"\1214e \1202d \121a0"}.ks-clay-stars-v2 .ks-clay-stars-player-copy:before{content:"\1227f \12157 \122d3"}.ks-clay-stars-v2 .epk-cosmology-head:before{content:"\12146 \12146 \12146"}.ks-clay-stars-v2 .epk-artwork>div:before{content:"\12029 \12146"}.ks-clay-stars-v2 .ks-epk-lyrics>div:first-child:before{content:"\122d3 \12157 \1207e"}.ks-clay-stars-v2 .epk-heading h1,.ks-clay-stars-v2 .ks-clay-stars-player h2,.ks-clay-stars-v2 .epk-cosmology h2,.ks-clay-stars-v2 .epk-artwork h2,.ks-clay-stars-v2 .ks-epk-lyrics h2{text-shadow:0 0 18px rgba(226,189,103,.1),0 4px 32px rgba(0,0,0,.3)}.ks-clay-stars-v2 .epk-button,.ks-clay-stars-v2 .epk-download,.ks-clay-stars-v2 .ks-clay-stars-chapters button{position:relative}.ks-clay-stars-v2 .epk-button:before,.ks-clay-stars-v2 .epk-download:before,.ks-clay-stars-v2 .ks-clay-stars-chapters button:before{content:"";position:absolute;z-index:2;inset:-6.3px;pointer-events:none;background:radial-gradient(circle,#D4AF37 0 1.2px,rgba(140,101,20,.62) 1.8px,transparent 3.4px),radial-gradient(circle,#C99716 0 1.2px,rgba(212,175,55,.44) 1.8px,transparent 3.4px),radial-gradient(circle,#FFD766 0 1px,rgba(212,175,55,.34) 1.7px,transparent 3px);background-repeat:no-repeat;background-size:7px 7px,7px 7px,6px 6px;background-position:0% 0%,100% 33%,33% 100%;filter:drop-shadow(0 0 4px rgba(212,175,55,.48));opacity:calc(.42 * var(--ks-master-intensity));animation:ks-gold-sparkle var(--dance-moves-192t, 6.206896552s) ease-in-out var(--dance-moves-neg-64t, -2.068965517s) infinite alternate;transform-origin:center}.ks-clay-stars-v2 .epk-button:after,.ks-clay-stars-v2 .epk-download:after,.ks-clay-stars-v2 .ks-clay-stars-chapters button:after{content:"";position:absolute;z-index:2;inset:-9.9px;pointer-events:none;background:radial-gradient(circle at 3% 52%,#D4AF37 0 1.1px,rgba(140,101,15,.7) 1.7px,transparent 3.2px),radial-gradient(circle at 18% 2%,#FFD766 0 1px,rgba(212,175,55,.56) 1.6px,transparent 3px),radial-gradient(circle at 48% 98%,#C99716 0 1.2px,rgba(140,101,15,.64) 1.8px,transparent 3.3px),radial-gradient(circle at 77% 1%,#E8C348 0 1px,rgba(212,175,55,.52) 1.6px,transparent 3px),radial-gradient(circle at 98% 46%,#D4AF37 0 1.2px,rgba(140,101,15,.68) 1.8px,transparent 3.3px),radial-gradient(circle at 82% 98%,#FFD766 0 1px,rgba(212,175,55,.5) 1.6px,transparent 3px);opacity:0;transform:rotate(0) scale(.96);transform-origin:center;filter:drop-shadow(0 0 4px rgba(212,175,55,.44));transition:opacity var(--ks-particle-release-duration) cubic-bezier(.22,.61,.36,1),transform var(--ks-particle-release-duration) cubic-bezier(.16,1,.3,1)}.ks-clay-stars-v2 .epk-signal-line{animation-duration:var(--dance-moves-432t, 13.965517241s)!important}.ks-clay-stars-v2 .epk-button:hover:before,.ks-clay-stars-v2 .epk-button:focus-visible:before,.ks-clay-stars-v2 .epk-download:hover:before,.ks-clay-stars-v2 .epk-download:focus-visible:before,.ks-clay-stars-v2 .ks-clay-stars-chapters button:hover:before,.ks-clay-stars-v2 .ks-clay-stars-chapters button:focus-visible:before{animation:ks-gold-button-wake var(--dance-moves-32t, 1.034482758s) cubic-bezier(.22,.68,.28,1) 1 both,ks-gold-button-dance var(--dance-moves-32t, 1.034482758s) ease-in-out var(--dance-moves-32t, 1.034482758s) infinite alternate}.ks-clay-stars-v2 .epk-button:hover:after,.ks-clay-stars-v2 .epk-button:focus-visible:after,.ks-clay-stars-v2 .epk-download:hover:after,.ks-clay-stars-v2 .epk-download:focus-visible:after,.ks-clay-stars-v2 .ks-clay-stars-chapters button:hover:after,.ks-clay-stars-v2 .ks-clay-stars-chapters button:focus-visible:after{animation:ks-gold-orbit-wake var(--dance-moves-32t, 1.034482758s) cubic-bezier(.333333,0,.666667,0) 1 both,ks-gold-orbit-fade-wake var(--dance-moves-32t, 1.034482758s) ease-out 1 both,ks-gold-orbit-dance var(--dance-moves-32t, 1.034482758s) linear var(--dance-moves-32t, 1.034482758s) infinite}.ks-clay-stars-v2 .epk-button.ks-particle-release:after,.ks-clay-stars-v2 .epk-download.ks-particle-release:after,.ks-clay-stars-v2 .ks-clay-stars-chapters button.ks-particle-release:after{animation:ks-gold-orbit-release var(--ks-particle-release-duration) linear 1 both}.ks-clay-stars-v2 .ks-clay-stars-chapters button[aria-current=true]:before{opacity:.72}.ks-clay-stars-v2 .epk-button,.ks-clay-stars-v2 .epk-download,.ks-clay-stars-v2 .ks-clay-stars-chapters button{transition:background-color var(--dance-moves-32t, 1.034482758s) cubic-bezier(.22,.61,.36,1),color var(--dance-moves-32t, 1.034482758s) cubic-bezier(.22,.61,.36,1),border-color var(--dance-moves-32t, 1.034482758s) ease,border-radius var(--dance-moves-32t, 1.034482758s) cubic-bezier(.16,1,.3,1),box-shadow var(--dance-moves-32t, 1.034482758s) ease,text-shadow var(--dance-moves-32t, 1.034482758s) ease}.ks-clay-stars-v2 .epk-button:hover,.ks-clay-stars-v2 .epk-button:focus-visible,.ks-clay-stars-v2 .epk-download:hover,.ks-clay-stars-v2 .epk-download:focus-visible,.ks-clay-stars-v2 .ks-clay-stars-chapters button:hover,.ks-clay-stars-v2 .ks-clay-stars-chapters button:focus-visible{background-color:#75432f;background-image:radial-gradient(circle at 17% 28%,rgba(48,22,16,.28) 0 1px,transparent 1.8px),radial-gradient(circle at 73% 61%,rgba(246,193,99,.13) 0 1px,transparent 2px),linear-gradient(112deg,#8b4f30f5,#683727fa 54%,#7e462cf5);background-size:19px 17px,27px 23px,100% 100%;border-color:#b98522;border-radius:6px 3px 7px 2px;color:#f2c14e;box-shadow:inset 0 2px #f6c16338,inset 0 -3px #3f1c1461,inset 2px 0 #5e2f1f4d,0 0 0 1px #8c650fb8,0 9px 22px #100b1961,0 0 18px #d4af372e;text-shadow:0 1px 0 #FFE28A,0 -1px 0 #5A3B06,0 0 7px rgba(212,175,55,.56)}.ks-clay-stars-v2 .epk-cover-wrap>.epk-cover{position:relative;z-index:1;transform:translateZ(0)}.ks-clay-stars-v2 .ks-warm-bloom,.ks-clay-stars-v2 .ks-lens-flare,.ks-clay-stars-v2 .ks-specular-sweep{position:absolute;display:block;pointer-events:none;user-select:none}.ks-clay-stars-v2 .ks-warm-bloom{z-index:0;inset:-15%;background:radial-gradient(ellipse at 70% 28%,rgba(196,153,134,.36) 0,rgba(163,101,76,.26) 19%,rgba(138,60,37,.12) 42%,transparent 70%),radial-gradient(ellipse at 26% 78%,rgba(138,60,37,.2),transparent 64%);filter:blur(28px) saturate(1.08);opacity:calc(.68 * var(--ks-master-intensity));transform:translate3d(var(--ks-bloom-x),var(--ks-bloom-y),-18px);transition:transform var(--dance-moves-6t, .193965517s) ease-out,opacity var(--dance-moves-6t, .193965517s) ease-out}.ks-clay-stars-v2 .ks-lens-flare{z-index:3;inset:-24%;background:radial-gradient(circle at 72% 24%,rgba(245,241,232,.58) 0 1px,rgba(196,153,134,.34) 2px 5px,rgba(163,101,76,.13) 10px,transparent 34px),radial-gradient(circle at 34% 62%,rgba(196,153,134,.13) 0 7px,transparent 9px 17px,rgba(138,60,37,.1) 19px,transparent 31px),linear-gradient(102deg,transparent 29%,rgba(196,153,134,.05) 43%,rgba(245,241,232,.13) 50%,rgba(163,101,76,.05) 57%,transparent 71%);mix-blend-mode:screen;opacity:calc(.54 * var(--ks-master-intensity));-webkit-mask-image:radial-gradient(ellipse at center,#000 0 43%,rgba(0,0,0,.78) 58%,rgba(0,0,0,.28) 72%,transparent 88%);mask-image:radial-gradient(ellipse at center,#000 0 43%,rgba(0,0,0,.78) 58%,rgba(0,0,0,.28) 72%,transparent 88%);transform:translate3d(var(--ks-flare-x),var(--ks-flare-y),28px);transition:transform var(--dance-moves-6t, .193965517s) ease-out,opacity var(--dance-moves-6t, .193965517s) ease-out}.ks-clay-stars-v2 .ks-specular-sweep{z-index:2;inset:-34%;background:linear-gradient(116deg,transparent 34%,rgba(163,101,76,.03) 42%,rgba(196,153,134,.18) 49%,rgba(245,241,232,.12) 51%,rgba(138,60,37,.04) 58%,transparent 66%);mix-blend-mode:screen;opacity:calc(.62 * var(--ks-master-intensity));-webkit-mask-image:radial-gradient(ellipse at center,#000 0 40%,rgba(0,0,0,.74) 57%,rgba(0,0,0,.22) 73%,transparent 89%);mask-image:radial-gradient(ellipse at center,#000 0 40%,rgba(0,0,0,.74) 57%,rgba(0,0,0,.22) 73%,transparent 89%);transform:translate3d(var(--ks-spec-x),var(--ks-spec-y),18px);transition:transform var(--dance-moves-6t, .193965517s) ease-out,opacity var(--dance-moves-6t, .193965517s) ease-out}.ks-clay-stars-v2 .epk-facts,.ks-clay-stars-v2 .ks-clay-stars-player,.ks-clay-stars-v2 .ks-clay-stars-player-console,.ks-clay-stars-v2 .epk-triptych,.ks-clay-stars-v2 .epk-signal,.ks-clay-stars-v2 .epk-artwork,.ks-clay-stars-v2 .ks-epk-lyrics-track{box-shadow:0 0 34px #8a3c251a,0 0 92px #33406c17,inset 0 1px #f5f1e80b,0 24px 70px #0000002e}.ks-clay-stars-v2 .ks-clay-stars-chapters button[aria-current=true]{box-shadow:0 0 0 1px #c499868f,0 0 26px #a3654c33,inset 0 1px #f5f1e89e}@keyframes ks-cloud-drift-a{0%{transform:translate3d(-3%,-1.5%,0) scale(1.04)}to{transform:translate3d(4%,2.5%,0) scale(1.09)}}@keyframes ks-cloud-drift-b{0%{transform:translate3d(3.5%,-2%,0) scale(1.08)}to{transform:translate3d(-4%,3%,0) scale(1.03)}}@keyframes ks-particle-dance{0%,to{transform:translateZ(0) rotate(0) scale(1);opacity:calc(.38 * var(--ks-master-intensity))}9%{transform:translate3d(2px,-1px,0) rotate(.02deg) scale(1.001);opacity:calc(.44 * var(--ks-master-intensity))}13%{transform:translate3d(13px,-8px,0) rotate(.18deg) scale(1.007);opacity:calc(.6 * var(--ks-master-intensity))}19%{transform:translate3d(5px,-4px,0) rotate(.04deg) scale(1.003);opacity:calc(.48 * var(--ks-master-intensity))}34%{transform:translate3d(-3px,2px,0) rotate(-.04deg) scale(1);opacity:calc(.43 * var(--ks-master-intensity))}39%{transform:translate3d(-14px,9px,0) rotate(-.2deg) scale(1.008);opacity:calc(.62 * var(--ks-master-intensity))}46%{transform:translate3d(-5px,5px,0) rotate(-.05deg) scale(1.002);opacity:calc(.49 * var(--ks-master-intensity))}60%{transform:translate3d(1px,0,0) rotate(0) scale(.999);opacity:calc(.42 * var(--ks-master-intensity))}66%{transform:translate3d(12px,10px,0) rotate(.17deg) scale(1.007);opacity:calc(.6 * var(--ks-master-intensity))}73%{transform:translate3d(4px,5px,0) rotate(.04deg) scale(1.002);opacity:calc(.48 * var(--ks-master-intensity))}84%{transform:translate3d(-2px,-2px,0) rotate(-.02deg) scale(1);opacity:calc(.43 * var(--ks-master-intensity))}89%{transform:translate3d(-10px,-9px,0) rotate(-.15deg) scale(1.006);opacity:calc(.57 * var(--ks-master-intensity))}95%{transform:translate3d(-3px,-3px,0) rotate(-.03deg) scale(1.001);opacity:calc(.45 * var(--ks-master-intensity))}}@keyframes ks-gold-sparkle{0%{opacity:.74;transform:translateZ(0) scale(.995)}to{opacity:.96;transform:translate3d(1px,-1px,0) scale(1.005)}}@keyframes ks-gold-button-wake{0%{opacity:.74;transform:translateZ(0) rotate(0) scale(.995)}45%{opacity:.79;transform:translate3d(.45px,-.36px,0) scale(1.002)}78%{opacity:.84;transform:translate3d(1.08px,-.81px,0) scale(1.006)}to{opacity:.88;transform:translate3d(0,-1.35px,0) scale(1.012)}}@keyframes ks-gold-button-dance{0%{opacity:.82;transform:translate3d(0,-1.35px,0) rotate(-.35deg) scale(1.008)}to{opacity:.96;transform:translate3d(1.4px,-2.1px,0) rotate(.35deg) scale(1.018)}}@keyframes ks-gold-orbit-wake{0%{transform:rotate(0) scale(1.04)}to{transform:translate3d(0,-1.8px,0) rotate(120deg) scale(1.04)}}@keyframes ks-gold-orbit-fade-wake{0%{opacity:0}45%,to{opacity:.86}}@keyframes ks-gold-orbit-dance{0%{opacity:.86;transform:translate3d(0,-1.8px,0) rotate(120deg) scale(1.04)}25%{opacity:.96;transform:translate3d(2.7px,-2.7px,0) rotate(210deg) scale(1.08)}50%{opacity:.84;transform:translate3d(-1.8px,1.8px,0) rotate(300deg) scale(1.03)}75%{opacity:.97;transform:translate3d(2.7px,2.25px,0) rotate(390deg) scale(1.08)}to{opacity:.86;transform:translate3d(0,-1.8px,0) rotate(480deg) scale(1.04)}}@keyframes ks-gold-orbit-release{0%{opacity:var(--ks-orbit-release-opacity, .86);transform:var(--ks-orbit-release-transform, rotate(120deg) scale(1.02))}18%{opacity:calc(var(--ks-orbit-release-opacity, .86) * .7);transform:var(--ks-orbit-release-transform, rotate(120deg) scale(1.02))}32%{opacity:calc(var(--ks-orbit-release-opacity, .86) * .84);transform:var(--ks-orbit-release-transform, rotate(120deg) scale(1.02))}48%{opacity:calc(var(--ks-orbit-release-opacity, .86) * .44);transform:var(--ks-orbit-release-transform, rotate(120deg) scale(1.02))}62%{opacity:calc(var(--ks-orbit-release-opacity, .86) * .56);transform:var(--ks-orbit-release-transform, rotate(120deg) scale(1.02))}78%{opacity:calc(var(--ks-orbit-release-opacity, .86) * .18);transform:var(--ks-orbit-release-transform, rotate(120deg) scale(1.02))}88%{opacity:calc(var(--ks-orbit-release-opacity, .86) * .26);transform:var(--ks-orbit-release-transform, rotate(120deg) scale(1.02))}to{opacity:0;transform:var(--ks-orbit-release-transform, rotate(120deg) scale(1.02))}}.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .ks-cloud-field:before,.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .ks-cloud-field:after{animation:none!important;transform:translateZ(0) scale(1.05)!important;will-change:auto}.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .epk-atmosphere:after{animation:none!important;transform:none!important;opacity:calc(.42 * var(--ks-master-intensity));will-change:auto}.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .epk-heading:before,.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .ks-clay-stars-player-copy:before,.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .epk-cosmology-head:before,.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .epk-artwork>div:before,.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .ks-epk-lyrics>div:first-child:before,.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .epk-button:before,.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .epk-download:before,.ks-clay-stars-v2:is([data-dance-moves-performance=constrained],[data-dance-moves-performance=minimal]) .ks-clay-stars-chapters button:before{animation:none!important;transform:translateZ(0) scale(1)!important}.ks-clay-stars-v2[data-dance-moves-performance=minimal] .ks-cloud-field:before,.ks-clay-stars-v2[data-dance-moves-performance=minimal] .ks-cloud-field:after,.ks-clay-stars-v2[data-dance-moves-performance=minimal] .epk-atmosphere:after{filter:none!important;mix-blend-mode:normal!important}@media(prefers-reduced-motion:reduce){.ks-clay-stars-v2 .epk-cover-wrap,.ks-clay-stars-v2 .ks-warm-bloom,.ks-clay-stars-v2 .ks-lens-flare,.ks-clay-stars-v2 .ks-specular-sweep,.ks-clay-stars-v2 .epk-button,.ks-clay-stars-v2 .epk-download,.ks-clay-stars-v2 .ks-clay-stars-chapters button{transition:none!important}.ks-clay-stars-v2 .ks-cloud-field:before,.ks-clay-stars-v2 .ks-cloud-field:after{animation:none!important;transform:none!important;will-change:auto}.ks-clay-stars-v2 .epk-atmosphere:after{animation:none!important;transform:none!important;filter:none!important;opacity:.42;will-change:auto}.ks-clay-stars-v2 .epk-heading:before,.ks-clay-stars-v2 .ks-clay-stars-player-copy:before,.ks-clay-stars-v2 .epk-cosmology-head:before,.ks-clay-stars-v2 .epk-artwork>div:before,.ks-clay-stars-v2 .ks-epk-lyrics>div:first-child:before,.ks-clay-stars-v2 .epk-button:before,.ks-clay-stars-v2 .epk-download:before,.ks-clay-stars-v2 .ks-clay-stars-chapters button:before,.ks-clay-stars-v2 .epk-button:after,.ks-clay-stars-v2 .epk-download:after,.ks-clay-stars-v2 .ks-clay-stars-chapters button:after{animation:none!important;transition:none!important;transform:none!important}.ks-clay-stars-v2 .epk-button:before,.ks-clay-stars-v2 .epk-download:before,.ks-clay-stars-v2 .ks-clay-stars-chapters button:before{opacity:.62}.ks-clay-stars-v2 .epk-button:hover:after,.ks-clay-stars-v2 .epk-button:focus-visible:after,.ks-clay-stars-v2 .epk-download:hover:after,.ks-clay-stars-v2 .epk-download:focus-visible:after,.ks-clay-stars-v2 .ks-clay-stars-chapters button:hover:after,.ks-clay-stars-v2 .ks-clay-stars-chapters button:focus-visible:after{opacity:.68}.ks-clay-stars-v2 .epk-button.ks-particle-release:after,.ks-clay-stars-v2 .epk-download.ks-particle-release:after,.ks-clay-stars-v2 .ks-clay-stars-chapters button.ks-particle-release:after{animation:none!important;opacity:0!important}.ks-clay-stars-v2 .ks-lens-flare{opacity:.34}.ks-clay-stars-v2 .ks-specular-sweep{opacity:.38}}@media(forced-colors:active){.ks-clay-stars-v2 .ks-warm-bloom,.ks-clay-stars-v2 .ks-lens-flare,.ks-clay-stars-v2 .ks-specular-sweep,.ks-clay-stars-v2 .ks-cloud-field{display:none}.ks-clay-stars-v2 .epk-facts,.ks-clay-stars-v2 .ks-clay-stars-player,.ks-clay-stars-v2 .ks-clay-stars-player-console,.ks-clay-stars-v2 .epk-triptych,.ks-clay-stars-v2 .epk-signal,.ks-clay-stars-v2 .epk-artwork,.ks-clay-stars-v2 .ks-epk-lyrics-track{box-shadow:none}.ks-clay-stars-v2 .epk-heading:before,.ks-clay-stars-v2 .ks-clay-stars-player-copy:before,.ks-clay-stars-v2 .epk-cosmology-head:before,.ks-clay-stars-v2 .epk-artwork>div:before,.ks-clay-stars-v2 .ks-epk-lyrics>div:first-child:before,.ks-clay-stars-v2 .epk-button:before,.ks-clay-stars-v2 .epk-download:before,.ks-clay-stars-v2 .ks-clay-stars-chapters button:before,.ks-clay-stars-v2 .epk-button:after,.ks-clay-stars-v2 .epk-download:after,.ks-clay-stars-v2 .ks-clay-stars-chapters button:after{display:none}.ks-clay-stars-v2 .ks-clay-stars-chapters button[aria-current=true]{box-shadow:none}}@media(max-width:760px),(hover:none),(pointer:coarse){.ks-clay-stars-v2 .ks-cloud-field:before{opacity:.4}.ks-clay-stars-v2 .ks-cloud-field:after{opacity:.32}.ks-clay-stars-v2 .ks-warm-bloom{opacity:.58}.ks-clay-stars-v2 .ks-lens-flare{opacity:.38}.ks-clay-stars-v2 .ks-specular-sweep{opacity:.42}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ks-clay-stars-v2[data-dance-moves-rudiment-clay=active][data-dance-moves-performance=full] .epk-atmosphere:after{animation:ks-clay-rudiment-treatment var(--dance-moves-128t) linear infinite both!important;animation-play-state:paused!important;translate:var(--ks-clay-rudiment-x, 0px) var(--ks-clay-rudiment-y, 0px);transition:none!important;will-change:translate,transform,opacity}.ks-clay-stars-v2[data-dance-moves-rudiment-clay=suspended] .epk-atmosphere:after{animation:none!important;translate:none!important;will-change:auto}@keyframes ks-clay-rudiment-treatment{0%,to{transform:rotate(0) scale(1);opacity:calc(.38 * var(--ks-master-intensity))}9%{transform:rotate(.02deg) scale(1.001);opacity:calc(.44 * var(--ks-master-intensity))}13%{transform:rotate(.18deg) scale(1.007);opacity:calc(.6 * var(--ks-master-intensity))}19%{transform:rotate(.04deg) scale(1.003);opacity:calc(.48 * var(--ks-master-intensity))}34%{transform:rotate(-.04deg) scale(1);opacity:calc(.43 * var(--ks-master-intensity))}39%{transform:rotate(-.2deg) scale(1.008);opacity:calc(.62 * var(--ks-master-intensity))}46%{transform:rotate(-.05deg) scale(1.002);opacity:calc(.49 * var(--ks-master-intensity))}60%{transform:rotate(0) scale(.999);opacity:calc(.42 * var(--ks-master-intensity))}66%{transform:rotate(.17deg) scale(1.007);opacity:calc(.6 * var(--ks-master-intensity))}73%{transform:rotate(.04deg) scale(1.002);opacity:calc(.48 * var(--ks-master-intensity))}84%{transform:rotate(-.02deg) scale(1);opacity:calc(.43 * var(--ks-master-intensity))}89%{transform:rotate(-.15deg) scale(1.006);opacity:calc(.57 * var(--ks-master-intensity))}95%{transform:rotate(-.03deg) scale(1.001);opacity:calc(.45 * var(--ks-master-intensity))}}@media(prefers-reduced-motion:reduce),(forced-colors:active){.ks-clay-stars-v2[data-dance-moves-rudiment-clay] .epk-atmosphere:after{animation:none!important;translate:none!important;transform:none!important;will-change:auto!important}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[data-dance-moves-start-interval]:not([data-dance-moves-started=true]),[data-dance-moves-start-interval]:not([data-dance-moves-started=true]):before,[data-dance-moves-start-interval]:not([data-dance-moves-started=true]):after{animation-play-state:paused!important}html[data-dance-moves-shared-controls=true] .ks-epk .epk-button,html[data-dance-moves-shared-controls=true] .ks-epk .epk-download{transition-property:background-color,color,transform,border-color!important;transition-duration:var(--dance-moves-shared-control-duration)!important;transition-timing-function:ease!important}.ks-epk .ks-epk-lyrics-track summary span[aria-hidden]{transition-property:transform!important;transition-duration:var(--dance-moves-lyric-disclosure-duration)!important;transition-timing-function:ease!important}.dance-moves-lyric-popover{--dance-moves-lyric-bg: rgba(20, 20, 24, .94);--dance-moves-lyric-border: rgba(255, 255, 255, .28);--dance-moves-lyric-color: #fff;position:fixed;z-index:9998;inset-inline:max(1rem,env(safe-area-inset-left)) max(1rem,env(safe-area-inset-right));bottom:max(1rem,env(safe-area-inset-bottom));display:flex;justify-content:center;pointer-events:none;opacity:0;transform:translateY(.75rem) scale(.98);transition:opacity var(--dance-moves-6t) ease,transform var(--dance-moves-6t) ease}.dance-moves-lyric-popover[data-dance-moves-lyric-state=active]{opacity:1;transform:translateY(0) scale(1)}.dance-moves-lyric-popover__text{display:block;max-width:min(44rem,100%);padding:.72rem 1rem;border:1px solid var(--dance-moves-lyric-border);border-radius:.75rem;background:var(--dance-moves-lyric-bg);color:var(--dance-moves-lyric-color);box-shadow:0 .6rem 1.8rem #00000052;font:700 clamp(1rem,2.4vw,1.35rem)/1.3 system-ui,sans-serif;text-align:center;text-wrap:balance}.dance-moves-lyric-popover[data-dance-moves-lyric-pulse=true] .dance-moves-lyric-popover__text{animation:dance-moves-lyric-arrive var(--dance-moves-6t) ease both}@keyframes dance-moves-lyric-arrive{0%{transform:translateY(.4rem) scale(.98)}to{transform:translateY(0) scale(1)}}@media(forced-colors:active){.dance-moves-lyric-popover__text{border:2px solid CanvasText;background:Canvas;color:CanvasText;box-shadow:none}}@media(prefers-reduced-motion:reduce){[data-dance-moves-start-interval],[data-dance-moves-start-interval]:before,[data-dance-moves-start-interval]:after{animation:none!important;transition-duration:.01ms!important}html[data-dance-moves-shared-controls=true] .ks-epk .epk-button,html[data-dance-moves-shared-controls=true] .ks-epk .epk-download,.ks-epk .ks-epk-lyrics-track summary span[aria-hidden]{transition:none!important}.dance-moves-lyric-popover,.dance-moves-lyric-popover__text{animation:none!important;transition:none!important;transform:none!important}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ks-epk-orientation-control{position:fixed;z-index:999998;left:max(.75rem,env(safe-area-inset-left));bottom:max(.75rem,env(safe-area-inset-bottom));min-height:2.75rem;padding:.65rem .9rem;border:1px solid rgba(255,255,255,.72);border-radius:999px;color:#fff;background:#0c0c10e0;box-shadow:0 .5rem 2rem #0000006b;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);font:700 .72rem/1 system-ui,sans-serif;letter-spacing:.05em;cursor:pointer}.ks-epk-orientation-control:focus-visible{outline:3px solid #fff;outline-offset:3px}.ks-epk-orientation-control:disabled{cursor:default;opacity:.72}.ks-epk[data-release=presents-and-chocolate][data-ks-orientation=active] .epk-cover-wrap{animation:none;transform:translate3d(var(--pc-sensor-x, 0px),var(--pc-sensor-y, 0px),0) rotate(var(--pc-sensor-rotate, 0deg))}#light-will-win-top[data-ks-orientation=active] .lww-hero{background-position:calc(50% + var(--lww-cover-x, 0px)) calc(44% + var(--lww-cover-y, 0px))}.ks-epk[data-release=walk-with-me][data-ks-orientation=active] .wwm-cover-stage{transform:perspective(1100px) rotateX(var(--wwm-tilt-x, 0deg)) rotateY(var(--wwm-tilt-y, 0deg)) translate(var(--wwm-shift-x, 0px),var(--wwm-shift-y, 0px))!important}#light-will-win-top[data-ks-orientation=active] .lww-hero{transition:background-position var(--dance-moves-2t, 62.5ms) cubic-bezier(.15,.8,.2,1)!important;will-change:background-position}#light-will-win-top[data-ks-orientation=active] :is(.lww-player-card,.lww-story-quote,.lww-glass,.lww-contact-card,.lww-fact),.dfad-motion-stage[data-ks-orientation=active] :is([data-tilt],[data-parallax] img),[data-ks-orientation-adapter=presents-and-chocolate][data-ks-orientation=active] .epk-cover-wrap,[data-ks-orientation-adapter=fully-nocturnal][data-ks-orientation=active] :is(.fnx-horizon-glow,.fnx-road,.epk-cover-wrap,.epk-cover),[data-ks-orientation-adapter=amnesty-honestly][data-ks-orientation=active] :is(.epk-cover-wrap,.epk-heading),[data-ks-orientation-adapter=walk-with-me][data-ks-orientation=active] .wwm-cover-stage,[data-ks-orientation-adapter=dmitri-my-talisman][data-ks-orientation=active] :is(.chamber,.cover-frame),[data-ks-orientation-adapter=clay-stars][data-ks-orientation=active] :is(.epk-cover-wrap,.ks-warm-bloom,.ks-lens-flare,.ks-specular-sweep),[data-ks-orientation-adapter=california-screamin][data-ks-orientation=active] :is(.cs-cover,.cs-cables,.cs-cover-glow){transition:transform var(--dance-moves-2t, 62.5ms) cubic-bezier(.15,.8,.2,1)!important;will-change:transform}@media(max-width:900px){#light-will-win-top[data-ks-orientation=active] .lww-hero{background-position:calc(58% + var(--lww-cover-x, 0px)) calc(46% + var(--lww-cover-y, 0px))}}@media(prefers-reduced-motion:reduce){.ks-epk-orientation-control{display:none!important}.ks-epk[data-release=presents-and-chocolate] .epk-cover-wrap,.ks-epk[data-release=walk-with-me] .wwm-cover-stage{transform:none!important}[data-ks-orientation] *,[data-ks-orientation] *:before,[data-ks-orientation] *:after{transition:none!important;will-change:auto!important}}@media(forced-colors:active){.ks-epk-orientation-control{color:ButtonText;background:ButtonFace;border-color:ButtonText;forced-color-adjust:auto}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ks-epk[data-release=paper-dreams-from-the-sky] .epk-hero{position:relative;isolation:isolate;overflow:hidden}.paper-dreams-flight{position:absolute;z-index:2;inset:0;overflow:hidden;pointer-events:none;contain:strict;clip-path:inset(0)}.paper-dreams-flight~*{position:relative}.paper-dreams-flight~.epk-cover-wrap{z-index:1}.paper-dreams-flight~.epk-heading{z-index:3}.paper-dreams-flight__plane{position:absolute;left:0;top:0;width:var(--plane-size,110px);aspect-ratio:1.5;background-image:var(--paper-dreams-atlas);background-size:600% 400%;background-position:var(--sprite-x) var(--sprite-y);background-repeat:no-repeat;opacity:var(--plane-opacity,.82);transform-origin:50% 50%;will-change:transform;contain:layout paint}.paper-dreams-flight__plane:before,.paper-dreams-flight__plane:after{content:"";position:absolute;z-index:-1;inset:0;background-image:var(--paper-dreams-atlas);background-size:600% 400%;background-position:var(--sprite-x) var(--sprite-y);background-repeat:no-repeat;pointer-events:none;transform-origin:50% 50%;opacity:.26;transform:translate3d(-20px,0,0) scaleX(1.18)}.paper-dreams-flight__plane:after{opacity:.13;transform:translate3d(-42px,0,0) scaleX(1.34)}.paper-dreams-flight__plane[data-flight-state=drop]:before,.paper-dreams-flight__plane[data-flight-state=recovery]:before,.paper-dreams-flight__plane[data-flight-state=swoop]:before{opacity:.42;transform:translate3d(-32px,0,0) scaleX(1.3)}.paper-dreams-flight__plane[data-flight-state=drop]:after,.paper-dreams-flight__plane[data-flight-state=recovery]:after,.paper-dreams-flight__plane[data-flight-state=swoop]:after{opacity:.22;transform:translate3d(-66px,0,0) scaleX(1.58)}.paper-dreams-flight[data-quality=compact] .paper-dreams-flight__plane:nth-child(n+6){display:none}.paper-dreams-flight[data-quality=static] .paper-dreams-flight__plane{display:none;will-change:auto}.paper-dreams-flight[data-quality=static] .paper-dreams-flight__plane:nth-child(-n+3){display:block;transform:var(--static-transform);opacity:.55}@media(max-width:760px){.paper-dreams-flight__plane{width:var(--plane-size-compact,76px)}.paper-dreams-flight{inset:72px 0 0}}@media(prefers-reduced-motion:reduce){.paper-dreams-flight__plane{display:none!important;will-change:auto!important}.paper-dreams-flight__plane:before,.paper-dreams-flight__plane:after{display:none!important}.ks-epk .epk-story-plane{animation:none!important}}@media(forced-colors:active){.paper-dreams-flight{display:none}}
|