@pixerate/editor 0.248.0 → 0.250.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/animation-editor/index.cjs +118 -114
- package/dist/animation-editor/index.js +11 -7
- package/dist/{brushstrokeRender-QLCXROJK.js → brushstrokeRender-2FHFLSEG.js} +8 -4
- package/dist/{brushstrokeRender-DTDPFBLC.cjs → brushstrokeRender-QGRXOKDA.cjs} +15 -11
- package/dist/canvas/index.cjs +71 -15
- package/dist/canvas/index.d.cts +1 -0
- package/dist/canvas/index.d.ts +1 -0
- package/dist/canvas/index.js +58 -2
- package/dist/canvas/stickers.d.cts +35 -0
- package/dist/canvas/stickers.d.ts +35 -0
- package/dist/{chunk-RXZL4NG5.js → chunk-226QDRO3.js} +1 -1
- package/dist/{chunk-SC2RZ5EF.js → chunk-2VJAVXLI.js} +2 -2
- package/dist/{chunk-OLNIPTB3.cjs → chunk-2VX55NFM.cjs} +1 -320
- package/dist/chunk-3K6HWEXZ.cjs +92 -0
- package/dist/{chunk-UOOK7HTX.js → chunk-3PPJRMIG.js} +1 -1
- package/dist/{chunk-ZFSLEOSQ.js → chunk-3TWOCSCY.js} +11 -9
- package/dist/chunk-4D6KP5BV.js +92 -0
- package/dist/chunk-4JNWA3VT.cjs +302 -0
- package/dist/{chunk-L3JFOTBQ.js → chunk-5E2Q7ZHI.js} +1 -1
- package/dist/{chunk-2ONK3ERD.cjs → chunk-75K3W4D6.cjs} +20 -20
- package/dist/{chunk-AU6MWQKZ.js → chunk-ABL7IWFZ.js} +1 -1
- package/dist/chunk-ATK6ABN3.cjs +303 -0
- package/dist/{chunk-7T7JWTVE.cjs → chunk-BOHDJJ2O.cjs} +8 -8
- package/dist/{chunk-2PBZBRP5.js → chunk-D5KGAO4Z.js} +10 -92
- package/dist/{chunk-HB4ICNNA.cjs → chunk-DPYAO5U6.cjs} +42 -42
- package/dist/{chunk-6G6ZDDDB.cjs → chunk-GT77U7QG.cjs} +303 -149
- package/dist/{chunk-PQ3H2AAN.cjs → chunk-I7NJPHWV.cjs} +122 -204
- package/dist/{chunk-42TWUPNJ.js → chunk-IRSTHLQQ.js} +1 -320
- package/dist/{chunk-GHCSC2WP.cjs → chunk-ISIO63Q5.cjs} +21 -15
- package/dist/{chunk-OFH6Q67U.js → chunk-JA57JIT5.js} +9 -3
- package/dist/{chunk-VMROIWLL.cjs → chunk-KBYB7OWB.cjs} +3 -3
- package/dist/{chunk-Q2HA52V4.js → chunk-KDLBJ6QR.js} +2 -2
- package/dist/{chunk-WVS5KQDH.cjs → chunk-M2VKFE5L.cjs} +246 -244
- package/dist/{chunk-5GLYUSNT.js → chunk-NOHJP5TK.js} +1 -1
- package/dist/{chunk-XNRBMYNB.js → chunk-NTRAVM2I.js} +1 -1
- package/dist/{chunk-VNBUDVD4.js → chunk-OTEPAQJX.js} +228 -74
- package/dist/chunk-OTTT5N3K.js +322 -0
- package/dist/{chunk-QOBCBGGI.cjs → chunk-QKXO6JPP.cjs} +14 -14
- package/dist/{chunk-NZ3O3A5C.js → chunk-SMSGP2HQ.js} +1 -1
- package/dist/chunk-SZTI6EER.js +13 -0
- package/dist/chunk-U4NUOKBT.js +303 -0
- package/dist/chunk-U67EN7GG.cjs +13 -0
- package/dist/chunk-W5M3J7PV.cjs +322 -0
- package/dist/{chunk-4P6H35HU.js → chunk-WA44NKPF.js} +2 -2
- package/dist/chunk-WKH5ZAUA.js +302 -0
- package/dist/{chunk-L6REDLNB.cjs → chunk-WPUXGDH4.cjs} +7 -7
- package/dist/{chunk-P3NIPIKS.js → chunk-WQCNC4DK.js} +1 -1
- package/dist/{chunk-IBDU6EGZ.cjs → chunk-X7WRL5ZZ.cjs} +35 -35
- package/dist/{chunk-XWTRATIM.cjs → chunk-YM6ZBTXG.cjs} +23 -23
- package/dist/{chunk-TPWB4Y6L.cjs → chunk-YW43M56C.cjs} +1 -1
- package/dist/{chunk-K5DS2JTA.cjs → chunk-Z3BRH4JK.cjs} +6 -6
- package/dist/{chunk-XNZFVYC2.cjs → chunk-ZBCT5MEA.cjs} +7 -7
- package/dist/effects/helpers.d.cts +6 -0
- package/dist/effects/helpers.d.ts +6 -0
- package/dist/effects/index.cjs +62 -60
- package/dist/effects/index.js +5 -3
- package/dist/effects/tools.d.cts +6 -0
- package/dist/effects/tools.d.ts +6 -0
- package/dist/image-editor/effects.d.cts +1 -1
- package/dist/image-editor/effects.d.ts +1 -1
- package/dist/image-editor/index.cjs +1097 -1069
- package/dist/image-editor/index.d.cts +1 -0
- package/dist/image-editor/index.d.ts +1 -0
- package/dist/image-editor/index.js +58 -30
- package/dist/image-editor/stickers.d.cts +9 -0
- package/dist/image-editor/stickers.d.ts +9 -0
- package/dist/paint/index.cjs +8 -5
- package/dist/paint/index.js +13 -10
- package/dist/paint-editor/controller.d.cts +37 -1
- package/dist/paint-editor/controller.d.ts +37 -1
- package/dist/paint-editor/index.cjs +753 -609
- package/dist/paint-editor/index.d.cts +3 -0
- package/dist/paint-editor/index.d.ts +3 -0
- package/dist/paint-editor/index.js +187 -43
- package/dist/paint-editor/sticker-art.d.cts +55 -0
- package/dist/paint-editor/sticker-art.d.ts +55 -0
- package/dist/paint-editor/stickers.d.cts +30 -17
- package/dist/paint-editor/stickers.d.ts +30 -17
- package/dist/paint-editor/stroke.d.cts +4 -0
- package/dist/paint-editor/stroke.d.ts +4 -0
- package/dist/paint-editor/ui.d.cts +10 -2
- package/dist/paint-editor/ui.d.ts +10 -2
- package/dist/raster/index.cjs +6 -4
- package/dist/raster/index.js +12 -10
- package/dist/stickers/browser.d.cts +48 -0
- package/dist/stickers/browser.d.ts +48 -0
- package/dist/stickers/combine.d.cts +10 -0
- package/dist/stickers/combine.d.ts +10 -0
- package/dist/stickers/conformance.d.cts +18 -0
- package/dist/stickers/conformance.d.ts +18 -0
- package/dist/stickers/editor.d.cts +14 -0
- package/dist/stickers/editor.d.ts +14 -0
- package/dist/stickers/errors.d.cts +6 -0
- package/dist/stickers/errors.d.ts +6 -0
- package/dist/stickers/fake.d.cts +16 -0
- package/dist/stickers/fake.d.ts +16 -0
- package/dist/stickers/helpers.d.cts +51 -0
- package/dist/stickers/helpers.d.ts +51 -0
- package/dist/stickers/index.cjs +337 -0
- package/dist/stickers/index.d.cts +16 -0
- package/dist/stickers/index.d.ts +16 -0
- package/dist/stickers/index.js +337 -0
- package/dist/stickers/stamps.d.cts +13 -0
- package/dist/stickers/stamps.d.ts +13 -0
- package/dist/stickers/tools.d.cts +81 -0
- package/dist/stickers/tools.d.ts +81 -0
- package/dist/stickers/types.d.cts +123 -0
- package/dist/stickers/types.d.ts +123 -0
- package/dist/vector/index.cjs +1018 -981
- package/dist/vector/index.d.cts +1 -0
- package/dist/vector/index.d.ts +1 -0
- package/dist/vector/index.js +44 -7
- package/dist/vector/stickers.d.cts +11 -0
- package/dist/vector/stickers.d.ts +11 -0
- package/dist/video-editor/index.cjs +344 -344
- package/dist/video-editor/index.js +4 -4
- package/package.json +11 -1
- package/skills/README.md +1 -0
- package/skills/pixerate-image-editor/SKILL.md +1 -1
- package/skills/pixerate-paint-editor/SKILL.md +8 -5
- package/skills/pixerate-stickers/SKILL.md +57 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import {
|
|
2
|
+
deflate,
|
|
3
|
+
inflate
|
|
4
|
+
} from "./chunk-QGHEDC7B.js";
|
|
5
|
+
|
|
6
|
+
// src/raster/png.ts
|
|
7
|
+
var SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
8
|
+
var crcTable = null;
|
|
9
|
+
function crc32(bytes, start, end) {
|
|
10
|
+
if (!crcTable) {
|
|
11
|
+
crcTable = new Uint32Array(256);
|
|
12
|
+
for (let n = 0; n < 256; n++) {
|
|
13
|
+
let c2 = n;
|
|
14
|
+
for (let k = 0; k < 8; k++) c2 = c2 & 1 ? 3988292384 ^ c2 >>> 1 : c2 >>> 1;
|
|
15
|
+
crcTable[n] = c2 >>> 0;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
let c = 4294967295;
|
|
19
|
+
for (let i = start; i < end; i++) c = crcTable[(c ^ bytes[i]) & 255] ^ c >>> 8;
|
|
20
|
+
return (c ^ 4294967295) >>> 0;
|
|
21
|
+
}
|
|
22
|
+
function paeth(a, b, c) {
|
|
23
|
+
const p = a + b - c;
|
|
24
|
+
const pa = Math.abs(p - a);
|
|
25
|
+
const pb = Math.abs(p - b);
|
|
26
|
+
const pc = Math.abs(p - c);
|
|
27
|
+
return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
|
|
28
|
+
}
|
|
29
|
+
function encodePng(width, height, data, channels = 4) {
|
|
30
|
+
const stride = width * channels;
|
|
31
|
+
const raw = new Uint8Array((stride + 1) * height);
|
|
32
|
+
const bpp = channels;
|
|
33
|
+
const cand = [new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride)];
|
|
34
|
+
for (let y = 0; y < height; y++) {
|
|
35
|
+
const row = y * stride;
|
|
36
|
+
const prevRow = (y - 1) * stride;
|
|
37
|
+
let best = 0;
|
|
38
|
+
let bestScore = Infinity;
|
|
39
|
+
for (let f = 0; f < 5; f++) {
|
|
40
|
+
const out2 = cand[f];
|
|
41
|
+
let score = 0;
|
|
42
|
+
for (let x = 0; x < stride; x++) {
|
|
43
|
+
const v = data[row + x];
|
|
44
|
+
const a = x >= bpp ? data[row + x - bpp] : 0;
|
|
45
|
+
const b = y > 0 ? data[prevRow + x] : 0;
|
|
46
|
+
const c = x >= bpp && y > 0 ? data[prevRow + x - bpp] : 0;
|
|
47
|
+
let r;
|
|
48
|
+
switch (f) {
|
|
49
|
+
case 0:
|
|
50
|
+
r = v;
|
|
51
|
+
break;
|
|
52
|
+
case 1:
|
|
53
|
+
r = v - a;
|
|
54
|
+
break;
|
|
55
|
+
case 2:
|
|
56
|
+
r = v - b;
|
|
57
|
+
break;
|
|
58
|
+
case 3:
|
|
59
|
+
r = v - (a + b >> 1);
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
r = v - paeth(a, b, c);
|
|
63
|
+
}
|
|
64
|
+
r &= 255;
|
|
65
|
+
out2[x] = r;
|
|
66
|
+
score += r < 128 ? r : 256 - r;
|
|
67
|
+
if (score >= bestScore) break;
|
|
68
|
+
}
|
|
69
|
+
if (score < bestScore) {
|
|
70
|
+
bestScore = score;
|
|
71
|
+
best = f;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const o = y * (stride + 1);
|
|
75
|
+
raw[o] = best;
|
|
76
|
+
raw.set(cand[best], o + 1);
|
|
77
|
+
}
|
|
78
|
+
const idat = deflate(raw);
|
|
79
|
+
const chunks = [];
|
|
80
|
+
const ihdr = new Uint8Array(13);
|
|
81
|
+
writeU32(ihdr, 0, width);
|
|
82
|
+
writeU32(ihdr, 4, height);
|
|
83
|
+
ihdr[8] = 8;
|
|
84
|
+
ihdr[9] = channels === 1 ? 0 : 6;
|
|
85
|
+
chunks.push(["IHDR", ihdr], ["IDAT", idat], ["IEND", new Uint8Array(0)]);
|
|
86
|
+
let size = 8;
|
|
87
|
+
for (const [, d] of chunks) size += 12 + d.length;
|
|
88
|
+
const out = new Uint8Array(size);
|
|
89
|
+
out.set(SIGNATURE, 0);
|
|
90
|
+
let p = 8;
|
|
91
|
+
for (const [type, d] of chunks) {
|
|
92
|
+
writeU32(out, p, d.length);
|
|
93
|
+
for (let i = 0; i < 4; i++) out[p + 4 + i] = type.charCodeAt(i);
|
|
94
|
+
out.set(d, p + 8);
|
|
95
|
+
writeU32(out, p + 8 + d.length, crc32(out, p + 4, p + 8 + d.length));
|
|
96
|
+
p += 12 + d.length;
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
function writeU32(b, o, v) {
|
|
101
|
+
b[o] = v >>> 24;
|
|
102
|
+
b[o + 1] = v >>> 16 & 255;
|
|
103
|
+
b[o + 2] = v >>> 8 & 255;
|
|
104
|
+
b[o + 3] = v & 255;
|
|
105
|
+
}
|
|
106
|
+
function readU32(b, o) {
|
|
107
|
+
return (b[o] << 24 | b[o + 1] << 16 | b[o + 2] << 8 | b[o + 3]) >>> 0;
|
|
108
|
+
}
|
|
109
|
+
function isPng(bytes) {
|
|
110
|
+
return bytes.length > 8 && SIGNATURE.every((v, i) => bytes[i] === v);
|
|
111
|
+
}
|
|
112
|
+
function decodePng(bytes, options = {}) {
|
|
113
|
+
if (!isPng(bytes)) throw new Error("Not a PNG image.");
|
|
114
|
+
let p = 8;
|
|
115
|
+
let width = 0;
|
|
116
|
+
let height = 0;
|
|
117
|
+
let depth = 0;
|
|
118
|
+
let type = 0;
|
|
119
|
+
let interlace = 0;
|
|
120
|
+
let palette = null;
|
|
121
|
+
let trns = null;
|
|
122
|
+
const idat = [];
|
|
123
|
+
while (p + 8 <= bytes.length) {
|
|
124
|
+
const len = readU32(bytes, p);
|
|
125
|
+
const t = String.fromCharCode(bytes[p + 4], bytes[p + 5], bytes[p + 6], bytes[p + 7]);
|
|
126
|
+
const body = bytes.subarray(p + 8, p + 8 + len);
|
|
127
|
+
if (p + 12 + len > bytes.length) throw new Error("Truncated PNG.");
|
|
128
|
+
if (t === "IHDR") {
|
|
129
|
+
width = readU32(body, 0);
|
|
130
|
+
height = readU32(body, 4);
|
|
131
|
+
depth = body[8];
|
|
132
|
+
type = body[9];
|
|
133
|
+
interlace = body[12];
|
|
134
|
+
} else if (t === "PLTE") palette = body;
|
|
135
|
+
else if (t === "tRNS") trns = body;
|
|
136
|
+
else if (t === "IDAT") idat.push(body);
|
|
137
|
+
else if (t === "IEND") break;
|
|
138
|
+
p += 12 + len;
|
|
139
|
+
}
|
|
140
|
+
if (!width || !height) throw new Error("PNG has no image header.");
|
|
141
|
+
if (interlace) throw new Error("Interlaced PNGs are not supported here; decode them with a canvas.");
|
|
142
|
+
const maxPixels = options.maxPixels ?? 1 << 28;
|
|
143
|
+
if (width * height > maxPixels) throw new Error(`PNG is too large (${width}\xD7${height}).`);
|
|
144
|
+
const samples = type === 0 ? 1 : type === 2 ? 3 : type === 3 ? 1 : type === 4 ? 2 : type === 6 ? 4 : 0;
|
|
145
|
+
if (!samples || ![1, 2, 4, 8, 16].includes(depth)) throw new Error(`Unsupported PNG format (type ${type}, depth ${depth}).`);
|
|
146
|
+
let total = 0;
|
|
147
|
+
for (const c of idat) total += c.length;
|
|
148
|
+
const z = new Uint8Array(total);
|
|
149
|
+
let o = 0;
|
|
150
|
+
for (const c of idat) {
|
|
151
|
+
z.set(c, o);
|
|
152
|
+
o += c.length;
|
|
153
|
+
}
|
|
154
|
+
const bitsPerPixel = samples * depth;
|
|
155
|
+
const stride = Math.ceil(width * bitsPerPixel / 8);
|
|
156
|
+
const raw = inflate(z, { maxOutput: (stride + 1) * height, sizeHint: (stride + 1) * height });
|
|
157
|
+
if (raw.length < (stride + 1) * height) throw new Error("PNG image data is truncated.");
|
|
158
|
+
const bpp = Math.max(1, bitsPerPixel >> 3);
|
|
159
|
+
const lines = new Uint8Array(stride * height);
|
|
160
|
+
for (let y = 0; y < height; y++) {
|
|
161
|
+
const f = raw[y * (stride + 1)];
|
|
162
|
+
const src = y * (stride + 1) + 1;
|
|
163
|
+
const dst = y * stride;
|
|
164
|
+
const up = dst - stride;
|
|
165
|
+
for (let x = 0; x < stride; x++) {
|
|
166
|
+
const v = raw[src + x];
|
|
167
|
+
const a = x >= bpp ? lines[dst + x - bpp] : 0;
|
|
168
|
+
const b = y > 0 ? lines[up + x] : 0;
|
|
169
|
+
const c = x >= bpp && y > 0 ? lines[up + x - bpp] : 0;
|
|
170
|
+
let r;
|
|
171
|
+
switch (f) {
|
|
172
|
+
case 0:
|
|
173
|
+
r = v;
|
|
174
|
+
break;
|
|
175
|
+
case 1:
|
|
176
|
+
r = v + a;
|
|
177
|
+
break;
|
|
178
|
+
case 2:
|
|
179
|
+
r = v + b;
|
|
180
|
+
break;
|
|
181
|
+
case 3:
|
|
182
|
+
r = v + (a + b >> 1);
|
|
183
|
+
break;
|
|
184
|
+
case 4:
|
|
185
|
+
r = v + paeth(a, b, c);
|
|
186
|
+
break;
|
|
187
|
+
default:
|
|
188
|
+
throw new Error(`Invalid PNG filter ${f}.`);
|
|
189
|
+
}
|
|
190
|
+
lines[dst + x] = r & 255;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const sample = (y, i) => {
|
|
194
|
+
const row = y * stride;
|
|
195
|
+
if (depth === 8) return lines[row + i];
|
|
196
|
+
if (depth === 16) return lines[row + i * 2];
|
|
197
|
+
const perByte = 8 / depth;
|
|
198
|
+
const byte = lines[row + Math.floor(i / perByte)];
|
|
199
|
+
const shift = 8 - depth * (i % perByte + 1);
|
|
200
|
+
const v = byte >> shift & (1 << depth) - 1;
|
|
201
|
+
return type === 3 ? v : Math.round(v * 255 / ((1 << depth) - 1));
|
|
202
|
+
};
|
|
203
|
+
const gray = options.keepGray && type === 0 && !trns;
|
|
204
|
+
const channels = gray ? 1 : 4;
|
|
205
|
+
const out = new Uint8ClampedArray(width * height * channels);
|
|
206
|
+
const trnsGray = trns && type === 0 ? depth === 16 ? trns[0] : sample16(trns, 0, depth) : -1;
|
|
207
|
+
const trnsRgb = trns && type === 2 ? [0, 1, 2].map((k) => depth === 16 ? trns[k * 2] : sample16(trns, k, depth)) : null;
|
|
208
|
+
for (let y = 0; y < height; y++) {
|
|
209
|
+
for (let x = 0; x < width; x++) {
|
|
210
|
+
const d = (y * width + x) * channels;
|
|
211
|
+
if (type === 0) {
|
|
212
|
+
const v = sample(y, x);
|
|
213
|
+
if (gray) out[d] = v;
|
|
214
|
+
else {
|
|
215
|
+
out[d] = out[d + 1] = out[d + 2] = v;
|
|
216
|
+
out[d + 3] = v === trnsGray && trns ? 0 : 255;
|
|
217
|
+
}
|
|
218
|
+
} else if (type === 2) {
|
|
219
|
+
const r = sample(y, x * 3);
|
|
220
|
+
const g = sample(y, x * 3 + 1);
|
|
221
|
+
const b = sample(y, x * 3 + 2);
|
|
222
|
+
out[d] = r;
|
|
223
|
+
out[d + 1] = g;
|
|
224
|
+
out[d + 2] = b;
|
|
225
|
+
out[d + 3] = trnsRgb && r === trnsRgb[0] && g === trnsRgb[1] && b === trnsRgb[2] ? 0 : 255;
|
|
226
|
+
} else if (type === 3) {
|
|
227
|
+
const i = sample(y, x);
|
|
228
|
+
if (!palette || i * 3 + 2 >= palette.length) throw new Error("PNG palette index out of range.");
|
|
229
|
+
out[d] = palette[i * 3];
|
|
230
|
+
out[d + 1] = palette[i * 3 + 1];
|
|
231
|
+
out[d + 2] = palette[i * 3 + 2];
|
|
232
|
+
out[d + 3] = trns && i < trns.length ? trns[i] : 255;
|
|
233
|
+
} else if (type === 4) {
|
|
234
|
+
const v = sample(y, x * 2);
|
|
235
|
+
out[d] = out[d + 1] = out[d + 2] = v;
|
|
236
|
+
out[d + 3] = sample(y, x * 2 + 1);
|
|
237
|
+
} else {
|
|
238
|
+
out[d] = sample(y, x * 4);
|
|
239
|
+
out[d + 1] = sample(y, x * 4 + 1);
|
|
240
|
+
out[d + 2] = sample(y, x * 4 + 2);
|
|
241
|
+
out[d + 3] = sample(y, x * 4 + 3);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return { width, height, channels, data: out };
|
|
246
|
+
}
|
|
247
|
+
function sample16(trns, k, depth) {
|
|
248
|
+
const v = trns[k * 2] << 8 | trns[k * 2 + 1];
|
|
249
|
+
if (depth === 8) return v & 255;
|
|
250
|
+
return Math.round((v & (1 << depth) - 1) * 255 / ((1 << depth) - 1));
|
|
251
|
+
}
|
|
252
|
+
var B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
253
|
+
var B64_INV = null;
|
|
254
|
+
function bytesToBase64(bytes) {
|
|
255
|
+
const parts = [];
|
|
256
|
+
const CHUNK = 3 * 4096;
|
|
257
|
+
for (let start = 0; start < bytes.length; start += CHUNK) {
|
|
258
|
+
const end = Math.min(bytes.length, start + CHUNK);
|
|
259
|
+
let s = "";
|
|
260
|
+
let i = start;
|
|
261
|
+
for (; i + 2 < end; i += 3) {
|
|
262
|
+
const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
263
|
+
s += B64[n >> 18] + B64[n >> 12 & 63] + B64[n >> 6 & 63] + B64[n & 63];
|
|
264
|
+
}
|
|
265
|
+
if (i < end) {
|
|
266
|
+
const n = bytes[i] << 16 | (i + 1 < end ? bytes[i + 1] << 8 : 0);
|
|
267
|
+
s += B64[n >> 18] + B64[n >> 12 & 63] + (i + 1 < end ? B64[n >> 6 & 63] : "=") + "=";
|
|
268
|
+
}
|
|
269
|
+
parts.push(s);
|
|
270
|
+
}
|
|
271
|
+
return parts.join("");
|
|
272
|
+
}
|
|
273
|
+
function base64ToBytes(text) {
|
|
274
|
+
if (!B64_INV) {
|
|
275
|
+
B64_INV = new Int16Array(128).fill(-1);
|
|
276
|
+
for (let i = 0; i < 64; i++) B64_INV[B64.charCodeAt(i)] = i;
|
|
277
|
+
B64_INV["-".charCodeAt(0)] = 62;
|
|
278
|
+
B64_INV["_".charCodeAt(0)] = 63;
|
|
279
|
+
}
|
|
280
|
+
const inv = B64_INV;
|
|
281
|
+
const clean = text.replace(/[\s=]/g, "");
|
|
282
|
+
const out = new Uint8Array(Math.floor(clean.length * 3 / 4));
|
|
283
|
+
let bits = 0;
|
|
284
|
+
let acc = 0;
|
|
285
|
+
let o = 0;
|
|
286
|
+
for (let i = 0; i < clean.length; i++) {
|
|
287
|
+
const c = clean.charCodeAt(i);
|
|
288
|
+
const v = c < 128 ? inv[c] : -1;
|
|
289
|
+
if (v < 0) throw new Error("Invalid base64 data.");
|
|
290
|
+
acc = acc << 6 | v;
|
|
291
|
+
bits += 6;
|
|
292
|
+
if (bits >= 8) {
|
|
293
|
+
bits -= 8;
|
|
294
|
+
out[o++] = acc >> bits & 255;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return out.subarray(0, o);
|
|
298
|
+
}
|
|
299
|
+
function parseDataUrl(url) {
|
|
300
|
+
const m = /^data:([^;,]*)((?:;[^;,]*)*?),/i.exec(url);
|
|
301
|
+
if (!m) return null;
|
|
302
|
+
const body = url.slice(m[0].length);
|
|
303
|
+
const isBase64 = /;base64/i.test(m[2]);
|
|
304
|
+
if (isBase64) return { mime: m[1] || "text/plain", bytes: base64ToBytes(body) };
|
|
305
|
+
const text = decodeURIComponent(body);
|
|
306
|
+
const bytes = new Uint8Array(text.length);
|
|
307
|
+
for (let i = 0; i < text.length; i++) bytes[i] = text.charCodeAt(i) & 255;
|
|
308
|
+
return { mime: m[1] || "text/plain", bytes };
|
|
309
|
+
}
|
|
310
|
+
function pngDataUrl(width, height, data, channels = 4) {
|
|
311
|
+
return `data:image/png;base64,${bytesToBase64(encodePng(width, height, data, channels))}`;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export {
|
|
315
|
+
encodePng,
|
|
316
|
+
isPng,
|
|
317
|
+
decodePng,
|
|
318
|
+
bytesToBase64,
|
|
319
|
+
base64ToBytes,
|
|
320
|
+
parseDataUrl,
|
|
321
|
+
pngDataUrl
|
|
322
|
+
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkISIO63Q5cjs = require('./chunk-ISIO63Q5.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
var _chunkWKPXOGZZcjs = require('./chunk-WKPXOGZZ.cjs');
|
|
@@ -26,7 +26,7 @@ function documentErrors(doc, description) {
|
|
|
26
26
|
const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
27
27
|
if (doc.values !== void 0) {
|
|
28
28
|
if (!isRecord(doc.values)) errors.push({ path: "/values", message: "must be an object of control values" });
|
|
29
|
-
else errors.push(...
|
|
29
|
+
else errors.push(..._chunkISIO63Q5cjs.effectValueErrors.call(void 0, description, doc.values).map((e) => ({ ...e, path: `/values${e.path}` })));
|
|
30
30
|
}
|
|
31
31
|
if (doc.tracks !== void 0) {
|
|
32
32
|
if (!isRecord(doc.tracks)) errors.push({ path: "/tracks", message: "must be an object of keyframe lists" });
|
|
@@ -39,7 +39,7 @@ function documentErrors(doc, description) {
|
|
|
39
39
|
kfs.forEach((kf, i) => {
|
|
40
40
|
if (!isRecord(kf)) return errors.push({ path: `${at}/${i}`, message: "must be a keyframe object" });
|
|
41
41
|
if (typeof kf.time !== "number" || !Number.isFinite(kf.time) || kf.time < 0) errors.push({ path: `${at}/${i}/time`, message: "must be a finite number of ms >= 0" });
|
|
42
|
-
errors.push(...
|
|
42
|
+
errors.push(..._chunkISIO63Q5cjs.effectValueErrors.call(void 0, description, { [control]: kf.value }).map((e) => ({ ...e, path: `${at}/${i}/value` })));
|
|
43
43
|
if (kf.easing !== void 0 && !_chunkDWJJI6RTcjs.isAnimationEasing.call(void 0, kf.easing)) errors.push({ path: `${at}/${i}/easing`, message: "is not a valid easing" });
|
|
44
44
|
});
|
|
45
45
|
}
|
|
@@ -49,7 +49,7 @@ function documentErrors(doc, description) {
|
|
|
49
49
|
else
|
|
50
50
|
doc.presets.forEach((p, i) => {
|
|
51
51
|
if (!isRecord(p) || typeof p.name !== "string" || !p.name) return errors.push({ path: `/presets/${i}`, message: "must have a name" });
|
|
52
|
-
errors.push(...
|
|
52
|
+
errors.push(..._chunkISIO63Q5cjs.effectValueErrors.call(void 0, description, p.values).map((e) => ({ ...e, path: `/presets/${i}/values${e.path}` })));
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
if (doc.duration !== void 0 && (typeof doc.duration !== "number" || !Number.isFinite(doc.duration) || !(doc.duration > 0))) {
|
|
@@ -170,7 +170,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
170
170
|
if (isDocumentSource(source)) {
|
|
171
171
|
const doc = source.document;
|
|
172
172
|
if (doc.version !== 1 || !doc.effectId) {
|
|
173
|
-
throw new (0,
|
|
173
|
+
throw new (0, _chunkISIO63Q5cjs.EffectUnsupportedError)("Invalid effect authoring document: version 1 required");
|
|
174
174
|
}
|
|
175
175
|
effectId = doc.effectId;
|
|
176
176
|
initialDoc = doc;
|
|
@@ -178,15 +178,15 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
178
178
|
effectId = source.effectId;
|
|
179
179
|
requestedPreset = source.preset;
|
|
180
180
|
} else {
|
|
181
|
-
throw new (0,
|
|
181
|
+
throw new (0, _chunkISIO63Q5cjs.EffectUnsupportedError)("Invalid effect authoring source");
|
|
182
182
|
}
|
|
183
183
|
const description = await provider.describe(effectId);
|
|
184
184
|
if (initialDoc) {
|
|
185
185
|
const problems = documentErrors(initialDoc, description);
|
|
186
|
-
if (problems.length) throw new (0,
|
|
186
|
+
if (problems.length) throw new (0, _chunkISIO63Q5cjs.EffectControlError)(effectId, problems);
|
|
187
187
|
}
|
|
188
188
|
if (description.kind === "motion") {
|
|
189
|
-
throw new (0,
|
|
189
|
+
throw new (0, _chunkISIO63Q5cjs.EffectUnsupportedError)("Motion effects cannot be authored as pixel effects", effectId);
|
|
190
190
|
}
|
|
191
191
|
let disposed = false;
|
|
192
192
|
let playing = false;
|
|
@@ -207,7 +207,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
207
207
|
const found = description.presets.find((p) => p.name === requestedPreset);
|
|
208
208
|
if (!found) {
|
|
209
209
|
const validNames = description.presets.map((p) => `"${p.name}"`).join(", ");
|
|
210
|
-
throw new (0,
|
|
210
|
+
throw new (0, _chunkISIO63Q5cjs.EffectUnsupportedError)(
|
|
211
211
|
`Unknown preset "${requestedPreset}" for effect "${effectId}". Valid presets are: ${validNames || "none"}`,
|
|
212
212
|
effectId
|
|
213
213
|
);
|
|
@@ -321,7 +321,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
321
321
|
if (!validNames.includes(name)) {
|
|
322
322
|
return { ok: false, message: `there is no control "${name}"; the controls are ${validNames.join(", ")}` };
|
|
323
323
|
}
|
|
324
|
-
const errors =
|
|
324
|
+
const errors = _chunkISIO63Q5cjs.effectValueErrors.call(void 0, description, { [name]: value });
|
|
325
325
|
if (errors.length > 0) {
|
|
326
326
|
return { ok: false, message: valueErrorMessage(errors) };
|
|
327
327
|
}
|
|
@@ -391,7 +391,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
391
391
|
if (!validNames.includes(k)) {
|
|
392
392
|
return { ok: false, message: `there is no control "${k}"; the controls are ${validNames.join(", ")}` };
|
|
393
393
|
}
|
|
394
|
-
const errors =
|
|
394
|
+
const errors = _chunkISIO63Q5cjs.effectValueErrors.call(void 0, description, { [k]: v });
|
|
395
395
|
if (errors.length > 0) {
|
|
396
396
|
return { ok: false, message: valueErrorMessage(errors) };
|
|
397
397
|
}
|
|
@@ -528,7 +528,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
528
528
|
return { ok: false, message: `invalid easing: ${String(easing)}` };
|
|
529
529
|
}
|
|
530
530
|
const targetValue = value !== void 0 ? value : valuesAtTime(time, baseValues, tracks)[name];
|
|
531
|
-
const errors =
|
|
531
|
+
const errors = _chunkISIO63Q5cjs.effectValueErrors.call(void 0, description, { [name]: targetValue });
|
|
532
532
|
if (errors.length > 0) {
|
|
533
533
|
return { ok: false, message: valueErrorMessage(errors) };
|
|
534
534
|
}
|
|
@@ -705,7 +705,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
705
705
|
},
|
|
706
706
|
async createPreview(opts) {
|
|
707
707
|
if (disposed) {
|
|
708
|
-
throw new (0,
|
|
708
|
+
throw new (0, _chunkISIO63Q5cjs.EffectDisposedError)(effectId);
|
|
709
709
|
}
|
|
710
710
|
let renderer;
|
|
711
711
|
try {
|
|
@@ -730,7 +730,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
730
730
|
height: renderer.height,
|
|
731
731
|
depth: renderer.depth,
|
|
732
732
|
render: async (req) => {
|
|
733
|
-
if (disposed) throw new (0,
|
|
733
|
+
if (disposed) throw new (0, _chunkISIO63Q5cjs.EffectDisposedError)(effectId);
|
|
734
734
|
const effectiveValues = _nullishCoalesce(req.values, () => ( valuesAtTime(req.time, baseValues, tracks)));
|
|
735
735
|
const pixels = await renderer.render({
|
|
736
736
|
...req,
|
|
@@ -74,7 +74,7 @@ function profileAlongPolyline(points, values, count = 32) {
|
|
|
74
74
|
var round3 = (v) => Math.round(v * 1e3) / 1e3;
|
|
75
75
|
var loading = null;
|
|
76
76
|
function loadCanvasBrushstrokeRenderer() {
|
|
77
|
-
loading ??= import("./brushstrokeRender-
|
|
77
|
+
loading ??= import("./brushstrokeRender-2FHFLSEG.js").catch((error) => {
|
|
78
78
|
loading = null;
|
|
79
79
|
throw error;
|
|
80
80
|
});
|