@plotdb/lotion 0.2.0 → 0.3.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/vector.js ADDED
@@ -0,0 +1,817 @@
1
+ (function(){
2
+ (function(){
3
+ var lotion, ref$, props, skip, i$, len$, s, c, textProps, unsupported, b64Bytes, b64, svgUri, fixUri, box, svgProps, svgSrc, bakeTransform, convert, fontCache, unquote, parseRange, parseSrc, faceOf, facesInText, facesInSheet, allFaces, getFaces, loadFont, hb, getHb, WGHT, subset, clamp, weightRank, fontsFor, render, vector;
4
+ lotion = window.lotion;
5
+ ref$ = lotion.libs;
6
+ ref$.satori = 'https://cdn.jsdelivr.net/npm/satori@0.36.0/+esm';
7
+ ref$.woff2 = 'https://cdn.jsdelivr.net/npm/woff2-encoder@2.0.0/dist/decompress.js';
8
+ ref$.hbsubset = 'https://cdn.jsdelivr.net/npm/harfbuzzjs@1.6.3/dist/harfbuzz-subset.wasm';
9
+ props = ['color', 'fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'lineHeight', 'letterSpacing', 'textAlign', 'whiteSpace', 'wordBreak', 'textTransform', 'textShadow', 'textIndent', 'backgroundColor', 'backgroundImage', 'backgroundPosition', 'backgroundSize', 'backgroundRepeat', 'backgroundClip', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'borderTopStyle', 'borderRightStyle', 'borderBottomStyle', 'borderLeftStyle', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'boxShadow', 'opacity', 'filter', 'clipPath', 'overflow', 'zIndex', 'transform', 'transformOrigin', 'maskImage', 'maskPosition', 'maskSize', 'maskRepeat'];
10
+ skip = {
11
+ textShadow: 'none',
12
+ textIndent: '0px',
13
+ textTransform: 'none',
14
+ backgroundColor: 'rgba(0, 0, 0, 0)',
15
+ backgroundImage: 'none',
16
+ backgroundPosition: '0% 0%',
17
+ backgroundSize: 'auto',
18
+ backgroundRepeat: 'repeat',
19
+ backgroundClip: 'border-box',
20
+ boxShadow: 'none',
21
+ opacity: '1',
22
+ filter: 'none',
23
+ clipPath: 'none',
24
+ overflow: 'visible',
25
+ zIndex: 'auto',
26
+ transform: 'none',
27
+ maskImage: 'none',
28
+ maskPosition: '0% 0%',
29
+ maskSize: 'auto',
30
+ maskRepeat: 'repeat',
31
+ lineHeight: 'normal',
32
+ letterSpacing: 'normal'
33
+ };
34
+ for (i$ = 0, len$ = (ref$ = ['Top', 'Right', 'Bottom', 'Left']).length; i$ < len$; ++i$) {
35
+ s = ref$[i$];
36
+ skip["border" + s + "Width"] = '0px';
37
+ skip["border" + s + "Style"] = 'none';
38
+ skip["padding" + s] = '0px';
39
+ }
40
+ for (i$ = 0, len$ = (ref$ = ['TopLeft', 'TopRight', 'BottomRight', 'BottomLeft']).length; i$ < len$; ++i$) {
41
+ c = ref$[i$];
42
+ skip["border" + c + "Radius"] = '0px';
43
+ }
44
+ textProps = ['color', 'fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'lineHeight', 'letterSpacing', 'textAlign', 'whiteSpace', 'wordBreak', 'textTransform', 'textShadow', 'textIndent'];
45
+ unsupported = {
46
+ backdropFilter: 'none',
47
+ textDecorationLine: 'none'
48
+ };
49
+ b64Bytes = function(buf){
50
+ var bytes, bin, i$, to$, i;
51
+ bytes = new Uint8Array(buf);
52
+ bin = '';
53
+ for (i$ = 0, to$ = bytes.length; i$ < to$; i$ += 0x8000) {
54
+ i = i$;
55
+ bin += String.fromCharCode.apply(null, bytes.subarray(i, i + 0x8000));
56
+ }
57
+ return btoa(bin);
58
+ };
59
+ b64 = function(str){
60
+ return b64Bytes(new TextEncoder().encode(str));
61
+ };
62
+ svgUri = function(xml){
63
+ return "data:image/svg+xml;base64," + b64(xml);
64
+ };
65
+ fixUri = function(v){
66
+ return v.replace(/url\("data:image\/svg\+xml(?:;charset=[^,;]+)?(?:;utf8)?,([^"]*)"\)/g, function(m, d){
67
+ var e;
68
+ return "url(\"" + svgUri((function(){
69
+ try {
70
+ return decodeURIComponent(d);
71
+ } catch (e$) {
72
+ e = e$;
73
+ return d;
74
+ }
75
+ }())) + "\")";
76
+ });
77
+ };
78
+ box = function(el, parent, cs, ctx){
79
+ var x, y, ref$, w, h;
80
+ if (el.offsetWidth != null) {
81
+ x = el.offsetLeft;
82
+ y = el.offsetTop;
83
+ if (el.offsetParent !== parent && parent.offsetParent === el.offsetParent) {
84
+ x -= parent.offsetLeft + parent.clientLeft;
85
+ y -= parent.offsetTop + parent.clientTop;
86
+ }
87
+ return [x, y, el.offsetWidth, el.offsetHeight];
88
+ }
89
+ ref$ = [parseFloat(cs.width) || 0, parseFloat(cs.height) || 0], w = ref$[0], h = ref$[1];
90
+ if ((ref$ = cs.position) === 'absolute' || ref$ === 'fixed') {
91
+ return [parseFloat(cs.left) || 0, parseFloat(cs.top) || 0, w, h];
92
+ }
93
+ ctx.warn("<" + el.tagName.toLowerCase() + "> not absolutely positioned: placed at its parent's origin");
94
+ return [0, 0, w, h];
95
+ };
96
+ svgProps = ['font-family', 'font-size', 'font-weight', 'font-style', 'letter-spacing', 'text-anchor', 'dominant-baseline', 'fill', 'fill-opacity', 'fill-rule', 'stroke', 'stroke-width', 'stroke-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'paint-order', 'opacity', 'visibility', 'display', 'filter', 'mask', 'clip-path', 'color'];
97
+ svgSrc = function(el, w, h, ctx, node){
98
+ var c, srcs, dsts, texts, ids, i$, len$, d, j$, ref$, len1$, a, re, m, defs;
99
+ c = el.cloneNode(true);
100
+ c.setAttribute('width', w);
101
+ c.setAttribute('height', h);
102
+ if (!c.getAttribute('viewBox')) {
103
+ c.setAttribute('viewBox', "0 0 " + w + " " + h);
104
+ }
105
+ c.removeAttribute('style');
106
+ srcs = [el].concat(Array.from(el.querySelectorAll('*')));
107
+ dsts = [c].concat(Array.from(c.querySelectorAll('*')));
108
+ texts = [];
109
+ srcs.map(function(e, i){
110
+ var d, cs, pcs, decl, i$, ref$, len$, k, v, f;
111
+ d = dsts[i];
112
+ cs = getComputedStyle(e);
113
+ pcs = i === 0
114
+ ? null
115
+ : getComputedStyle(e.parentNode);
116
+ decl = [];
117
+ for (i$ = 0, len$ = (ref$ = svgProps).length; i$ < len$; ++i$) {
118
+ k = ref$[i$];
119
+ v = cs.getPropertyValue(k);
120
+ if (pcs && pcs.getPropertyValue(k) === v) {
121
+ continue;
122
+ }
123
+ if (i === 0 && (k === 'opacity' || k === 'visibility' || k === 'display' || k === 'filter' || k === 'mask' || k === 'clip-path')) {
124
+ continue;
125
+ }
126
+ decl.push(k + ":" + v);
127
+ }
128
+ if (decl.length) {
129
+ d.setAttribute('style', decl.join(';'));
130
+ }
131
+ if (((ref$ = e.tagName.toLowerCase()) === 'text' || ref$ === 'tspan' || ref$ === 'textpath') && !e.querySelector('tspan, textPath')) {
132
+ f = {};
133
+ ctx.text(cs, e.textContent, f);
134
+ return texts.push([d, f]);
135
+ }
136
+ });
137
+ ids = new Set;
138
+ for (i$ = 0, len$ = dsts.length; i$ < len$; ++i$) {
139
+ d = dsts[i$];
140
+ for (j$ = 0, len1$ = (ref$ = Array.from(d.attributes)).length; j$ < len1$; ++j$) {
141
+ a = ref$[j$];
142
+ re = /url\(\s*['"]?#([^'")\s]+)['"]?\s*\)|^#(.+)$/g;
143
+ while (m = re.exec(a.value)) {
144
+ ids.add(m[1] || m[2]);
145
+ }
146
+ }
147
+ }
148
+ defs = null;
149
+ ids.forEach(function(id){
150
+ var src;
151
+ if (c.querySelector("[id=\"" + CSS.escape(id) + "\"]")) {
152
+ return;
153
+ }
154
+ if (!(src = document.getElementById(id))) {
155
+ return;
156
+ }
157
+ if (!defs) {
158
+ defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
159
+ c.insertBefore(defs, c.firstChild);
160
+ }
161
+ return defs.appendChild(src.cloneNode(true));
162
+ });
163
+ ctx.later(function(fonts){
164
+ var names, i$, ref$, len$, ref1$, d, f, st, j$, len1$, n, faces;
165
+ names = new Set;
166
+ for (i$ = 0, len$ = (ref$ = texts).length; i$ < len$; ++i$) {
167
+ ref1$ = ref$[i$], d = ref1$[0], f = ref1$[1];
168
+ if (!f.fontFamily) {
169
+ continue;
170
+ }
171
+ st = d.getAttribute('style') || '';
172
+ d.setAttribute('style', st + ";font-family:" + f.fontFamily);
173
+ for (j$ = 0, len1$ = (ref1$ = f.fontFamily.split(',')).length; j$ < len1$; ++j$) {
174
+ n = ref1$[j$];
175
+ names.add(n.trim().replace(/'/g, ''));
176
+ }
177
+ }
178
+ faces = fonts.filter(function(it){
179
+ return names.has(it.name);
180
+ }).map(function(f){
181
+ return ("@font-face{font-family:'" + f.name + "';font-weight:" + f.weight + ";font-style:" + f.style + ";") + ("src:url(data:font/ttf;base64," + b64Bytes(f.data) + ") format('truetype')}");
182
+ });
183
+ if (faces.length) {
184
+ st = document.createElementNS('http://www.w3.org/2000/svg', 'style');
185
+ st.textContent = faces.join('');
186
+ c.insertBefore(st, c.firstChild);
187
+ }
188
+ return node.props.src = svgUri(new XMLSerializer().serializeToString(c));
189
+ });
190
+ return '';
191
+ };
192
+ bakeTransform = function(node, ctx){
193
+ var st, m, v;
194
+ st = node.props.style;
195
+ if (!(st.maskImage || st.clipPath)) {
196
+ return node;
197
+ }
198
+ if (!st.transform) {
199
+ return node;
200
+ }
201
+ m = /^matrix\(([^)]+)\)$/.exec(st.transform);
202
+ v = m ? m[1].split(',').map(function(it){
203
+ return +it;
204
+ }) : null;
205
+ if (v && v[0] === 1 && v[1] === 0 && v[2] === 0 && v[3] === 1) {
206
+ st.left += v[4];
207
+ st.top += v[5];
208
+ delete st.transform;
209
+ delete st.transformOrigin;
210
+ } else {
211
+ ctx.warn("mask / clip-path with a non-translation transform: misplaced");
212
+ }
213
+ return node;
214
+ };
215
+ convert = function(el, ctx, depth){
216
+ var root, cs, tag, ref$, x, y, w, h, hidden, k, v, blend, kids, texts, elems, style, i$, len$, s, node, children, text, jc, c, that;
217
+ depth == null && (depth = 0);
218
+ root = depth === 0;
219
+ cs = getComputedStyle(el);
220
+ if (cs.display === 'none' || +cs.opacity === 0) {
221
+ return null;
222
+ }
223
+ tag = el.tagName.toLowerCase();
224
+ ref$ = box(el, el.parentNode, cs, ctx), x = ref$[0], y = ref$[1], w = ref$[2], h = ref$[3];
225
+ hidden = cs.visibility !== 'visible';
226
+ for (k in ref$ = unsupported) {
227
+ v = ref$[k];
228
+ if (cs[k] && cs[k] !== v) {
229
+ ctx.warn(k + ": " + cs[k]);
230
+ }
231
+ }
232
+ blend = cs.mixBlendMode !== 'normal' ? cs.mixBlendMode : null;
233
+ if (blend && depth !== 1) {
234
+ ctx.warn("mixBlendMode on a nested element: " + blend + " ignored");
235
+ }
236
+ kids = Array.from(el.childNodes);
237
+ texts = kids.filter(function(n){
238
+ return n.nodeType === 3 && n.textContent.trim();
239
+ });
240
+ elems = kids.filter(function(n){
241
+ return n.nodeType === 1;
242
+ });
243
+ if (texts.length && elems.length) {
244
+ ctx.warn("mixed text and elements in <" + tag + ">");
245
+ }
246
+ style = {
247
+ display: 'flex',
248
+ boxSizing: 'border-box',
249
+ width: w,
250
+ height: h
251
+ };
252
+ if (!root) {
253
+ style.position = 'absolute';
254
+ style.left = x;
255
+ style.top = y;
256
+ }
257
+ for (i$ = 0, len$ = (ref$ = props).length; i$ < len$; ++i$) {
258
+ k = ref$[i$];
259
+ if (!texts.length && in$(k, textProps)) {
260
+ continue;
261
+ }
262
+ v = cs[k];
263
+ if (!v || skip[k] === v) {
264
+ continue;
265
+ }
266
+ style[k] = /data:image\/svg/.test(v) ? fixUri(v) : v;
267
+ }
268
+ for (i$ = 0, len$ = (ref$ = ['Top', 'Right', 'Bottom', 'Left']).length; i$ < len$; ++i$) {
269
+ s = ref$[i$];
270
+ if (!style["border" + s + "Width"]) {
271
+ delete style["border" + s + "Color"];
272
+ }
273
+ }
274
+ if (style.overflow) {
275
+ style.overflow = 'hidden';
276
+ }
277
+ if (style.transform) {
278
+ style.transformOrigin = cs.transformOrigin;
279
+ } else {
280
+ delete style.transformOrigin;
281
+ }
282
+ if (hidden) {
283
+ for (i$ = 0, len$ = (ref$ = ['backgroundColor', 'backgroundImage', 'boxShadow', 'color', 'textShadow']).length; i$ < len$; ++i$) {
284
+ k = ref$[i$];
285
+ delete style[k];
286
+ }
287
+ for (i$ = 0, len$ = (ref$ = ['Top', 'Right', 'Bottom', 'Left']).length; i$ < len$; ++i$) {
288
+ s = ref$[i$];
289
+ delete style["border" + s + "Width"];
290
+ }
291
+ }
292
+ if (tag === 'img' || tag === 'canvas' || tag === 'svg') {
293
+ if (hidden) {
294
+ return null;
295
+ }
296
+ node = {
297
+ blend: depth === 1 ? blend : null,
298
+ type: 'img',
299
+ props: {
300
+ width: w,
301
+ height: h,
302
+ style: style
303
+ }
304
+ };
305
+ node.props.src = (function(){
306
+ switch (tag) {
307
+ case 'img':
308
+ return el.currentSrc || el.src;
309
+ case 'canvas':
310
+ return el.toDataURL();
311
+ case 'svg':
312
+ return svgSrc(el, w, h, ctx, node);
313
+ }
314
+ }());
315
+ return bakeTransform(node, ctx);
316
+ }
317
+ children = [];
318
+ if (texts.length && !hidden) {
319
+ text = texts.map(function(it){
320
+ return it.textContent;
321
+ }).join('');
322
+ ctx.text(cs, text, style);
323
+ children.push(text);
324
+ jc = {
325
+ center: 'center',
326
+ right: 'flex-end',
327
+ end: 'flex-end'
328
+ }[cs.textAlign];
329
+ if (jc && !elems.length) {
330
+ style.justifyContent = jc;
331
+ }
332
+ }
333
+ for (i$ = 0, len$ = elems.length; i$ < len$; ++i$) {
334
+ c = elems[i$];
335
+ if (that = convert(c, ctx, depth + 1)) {
336
+ children.push(that);
337
+ }
338
+ }
339
+ node = {
340
+ type: 'div',
341
+ props: {
342
+ style: style,
343
+ children: children
344
+ }
345
+ };
346
+ if (blend && depth === 1) {
347
+ node.blend = blend;
348
+ }
349
+ return bakeTransform(node, ctx);
350
+ };
351
+ fontCache = {};
352
+ unquote = function(s){
353
+ return s.trim().replace(/^["']|["']$/g, '');
354
+ };
355
+ parseRange = function(s){
356
+ if (!s) {
357
+ return [[0, 0x10FFFF]];
358
+ }
359
+ return s.split(',').map(function(r){
360
+ var ref$, a, b;
361
+ r = r.trim().replace(/^u\+/i, '');
362
+ if (/\?/.test(r)) {
363
+ return [parseInt(r.replace(/\?/g, '0'), 16), parseInt(r.replace(/\?/g, 'F'), 16)];
364
+ }
365
+ ref$ = r.split('-'), a = ref$[0], b = ref$[1];
366
+ return [parseInt(a, 16), parseInt(b || a, 16)];
367
+ });
368
+ };
369
+ parseSrc = function(s, base){
370
+ var ret, re, m;
371
+ ret = [];
372
+ re = /url\(\s*(['"]?)([^'")]+)\1\s*\)\s*(?:format\(\s*['"]?([^'")]+)['"]?\s*\))?/g;
373
+ while (m = re.exec(s)) {
374
+ try {
375
+ ret.push({
376
+ url: new URL(m[2], base).href,
377
+ format: (m[3] || m[2].split('.').pop()).toLowerCase()
378
+ });
379
+ } catch (e$) {}
380
+ }
381
+ return ret;
382
+ };
383
+ faceOf = function(get, base){
384
+ return {
385
+ family: unquote(get('font-family')),
386
+ weight: (get('font-weight') || '400').split(/\s+/).map(function(it){
387
+ if (it === 'normal') {
388
+ return 400;
389
+ } else if (it === 'bold') {
390
+ return 700;
391
+ } else {
392
+ return +it;
393
+ }
394
+ }),
395
+ style: get('font-style') || 'normal',
396
+ range: parseRange(get('unicode-range')),
397
+ src: parseSrc(get('src'), base)
398
+ };
399
+ };
400
+ facesInText = function(text, base){
401
+ return (text.match(/@font-face\s*\{[^}]*\}/g) || []).map(function(b){
402
+ return faceOf(function(k){
403
+ return (new RegExp("(?:^|[{;\\s])" + k + "\\s*:\\s*([^;}]+)").exec(b) || [])[1];
404
+ }, base);
405
+ });
406
+ };
407
+ facesInSheet = function(sheet){
408
+ var base, rules, e;
409
+ base = sheet.href || location.href;
410
+ try {
411
+ rules = sheet.cssRules;
412
+ } catch (e$) {
413
+ e = e$;
414
+ rules = null;
415
+ }
416
+ if (!rules) {
417
+ return sheet.href
418
+ ? fetch(sheet.href).then(function(r){
419
+ return r.text();
420
+ }).then(function(t){
421
+ return facesInText(t, base);
422
+ })['catch'](function(){
423
+ return [];
424
+ })
425
+ : Promise.resolve([]);
426
+ }
427
+ return Promise.all(Array.from(rules).map(function(r){
428
+ if (r.styleSheet) {
429
+ return facesInSheet(r.styleSheet);
430
+ }
431
+ if (r.type === 5) {
432
+ return [faceOf(function(k){
433
+ return r.style.getPropertyValue(k);
434
+ }, base)];
435
+ }
436
+ return [];
437
+ })).then(function(l){
438
+ return l.flat();
439
+ });
440
+ };
441
+ allFaces = null;
442
+ getFaces = function(){
443
+ var allFaces;
444
+ return allFaces != null
445
+ ? allFaces
446
+ : allFaces = Promise.all(Array.from(document.styleSheets).map(facesInSheet)).then(function(l){
447
+ return l.flat();
448
+ });
449
+ };
450
+ loadFont = function(src){
451
+ var pick, key$, ref$;
452
+ pick = src.find(function(it){
453
+ var ref$;
454
+ return (ref$ = it.format) === 'truetype' || ref$ === 'opentype' || ref$ === 'woff' || ref$ === 'ttf' || ref$ === 'otf';
455
+ }) || src.find(function(it){
456
+ return it.format === 'woff2';
457
+ });
458
+ if (!pick) {
459
+ return Promise.resolve(null);
460
+ }
461
+ return (ref$ = fontCache[key$ = pick.url]) != null
462
+ ? ref$
463
+ : fontCache[key$] = fetch(pick.url).then(function(r){
464
+ return r.arrayBuffer();
465
+ }).then(function(buf){
466
+ if (pick.format !== 'woff2') {
467
+ return buf;
468
+ }
469
+ return lotion.lib('woff2').then(function(m){
470
+ var decompress;
471
+ decompress = m.decompress || m['default'];
472
+ return decompress(buf);
473
+ }).then(function(u8){
474
+ return u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength);
475
+ });
476
+ });
477
+ };
478
+ hb = null;
479
+ getHb = function(){
480
+ var hb;
481
+ return hb != null
482
+ ? hb
483
+ : hb = fetch(lotion.libs.hbsubset).then(function(r){
484
+ return r.arrayBuffer();
485
+ }).then(function(b){
486
+ return WebAssembly.instantiate(b, {});
487
+ }).then(function(arg$){
488
+ var instance, e;
489
+ instance = arg$.instance;
490
+ e = instance.exports;
491
+ if (e._initialize) {
492
+ e._initialize();
493
+ }
494
+ return e;
495
+ });
496
+ };
497
+ WGHT = 0x77676874;
498
+ subset = function(buf, weight, cps){
499
+ return getHb().then(function(e){
500
+ var n, p, blob, face, input, us, i$, ref$, len$, c, sub, ret, rb, d;
501
+ n = buf.byteLength;
502
+ p = e.malloc(n);
503
+ new Uint8Array(e.memory.buffer).set(new Uint8Array(buf), p);
504
+ blob = e.hb_blob_create(p, n, 1, 0, 0);
505
+ face = e.hb_face_create(blob, 0);
506
+ e.hb_blob_destroy(blob);
507
+ input = e.hb_subset_input_create_or_fail();
508
+ us = e.hb_subset_input_unicode_set(input);
509
+ for (i$ = 0, len$ = (ref$ = cps).length; i$ < len$; ++i$) {
510
+ c = ref$[i$];
511
+ e.hb_set_add(us, c);
512
+ }
513
+ e.hb_subset_input_pin_axis_location(input, face, WGHT, weight);
514
+ sub = e.hb_subset_or_fail(face, input);
515
+ e.hb_subset_input_destroy(input);
516
+ ret = null;
517
+ if (sub) {
518
+ rb = e.hb_face_reference_blob(sub);
519
+ d = e.hb_blob_get_data(rb, 0);
520
+ ret = new Uint8Array(e.memory.buffer).slice(d, d + e.hb_blob_get_length(rb)).buffer;
521
+ e.hb_blob_destroy(rb);
522
+ e.hb_face_destroy(sub);
523
+ }
524
+ e.hb_face_destroy(face);
525
+ e.free(p);
526
+ return ret;
527
+ });
528
+ };
529
+ clamp = function(v, a, b){
530
+ return Math.min(b, Math.max(a, v));
531
+ };
532
+ weightRank = function(f, w){
533
+ var ref$, a, b;
534
+ ref$ = [f.weight[0], f.weight[1] || f.weight[0]], a = ref$[0], b = ref$[1];
535
+ if (w >= a && w <= b) {
536
+ return 0;
537
+ }
538
+ if (w > 500) {
539
+ return a > w
540
+ ? a - w
541
+ : 1000 + w - b;
542
+ }
543
+ if (w < 400) {
544
+ return b < w
545
+ ? w - b
546
+ : 1000 + a - w;
547
+ }
548
+ if (a > w && a <= 500) {
549
+ return a - w;
550
+ } else if (b < w) {
551
+ return 1000 + w - b;
552
+ } else {
553
+ return 2000 + a - w;
554
+ }
555
+ };
556
+ fontsFor = function(used, ctx){
557
+ return getFaces().then(function(faces){
558
+ var groups, missing, nGroup, key, ref$, u, i$, ref1$, len$, c, cp, f, j$, ref2$, len1$, fam, cand, same, pin, gk, g, k, v;
559
+ groups = {};
560
+ missing = 0;
561
+ nGroup = 0;
562
+ for (key in ref$ = used) {
563
+ u = ref$[key];
564
+ u.names = [];
565
+ for (i$ = 0, len$ = (ref1$ = Array.from(u.chars)).length; i$ < len$; ++i$) {
566
+ c = ref1$[i$];
567
+ cp = c.codePointAt(0);
568
+ if (cp < 33) {
569
+ continue;
570
+ }
571
+ f = null;
572
+ for (j$ = 0, len1$ = (ref2$ = u.families).length; j$ < len1$; ++j$) {
573
+ fam = ref2$[j$];
574
+ cand = faces.filter(fn$);
575
+ if (!cand.length) {
576
+ continue;
577
+ }
578
+ same = cand.filter(fn1$);
579
+ if (same.length) {
580
+ cand = same;
581
+ }
582
+ f = cand.reduce(fn2$);
583
+ break;
584
+ }
585
+ if (!f) {
586
+ missing++;
587
+ continue;
588
+ }
589
+ pin = clamp(u.weight, f.weight[0], f.weight[1] || f.weight[0]);
590
+ gk = f.src[0].url + "|" + u.weight + "|" + u.style;
591
+ g = (ref2$ = groups[gk]) != null
592
+ ? ref2$
593
+ : groups[gk] = {
594
+ name: "lotion-font-" + (nGroup++),
595
+ face: f,
596
+ weight: u.weight,
597
+ pin: pin,
598
+ style: u.style,
599
+ cps: new Set([32])
600
+ };
601
+ g.cps.add(cp);
602
+ if (!in$(g.name, u.names)) {
603
+ u.names.push(g.name);
604
+ }
605
+ }
606
+ }
607
+ if (missing) {
608
+ ctx.warn(missing + " characters have no web font ( system fonts are not available to satori )");
609
+ }
610
+ return Promise.all((function(){
611
+ var ref$, results$ = [];
612
+ for (k in ref$ = groups) {
613
+ v = ref$[k];
614
+ results$.push(v);
615
+ }
616
+ return results$;
617
+ }()).map(function(g){
618
+ return loadFont(g.face.src).then(function(buf){
619
+ if (!buf) {
620
+ return null;
621
+ }
622
+ return subset(buf, g.pin, Array.from(g.cps)).then(function(data){
623
+ if (!data) {
624
+ ctx.warn("font " + g.face.family + ": subset failed");
625
+ return null;
626
+ }
627
+ return {
628
+ name: g.name,
629
+ data: data,
630
+ weight: g.weight,
631
+ style: g.style
632
+ };
633
+ });
634
+ });
635
+ })).then(function(l){
636
+ return l.filter(function(it){
637
+ return it;
638
+ });
639
+ });
640
+ function fn$(f){
641
+ return f.family === fam && f.src.length && f.range.some(function(r){
642
+ return cp >= r[0] && cp <= r[1];
643
+ });
644
+ }
645
+ function fn1$(f){
646
+ return f.style === u.style;
647
+ }
648
+ function fn2$(a, b){
649
+ if (weightRank(b, u.weight) < weightRank(a, u.weight)) {
650
+ return b;
651
+ } else {
652
+ return a;
653
+ }
654
+ }
655
+ });
656
+ };
657
+ render = function(satori, tree, o){
658
+ var kids, segs, i$, len$, k, bare;
659
+ kids = tree.props.children;
660
+ if (!kids.some(function(it){
661
+ return it.blend;
662
+ })) {
663
+ return satori(tree, o);
664
+ }
665
+ segs = [{
666
+ kids: []
667
+ }];
668
+ for (i$ = 0, len$ = kids.length; i$ < len$; ++i$) {
669
+ k = kids[i$];
670
+ if (k.blend) {
671
+ segs.push({
672
+ blend: k.blend,
673
+ kids: [k]
674
+ });
675
+ } else if (segs[segs.length - 1].blend) {
676
+ segs.push({
677
+ kids: [k]
678
+ });
679
+ } else {
680
+ segs[segs.length - 1].kids.push(k);
681
+ }
682
+ }
683
+ bare = {
684
+ display: 'flex',
685
+ width: o.width,
686
+ height: o.height,
687
+ overflow: 'hidden'
688
+ };
689
+ return Promise.all(segs.map(function(g, i){
690
+ return satori({
691
+ type: 'div',
692
+ props: {
693
+ style: i === 0 ? tree.props.style : bare,
694
+ children: g.kids
695
+ }
696
+ }, o).then(function(svg){
697
+ var inner;
698
+ inner = svg.replace(/^<svg[^>]*>/, '').replace(/<\/svg>\s*$/, '').replace(/satori_/g, "satori_" + i + "_");
699
+ if (g.blend) {
700
+ return "<g style=\"mix-blend-mode:" + g.blend + "\">" + inner + "</g>";
701
+ } else {
702
+ return "<g>" + inner + "</g>";
703
+ }
704
+ });
705
+ })).then(function(layers){
706
+ return "<svg width=\"" + o.width + "\" height=\"" + o.height + "\" viewBox=\"0 0 " + o.width + " " + o.height + "\" xmlns=\"http://www.w3.org/2000/svg\">" + layers.join('') + "</svg>";
707
+ });
708
+ };
709
+ vector = function(el, opt){
710
+ var warns, used, laters, ctx, tree, w, h, ref$, that;
711
+ opt == null && (opt = {});
712
+ warns = {};
713
+ used = {};
714
+ laters = [];
715
+ ctx = {
716
+ warn: function(m){
717
+ return warns[m] = (warns[m] || 0) + 1;
718
+ },
719
+ later: function(f){
720
+ return laters.push(f);
721
+ },
722
+ text: function(cs, text, style){
723
+ var weight, key, u, ref$, i$, len$, c;
724
+ weight = +cs.fontWeight || 400;
725
+ key = cs.fontFamily + "|" + weight + "|" + cs.fontStyle;
726
+ u = (ref$ = used[key]) != null
727
+ ? ref$
728
+ : used[key] = {
729
+ families: cs.fontFamily.split(',').map(unquote),
730
+ weight: weight,
731
+ style: cs.fontStyle,
732
+ chars: new Set,
733
+ styles: []
734
+ };
735
+ for (i$ = 0, len$ = (ref$ = Array.from(text)).length; i$ < len$; ++i$) {
736
+ c = ref$[i$];
737
+ u.chars.add(c);
738
+ }
739
+ return u.styles.push(style);
740
+ }
741
+ };
742
+ tree = convert(el, ctx);
743
+ w = opt.width || el.offsetWidth;
744
+ h = opt.height || el.offsetHeight;
745
+ ref$ = tree.props.style;
746
+ ref$.width = w;
747
+ ref$.height = h;
748
+ ref$.overflow = 'hidden';
749
+ delete tree.props.style.transform;
750
+ delete tree.props.style.transformOrigin;
751
+ return Promise.all([
752
+ (that = opt.satori)
753
+ ? Promise.resolve(that)
754
+ : lotion.lib('satori'), (that = opt.fonts)
755
+ ? Promise.resolve(that)
756
+ : fontsFor(used, ctx)
757
+ ]).then(function(arg$){
758
+ var m, fonts, k, ref$, u, i$, ref1$, len$, s, f, satori;
759
+ m = arg$[0], fonts = arg$[1];
760
+ if (!opt.fonts) {
761
+ for (k in ref$ = used) {
762
+ u = ref$[k];
763
+ for (i$ = 0, len$ = (ref1$ = u.styles).length; i$ < len$; ++i$) {
764
+ s = ref1$[i$];
765
+ s.fontFamily = u.names.map(fn$).join(', ');
766
+ }
767
+ }
768
+ }
769
+ for (i$ = 0, len$ = (ref$ = laters).length; i$ < len$; ++i$) {
770
+ f = ref$[i$];
771
+ f(fonts);
772
+ }
773
+ satori = m['default'] || m.satori || m;
774
+ return render(satori, tree, {
775
+ width: w,
776
+ height: h,
777
+ fonts: fonts
778
+ });
779
+ function fn$(it){
780
+ return "'" + it + "'";
781
+ }
782
+ }).then(function(svg){
783
+ var k, v;
784
+ return {
785
+ svg: svg,
786
+ warnings: (function(){
787
+ var ref$, results$ = [];
788
+ for (k in ref$ = warns) {
789
+ v = ref$[k];
790
+ results$.push(k + (v > 1 ? " ( x" + v + " )" : ''));
791
+ }
792
+ return results$;
793
+ }())
794
+ };
795
+ });
796
+ };
797
+ lotion.vector = vector;
798
+ return lotion.player.prototype.vector = function(t, opt){
799
+ var this$ = this;
800
+ opt == null && (opt = {});
801
+ if (t != null) {
802
+ this.opt.seek(t);
803
+ }
804
+ return vector(this.stage, opt).then(function(r){
805
+ if (t != null) {
806
+ this$.opt.seek(this$.t);
807
+ }
808
+ return r;
809
+ });
810
+ };
811
+ })();
812
+ function in$(x, xs){
813
+ var i = -1, l = xs.length >>> 0;
814
+ while (++i < l) if (x === xs[i]) return true;
815
+ return false;
816
+ }
817
+ }).call(this);