@remotion/paths 4.0.232 → 4.0.233

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.
@@ -0,0 +1,3745 @@
1
+ // src/cut-instruction.ts
2
+ var cutLInstruction = ({
3
+ instruction,
4
+ lastPoint,
5
+ progress
6
+ }) => {
7
+ const x = lastPoint.x + (instruction.x - lastPoint.x) * progress;
8
+ const y = lastPoint.y + (instruction.y - lastPoint.y) * progress;
9
+ return {
10
+ type: "L",
11
+ x,
12
+ y
13
+ };
14
+ };
15
+ function interpolatePoint(pA, pB, factor) {
16
+ return {
17
+ x: pA.x + (pB.x - pA.x) * factor,
18
+ y: pA.y + (pB.y - pA.y) * factor
19
+ };
20
+ }
21
+ function cutCInstruction({
22
+ progress,
23
+ lastPoint,
24
+ instruction
25
+ }) {
26
+ const u = progress;
27
+ const p0 = { x: lastPoint.x, y: lastPoint.y };
28
+ const p1 = { x: instruction.cp1x, y: instruction.cp1y };
29
+ const p2 = { x: instruction.cp2x, y: instruction.cp2y };
30
+ const p3 = { x: instruction.x, y: instruction.y };
31
+ const p01 = interpolatePoint(p0, p1, u);
32
+ const p12 = interpolatePoint(p1, p2, u);
33
+ const p23 = interpolatePoint(p2, p3, u);
34
+ const p012 = interpolatePoint(p01, p12, u);
35
+ const p123 = interpolatePoint(p12, p23, u);
36
+ const p0123 = interpolatePoint(p012, p123, u);
37
+ return {
38
+ type: "C",
39
+ cp1x: p01.x,
40
+ cp1y: p01.y,
41
+ cp2x: p012.x,
42
+ cp2y: p012.y,
43
+ x: p0123.x,
44
+ y: p0123.y
45
+ };
46
+ }
47
+ var cutInstruction = ({
48
+ instruction,
49
+ lastPoint,
50
+ progress
51
+ }) => {
52
+ if (instruction.type === "M") {
53
+ return instruction;
54
+ }
55
+ if (instruction.type === "L") {
56
+ return cutLInstruction({ instruction, lastPoint, progress });
57
+ }
58
+ if (instruction.type === "C") {
59
+ return cutCInstruction({ instruction, lastPoint, progress });
60
+ }
61
+ if (instruction.type === "Z") {
62
+ return instruction;
63
+ }
64
+ throw new TypeError(`${instruction.type} is not supported.`);
65
+ };
66
+
67
+ // src/helpers/bezier-values.ts
68
+ var tValues = [
69
+ [],
70
+ [],
71
+ [
72
+ -0.5773502691896257,
73
+ 0.5773502691896257
74
+ ],
75
+ [
76
+ 0,
77
+ -0.7745966692414834,
78
+ 0.7745966692414834
79
+ ],
80
+ [
81
+ -0.33998104358485626,
82
+ 0.33998104358485626,
83
+ -0.8611363115940526,
84
+ 0.8611363115940526
85
+ ],
86
+ [
87
+ 0,
88
+ -0.5384693101056831,
89
+ 0.5384693101056831,
90
+ -0.906179845938664,
91
+ 0.906179845938664
92
+ ],
93
+ [
94
+ 0.6612093864662645,
95
+ -0.6612093864662645,
96
+ -0.2386191860831969,
97
+ 0.2386191860831969,
98
+ -0.932469514203152,
99
+ 0.932469514203152
100
+ ],
101
+ [
102
+ 0,
103
+ 0.4058451513773972,
104
+ -0.4058451513773972,
105
+ -0.7415311855993945,
106
+ 0.7415311855993945,
107
+ -0.9491079123427585,
108
+ 0.9491079123427585
109
+ ],
110
+ [
111
+ -0.1834346424956498,
112
+ 0.1834346424956498,
113
+ -0.525532409916329,
114
+ 0.525532409916329,
115
+ -0.7966664774136267,
116
+ 0.7966664774136267,
117
+ -0.9602898564975363,
118
+ 0.9602898564975363
119
+ ],
120
+ [
121
+ 0,
122
+ -0.8360311073266358,
123
+ 0.8360311073266358,
124
+ -0.9681602395076261,
125
+ 0.9681602395076261,
126
+ -0.3242534234038089,
127
+ 0.3242534234038089,
128
+ -0.6133714327005904,
129
+ 0.6133714327005904
130
+ ],
131
+ [
132
+ -0.14887433898163122,
133
+ 0.14887433898163122,
134
+ -0.4333953941292472,
135
+ 0.4333953941292472,
136
+ -0.6794095682990244,
137
+ 0.6794095682990244,
138
+ -0.8650633666889845,
139
+ 0.8650633666889845,
140
+ -0.9739065285171717,
141
+ 0.9739065285171717
142
+ ],
143
+ [
144
+ 0,
145
+ -0.26954315595234496,
146
+ 0.26954315595234496,
147
+ -0.5190961292068118,
148
+ 0.5190961292068118,
149
+ -0.7301520055740494,
150
+ 0.7301520055740494,
151
+ -0.8870625997680953,
152
+ 0.8870625997680953,
153
+ -0.978228658146057,
154
+ 0.978228658146057
155
+ ],
156
+ [
157
+ -0.1252334085114689,
158
+ 0.1252334085114689,
159
+ -0.3678314989981802,
160
+ 0.3678314989981802,
161
+ -0.5873179542866175,
162
+ 0.5873179542866175,
163
+ -0.7699026741943047,
164
+ 0.7699026741943047,
165
+ -0.9041172563704749,
166
+ 0.9041172563704749,
167
+ -0.9815606342467192,
168
+ 0.9815606342467192
169
+ ],
170
+ [
171
+ 0,
172
+ -0.2304583159551348,
173
+ 0.2304583159551348,
174
+ -0.44849275103644687,
175
+ 0.44849275103644687,
176
+ -0.6423493394403402,
177
+ 0.6423493394403402,
178
+ -0.8015780907333099,
179
+ 0.8015780907333099,
180
+ -0.9175983992229779,
181
+ 0.9175983992229779,
182
+ -0.9841830547185881,
183
+ 0.9841830547185881
184
+ ],
185
+ [
186
+ -0.10805494870734367,
187
+ 0.10805494870734367,
188
+ -0.31911236892788974,
189
+ 0.31911236892788974,
190
+ -0.5152486363581541,
191
+ 0.5152486363581541,
192
+ -0.6872929048116855,
193
+ 0.6872929048116855,
194
+ -0.827201315069765,
195
+ 0.827201315069765,
196
+ -0.9284348836635735,
197
+ 0.9284348836635735,
198
+ -0.9862838086968123,
199
+ 0.9862838086968123
200
+ ],
201
+ [
202
+ 0,
203
+ -0.20119409399743451,
204
+ 0.20119409399743451,
205
+ -0.3941513470775634,
206
+ 0.3941513470775634,
207
+ -0.5709721726085388,
208
+ 0.5709721726085388,
209
+ -0.7244177313601701,
210
+ 0.7244177313601701,
211
+ -0.8482065834104272,
212
+ 0.8482065834104272,
213
+ -0.937273392400706,
214
+ 0.937273392400706,
215
+ -0.9879925180204854,
216
+ 0.9879925180204854
217
+ ],
218
+ [
219
+ -0.09501250983763744,
220
+ 0.09501250983763744,
221
+ -0.2816035507792589,
222
+ 0.2816035507792589,
223
+ -0.45801677765722737,
224
+ 0.45801677765722737,
225
+ -0.6178762444026438,
226
+ 0.6178762444026438,
227
+ -0.755404408355003,
228
+ 0.755404408355003,
229
+ -0.8656312023878318,
230
+ 0.8656312023878318,
231
+ -0.9445750230732326,
232
+ 0.9445750230732326,
233
+ -0.9894009349916499,
234
+ 0.9894009349916499
235
+ ],
236
+ [
237
+ 0,
238
+ -0.17848418149584785,
239
+ 0.17848418149584785,
240
+ -0.3512317634538763,
241
+ 0.3512317634538763,
242
+ -0.5126905370864769,
243
+ 0.5126905370864769,
244
+ -0.6576711592166907,
245
+ 0.6576711592166907,
246
+ -0.7815140038968014,
247
+ 0.7815140038968014,
248
+ -0.8802391537269859,
249
+ 0.8802391537269859,
250
+ -0.9506755217687678,
251
+ 0.9506755217687678,
252
+ -0.9905754753144174,
253
+ 0.9905754753144174
254
+ ],
255
+ [
256
+ -0.0847750130417353,
257
+ 0.0847750130417353,
258
+ -0.2518862256915055,
259
+ 0.2518862256915055,
260
+ -0.41175116146284263,
261
+ 0.41175116146284263,
262
+ -0.5597708310739475,
263
+ 0.5597708310739475,
264
+ -0.6916870430603532,
265
+ 0.6916870430603532,
266
+ -0.8037049589725231,
267
+ 0.8037049589725231,
268
+ -0.8926024664975557,
269
+ 0.8926024664975557,
270
+ -0.9558239495713977,
271
+ 0.9558239495713977,
272
+ -0.9915651684209309,
273
+ 0.9915651684209309
274
+ ],
275
+ [
276
+ 0,
277
+ -0.16035864564022537,
278
+ 0.16035864564022537,
279
+ -0.31656409996362983,
280
+ 0.31656409996362983,
281
+ -0.46457074137596094,
282
+ 0.46457074137596094,
283
+ -0.600545304661681,
284
+ 0.600545304661681,
285
+ -0.7209661773352294,
286
+ 0.7209661773352294,
287
+ -0.8227146565371428,
288
+ 0.8227146565371428,
289
+ -0.9031559036148179,
290
+ 0.9031559036148179,
291
+ -0.96020815213483,
292
+ 0.96020815213483,
293
+ -0.9924068438435844,
294
+ 0.9924068438435844
295
+ ],
296
+ [
297
+ -0.07652652113349734,
298
+ 0.07652652113349734,
299
+ -0.22778585114164507,
300
+ 0.22778585114164507,
301
+ -0.37370608871541955,
302
+ 0.37370608871541955,
303
+ -0.5108670019508271,
304
+ 0.5108670019508271,
305
+ -0.636053680726515,
306
+ 0.636053680726515,
307
+ -0.7463319064601508,
308
+ 0.7463319064601508,
309
+ -0.8391169718222188,
310
+ 0.8391169718222188,
311
+ -0.912234428251326,
312
+ 0.912234428251326,
313
+ -0.9639719272779138,
314
+ 0.9639719272779138,
315
+ -0.9931285991850949,
316
+ 0.9931285991850949
317
+ ],
318
+ [
319
+ 0,
320
+ -0.1455618541608951,
321
+ 0.1455618541608951,
322
+ -0.2880213168024011,
323
+ 0.2880213168024011,
324
+ -0.4243421202074388,
325
+ 0.4243421202074388,
326
+ -0.5516188358872198,
327
+ 0.5516188358872198,
328
+ -0.6671388041974123,
329
+ 0.6671388041974123,
330
+ -0.7684399634756779,
331
+ 0.7684399634756779,
332
+ -0.8533633645833173,
333
+ 0.8533633645833173,
334
+ -0.9200993341504008,
335
+ 0.9200993341504008,
336
+ -0.9672268385663063,
337
+ 0.9672268385663063,
338
+ -0.9937521706203895,
339
+ 0.9937521706203895
340
+ ],
341
+ [
342
+ -0.06973927331972223,
343
+ 0.06973927331972223,
344
+ -0.20786042668822127,
345
+ 0.20786042668822127,
346
+ -0.34193582089208424,
347
+ 0.34193582089208424,
348
+ -0.469355837986757,
349
+ 0.469355837986757,
350
+ -0.5876404035069116,
351
+ 0.5876404035069116,
352
+ -0.6944872631866827,
353
+ 0.6944872631866827,
354
+ -0.7878168059792081,
355
+ 0.7878168059792081,
356
+ -0.8658125777203002,
357
+ 0.8658125777203002,
358
+ -0.926956772187174,
359
+ 0.926956772187174,
360
+ -0.9700604978354287,
361
+ 0.9700604978354287,
362
+ -0.9942945854823992,
363
+ 0.9942945854823992
364
+ ],
365
+ [
366
+ 0,
367
+ -0.1332568242984661,
368
+ 0.1332568242984661,
369
+ -0.26413568097034495,
370
+ 0.26413568097034495,
371
+ -0.3903010380302908,
372
+ 0.3903010380302908,
373
+ -0.5095014778460075,
374
+ 0.5095014778460075,
375
+ -0.6196098757636461,
376
+ 0.6196098757636461,
377
+ -0.7186613631319502,
378
+ 0.7186613631319502,
379
+ -0.8048884016188399,
380
+ 0.8048884016188399,
381
+ -0.8767523582704416,
382
+ 0.8767523582704416,
383
+ -0.9329710868260161,
384
+ 0.9329710868260161,
385
+ -0.9725424712181152,
386
+ 0.9725424712181152,
387
+ -0.9947693349975522,
388
+ 0.9947693349975522
389
+ ],
390
+ [
391
+ -0.06405689286260563,
392
+ 0.06405689286260563,
393
+ -0.1911188674736163,
394
+ 0.1911188674736163,
395
+ -0.3150426796961634,
396
+ 0.3150426796961634,
397
+ -0.4337935076260451,
398
+ 0.4337935076260451,
399
+ -0.5454214713888396,
400
+ 0.5454214713888396,
401
+ -0.6480936519369755,
402
+ 0.6480936519369755,
403
+ -0.7401241915785544,
404
+ 0.7401241915785544,
405
+ -0.820001985973903,
406
+ 0.820001985973903,
407
+ -0.8864155270044011,
408
+ 0.8864155270044011,
409
+ -0.9382745520027328,
410
+ 0.9382745520027328,
411
+ -0.9747285559713095,
412
+ 0.9747285559713095,
413
+ -0.9951872199970213,
414
+ 0.9951872199970213
415
+ ]
416
+ ];
417
+ var cValues = [
418
+ [],
419
+ [],
420
+ [1, 1],
421
+ [
422
+ 0.8888888888888888,
423
+ 0.5555555555555556,
424
+ 0.5555555555555556
425
+ ],
426
+ [
427
+ 0.6521451548625461,
428
+ 0.6521451548625461,
429
+ 0.34785484513745385,
430
+ 0.34785484513745385
431
+ ],
432
+ [
433
+ 0.5688888888888889,
434
+ 0.47862867049936647,
435
+ 0.47862867049936647,
436
+ 0.23692688505618908,
437
+ 0.23692688505618908
438
+ ],
439
+ [
440
+ 0.3607615730481386,
441
+ 0.3607615730481386,
442
+ 0.46791393457269104,
443
+ 0.46791393457269104,
444
+ 0.17132449237917036,
445
+ 0.17132449237917036
446
+ ],
447
+ [
448
+ 0.4179591836734694,
449
+ 0.3818300505051189,
450
+ 0.3818300505051189,
451
+ 0.27970539148927664,
452
+ 0.27970539148927664,
453
+ 0.1294849661688697,
454
+ 0.1294849661688697
455
+ ],
456
+ [
457
+ 0.362683783378362,
458
+ 0.362683783378362,
459
+ 0.31370664587788727,
460
+ 0.31370664587788727,
461
+ 0.22238103445337448,
462
+ 0.22238103445337448,
463
+ 0.10122853629037626,
464
+ 0.10122853629037626
465
+ ],
466
+ [
467
+ 0.3302393550012598,
468
+ 0.1806481606948574,
469
+ 0.1806481606948574,
470
+ 0.08127438836157441,
471
+ 0.08127438836157441,
472
+ 0.31234707704000286,
473
+ 0.31234707704000286,
474
+ 0.26061069640293544,
475
+ 0.26061069640293544
476
+ ],
477
+ [
478
+ 0.29552422471475287,
479
+ 0.29552422471475287,
480
+ 0.26926671930999635,
481
+ 0.26926671930999635,
482
+ 0.21908636251598204,
483
+ 0.21908636251598204,
484
+ 0.1494513491505806,
485
+ 0.1494513491505806,
486
+ 0.06667134430868814,
487
+ 0.06667134430868814
488
+ ],
489
+ [
490
+ 0.2729250867779006,
491
+ 0.26280454451024665,
492
+ 0.26280454451024665,
493
+ 0.23319376459199048,
494
+ 0.23319376459199048,
495
+ 0.18629021092773426,
496
+ 0.18629021092773426,
497
+ 0.1255803694649046,
498
+ 0.1255803694649046,
499
+ 0.05566856711617366,
500
+ 0.05566856711617366
501
+ ],
502
+ [
503
+ 0.24914704581340277,
504
+ 0.24914704581340277,
505
+ 0.2334925365383548,
506
+ 0.2334925365383548,
507
+ 0.20316742672306592,
508
+ 0.20316742672306592,
509
+ 0.16007832854334622,
510
+ 0.16007832854334622,
511
+ 0.10693932599531843,
512
+ 0.10693932599531843,
513
+ 0.04717533638651183,
514
+ 0.04717533638651183
515
+ ],
516
+ [
517
+ 0.2325515532308739,
518
+ 0.22628318026289723,
519
+ 0.22628318026289723,
520
+ 0.2078160475368885,
521
+ 0.2078160475368885,
522
+ 0.17814598076194574,
523
+ 0.17814598076194574,
524
+ 0.13887351021978725,
525
+ 0.13887351021978725,
526
+ 0.09212149983772845,
527
+ 0.09212149983772845,
528
+ 0.04048400476531588,
529
+ 0.04048400476531588
530
+ ],
531
+ [
532
+ 0.2152638534631578,
533
+ 0.2152638534631578,
534
+ 0.2051984637212956,
535
+ 0.2051984637212956,
536
+ 0.18553839747793782,
537
+ 0.18553839747793782,
538
+ 0.15720316715819355,
539
+ 0.15720316715819355,
540
+ 0.12151857068790319,
541
+ 0.12151857068790319,
542
+ 0.08015808715976021,
543
+ 0.08015808715976021,
544
+ 0.03511946033175186,
545
+ 0.03511946033175186
546
+ ],
547
+ [
548
+ 0.2025782419255613,
549
+ 0.19843148532711158,
550
+ 0.19843148532711158,
551
+ 0.1861610000155622,
552
+ 0.1861610000155622,
553
+ 0.16626920581699392,
554
+ 0.16626920581699392,
555
+ 0.13957067792615432,
556
+ 0.13957067792615432,
557
+ 0.10715922046717194,
558
+ 0.10715922046717194,
559
+ 0.07036604748810812,
560
+ 0.07036604748810812,
561
+ 0.03075324199611727,
562
+ 0.03075324199611727
563
+ ],
564
+ [
565
+ 0.1894506104550685,
566
+ 0.1894506104550685,
567
+ 0.18260341504492358,
568
+ 0.18260341504492358,
569
+ 0.16915651939500254,
570
+ 0.16915651939500254,
571
+ 0.14959598881657674,
572
+ 0.14959598881657674,
573
+ 0.12462897125553388,
574
+ 0.12462897125553388,
575
+ 0.09515851168249279,
576
+ 0.09515851168249279,
577
+ 0.062253523938647894,
578
+ 0.062253523938647894,
579
+ 0.027152459411754096,
580
+ 0.027152459411754096
581
+ ],
582
+ [
583
+ 0.17944647035620653,
584
+ 0.17656270536699264,
585
+ 0.17656270536699264,
586
+ 0.16800410215645004,
587
+ 0.16800410215645004,
588
+ 0.15404576107681028,
589
+ 0.15404576107681028,
590
+ 0.13513636846852548,
591
+ 0.13513636846852548,
592
+ 0.11188384719340397,
593
+ 0.11188384719340397,
594
+ 0.08503614831717918,
595
+ 0.08503614831717918,
596
+ 0.0554595293739872,
597
+ 0.0554595293739872,
598
+ 0.02414830286854793,
599
+ 0.02414830286854793
600
+ ],
601
+ [
602
+ 0.1691423829631436,
603
+ 0.1691423829631436,
604
+ 0.16427648374583273,
605
+ 0.16427648374583273,
606
+ 0.15468467512626524,
607
+ 0.15468467512626524,
608
+ 0.14064291467065065,
609
+ 0.14064291467065065,
610
+ 0.12255520671147846,
611
+ 0.12255520671147846,
612
+ 0.10094204410628717,
613
+ 0.10094204410628717,
614
+ 0.07642573025488905,
615
+ 0.07642573025488905,
616
+ 0.0497145488949698,
617
+ 0.0497145488949698,
618
+ 0.02161601352648331,
619
+ 0.02161601352648331
620
+ ],
621
+ [
622
+ 0.1610544498487837,
623
+ 0.15896884339395434,
624
+ 0.15896884339395434,
625
+ 0.15276604206585967,
626
+ 0.15276604206585967,
627
+ 0.1426067021736066,
628
+ 0.1426067021736066,
629
+ 0.12875396253933621,
630
+ 0.12875396253933621,
631
+ 0.11156664554733399,
632
+ 0.11156664554733399,
633
+ 0.09149002162245,
634
+ 0.09149002162245,
635
+ 0.06904454273764123,
636
+ 0.06904454273764123,
637
+ 0.0448142267656996,
638
+ 0.0448142267656996,
639
+ 0.019461788229726478,
640
+ 0.019461788229726478
641
+ ],
642
+ [
643
+ 0.15275338713072584,
644
+ 0.15275338713072584,
645
+ 0.14917298647260374,
646
+ 0.14917298647260374,
647
+ 0.14209610931838204,
648
+ 0.14209610931838204,
649
+ 0.13168863844917664,
650
+ 0.13168863844917664,
651
+ 0.11819453196151841,
652
+ 0.11819453196151841,
653
+ 0.10193011981724044,
654
+ 0.10193011981724044,
655
+ 0.08327674157670475,
656
+ 0.08327674157670475,
657
+ 0.06267204833410907,
658
+ 0.06267204833410907,
659
+ 0.04060142980038694,
660
+ 0.04060142980038694,
661
+ 0.017614007139152118,
662
+ 0.017614007139152118
663
+ ],
664
+ [
665
+ 0.14608113364969041,
666
+ 0.14452440398997005,
667
+ 0.14452440398997005,
668
+ 0.13988739479107315,
669
+ 0.13988739479107315,
670
+ 0.13226893863333747,
671
+ 0.13226893863333747,
672
+ 0.12183141605372853,
673
+ 0.12183141605372853,
674
+ 0.10879729916714838,
675
+ 0.10879729916714838,
676
+ 0.09344442345603386,
677
+ 0.09344442345603386,
678
+ 0.0761001136283793,
679
+ 0.0761001136283793,
680
+ 0.057134425426857205,
681
+ 0.057134425426857205,
682
+ 0.036953789770852494,
683
+ 0.036953789770852494,
684
+ 0.016017228257774335,
685
+ 0.016017228257774335
686
+ ],
687
+ [
688
+ 0.13925187285563198,
689
+ 0.13925187285563198,
690
+ 0.13654149834601517,
691
+ 0.13654149834601517,
692
+ 0.13117350478706238,
693
+ 0.13117350478706238,
694
+ 0.12325237681051242,
695
+ 0.12325237681051242,
696
+ 0.11293229608053922,
697
+ 0.11293229608053922,
698
+ 0.10041414444288096,
699
+ 0.10041414444288096,
700
+ 0.08594160621706773,
701
+ 0.08594160621706773,
702
+ 0.06979646842452049,
703
+ 0.06979646842452049,
704
+ 0.052293335152683286,
705
+ 0.052293335152683286,
706
+ 0.03377490158481415,
707
+ 0.03377490158481415,
708
+ 0.0146279952982722,
709
+ 0.0146279952982722
710
+ ],
711
+ [
712
+ 0.13365457218610619,
713
+ 0.1324620394046966,
714
+ 0.1324620394046966,
715
+ 0.12890572218808216,
716
+ 0.12890572218808216,
717
+ 0.12304908430672953,
718
+ 0.12304908430672953,
719
+ 0.11499664022241136,
720
+ 0.11499664022241136,
721
+ 0.10489209146454141,
722
+ 0.10489209146454141,
723
+ 0.09291576606003515,
724
+ 0.09291576606003515,
725
+ 0.07928141177671895,
726
+ 0.07928141177671895,
727
+ 0.06423242140852585,
728
+ 0.06423242140852585,
729
+ 0.04803767173108467,
730
+ 0.04803767173108467,
731
+ 0.030988005856979445,
732
+ 0.030988005856979445,
733
+ 0.013411859487141771,
734
+ 0.013411859487141771
735
+ ],
736
+ [
737
+ 0.12793819534675216,
738
+ 0.12793819534675216,
739
+ 0.1258374563468283,
740
+ 0.1258374563468283,
741
+ 0.12167047292780339,
742
+ 0.12167047292780339,
743
+ 0.1155056680537256,
744
+ 0.1155056680537256,
745
+ 0.10744427011596563,
746
+ 0.10744427011596563,
747
+ 0.09761865210411388,
748
+ 0.09761865210411388,
749
+ 0.08619016153195327,
750
+ 0.08619016153195327,
751
+ 0.0733464814110803,
752
+ 0.0733464814110803,
753
+ 0.05929858491543678,
754
+ 0.05929858491543678,
755
+ 0.04427743881741981,
756
+ 0.04427743881741981,
757
+ 0.028531388628933663,
758
+ 0.028531388628933663,
759
+ 0.0123412297999872,
760
+ 0.0123412297999872
761
+ ]
762
+ ];
763
+ var binomialCoefficients = [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]];
764
+
765
+ // src/helpers/bezier-functions.ts
766
+ var cubicPoint = (xs, ys, t) => {
767
+ const x = (1 - t) * (1 - t) * (1 - t) * xs[0] + 3 * (1 - t) * (1 - t) * t * xs[1] + 3 * (1 - t) * t * t * xs[2] + t * t * t * xs[3];
768
+ const y = (1 - t) * (1 - t) * (1 - t) * ys[0] + 3 * (1 - t) * (1 - t) * t * ys[1] + 3 * (1 - t) * t * t * ys[2] + t * t * t * ys[3];
769
+ return { x, y };
770
+ };
771
+ var getDerivative = (derivative, t, vs) => {
772
+ const n = vs.length - 1;
773
+ let value;
774
+ if (n === 0) {
775
+ return 0;
776
+ }
777
+ if (derivative === 0) {
778
+ value = 0;
779
+ for (let k = 0;k <= n; k++) {
780
+ value += binomialCoefficients[n][k] * (1 - t) ** (n - k) * t ** k * vs[k];
781
+ }
782
+ return value;
783
+ }
784
+ const _vs = new Array(n);
785
+ for (let k = 0;k < n; k++) {
786
+ _vs[k] = n * (vs[k + 1] - vs[k]);
787
+ }
788
+ return getDerivative(derivative - 1, t, _vs);
789
+ };
790
+ function bFunc(xs, ys, t) {
791
+ const xbase = getDerivative(1, t, xs);
792
+ const ybase = getDerivative(1, t, ys);
793
+ const combined = xbase * xbase + ybase * ybase;
794
+ return Math.sqrt(combined);
795
+ }
796
+ var getCubicArcLength = ({
797
+ sx,
798
+ sy,
799
+ t
800
+ }) => {
801
+ let correctedT;
802
+ const n = 20;
803
+ const z = t / 2;
804
+ let sum = 0;
805
+ for (let i = 0;i < n; i++) {
806
+ correctedT = z * tValues[n][i] + z;
807
+ sum += cValues[n][i] * bFunc(sx, sy, correctedT);
808
+ }
809
+ return z * sum;
810
+ };
811
+ var quadraticPoint = (xs, ys, t) => {
812
+ const x = (1 - t) * (1 - t) * xs[0] + 2 * (1 - t) * t * xs[1] + t * t * xs[2];
813
+ const y = (1 - t) * (1 - t) * ys[0] + 2 * (1 - t) * t * ys[1] + t * t * ys[2];
814
+ return { x, y };
815
+ };
816
+ var cubicDerivative = (xs, ys, t) => {
817
+ const derivative = quadraticPoint([3 * (xs[1] - xs[0]), 3 * (xs[2] - xs[1]), 3 * (xs[3] - xs[2])], [3 * (ys[1] - ys[0]), 3 * (ys[2] - ys[1]), 3 * (ys[3] - ys[2])], t);
818
+ return derivative;
819
+ };
820
+ var getQuadraticArcLength = (xs, ys, t) => {
821
+ if (t === undefined) {
822
+ t = 1;
823
+ }
824
+ const ax = xs[0] - 2 * xs[1] + xs[2];
825
+ const ay = ys[0] - 2 * ys[1] + ys[2];
826
+ const bx = 2 * xs[1] - 2 * xs[0];
827
+ const by = 2 * ys[1] - 2 * ys[0];
828
+ const A = 4 * (ax * ax + ay * ay);
829
+ const B = 4 * (ax * bx + ay * by);
830
+ const C = bx * bx + by * by;
831
+ if (A === 0) {
832
+ return t * Math.sqrt((xs[2] - xs[0]) ** 2 + (ys[2] - ys[0]) ** 2);
833
+ }
834
+ const b = B / (2 * A);
835
+ const c = C / A;
836
+ const u = t + b;
837
+ const k = c - b * b;
838
+ const uuk = u * u + k > 0 ? Math.sqrt(u * u + k) : 0;
839
+ const bbk = b * b + k > 0 ? Math.sqrt(b * b + k) : 0;
840
+ const term = b + Math.sqrt(b * b + k) === 0 ? 0 : k * Math.log(Math.abs((u + uuk) / (b + bbk)));
841
+ return Math.sqrt(A) / 2 * (u * uuk - b * bbk + term);
842
+ };
843
+ var quadraticDerivative = (xs, ys, t) => {
844
+ return {
845
+ x: (1 - t) * 2 * (xs[1] - xs[0]) + t * 2 * (xs[2] - xs[1]),
846
+ y: (1 - t) * 2 * (ys[1] - ys[0]) + t * 2 * (ys[2] - ys[1])
847
+ };
848
+ };
849
+ var t2length = ({
850
+ length,
851
+ totalLength,
852
+ func
853
+ }) => {
854
+ let error = 1;
855
+ let t = length / totalLength;
856
+ let step = (length - func(t)) / totalLength;
857
+ let numIterations = 0;
858
+ while (error > 0.001) {
859
+ const increasedTLength = func(t + step);
860
+ const increasedTError = Math.abs(length - increasedTLength) / totalLength;
861
+ if (increasedTError < error) {
862
+ error = increasedTError;
863
+ t += step;
864
+ } else {
865
+ const decreasedTLength = func(t - step);
866
+ const decreasedTError = Math.abs(length - decreasedTLength) / totalLength;
867
+ if (decreasedTError < error) {
868
+ error = decreasedTError;
869
+ t -= step;
870
+ } else {
871
+ step /= 2;
872
+ }
873
+ }
874
+ numIterations++;
875
+ if (numIterations > 500) {
876
+ break;
877
+ }
878
+ }
879
+ return t;
880
+ };
881
+
882
+ // src/helpers/bezier.ts
883
+ var makeQuadratic = ({
884
+ startX,
885
+ startY,
886
+ cpx,
887
+ cpy,
888
+ x,
889
+ y
890
+ }) => {
891
+ const a = { x: startX, y: startY };
892
+ const b = { x: cpx, y: cpy };
893
+ const c = { x, y };
894
+ const length = getQuadraticArcLength([a.x, b.x, c.x, 0], [a.y, b.y, c.y, 0], 1);
895
+ const getTotalLength = () => {
896
+ return length;
897
+ };
898
+ const getPointAtLength = (len) => {
899
+ const xs = [a.x, b.x, c.x, 0];
900
+ const xy = [a.y, b.y, c.y, 0];
901
+ const t = t2length({
902
+ length: len,
903
+ totalLength: length,
904
+ func: (i) => getQuadraticArcLength(xs, xy, i)
905
+ });
906
+ return quadraticPoint(xs, xy, t);
907
+ };
908
+ const getTangentAtLength = (len) => {
909
+ const xs = [a.x, b.x, c.x, 0];
910
+ const xy = [a.y, b.y, c.y, 0];
911
+ const t = t2length({
912
+ length: len,
913
+ totalLength: length,
914
+ func: (i) => getQuadraticArcLength(xs, xy, i)
915
+ });
916
+ const derivative = quadraticDerivative(xs, xy, t);
917
+ const mdl = Math.sqrt(derivative.x * derivative.x + derivative.y * derivative.y);
918
+ let tangent;
919
+ if (mdl > 0) {
920
+ tangent = { x: derivative.x / mdl, y: derivative.y / mdl };
921
+ } else {
922
+ tangent = { x: 0, y: 0 };
923
+ }
924
+ return tangent;
925
+ };
926
+ const getC = () => {
927
+ return c;
928
+ };
929
+ return {
930
+ getPointAtLength,
931
+ getTangentAtLength,
932
+ getTotalLength,
933
+ getC,
934
+ type: "quadratic-bezier",
935
+ getD: () => ({ x: 0, y: 0 })
936
+ };
937
+ };
938
+ var makeCubic = ({
939
+ startX,
940
+ startY,
941
+ cp1x,
942
+ cp1y,
943
+ cp2x,
944
+ cp2y,
945
+ x,
946
+ y
947
+ }) => {
948
+ const a = { x: startX, y: startY };
949
+ const b = { x: cp1x, y: cp1y };
950
+ const c = { x: cp2x, y: cp2y };
951
+ const d = { x, y };
952
+ const length = getCubicArcLength({
953
+ sx: [a.x, b.x, c.x, d.x],
954
+ sy: [a.y, b.y, c.y, d.y],
955
+ t: 1
956
+ });
957
+ const getTotalLength = () => {
958
+ return length;
959
+ };
960
+ const getPointAtLength = (len) => {
961
+ const sx = [a.x, b.x, c.x, d.x];
962
+ const sy = [a.y, b.y, c.y, d.y];
963
+ const t = t2length({
964
+ length: len,
965
+ totalLength: length,
966
+ func: (i) => {
967
+ return getCubicArcLength({ sx, sy, t: i });
968
+ }
969
+ });
970
+ return cubicPoint(sx, sy, t);
971
+ };
972
+ const getTangentAtLength = (len) => {
973
+ const xs = [a.x, b.x, c.x, d.x];
974
+ const xy = [a.y, b.y, c.y, d.y];
975
+ const t = t2length({
976
+ length: len,
977
+ totalLength: length,
978
+ func: (i) => getCubicArcLength({ sx: xs, sy: xy, t: i })
979
+ });
980
+ const derivative = cubicDerivative(xs, xy, t);
981
+ const mdl = Math.sqrt(derivative.x * derivative.x + derivative.y * derivative.y);
982
+ let tangent;
983
+ if (mdl > 0) {
984
+ tangent = { x: derivative.x / mdl, y: derivative.y / mdl };
985
+ } else {
986
+ tangent = { x: 0, y: 0 };
987
+ }
988
+ return tangent;
989
+ };
990
+ const getC = () => {
991
+ return c;
992
+ };
993
+ const getD = () => {
994
+ return d;
995
+ };
996
+ return {
997
+ getPointAtLength,
998
+ getTangentAtLength,
999
+ getTotalLength,
1000
+ getC,
1001
+ getD,
1002
+ type: "cubic-bezier"
1003
+ };
1004
+ };
1005
+
1006
+ // src/helpers/linear.ts
1007
+ var makeLinearPosition = ({
1008
+ x0,
1009
+ x1,
1010
+ y0,
1011
+ y1
1012
+ }) => {
1013
+ return {
1014
+ getTotalLength: () => {
1015
+ return Math.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2);
1016
+ },
1017
+ getPointAtLength: (pos) => {
1018
+ let fraction = pos / Math.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2);
1019
+ fraction = Number.isNaN(fraction) ? 1 : fraction;
1020
+ const newDeltaX = (x1 - x0) * fraction;
1021
+ const newDeltaY = (y1 - y0) * fraction;
1022
+ return { x: x0 + newDeltaX, y: y0 + newDeltaY };
1023
+ },
1024
+ getTangentAtLength: () => {
1025
+ const module = Math.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
1026
+ return { x: (x1 - x0) / module, y: (y1 - y0) / module };
1027
+ },
1028
+ type: "linear"
1029
+ };
1030
+ };
1031
+
1032
+ // src/helpers/reduced-analysis.ts
1033
+ var conductAnalysis = (instructions) => {
1034
+ let currentPoint = { x: 0, y: 0 };
1035
+ let moveStart = { x: 0, y: 0 };
1036
+ const segments = [];
1037
+ for (let i = 0;i < instructions.length; i++) {
1038
+ const instruction = instructions[i];
1039
+ if (instruction.type === "M") {
1040
+ currentPoint = { x: instruction.x, y: instruction.y };
1041
+ moveStart = { x: currentPoint.x, y: currentPoint.y };
1042
+ segments.push({
1043
+ startPoint: { x: instruction.x, y: instruction.y },
1044
+ instructionsAndInfo: [
1045
+ {
1046
+ instruction,
1047
+ function: null,
1048
+ length: 0,
1049
+ startPoint: currentPoint
1050
+ }
1051
+ ]
1052
+ });
1053
+ }
1054
+ if (instruction.type === "L") {
1055
+ if (segments.length > 0) {
1056
+ const length = Math.sqrt((currentPoint.x - instruction.x) ** 2 + (currentPoint.y - instruction.y) ** 2);
1057
+ segments[segments.length - 1].instructionsAndInfo.push({
1058
+ instruction,
1059
+ length,
1060
+ function: makeLinearPosition({
1061
+ x0: currentPoint.x,
1062
+ x1: instruction.x,
1063
+ y0: currentPoint.y,
1064
+ y1: instruction.y
1065
+ }),
1066
+ startPoint: currentPoint
1067
+ });
1068
+ }
1069
+ currentPoint = { x: instruction.x, y: instruction.y };
1070
+ }
1071
+ if (instruction.type === "Z") {
1072
+ if (segments.length > 0) {
1073
+ const length = Math.sqrt((segments[segments.length - 1].startPoint.x - currentPoint.x) ** 2 + (segments[segments.length - 1].startPoint.y - currentPoint.y) ** 2);
1074
+ segments[segments.length - 1].instructionsAndInfo.push({
1075
+ instruction,
1076
+ function: makeLinearPosition({
1077
+ x0: currentPoint.x,
1078
+ x1: moveStart.x,
1079
+ y0: currentPoint.y,
1080
+ y1: moveStart.y
1081
+ }),
1082
+ length,
1083
+ startPoint: { ...currentPoint }
1084
+ });
1085
+ }
1086
+ currentPoint = { x: moveStart.x, y: moveStart.y };
1087
+ }
1088
+ if (instruction.type === "C") {
1089
+ const curve = makeCubic({
1090
+ startX: currentPoint.x,
1091
+ startY: currentPoint.y,
1092
+ cp1x: instruction.cp1x,
1093
+ cp1y: instruction.cp1y,
1094
+ cp2x: instruction.cp2x,
1095
+ cp2y: instruction.cp2y,
1096
+ x: instruction.x,
1097
+ y: instruction.y
1098
+ });
1099
+ const length = curve.getTotalLength();
1100
+ if (segments.length > 0) {
1101
+ segments[segments.length - 1].instructionsAndInfo.push({
1102
+ instruction,
1103
+ length,
1104
+ function: curve,
1105
+ startPoint: { ...currentPoint }
1106
+ });
1107
+ }
1108
+ currentPoint = { x: instruction.x, y: instruction.y };
1109
+ }
1110
+ }
1111
+ return segments;
1112
+ };
1113
+
1114
+ // src/parse-path.ts
1115
+ var length = {
1116
+ a: 7,
1117
+ A: 7,
1118
+ C: 6,
1119
+ c: 6,
1120
+ H: 1,
1121
+ h: 1,
1122
+ L: 2,
1123
+ l: 2,
1124
+ M: 2,
1125
+ m: 2,
1126
+ Q: 4,
1127
+ q: 4,
1128
+ S: 4,
1129
+ s: 4,
1130
+ T: 2,
1131
+ t: 2,
1132
+ V: 1,
1133
+ v: 1,
1134
+ Z: 0,
1135
+ z: 0
1136
+ };
1137
+ var chunkExact = (array, instruction) => {
1138
+ const chunks = [];
1139
+ const expectedSize = length[instruction];
1140
+ if (array.length % expectedSize !== 0) {
1141
+ throw new Error(`Expected number of arguments of SVG instruction "${instruction} ${array.join(" ")}" to be a multiple of ${expectedSize}`);
1142
+ }
1143
+ for (let i = 0;i < array.length; i += expectedSize) {
1144
+ chunks.push(array.slice(i, i + expectedSize));
1145
+ }
1146
+ return chunks;
1147
+ };
1148
+ var makeInstructions = (arr, instruction, cb) => {
1149
+ return chunkExact(arr, instruction).map((args) => {
1150
+ return cb(args);
1151
+ });
1152
+ };
1153
+ var segmentRegExp = /([astvzqmhlc])([^astvzqmhlc]*)/gi;
1154
+ var numberRegExp = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi;
1155
+ var parseValues = (args, instructionType) => {
1156
+ const numbers = args.match(numberRegExp);
1157
+ if (!numbers) {
1158
+ if (instructionType === "Z" || instructionType === "z") {
1159
+ return [];
1160
+ }
1161
+ throw new Error(`Malformed path data: ${instructionType} was expected to have numbers afterwards`);
1162
+ }
1163
+ const expectedArguments = length[instructionType];
1164
+ if (numbers.length % expectedArguments !== 0) {
1165
+ throw new Error(`Malformed path data: ${instructionType} was expected to have a multiple of ${expectedArguments} numbers, but got "${instructionType} ${numbers.join(" ")} instead"`);
1166
+ }
1167
+ return numbers.map(Number);
1168
+ };
1169
+ var parsePath = (path) => {
1170
+ if (!path) {
1171
+ throw new Error("No path provided");
1172
+ }
1173
+ const segments = path.match(segmentRegExp);
1174
+ if (!segments) {
1175
+ throw new Error(`No path elements found in string ${path}`);
1176
+ }
1177
+ return segments.map((segmentString) => {
1178
+ const command = segmentString.charAt(0);
1179
+ const args = parseValues(segmentString.substring(1), command);
1180
+ if (command === "M" && args.length > 2) {
1181
+ const segmentsArray = [];
1182
+ segmentsArray.push({
1183
+ type: command,
1184
+ x: args[0],
1185
+ y: args[1]
1186
+ });
1187
+ segmentsArray.push(...makeInstructions(args.slice(2), "L", (numbers) => ({
1188
+ type: "L",
1189
+ x: numbers[0],
1190
+ y: numbers[1]
1191
+ })));
1192
+ return segmentsArray;
1193
+ }
1194
+ if (command === "m" && args.length > 2) {
1195
+ const segmentsArray = [];
1196
+ segmentsArray.push({
1197
+ type: command,
1198
+ dx: args[0],
1199
+ dy: args[1]
1200
+ });
1201
+ segmentsArray.push(...makeInstructions(args.slice(2), "l", (numbers) => ({
1202
+ type: "l",
1203
+ dx: numbers[0],
1204
+ dy: numbers[1]
1205
+ })));
1206
+ return segmentsArray;
1207
+ }
1208
+ if (command === "Z" || command === "z") {
1209
+ return [
1210
+ {
1211
+ type: "Z"
1212
+ }
1213
+ ];
1214
+ }
1215
+ if (command === "A") {
1216
+ return makeInstructions(args, command, (numbers) => ({
1217
+ type: command,
1218
+ rx: numbers[0],
1219
+ ry: numbers[1],
1220
+ xAxisRotation: numbers[2],
1221
+ largeArcFlag: numbers[3] === 1,
1222
+ sweepFlag: numbers[4] === 1,
1223
+ x: numbers[5],
1224
+ y: numbers[6]
1225
+ }));
1226
+ }
1227
+ if (command === "a") {
1228
+ return makeInstructions(args, command, (numbers) => ({
1229
+ type: command,
1230
+ rx: numbers[0],
1231
+ ry: numbers[1],
1232
+ xAxisRotation: numbers[2],
1233
+ largeArcFlag: numbers[3] === 1,
1234
+ sweepFlag: numbers[4] === 1,
1235
+ dx: numbers[5],
1236
+ dy: numbers[6]
1237
+ }));
1238
+ }
1239
+ if (command === "C") {
1240
+ return makeInstructions(args, command, (numbers) => ({
1241
+ type: command,
1242
+ cp1x: numbers[0],
1243
+ cp1y: numbers[1],
1244
+ cp2x: numbers[2],
1245
+ cp2y: numbers[3],
1246
+ x: numbers[4],
1247
+ y: numbers[5]
1248
+ }));
1249
+ }
1250
+ if (command === "c") {
1251
+ return makeInstructions(args, command, (numbers) => ({
1252
+ type: command,
1253
+ cp1dx: numbers[0],
1254
+ cp1dy: numbers[1],
1255
+ cp2dx: numbers[2],
1256
+ cp2dy: numbers[3],
1257
+ dx: numbers[4],
1258
+ dy: numbers[5]
1259
+ }));
1260
+ }
1261
+ if (command === "S") {
1262
+ return makeInstructions(args, command, (numbers) => ({
1263
+ type: command,
1264
+ cpx: numbers[0],
1265
+ cpy: numbers[1],
1266
+ x: numbers[2],
1267
+ y: numbers[3]
1268
+ }));
1269
+ }
1270
+ if (command === "s") {
1271
+ return makeInstructions(args, command, (numbers) => ({
1272
+ type: command,
1273
+ cpdx: numbers[0],
1274
+ cpdy: numbers[1],
1275
+ dx: numbers[2],
1276
+ dy: numbers[3]
1277
+ }));
1278
+ }
1279
+ if (command === "H") {
1280
+ return makeInstructions(args, command, (numbers) => ({
1281
+ type: command,
1282
+ x: numbers[0]
1283
+ }));
1284
+ }
1285
+ if (command === "h") {
1286
+ return makeInstructions(args, command, (numbers) => ({
1287
+ type: command,
1288
+ dx: numbers[0]
1289
+ }));
1290
+ }
1291
+ if (command === "V") {
1292
+ return makeInstructions(args, command, (numbers) => ({
1293
+ type: command,
1294
+ y: numbers[0]
1295
+ }));
1296
+ }
1297
+ if (command === "v") {
1298
+ return makeInstructions(args, command, (numbers) => ({
1299
+ type: command,
1300
+ dy: numbers[0]
1301
+ }));
1302
+ }
1303
+ if (command === "L") {
1304
+ return makeInstructions(args, command, (numbers) => ({
1305
+ type: command,
1306
+ x: numbers[0],
1307
+ y: numbers[1]
1308
+ }));
1309
+ }
1310
+ if (command === "M") {
1311
+ return makeInstructions(args, command, (numbers) => ({
1312
+ type: command,
1313
+ x: numbers[0],
1314
+ y: numbers[1]
1315
+ }));
1316
+ }
1317
+ if (command === "m") {
1318
+ return makeInstructions(args, command, (numbers) => ({
1319
+ type: command,
1320
+ dx: numbers[0],
1321
+ dy: numbers[1]
1322
+ }));
1323
+ }
1324
+ if (command === "l") {
1325
+ return makeInstructions(args, command, (numbers) => ({
1326
+ type: command,
1327
+ dx: numbers[0],
1328
+ dy: numbers[1]
1329
+ }));
1330
+ }
1331
+ if (command === "Q") {
1332
+ return makeInstructions(args, command, (numbers) => ({
1333
+ type: command,
1334
+ cpx: numbers[0],
1335
+ cpy: numbers[1],
1336
+ x: numbers[2],
1337
+ y: numbers[3]
1338
+ }));
1339
+ }
1340
+ if (command === "q") {
1341
+ return makeInstructions(args, command, (numbers) => ({
1342
+ type: command,
1343
+ cpdx: numbers[0],
1344
+ cpdy: numbers[1],
1345
+ dx: numbers[2],
1346
+ dy: numbers[3]
1347
+ }));
1348
+ }
1349
+ if (command === "T") {
1350
+ return makeInstructions(args, command, (numbers) => ({
1351
+ type: command,
1352
+ x: numbers[0],
1353
+ y: numbers[1]
1354
+ }));
1355
+ }
1356
+ if (command === "t") {
1357
+ return makeInstructions(args, command, (numbers) => ({
1358
+ type: command,
1359
+ dx: numbers[0],
1360
+ dy: numbers[1]
1361
+ }));
1362
+ }
1363
+ throw new Error(`Invalid path element ${segmentString}`);
1364
+ }, []).flat(1);
1365
+ };
1366
+
1367
+ // src/helpers/convert-q-to-c-instruction.ts
1368
+ var convertQToCInstruction = (instruction, startPoint) => {
1369
+ const cp1x = startPoint.x + 2 / 3 * (instruction.cpx - startPoint.x);
1370
+ const cp1y = startPoint.y + 2 / 3 * (instruction.cpy - startPoint.y);
1371
+ const cp2x = instruction.x + 2 / 3 * (instruction.cpx - instruction.x);
1372
+ const cp2y = instruction.y + 2 / 3 * (instruction.cpy - instruction.y);
1373
+ return {
1374
+ type: "C",
1375
+ cp1x,
1376
+ cp1y,
1377
+ cp2x,
1378
+ cp2y,
1379
+ x: instruction.x,
1380
+ y: instruction.y
1381
+ };
1382
+ };
1383
+
1384
+ // src/helpers/iterate.ts
1385
+ var iterateOverSegments = ({
1386
+ segments,
1387
+ iterate
1388
+ }) => {
1389
+ let x = 0;
1390
+ let y = 0;
1391
+ let initialX = 0;
1392
+ let initialY = 0;
1393
+ let cpX = null;
1394
+ let cpY = null;
1395
+ const newSegments = segments.map((s, i) => {
1396
+ const newSeg = iterate({
1397
+ segment: s,
1398
+ x,
1399
+ y,
1400
+ prevSegment: segments[i - 1] ?? null,
1401
+ initialX,
1402
+ initialY,
1403
+ cpX,
1404
+ cpY
1405
+ });
1406
+ switch (s.type) {
1407
+ case "M":
1408
+ initialX = s.x;
1409
+ initialY = s.y;
1410
+ x = s.x;
1411
+ y = s.y;
1412
+ cpX = null;
1413
+ cpY = null;
1414
+ break;
1415
+ case "Q":
1416
+ x = s.x;
1417
+ y = s.y;
1418
+ cpX = s.cpx;
1419
+ cpY = s.cpy;
1420
+ break;
1421
+ case "A":
1422
+ x = s.x;
1423
+ y = s.y;
1424
+ cpX = null;
1425
+ cpY = null;
1426
+ break;
1427
+ case "C":
1428
+ x = s.x;
1429
+ y = s.y;
1430
+ cpX = s.cp2x;
1431
+ cpY = s.cp2y;
1432
+ break;
1433
+ case "S":
1434
+ x = s.x;
1435
+ y = s.y;
1436
+ cpX = s.cpx;
1437
+ cpY = s.cpy;
1438
+ break;
1439
+ case "T":
1440
+ if (cpX !== null && cpY !== null) {
1441
+ cpX = x - (cpX - x);
1442
+ cpY = y - (cpY - y);
1443
+ }
1444
+ x = s.x;
1445
+ y = s.y;
1446
+ break;
1447
+ case "L":
1448
+ x = s.x;
1449
+ y = s.y;
1450
+ cpX = null;
1451
+ cpY = null;
1452
+ break;
1453
+ case "V":
1454
+ y = s.y;
1455
+ cpX = null;
1456
+ cpY = null;
1457
+ break;
1458
+ case "H":
1459
+ x = s.x;
1460
+ cpX = null;
1461
+ cpY = null;
1462
+ break;
1463
+ case "Z":
1464
+ x = initialX;
1465
+ y = initialY;
1466
+ cpX = null;
1467
+ cpY = null;
1468
+ break;
1469
+ default:
1470
+ throw new Error(`Unexpected instruction ${s.type}`);
1471
+ }
1472
+ return newSeg;
1473
+ });
1474
+ return newSegments.flat(1);
1475
+ };
1476
+
1477
+ // src/helpers/remove-a-s-t-curves.ts
1478
+ var TAU = Math.PI * 2;
1479
+ function approximate_unit_arc(theta1, delta_theta) {
1480
+ const alpha = 4 / 3 * Math.tan(delta_theta / 4);
1481
+ const x1 = Math.cos(theta1);
1482
+ const y1 = Math.sin(theta1);
1483
+ const x2 = Math.cos(theta1 + delta_theta);
1484
+ const y2 = Math.sin(theta1 + delta_theta);
1485
+ return [
1486
+ x1,
1487
+ y1,
1488
+ x1 - y1 * alpha,
1489
+ y1 + x1 * alpha,
1490
+ x2 + y2 * alpha,
1491
+ y2 - x2 * alpha,
1492
+ x2,
1493
+ y2
1494
+ ];
1495
+ }
1496
+ function unit_vector_angle(ux, uy, vx, vy) {
1497
+ const sign = ux * vy - uy * vx < 0 ? -1 : 1;
1498
+ let dot = ux * vx + uy * vy;
1499
+ if (dot > 1) {
1500
+ dot = 1;
1501
+ }
1502
+ if (dot < -1) {
1503
+ dot = -1;
1504
+ }
1505
+ return sign * Math.acos(dot);
1506
+ }
1507
+ function get_arc_center({
1508
+ x1,
1509
+ y1,
1510
+ x2,
1511
+ y2,
1512
+ largeArcFlag,
1513
+ sweepFlag,
1514
+ rx,
1515
+ ry,
1516
+ sin_phi,
1517
+ cos_phi
1518
+ }) {
1519
+ const x1p = cos_phi * (x1 - x2) / 2 + sin_phi * (y1 - y2) / 2;
1520
+ const y1p = -sin_phi * (x1 - x2) / 2 + cos_phi * (y1 - y2) / 2;
1521
+ const rx_sq = rx * rx;
1522
+ const ry_sq = ry * ry;
1523
+ const x1p_sq = x1p * x1p;
1524
+ const y1p_sq = y1p * y1p;
1525
+ let radicant = rx_sq * ry_sq - rx_sq * y1p_sq - ry_sq * x1p_sq;
1526
+ if (radicant < 0) {
1527
+ radicant = 0;
1528
+ }
1529
+ radicant /= rx_sq * y1p_sq + ry_sq * x1p_sq;
1530
+ radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1);
1531
+ const cxp = radicant * rx / ry * y1p;
1532
+ const cyp = radicant * -ry / rx * x1p;
1533
+ const cx = cos_phi * cxp - sin_phi * cyp + (x1 + x2) / 2;
1534
+ const cy = sin_phi * cxp + cos_phi * cyp + (y1 + y2) / 2;
1535
+ const v1x = (x1p - cxp) / rx;
1536
+ const v1y = (y1p - cyp) / ry;
1537
+ const v2x = (-x1p - cxp) / rx;
1538
+ const v2y = (-y1p - cyp) / ry;
1539
+ const theta1 = unit_vector_angle(1, 0, v1x, v1y);
1540
+ let delta_theta = unit_vector_angle(v1x, v1y, v2x, v2y);
1541
+ if (sweepFlag === false && delta_theta > 0) {
1542
+ delta_theta -= TAU;
1543
+ }
1544
+ if (sweepFlag === true && delta_theta < 0) {
1545
+ delta_theta += TAU;
1546
+ }
1547
+ return [cx, cy, theta1, delta_theta];
1548
+ }
1549
+ function arcToCircle({
1550
+ x1,
1551
+ y1,
1552
+ x2,
1553
+ y2,
1554
+ largeArcFlag,
1555
+ sweepFlag,
1556
+ rx,
1557
+ ry,
1558
+ phi
1559
+ }) {
1560
+ const sin_phi = Math.sin(phi * TAU / 360);
1561
+ const cos_phi = Math.cos(phi * TAU / 360);
1562
+ const x1p = cos_phi * (x1 - x2) / 2 + sin_phi * (y1 - y2) / 2;
1563
+ const y1p = -sin_phi * (x1 - x2) / 2 + cos_phi * (y1 - y2) / 2;
1564
+ if (x1p === 0 && y1p === 0) {
1565
+ return [];
1566
+ }
1567
+ if (rx === 0 || ry === 0) {
1568
+ return [];
1569
+ }
1570
+ rx = Math.abs(rx);
1571
+ ry = Math.abs(ry);
1572
+ const lambda = x1p * x1p / (rx * rx) + y1p * y1p / (ry * ry);
1573
+ if (lambda > 1) {
1574
+ rx *= Math.sqrt(lambda);
1575
+ ry *= Math.sqrt(lambda);
1576
+ }
1577
+ const cc = get_arc_center({
1578
+ x1,
1579
+ y1,
1580
+ x2,
1581
+ y2,
1582
+ largeArcFlag,
1583
+ sweepFlag,
1584
+ rx,
1585
+ ry,
1586
+ sin_phi,
1587
+ cos_phi
1588
+ });
1589
+ const result = [];
1590
+ let theta1 = cc[2];
1591
+ let delta_theta = cc[3];
1592
+ const segments = Math.max(Math.ceil(Math.abs(delta_theta) / (TAU / 4)), 1);
1593
+ delta_theta /= segments;
1594
+ for (let i = 0;i < segments; i++) {
1595
+ result.push(approximate_unit_arc(theta1, delta_theta));
1596
+ theta1 += delta_theta;
1597
+ }
1598
+ return result.map((curve) => {
1599
+ for (let i = 0;i < curve.length; i += 2) {
1600
+ let x = curve[i + 0];
1601
+ let y = curve[i + 1];
1602
+ x *= rx;
1603
+ y *= ry;
1604
+ const xp = cos_phi * x - sin_phi * y;
1605
+ const yp = sin_phi * x + cos_phi * y;
1606
+ curve[i + 0] = xp + cc[0];
1607
+ curve[i + 1] = yp + cc[1];
1608
+ }
1609
+ return curve;
1610
+ });
1611
+ }
1612
+ var removeATSHVQInstructions = (segments) => {
1613
+ return iterateOverSegments({
1614
+ segments,
1615
+ iterate: ({ segment, prevSegment, x, y, cpX, cpY }) => {
1616
+ if (segment.type === "H") {
1617
+ return [{ type: "L", x: segment.x, y }];
1618
+ }
1619
+ if (segment.type === "V") {
1620
+ return [{ type: "L", x, y: segment.y }];
1621
+ }
1622
+ if (segment.type === "A") {
1623
+ const nextX = segment.x;
1624
+ const nextY = segment.y;
1625
+ const new_segments = arcToCircle({
1626
+ x1: x,
1627
+ y1: y,
1628
+ x2: nextX,
1629
+ y2: nextY,
1630
+ largeArcFlag: segment.largeArcFlag,
1631
+ sweepFlag: segment.sweepFlag,
1632
+ rx: segment.rx,
1633
+ ry: segment.ry,
1634
+ phi: segment.xAxisRotation
1635
+ });
1636
+ if (new_segments.length === 0) {
1637
+ return [
1638
+ {
1639
+ type: "L",
1640
+ x: segment.x,
1641
+ y: segment.y
1642
+ }
1643
+ ];
1644
+ }
1645
+ const result = new_segments.map((_s) => {
1646
+ return {
1647
+ type: "C",
1648
+ cp1x: _s[2],
1649
+ cp1y: _s[3],
1650
+ cp2x: _s[4],
1651
+ cp2y: _s[5],
1652
+ x: _s[6],
1653
+ y: _s[7]
1654
+ };
1655
+ });
1656
+ return result;
1657
+ }
1658
+ if (segment.type === "T") {
1659
+ let prevControlX = 0;
1660
+ let prevControlY = 0;
1661
+ if (prevSegment && (prevSegment.type === "Q" || prevSegment.type === "T")) {
1662
+ prevControlX = cpX;
1663
+ prevControlY = cpY;
1664
+ } else {
1665
+ prevControlX = x;
1666
+ prevControlY = y;
1667
+ }
1668
+ const vectorX = prevControlX - x;
1669
+ const vectorY = prevControlY - y;
1670
+ const newControlX = x - vectorX;
1671
+ const newControlY = y - vectorY;
1672
+ return [
1673
+ convertQToCInstruction({
1674
+ type: "Q",
1675
+ cpx: newControlX,
1676
+ cpy: newControlY,
1677
+ x: segment.x,
1678
+ y: segment.y
1679
+ }, { x, y })
1680
+ ];
1681
+ }
1682
+ if (segment.type === "S") {
1683
+ let prevControlX = 0;
1684
+ let prevControlY = 0;
1685
+ if (prevSegment && prevSegment.type === "C") {
1686
+ prevControlX = prevSegment.cp2x;
1687
+ prevControlY = prevSegment.cp2y;
1688
+ } else if (prevSegment && prevSegment.type === "S") {
1689
+ prevControlX = prevSegment.cpx;
1690
+ prevControlY = prevSegment.cpy;
1691
+ } else {
1692
+ prevControlX = x;
1693
+ prevControlY = y;
1694
+ }
1695
+ const vectorX = prevControlX - x;
1696
+ const vectorY = prevControlY - y;
1697
+ const newControlX = x - vectorX;
1698
+ const newControlY = y - vectorY;
1699
+ return [
1700
+ {
1701
+ type: "C",
1702
+ cp1x: newControlX,
1703
+ cp1y: newControlY,
1704
+ cp2x: segment.cpx,
1705
+ cp2y: segment.cpy,
1706
+ x: segment.x,
1707
+ y: segment.y
1708
+ }
1709
+ ];
1710
+ }
1711
+ if (segment.type === "Q") {
1712
+ return [convertQToCInstruction(segment, { x, y })];
1713
+ }
1714
+ return [segment];
1715
+ }
1716
+ });
1717
+ };
1718
+
1719
+ // src/serialize-instructions.ts
1720
+ var serializeInstruction = (instruction) => {
1721
+ if (instruction.type === "A") {
1722
+ return `A ${instruction.rx} ${instruction.ry} ${instruction.xAxisRotation} ${Number(instruction.largeArcFlag)} ${Number(instruction.sweepFlag)} ${instruction.x} ${instruction.y}`;
1723
+ }
1724
+ if (instruction.type === "a") {
1725
+ return `a ${instruction.rx} ${instruction.ry} ${instruction.xAxisRotation} ${Number(instruction.largeArcFlag)} ${Number(instruction.sweepFlag)} ${instruction.dx} ${instruction.dy}`;
1726
+ }
1727
+ if (instruction.type === "C") {
1728
+ return `C ${instruction.cp1x} ${instruction.cp1y} ${instruction.cp2x} ${instruction.cp2y} ${instruction.x} ${instruction.y}`;
1729
+ }
1730
+ if (instruction.type === "c") {
1731
+ return `c ${instruction.cp1dx} ${instruction.cp1dy} ${instruction.cp2dx} ${instruction.cp2dy} ${instruction.dx} ${instruction.dy}`;
1732
+ }
1733
+ if (instruction.type === "S") {
1734
+ return `S ${instruction.cpx} ${instruction.cpy} ${instruction.x} ${instruction.y}`;
1735
+ }
1736
+ if (instruction.type === "s") {
1737
+ return `s ${instruction.cpdx} ${instruction.cpdy} ${instruction.dx} ${instruction.dy}`;
1738
+ }
1739
+ if (instruction.type === "Q") {
1740
+ return `Q ${instruction.cpx} ${instruction.cpy} ${instruction.x} ${instruction.y}`;
1741
+ }
1742
+ if (instruction.type === "q") {
1743
+ return `q ${instruction.cpdx} ${instruction.cpdy} ${instruction.dx} ${instruction.dy}`;
1744
+ }
1745
+ if (instruction.type === "Z") {
1746
+ return "Z";
1747
+ }
1748
+ if (instruction.type === "H") {
1749
+ return `H ${instruction.x}`;
1750
+ }
1751
+ if (instruction.type === "h") {
1752
+ return `h ${instruction.dx}`;
1753
+ }
1754
+ if (instruction.type === "V") {
1755
+ return `V ${instruction.y}`;
1756
+ }
1757
+ if (instruction.type === "v") {
1758
+ return `v ${instruction.dy}`;
1759
+ }
1760
+ if (instruction.type === "L") {
1761
+ return `L ${instruction.x} ${instruction.y}`;
1762
+ }
1763
+ if (instruction.type === "l") {
1764
+ return `l ${instruction.dx} ${instruction.dy}`;
1765
+ }
1766
+ if (instruction.type === "M") {
1767
+ return `M ${instruction.x} ${instruction.y}`;
1768
+ }
1769
+ if (instruction.type === "m") {
1770
+ return `m ${instruction.dx} ${instruction.dy}`;
1771
+ }
1772
+ if (instruction.type === "T") {
1773
+ return `T ${instruction.x} ${instruction.y}`;
1774
+ }
1775
+ if (instruction.type === "t") {
1776
+ return `t ${instruction.dx} ${instruction.dy}`;
1777
+ }
1778
+ throw new Error(`Unknown instruction type: ${instruction.type}`);
1779
+ };
1780
+ var serializeInstructions = (path) => {
1781
+ return path.map((p) => {
1782
+ return serializeInstruction(p);
1783
+ }).join(" ");
1784
+ };
1785
+
1786
+ // src/normalize-path.ts
1787
+ var normalizeInstructions = (instructions) => {
1788
+ const normalized = [];
1789
+ let x = 0;
1790
+ let y = 0;
1791
+ let moveX = 0;
1792
+ let moveY = 0;
1793
+ for (let i = 0;i < instructions.length; i++) {
1794
+ const instruction = instructions[i];
1795
+ if (instruction.type === "M") {
1796
+ moveX = instruction.x;
1797
+ moveY = instruction.y;
1798
+ } else if (instruction.type === "m") {
1799
+ moveX += instruction.dx;
1800
+ moveY += instruction.dy;
1801
+ }
1802
+ if (instruction.type === "A" || instruction.type === "C" || instruction.type === "L" || instruction.type === "M" || instruction.type === "Q" || instruction.type === "S" || instruction.type === "T") {
1803
+ normalized.push(instruction);
1804
+ x = instruction.x;
1805
+ y = instruction.y;
1806
+ continue;
1807
+ }
1808
+ if (instruction.type === "a" || instruction.type === "c" || instruction.type === "l" || instruction.type === "m" || instruction.type === "q" || instruction.type === "s" || instruction.type === "t") {
1809
+ const currentX = x;
1810
+ const currentY = y;
1811
+ x += instruction.dx;
1812
+ y += instruction.dy;
1813
+ if (instruction.type === "a") {
1814
+ normalized.push({
1815
+ type: "A",
1816
+ largeArcFlag: instruction.largeArcFlag,
1817
+ rx: instruction.rx,
1818
+ ry: instruction.ry,
1819
+ sweepFlag: instruction.sweepFlag,
1820
+ xAxisRotation: instruction.xAxisRotation,
1821
+ x,
1822
+ y
1823
+ });
1824
+ continue;
1825
+ }
1826
+ if (instruction.type === "c") {
1827
+ normalized.push({
1828
+ type: "C",
1829
+ cp1x: instruction.cp1dx + currentX,
1830
+ cp1y: instruction.cp1dy + currentY,
1831
+ cp2x: instruction.cp2dx + currentX,
1832
+ cp2y: instruction.cp2dy + currentY,
1833
+ x,
1834
+ y
1835
+ });
1836
+ continue;
1837
+ }
1838
+ if (instruction.type === "l") {
1839
+ normalized.push({
1840
+ type: "L",
1841
+ x,
1842
+ y
1843
+ });
1844
+ continue;
1845
+ }
1846
+ if (instruction.type === "m") {
1847
+ normalized.push({
1848
+ type: "M",
1849
+ x,
1850
+ y
1851
+ });
1852
+ continue;
1853
+ }
1854
+ if (instruction.type === "q") {
1855
+ normalized.push({
1856
+ type: "Q",
1857
+ cpx: instruction.cpdx + currentX,
1858
+ cpy: instruction.cpdy + currentY,
1859
+ x,
1860
+ y
1861
+ });
1862
+ continue;
1863
+ }
1864
+ if (instruction.type === "s") {
1865
+ normalized.push({
1866
+ type: "S",
1867
+ cpx: instruction.cpdx + currentX,
1868
+ cpy: instruction.cpdy + currentY,
1869
+ x,
1870
+ y
1871
+ });
1872
+ continue;
1873
+ }
1874
+ if (instruction.type === "t") {
1875
+ normalized.push({
1876
+ type: "T",
1877
+ x,
1878
+ y
1879
+ });
1880
+ continue;
1881
+ }
1882
+ }
1883
+ if (instruction.type === "H") {
1884
+ normalized.push(instruction);
1885
+ x = instruction.x;
1886
+ continue;
1887
+ }
1888
+ if (instruction.type === "V") {
1889
+ normalized.push(instruction);
1890
+ y = instruction.y;
1891
+ continue;
1892
+ }
1893
+ if (instruction.type === "Z") {
1894
+ normalized.push(instruction);
1895
+ x = moveX;
1896
+ y = moveY;
1897
+ continue;
1898
+ }
1899
+ if (instruction.type === "h") {
1900
+ x += instruction.dx;
1901
+ normalized.push({
1902
+ type: "H",
1903
+ x
1904
+ });
1905
+ continue;
1906
+ }
1907
+ if (instruction.type === "v") {
1908
+ y += instruction.dy;
1909
+ normalized.push({
1910
+ type: "V",
1911
+ y
1912
+ });
1913
+ continue;
1914
+ }
1915
+ throw new Error("Unknown instruction type: " + instruction.type);
1916
+ }
1917
+ return normalized;
1918
+ };
1919
+ var normalizePath = (path) => {
1920
+ const instructions = parsePath(path);
1921
+ const normalized = normalizeInstructions(instructions);
1922
+ return serializeInstructions(normalized);
1923
+ };
1924
+
1925
+ // src/reduce-instructions.ts
1926
+ var reduceInstructions = (instruction) => {
1927
+ const simplified = normalizeInstructions(instruction);
1928
+ return removeATSHVQInstructions(simplified);
1929
+ };
1930
+
1931
+ // src/cut-path.ts
1932
+ var cutPath = (d, length2) => {
1933
+ const parsed = parsePath(d);
1934
+ const reduced = reduceInstructions(parsed);
1935
+ const constructed = conductAnalysis(reduced);
1936
+ const newInstructions = [];
1937
+ let summedUpLength = 0;
1938
+ for (const segment of constructed) {
1939
+ for (const instructionAndInfo of segment.instructionsAndInfo) {
1940
+ if (summedUpLength + instructionAndInfo.length > length2) {
1941
+ const remainingLength = length2 - summedUpLength;
1942
+ const progress = remainingLength / instructionAndInfo.length;
1943
+ const cut = cutInstruction({
1944
+ instruction: instructionAndInfo.instruction,
1945
+ lastPoint: instructionAndInfo.startPoint,
1946
+ progress
1947
+ });
1948
+ newInstructions.push(cut);
1949
+ return serializeInstructions(newInstructions);
1950
+ }
1951
+ summedUpLength += instructionAndInfo.length;
1952
+ newInstructions.push(instructionAndInfo.instruction);
1953
+ if (summedUpLength === length2) {
1954
+ return serializeInstructions(newInstructions);
1955
+ }
1956
+ }
1957
+ }
1958
+ return serializeInstructions(newInstructions);
1959
+ };
1960
+
1961
+ // src/debug-path.ts
1962
+ var debugPath = (d) => {
1963
+ const instructions = normalizeInstructions(parsePath(d));
1964
+ return instructions.map((inst, i) => {
1965
+ if (inst.type === "Z") {
1966
+ return null;
1967
+ }
1968
+ if (inst.type === "H" || inst.type === "V") {
1969
+ return null;
1970
+ }
1971
+ const topLeft = [inst.x - 5, inst.y - 5];
1972
+ const topRight = [inst.x + 5, inst.y - 5];
1973
+ const bottomLeft = [inst.x - 5, inst.y + 5];
1974
+ const bottomRight = [inst.x + 5, inst.y + 5];
1975
+ const triangle = [
1976
+ {
1977
+ type: "M",
1978
+ x: topLeft[0],
1979
+ y: topLeft[1]
1980
+ },
1981
+ {
1982
+ type: "L",
1983
+ x: topRight[0],
1984
+ y: topRight[1]
1985
+ },
1986
+ {
1987
+ type: "L",
1988
+ x: bottomRight[0],
1989
+ y: bottomRight[1]
1990
+ },
1991
+ {
1992
+ type: "L",
1993
+ x: bottomLeft[0],
1994
+ y: bottomLeft[1]
1995
+ },
1996
+ {
1997
+ type: "Z"
1998
+ }
1999
+ ];
2000
+ return {
2001
+ d: serializeInstructions(triangle),
2002
+ color: i === instructions.length - 1 ? "red" : inst.type === "M" ? "blue" : "green"
2003
+ };
2004
+ }).filter(Boolean);
2005
+ };
2006
+
2007
+ // src/get-bounding-box.ts
2008
+ var CBEZIER_MINMAX_EPSILON = 0.00000001;
2009
+ function minmaxQ(A) {
2010
+ const min = Math.min(A[0], A[2]);
2011
+ const max = Math.max(A[0], A[2]);
2012
+ if (A[1] > A[0] ? A[2] >= A[1] : A[2] <= A[1]) {
2013
+ return [min, max];
2014
+ }
2015
+ const E = (A[0] * A[2] - A[1] * A[1]) / (A[0] - 2 * A[1] + A[2]);
2016
+ return E < min ? [E, max] : [min, E];
2017
+ }
2018
+ function minmaxC(A) {
2019
+ const K = A[0] - 3 * A[1] + 3 * A[2] - A[3];
2020
+ if (Math.abs(K) < CBEZIER_MINMAX_EPSILON) {
2021
+ if (A[0] === A[3] && A[0] === A[1]) {
2022
+ return [A[0], A[3]];
2023
+ }
2024
+ return minmaxQ([
2025
+ A[0],
2026
+ -0.5 * A[0] + 1.5 * A[1],
2027
+ A[0] - 3 * A[1] + 3 * A[2]
2028
+ ]);
2029
+ }
2030
+ const T = -A[0] * A[2] + A[0] * A[3] - A[1] * A[2] - A[1] * A[3] + A[1] * A[1] + A[2] * A[2];
2031
+ if (T <= 0) {
2032
+ return [Math.min(A[0], A[3]), Math.max(A[0], A[3])];
2033
+ }
2034
+ const S = Math.sqrt(T);
2035
+ let min = Math.min(A[0], A[3]);
2036
+ let max = Math.max(A[0], A[3]);
2037
+ const L = A[0] - 2 * A[1] + A[2];
2038
+ for (let R = (L + S) / K, i = 1;i <= 2; R = (L - S) / K, i++) {
2039
+ if (R > 0 && R < 1) {
2040
+ const Q = A[0] * (1 - R) * (1 - R) * (1 - R) + A[1] * 3 * (1 - R) * (1 - R) * R + A[2] * 3 * (1 - R) * R * R + A[3] * R * R * R;
2041
+ if (Q < min) {
2042
+ min = Q;
2043
+ }
2044
+ if (Q > max) {
2045
+ max = Q;
2046
+ }
2047
+ }
2048
+ }
2049
+ return [min, max];
2050
+ }
2051
+ var getBoundingBoxFromInstructions = (instructions) => {
2052
+ let minX = Infinity;
2053
+ let minY = Infinity;
2054
+ let maxX = -Infinity;
2055
+ let maxY = -Infinity;
2056
+ let x = 0;
2057
+ let y = 0;
2058
+ let lastMoveX = 0;
2059
+ let lastMoveY = 0;
2060
+ for (const seg of instructions) {
2061
+ switch (seg.type) {
2062
+ case "M": {
2063
+ lastMoveX = seg.x;
2064
+ lastMoveY = seg.y;
2065
+ if (minX > seg.x) {
2066
+ minX = seg.x;
2067
+ }
2068
+ if (minY > seg.y) {
2069
+ minY = seg.y;
2070
+ }
2071
+ if (maxX < seg.x) {
2072
+ maxX = seg.x;
2073
+ }
2074
+ if (maxY < seg.y) {
2075
+ maxY = seg.y;
2076
+ }
2077
+ x = seg.x;
2078
+ y = seg.y;
2079
+ break;
2080
+ }
2081
+ case "L": {
2082
+ if (minX > seg.x) {
2083
+ minX = seg.x;
2084
+ }
2085
+ if (minY > seg.y) {
2086
+ minY = seg.y;
2087
+ }
2088
+ if (maxX < seg.x) {
2089
+ maxX = seg.x;
2090
+ }
2091
+ if (maxY < seg.y) {
2092
+ maxY = seg.y;
2093
+ }
2094
+ x = seg.x;
2095
+ y = seg.y;
2096
+ break;
2097
+ }
2098
+ case "C": {
2099
+ const cxMinMax = minmaxC([x, seg.cp1x, seg.cp2x, seg.x]);
2100
+ if (minX > cxMinMax[0]) {
2101
+ minX = cxMinMax[0];
2102
+ }
2103
+ if (maxX < cxMinMax[1]) {
2104
+ maxX = cxMinMax[1];
2105
+ }
2106
+ const cyMinMax = minmaxC([y, seg.cp1y, seg.cp2y, seg.y]);
2107
+ if (minY > cyMinMax[0]) {
2108
+ minY = cyMinMax[0];
2109
+ }
2110
+ if (maxY < cyMinMax[1]) {
2111
+ maxY = cyMinMax[1];
2112
+ }
2113
+ x = seg.x;
2114
+ y = seg.y;
2115
+ break;
2116
+ }
2117
+ case "Z":
2118
+ x = lastMoveX;
2119
+ y = lastMoveY;
2120
+ break;
2121
+ default:
2122
+ throw new Error(`Unknown instruction ${seg.type}`);
2123
+ }
2124
+ }
2125
+ return {
2126
+ x1: minX,
2127
+ y1: minY,
2128
+ x2: maxX,
2129
+ y2: maxY,
2130
+ viewBox: `${minX} ${minY} ${maxX - minX} ${maxY - minY}`,
2131
+ width: maxX - minX,
2132
+ height: maxY - minY
2133
+ };
2134
+ };
2135
+ var getBoundingBox = (d) => {
2136
+ const parsed = parsePath(d);
2137
+ const unarced = removeATSHVQInstructions(normalizeInstructions(parsed));
2138
+ return getBoundingBoxFromInstructions(unarced);
2139
+ };
2140
+
2141
+ // src/helpers/arc.ts
2142
+ var mod = (x, m) => {
2143
+ return (x % m + m) % m;
2144
+ };
2145
+ var toRadians = (angle) => {
2146
+ return angle * (Math.PI / 180);
2147
+ };
2148
+ var distance = (p0, p1) => {
2149
+ return Math.sqrt((p1.x - p0.x) ** 2 + (p1.y - p0.y) ** 2);
2150
+ };
2151
+ var clamp = (val, min, max) => {
2152
+ return Math.min(Math.max(val, min), max);
2153
+ };
2154
+ var angleBetween = (v0, v1) => {
2155
+ const p = v0.x * v1.x + v0.y * v1.y;
2156
+ const n = Math.sqrt((v0.x ** 2 + v0.y ** 2) * (v1.x ** 2 + v1.y ** 2));
2157
+ const sign = v0.x * v1.y - v0.y * v1.x < 0 ? -1 : 1;
2158
+ const angle = sign * Math.acos(p / n);
2159
+ return angle;
2160
+ };
2161
+ var pointOnEllipticalArc = ({
2162
+ p0,
2163
+ rx,
2164
+ ry,
2165
+ xAxisRotation,
2166
+ largeArcFlag,
2167
+ sweepFlag,
2168
+ p1,
2169
+ t
2170
+ }) => {
2171
+ rx = Math.abs(rx);
2172
+ ry = Math.abs(ry);
2173
+ xAxisRotation = mod(xAxisRotation, 360);
2174
+ const xAxisRotationRadians = toRadians(xAxisRotation);
2175
+ if (p0.x === p1.x && p0.y === p1.y) {
2176
+ return { x: p0.x, y: p0.y, ellipticalArcAngle: 0 };
2177
+ }
2178
+ if (rx === 0 || ry === 0) {
2179
+ return { x: 0, y: 0, ellipticalArcAngle: 0 };
2180
+ }
2181
+ const dx = (p0.x - p1.x) / 2;
2182
+ const dy = (p0.y - p1.y) / 2;
2183
+ const transformedPoint = {
2184
+ x: Math.cos(xAxisRotationRadians) * dx + Math.sin(xAxisRotationRadians) * dy,
2185
+ y: -Math.sin(xAxisRotationRadians) * dx + Math.cos(xAxisRotationRadians) * dy
2186
+ };
2187
+ const radiiCheck = transformedPoint.x ** 2 / rx ** 2 + transformedPoint.y ** 2 / ry ** 2;
2188
+ if (radiiCheck > 1) {
2189
+ rx *= Math.sqrt(radiiCheck);
2190
+ ry *= Math.sqrt(radiiCheck);
2191
+ }
2192
+ const cSquareNumerator = rx ** 2 * ry ** 2 - rx ** 2 * transformedPoint.y ** 2 - ry ** 2 * transformedPoint.x ** 2;
2193
+ const cSquareRootDenom = rx ** 2 * transformedPoint.y ** 2 + ry ** 2 * transformedPoint.x ** 2;
2194
+ let cRadicand = cSquareNumerator / cSquareRootDenom;
2195
+ cRadicand = cRadicand < 0 ? 0 : cRadicand;
2196
+ const cCoef = (largeArcFlag === sweepFlag ? -1 : 1) * Math.sqrt(cRadicand);
2197
+ const transformedCenter = {
2198
+ x: cCoef * (rx * transformedPoint.y / ry),
2199
+ y: cCoef * (-(ry * transformedPoint.x) / rx)
2200
+ };
2201
+ const center = {
2202
+ x: Math.cos(xAxisRotationRadians) * transformedCenter.x - Math.sin(xAxisRotationRadians) * transformedCenter.y + (p0.x + p1.x) / 2,
2203
+ y: Math.sin(xAxisRotationRadians) * transformedCenter.x + Math.cos(xAxisRotationRadians) * transformedCenter.y + (p0.y + p1.y) / 2
2204
+ };
2205
+ const startVector = {
2206
+ x: (transformedPoint.x - transformedCenter.x) / rx,
2207
+ y: (transformedPoint.y - transformedCenter.y) / ry
2208
+ };
2209
+ const startAngle = angleBetween({
2210
+ x: 1,
2211
+ y: 0
2212
+ }, startVector);
2213
+ const endVector = {
2214
+ x: (-transformedPoint.x - transformedCenter.x) / rx,
2215
+ y: (-transformedPoint.y - transformedCenter.y) / ry
2216
+ };
2217
+ let sweepAngle = angleBetween(startVector, endVector);
2218
+ if (!sweepFlag && sweepAngle > 0) {
2219
+ sweepAngle -= 2 * Math.PI;
2220
+ } else if (sweepFlag && sweepAngle < 0) {
2221
+ sweepAngle += 2 * Math.PI;
2222
+ }
2223
+ sweepAngle %= 2 * Math.PI;
2224
+ const angle = startAngle + sweepAngle * t;
2225
+ const ellipseComponentX = rx * Math.cos(angle);
2226
+ const ellipseComponentY = ry * Math.sin(angle);
2227
+ const point = {
2228
+ x: Math.cos(xAxisRotationRadians) * ellipseComponentX - Math.sin(xAxisRotationRadians) * ellipseComponentY + center.x,
2229
+ y: Math.sin(xAxisRotationRadians) * ellipseComponentX + Math.cos(xAxisRotationRadians) * ellipseComponentY + center.y,
2230
+ ellipticalArcStartAngle: startAngle,
2231
+ ellipticalArcEndAngle: startAngle + sweepAngle,
2232
+ ellipticalArcAngle: angle,
2233
+ ellipticalArcCenter: center,
2234
+ resultantRx: rx,
2235
+ resultantRy: ry
2236
+ };
2237
+ return point;
2238
+ };
2239
+ var approximateArcLengthOfCurve = (resolution, pointOnCurveFunc) => {
2240
+ resolution = resolution ? resolution : 500;
2241
+ let resultantArcLength = 0;
2242
+ const arcLengthMap = [];
2243
+ const approximationLines = [];
2244
+ let prevPoint = pointOnCurveFunc(0);
2245
+ let nextPoint;
2246
+ for (let i = 0;i < resolution; i++) {
2247
+ const t = clamp(i * (1 / resolution), 0, 1);
2248
+ nextPoint = pointOnCurveFunc(t);
2249
+ resultantArcLength += distance(prevPoint, nextPoint);
2250
+ approximationLines.push([prevPoint, nextPoint]);
2251
+ arcLengthMap.push({
2252
+ t,
2253
+ arcLength: resultantArcLength
2254
+ });
2255
+ prevPoint = nextPoint;
2256
+ }
2257
+ nextPoint = pointOnCurveFunc(1);
2258
+ approximationLines.push([prevPoint, nextPoint]);
2259
+ resultantArcLength += distance(prevPoint, nextPoint);
2260
+ arcLengthMap.push({
2261
+ t: 1,
2262
+ arcLength: resultantArcLength
2263
+ });
2264
+ return {
2265
+ arcLength: resultantArcLength,
2266
+ arcLengthMap,
2267
+ approximationLines
2268
+ };
2269
+ };
2270
+ var makeArc = ({
2271
+ x0,
2272
+ y0,
2273
+ rx,
2274
+ ry,
2275
+ xAxisRotate,
2276
+ LargeArcFlag,
2277
+ SweepFlag,
2278
+ x1,
2279
+ y1
2280
+ }) => {
2281
+ const lengthProperties = approximateArcLengthOfCurve(300, (t) => {
2282
+ return pointOnEllipticalArc({
2283
+ p0: { x: x0, y: y0 },
2284
+ rx,
2285
+ ry,
2286
+ xAxisRotation: xAxisRotate,
2287
+ largeArcFlag: LargeArcFlag,
2288
+ sweepFlag: SweepFlag,
2289
+ p1: { x: x1, y: y1 },
2290
+ t
2291
+ });
2292
+ });
2293
+ const length2 = lengthProperties.arcLength;
2294
+ const getPointAtLength = (fractionLength) => {
2295
+ if (fractionLength < 0) {
2296
+ fractionLength = 0;
2297
+ } else if (fractionLength > length2) {
2298
+ fractionLength = length2;
2299
+ }
2300
+ const position = pointOnEllipticalArc({
2301
+ p0: { x: x0, y: y0 },
2302
+ rx,
2303
+ ry,
2304
+ xAxisRotation: xAxisRotate,
2305
+ largeArcFlag: LargeArcFlag,
2306
+ sweepFlag: SweepFlag,
2307
+ p1: { x: x1, y: y1 },
2308
+ t: fractionLength / length2
2309
+ });
2310
+ return { x: position.x, y: position.y };
2311
+ };
2312
+ return {
2313
+ getPointAtLength,
2314
+ getTangentAtLength: (fractionLength) => {
2315
+ if (fractionLength < 0) {
2316
+ fractionLength = 0;
2317
+ } else if (fractionLength > length2) {
2318
+ fractionLength = length2;
2319
+ }
2320
+ const point_dist = 0.05;
2321
+ const p1 = getPointAtLength(fractionLength);
2322
+ let p2;
2323
+ if (fractionLength < 0) {
2324
+ fractionLength = 0;
2325
+ } else if (fractionLength > length2) {
2326
+ fractionLength = length2;
2327
+ }
2328
+ if (fractionLength < length2 - point_dist) {
2329
+ p2 = getPointAtLength(fractionLength + point_dist);
2330
+ } else {
2331
+ p2 = getPointAtLength(fractionLength - point_dist);
2332
+ }
2333
+ const xDist = p2.x - p1.x;
2334
+ const yDist = p2.y - p1.y;
2335
+ const dist = Math.sqrt(xDist * xDist + yDist * yDist);
2336
+ if (fractionLength < length2 - point_dist) {
2337
+ return { x: -xDist / dist, y: -yDist / dist };
2338
+ }
2339
+ return { x: xDist / dist, y: yDist / dist };
2340
+ },
2341
+ getTotalLength: () => {
2342
+ return length2;
2343
+ },
2344
+ type: "arc"
2345
+ };
2346
+ };
2347
+
2348
+ // src/helpers/construct.ts
2349
+ var constructFromInstructions = (instructions) => {
2350
+ let totalLength = 0;
2351
+ const partialLengths = [];
2352
+ const functions = [];
2353
+ let initialPoint = null;
2354
+ let cur = [0, 0];
2355
+ let prev_point = [0, 0];
2356
+ let curve;
2357
+ let ringStart = [0, 0];
2358
+ const segments = [];
2359
+ for (let i = 0;i < instructions.length; i++) {
2360
+ const instruction = instructions[i];
2361
+ if (instruction.type !== "m" && instruction.type !== "M" && segments.length > 0) {
2362
+ segments[segments.length - 1].push(instruction);
2363
+ }
2364
+ if (instruction.type === "M") {
2365
+ cur = [instruction.x, instruction.y];
2366
+ ringStart = [cur[0], cur[1]];
2367
+ segments.push([instruction]);
2368
+ functions.push(null);
2369
+ if (i === 0) {
2370
+ initialPoint = { x: instruction.x, y: instruction.y };
2371
+ }
2372
+ }
2373
+ if (instruction.type === "m") {
2374
+ cur = [instruction.dx + cur[0], instruction.dy + cur[1]];
2375
+ ringStart = [cur[0], cur[1]];
2376
+ segments.push([{ type: "M", x: cur[0], y: cur[1] }]);
2377
+ functions.push(null);
2378
+ }
2379
+ if (instruction.type === "L") {
2380
+ totalLength += Math.sqrt((cur[0] - instruction.x) ** 2 + (cur[1] - instruction.y) ** 2);
2381
+ functions.push(makeLinearPosition({
2382
+ x0: cur[0],
2383
+ x1: instruction.x,
2384
+ y0: cur[1],
2385
+ y1: instruction.y
2386
+ }));
2387
+ cur = [instruction.x, instruction.y];
2388
+ }
2389
+ if (instruction.type === "l") {
2390
+ totalLength += Math.sqrt(instruction.dx ** 2 + instruction.dy ** 2);
2391
+ functions.push(makeLinearPosition({
2392
+ x0: cur[0],
2393
+ x1: instruction.dx + cur[0],
2394
+ y0: cur[1],
2395
+ y1: instruction.dy + cur[1]
2396
+ }));
2397
+ cur = [instruction.dx + cur[0], instruction.dy + cur[1]];
2398
+ }
2399
+ if (instruction.type === "H") {
2400
+ totalLength += Math.abs(cur[0] - instruction.x);
2401
+ functions.push(makeLinearPosition({
2402
+ x0: cur[0],
2403
+ x1: instruction.x,
2404
+ y0: cur[1],
2405
+ y1: cur[1]
2406
+ }));
2407
+ cur[0] = instruction.x;
2408
+ }
2409
+ if (instruction.type === "h") {
2410
+ totalLength += Math.abs(instruction.dx);
2411
+ functions.push(makeLinearPosition({
2412
+ x0: cur[0],
2413
+ x1: cur[0] + instruction.dx,
2414
+ y0: cur[1],
2415
+ y1: cur[1]
2416
+ }));
2417
+ cur[0] = instruction.dx + cur[0];
2418
+ } else if (instruction.type === "V") {
2419
+ totalLength += Math.abs(cur[1] - instruction.y);
2420
+ functions.push(makeLinearPosition({
2421
+ x0: cur[0],
2422
+ x1: cur[0],
2423
+ y0: cur[1],
2424
+ y1: instruction.y
2425
+ }));
2426
+ cur[1] = instruction.y;
2427
+ }
2428
+ if (instruction.type === "v") {
2429
+ totalLength += Math.abs(instruction.dy);
2430
+ functions.push(makeLinearPosition({
2431
+ x0: cur[0],
2432
+ x1: cur[0],
2433
+ y0: cur[1],
2434
+ y1: cur[1] + instruction.dy
2435
+ }));
2436
+ cur[1] = instruction.dy + cur[1];
2437
+ } else if (instruction.type === "Z") {
2438
+ totalLength += Math.sqrt((ringStart[0] - cur[0]) ** 2 + (ringStart[1] - cur[1]) ** 2);
2439
+ functions.push(makeLinearPosition({
2440
+ x0: cur[0],
2441
+ x1: ringStart[0],
2442
+ y0: cur[1],
2443
+ y1: ringStart[1]
2444
+ }));
2445
+ cur = [ringStart[0], ringStart[1]];
2446
+ }
2447
+ if (instruction.type === "C") {
2448
+ curve = makeCubic({
2449
+ startX: cur[0],
2450
+ startY: cur[1],
2451
+ cp1x: instruction.cp1x,
2452
+ cp1y: instruction.cp1y,
2453
+ cp2x: instruction.cp2x,
2454
+ cp2y: instruction.cp2y,
2455
+ x: instruction.x,
2456
+ y: instruction.y
2457
+ });
2458
+ totalLength += curve.getTotalLength();
2459
+ cur = [instruction.x, instruction.y];
2460
+ functions.push(curve);
2461
+ } else if (instruction.type === "c") {
2462
+ curve = makeCubic({
2463
+ startX: cur[0],
2464
+ startY: cur[1],
2465
+ cp1x: cur[0] + instruction.cp1dx,
2466
+ cp1y: cur[1] + instruction.cp1dy,
2467
+ cp2x: cur[0] + instruction.cp2dx,
2468
+ cp2y: cur[1] + instruction.cp2dy,
2469
+ x: cur[0] + instruction.dx,
2470
+ y: cur[1] + instruction.dy
2471
+ });
2472
+ if (curve.getTotalLength() > 0) {
2473
+ totalLength += curve.getTotalLength();
2474
+ functions.push(curve);
2475
+ cur = [instruction.dx + cur[0], instruction.dy + cur[1]];
2476
+ } else {
2477
+ functions.push(makeLinearPosition({ x0: cur[0], x1: cur[0], y0: cur[1], y1: cur[1] }));
2478
+ }
2479
+ }
2480
+ if (instruction.type === "S") {
2481
+ const prev = instructions[i - 1];
2482
+ const prevWasCurve = prev.type === "C" || prev.type === "c" || prev.type === "S" || prev.type === "s";
2483
+ if (i > 0 && prevWasCurve) {
2484
+ if (curve) {
2485
+ const c = curve.getC();
2486
+ curve = makeCubic({
2487
+ startX: cur[0],
2488
+ startY: cur[1],
2489
+ cp1x: 2 * cur[0] - c.x,
2490
+ cp1y: 2 * cur[1] - c.y,
2491
+ cp2x: instruction.cpx,
2492
+ cp2y: instruction.cpy,
2493
+ x: instruction.x,
2494
+ y: instruction.y
2495
+ });
2496
+ }
2497
+ } else {
2498
+ curve = makeCubic({
2499
+ startX: cur[0],
2500
+ startY: cur[1],
2501
+ cp1x: cur[0],
2502
+ cp1y: cur[1],
2503
+ cp2x: instruction.cpx,
2504
+ cp2y: instruction.cpy,
2505
+ x: instruction.x,
2506
+ y: instruction.y
2507
+ });
2508
+ }
2509
+ if (curve) {
2510
+ totalLength += curve.getTotalLength();
2511
+ cur = [instruction.x, instruction.y];
2512
+ functions.push(curve);
2513
+ }
2514
+ }
2515
+ if (instruction.type === "s") {
2516
+ const prev = instructions[i - 1];
2517
+ const prevWasCurve = prev.type === "C" || prev.type === "c" || prev.type === "S" || prev.type === "s";
2518
+ if (i > 0 && prevWasCurve) {
2519
+ if (curve) {
2520
+ const c = curve.getC();
2521
+ const d = curve.getD();
2522
+ curve = makeCubic({
2523
+ startX: cur[0],
2524
+ startY: cur[1],
2525
+ cp1x: cur[0] + d.x - c.x,
2526
+ cp1y: cur[1] + d.y - c.y,
2527
+ cp2x: cur[0] + instruction.cpdx,
2528
+ cp2y: cur[1] + instruction.cpdy,
2529
+ x: cur[0] + instruction.dx,
2530
+ y: cur[1] + instruction.dy
2531
+ });
2532
+ }
2533
+ } else {
2534
+ curve = makeCubic({
2535
+ startX: cur[0],
2536
+ startY: cur[1],
2537
+ cp1x: cur[0],
2538
+ cp1y: cur[1],
2539
+ cp2x: cur[0] + instruction.cpdx,
2540
+ cp2y: cur[1] + instruction.cpdy,
2541
+ x: cur[0] + instruction.dx,
2542
+ y: cur[1] + instruction.dy
2543
+ });
2544
+ }
2545
+ if (curve) {
2546
+ totalLength += curve.getTotalLength();
2547
+ cur = [instruction.dx + cur[0], instruction.dy + cur[1]];
2548
+ functions.push(curve);
2549
+ }
2550
+ }
2551
+ if (instruction.type === "Q") {
2552
+ if (cur[0] === instruction.cpx && cur[1] === instruction.cpy) {
2553
+ const linearCurve = makeLinearPosition({
2554
+ x0: instruction.cpx,
2555
+ x1: instruction.x,
2556
+ y0: instruction.cpy,
2557
+ y1: instruction.y
2558
+ });
2559
+ totalLength += linearCurve.getTotalLength();
2560
+ functions.push(linearCurve);
2561
+ } else {
2562
+ curve = makeQuadratic({
2563
+ startX: cur[0],
2564
+ startY: cur[1],
2565
+ cpx: instruction.cpx,
2566
+ cpy: instruction.cpy,
2567
+ x: instruction.x,
2568
+ y: instruction.y
2569
+ });
2570
+ totalLength += curve.getTotalLength();
2571
+ functions.push(curve);
2572
+ }
2573
+ cur = [instruction.x, instruction.y];
2574
+ prev_point = [instruction.cpx, instruction.cpy];
2575
+ }
2576
+ if (instruction.type === "q") {
2577
+ if (instruction.cpdx === 0 && instruction.cpdy === 0) {
2578
+ const linearCurve = makeLinearPosition({
2579
+ x0: cur[0] + instruction.cpdx,
2580
+ x1: cur[0] + instruction.cpdy,
2581
+ y0: cur[1] + instruction.dx,
2582
+ y1: cur[1] + instruction.dy
2583
+ });
2584
+ totalLength += linearCurve.getTotalLength();
2585
+ functions.push(linearCurve);
2586
+ } else {
2587
+ curve = makeQuadratic({
2588
+ startX: cur[0],
2589
+ startY: cur[1],
2590
+ cpx: cur[0] + instruction.cpdx,
2591
+ cpy: cur[1] + instruction.cpdy,
2592
+ x: cur[0] + instruction.dx,
2593
+ y: cur[1] + instruction.dy
2594
+ });
2595
+ totalLength += curve.getTotalLength();
2596
+ functions.push(curve);
2597
+ }
2598
+ prev_point = [cur[0] + instruction.cpdx, cur[1] + instruction.cpdy];
2599
+ cur = [instruction.dx + cur[0], instruction.dy + cur[1]];
2600
+ }
2601
+ if (instruction.type === "T") {
2602
+ const prev = instructions[i - 1];
2603
+ const prevWasQ = prev.type === "Q" || prev.type === "q" || prev.type === "T" || prev.type === "t";
2604
+ if (i > 0 && prevWasQ) {
2605
+ curve = makeQuadratic({
2606
+ startX: cur[0],
2607
+ startY: cur[1],
2608
+ cpx: 2 * cur[0] - prev_point[0],
2609
+ cpy: 2 * cur[1] - prev_point[1],
2610
+ x: instruction.x,
2611
+ y: instruction.y
2612
+ });
2613
+ functions.push(curve);
2614
+ totalLength += curve.getTotalLength();
2615
+ } else {
2616
+ const linearCurve = makeLinearPosition({
2617
+ x0: cur[0],
2618
+ x1: instruction.x,
2619
+ y0: cur[1],
2620
+ y1: instruction.y
2621
+ });
2622
+ functions.push(linearCurve);
2623
+ totalLength += linearCurve.getTotalLength();
2624
+ }
2625
+ prev_point = [2 * cur[0] - prev_point[0], 2 * cur[1] - prev_point[1]];
2626
+ cur = [instruction.x, instruction.y];
2627
+ }
2628
+ if (instruction.type === "t") {
2629
+ const prev = instructions[i - 1];
2630
+ const prevWasQ = prev.type === "Q" || prev.type === "q" || prev.type === "T" || prev.type === "t";
2631
+ if (i > 0 && prevWasQ) {
2632
+ curve = makeQuadratic({
2633
+ startX: cur[0],
2634
+ startY: cur[1],
2635
+ cpx: 2 * cur[0] - prev_point[0],
2636
+ cpy: 2 * cur[1] - prev_point[1],
2637
+ x: cur[0] + instruction.dx,
2638
+ y: cur[1] + instruction.dy
2639
+ });
2640
+ totalLength += curve.getTotalLength();
2641
+ functions.push(curve);
2642
+ } else {
2643
+ const linearCurve = makeLinearPosition({
2644
+ x0: cur[0],
2645
+ x1: cur[0] + instruction.dx,
2646
+ y0: cur[1],
2647
+ y1: cur[1] + instruction.dy
2648
+ });
2649
+ totalLength += linearCurve.getTotalLength();
2650
+ functions.push(linearCurve);
2651
+ }
2652
+ prev_point = [2 * cur[0] - prev_point[0], 2 * cur[1] - prev_point[1]];
2653
+ cur = [instruction.dx + cur[0], instruction.dy + cur[1]];
2654
+ }
2655
+ if (instruction.type === "A") {
2656
+ const arcCurve = makeArc({
2657
+ x0: cur[0],
2658
+ y0: cur[1],
2659
+ rx: instruction.rx,
2660
+ ry: instruction.ry,
2661
+ xAxisRotate: instruction.xAxisRotation,
2662
+ LargeArcFlag: instruction.largeArcFlag,
2663
+ SweepFlag: instruction.sweepFlag,
2664
+ x1: instruction.x,
2665
+ y1: instruction.y
2666
+ });
2667
+ totalLength += arcCurve.getTotalLength();
2668
+ cur = [instruction.x, instruction.y];
2669
+ functions.push(arcCurve);
2670
+ }
2671
+ if (instruction.type === "a") {
2672
+ const arcCurve = makeArc({
2673
+ x0: cur[0],
2674
+ y0: cur[1],
2675
+ rx: instruction.rx,
2676
+ ry: instruction.ry,
2677
+ xAxisRotate: instruction.xAxisRotation,
2678
+ LargeArcFlag: instruction.largeArcFlag,
2679
+ SweepFlag: instruction.sweepFlag,
2680
+ x1: cur[0] + instruction.dx,
2681
+ y1: cur[1] + instruction.dy
2682
+ });
2683
+ totalLength += arcCurve.getTotalLength();
2684
+ cur = [cur[0] + instruction.dx, cur[1] + instruction.dy];
2685
+ functions.push(arcCurve);
2686
+ }
2687
+ partialLengths.push(totalLength);
2688
+ }
2689
+ return {
2690
+ segments,
2691
+ initialPoint,
2692
+ totalLength,
2693
+ partialLengths,
2694
+ functions
2695
+ };
2696
+ };
2697
+ var construct = (string) => {
2698
+ const parsed = parsePath(string);
2699
+ return constructFromInstructions(parsed);
2700
+ };
2701
+
2702
+ // src/get-length.ts
2703
+ var getLength = (path) => {
2704
+ const constructucted = construct(path);
2705
+ return constructucted.totalLength;
2706
+ };
2707
+
2708
+ // src/evolve-path.ts
2709
+ var evolvePath = (progress, path) => {
2710
+ const length2 = getLength(path);
2711
+ if (progress === 0) {
2712
+ const extendedLength = length2 * 1.5;
2713
+ return {
2714
+ strokeDasharray: `${extendedLength} ${extendedLength}`,
2715
+ strokeDashoffset: extendedLength
2716
+ };
2717
+ }
2718
+ const strokeDasharray = `${length2} ${length2}`;
2719
+ const strokeDashoffset = length2 - progress * length2;
2720
+ return { strokeDasharray, strokeDashoffset };
2721
+ };
2722
+ // src/extend-viewbox.ts
2723
+ var extendViewBox = (currentViewBox, scale) => {
2724
+ const relativeScale = scale - 1;
2725
+ const splitted = currentViewBox.split(" ").map((a) => a.trim()).filter((a) => a !== "").map(Number);
2726
+ if (splitted.length !== 4) {
2727
+ throw new Error(`currentViewBox must be 4 valid numbers, but got "${currentViewBox}"`);
2728
+ }
2729
+ for (const part of splitted) {
2730
+ if (Number.isNaN(part)) {
2731
+ throw new Error(`currentViewBox must be 4 valid numbers, but got "${currentViewBox}"`);
2732
+ }
2733
+ if (!Number.isFinite(part)) {
2734
+ throw new Error(`currentViewBox must be 4 valid numbers, but got "${currentViewBox}"`);
2735
+ }
2736
+ }
2737
+ const [x, y, width, height] = splitted;
2738
+ return [
2739
+ x - relativeScale * width / 2,
2740
+ y - relativeScale * height / 2,
2741
+ width + relativeScale * width,
2742
+ height + relativeScale * height
2743
+ ].join(" ");
2744
+ };
2745
+ // src/get-instruction-index-at-length.ts
2746
+ var getInstructionIndexAtLengthFromConstructed = (constructed, fractionLength) => {
2747
+ if (fractionLength < 0) {
2748
+ throw new Error("Length less than 0 was passed");
2749
+ }
2750
+ if (fractionLength > constructed.totalLength) {
2751
+ fractionLength = constructed.totalLength;
2752
+ }
2753
+ let index = constructed.partialLengths.length - 1;
2754
+ while (constructed.partialLengths[index] >= fractionLength && index > 0) {
2755
+ index--;
2756
+ }
2757
+ return {
2758
+ lengthIntoInstruction: fractionLength - constructed.partialLengths[index],
2759
+ index
2760
+ };
2761
+ };
2762
+ var getInstructionIndexAtLength = (path, length2) => {
2763
+ const constructed = construct(path);
2764
+ if (length2 > constructed.totalLength) {
2765
+ throw new Error(`A length of ${length2} was passed to getInstructionIndexAtLength() but the total length of the path is only ${constructed.totalLength}`);
2766
+ }
2767
+ return getInstructionIndexAtLengthFromConstructed(constructed, length2);
2768
+ };
2769
+ // src/get-point-at-length.ts
2770
+ var getPointAtLength = (path, length2) => {
2771
+ const constructed = construct(path);
2772
+ const fractionPart = getInstructionIndexAtLengthFromConstructed(constructed, length2);
2773
+ const functionAtPart = constructed.functions[fractionPart.index + 1];
2774
+ if (functionAtPart) {
2775
+ return functionAtPart.getPointAtLength(fractionPart.lengthIntoInstruction);
2776
+ }
2777
+ if (constructed.initialPoint) {
2778
+ return constructed.initialPoint;
2779
+ }
2780
+ throw new Error("Wrong function at this part.");
2781
+ };
2782
+ // src/get-subpaths.ts
2783
+ var getSubpaths = (path) => {
2784
+ const parsed = parsePath(path);
2785
+ const { segments } = constructFromInstructions(parsed);
2786
+ return segments.map((seg) => {
2787
+ return serializeInstructions(seg);
2788
+ });
2789
+ };
2790
+ // src/get-tangent-at-length.ts
2791
+ var getTangentAtLength = (path, length2) => {
2792
+ const constructed = construct(path);
2793
+ const fractionPart = getInstructionIndexAtLengthFromConstructed(constructed, length2);
2794
+ const functionAtPart = constructed.functions[fractionPart.index + 1];
2795
+ if (functionAtPart) {
2796
+ return functionAtPart.getTangentAtLength(fractionPart.lengthIntoInstruction);
2797
+ }
2798
+ if (constructed.initialPoint) {
2799
+ return { x: 0, y: 0 };
2800
+ }
2801
+ throw new Error("Wrong function at this part.");
2802
+ };
2803
+ // src/get-end-position.ts
2804
+ var getEndPosition = (instructions) => {
2805
+ let x = 0;
2806
+ let y = 0;
2807
+ let moveX = 0;
2808
+ let moveY = 0;
2809
+ for (let i = 0;i < instructions.length; i++) {
2810
+ const instruction = instructions[i];
2811
+ if (instruction.type === "M") {
2812
+ moveX = instruction.x;
2813
+ moveY = instruction.y;
2814
+ } else if (instruction.type === "m") {
2815
+ moveX += instruction.dx;
2816
+ moveY += instruction.dy;
2817
+ }
2818
+ if (instruction.type === "A" || instruction.type === "C" || instruction.type === "L" || instruction.type === "M" || instruction.type === "Q" || instruction.type === "S" || instruction.type === "T") {
2819
+ x = instruction.x;
2820
+ y = instruction.y;
2821
+ continue;
2822
+ }
2823
+ if (instruction.type === "a" || instruction.type === "c" || instruction.type === "l" || instruction.type === "m" || instruction.type === "q" || instruction.type === "s" || instruction.type === "t") {
2824
+ x += instruction.dx;
2825
+ y += instruction.dy;
2826
+ continue;
2827
+ }
2828
+ if (instruction.type === "H") {
2829
+ x = instruction.x;
2830
+ continue;
2831
+ }
2832
+ if (instruction.type === "V") {
2833
+ y = instruction.y;
2834
+ continue;
2835
+ }
2836
+ if (instruction.type === "Z") {
2837
+ x = moveX;
2838
+ y = moveY;
2839
+ continue;
2840
+ }
2841
+ if (instruction.type === "h") {
2842
+ x += instruction.dx;
2843
+ continue;
2844
+ }
2845
+ if (instruction.type === "v") {
2846
+ y += instruction.dy;
2847
+ continue;
2848
+ }
2849
+ throw new Error("Unknown instruction type: " + instruction.type);
2850
+ }
2851
+ return {
2852
+ x,
2853
+ y
2854
+ };
2855
+ };
2856
+
2857
+ // src/interpolate-path/convert-to-same-instruction-type.ts
2858
+ var convertToLCommand = (command) => {
2859
+ if (command.type === "M" || command.type === "L" || command.type === "Z") {
2860
+ throw new Error("unexpected");
2861
+ }
2862
+ return {
2863
+ type: "L",
2864
+ x: command.x,
2865
+ y: command.y
2866
+ };
2867
+ };
2868
+ var convertToCCommand = (command, currentPoint) => {
2869
+ if (command.type === "M" || command.type === "C" || command.type === "Z") {
2870
+ throw new Error("unexpected");
2871
+ }
2872
+ if (command.type === "L") {
2873
+ return {
2874
+ type: "C",
2875
+ cp1x: currentPoint.x,
2876
+ cp1y: currentPoint.y,
2877
+ cp2x: command.x,
2878
+ cp2y: command.y,
2879
+ x: command.x,
2880
+ y: command.y
2881
+ };
2882
+ }
2883
+ throw new Error("all types should be handled");
2884
+ };
2885
+ function convertToSameInstructionType(aCommand, bCommand, currentPoint) {
2886
+ if (aCommand.type === "M" || bCommand.type === "M") {
2887
+ return { ...aCommand };
2888
+ }
2889
+ if (aCommand.type === bCommand.type) {
2890
+ return { ...aCommand };
2891
+ }
2892
+ if (bCommand.type === "C") {
2893
+ return convertToCCommand(aCommand, currentPoint);
2894
+ }
2895
+ if (bCommand.type === "L") {
2896
+ return convertToLCommand(aCommand);
2897
+ }
2898
+ if (bCommand.type === "Z") {
2899
+ return {
2900
+ type: "Z"
2901
+ };
2902
+ }
2903
+ throw new TypeError("unhandled");
2904
+ }
2905
+
2906
+ // src/interpolate-path/points-to-command.ts
2907
+ function pointsToInstruction(points) {
2908
+ const x = points[points.length - 1][0];
2909
+ const y = points[points.length - 1][1];
2910
+ if (points.length === 4) {
2911
+ const x1 = points[1][0];
2912
+ const y1 = points[1][1];
2913
+ const x2 = points[2][0];
2914
+ const y2 = points[2][1];
2915
+ return {
2916
+ type: "C",
2917
+ cp1x: x1,
2918
+ cp1y: y1,
2919
+ cp2x: x2,
2920
+ cp2y: y2,
2921
+ x,
2922
+ y
2923
+ };
2924
+ }
2925
+ if (points.length === 3) {
2926
+ const x1 = points[1][0];
2927
+ const y1 = points[1][1];
2928
+ return convertQToCInstruction({
2929
+ type: "Q",
2930
+ cpx: x1,
2931
+ cpy: y1,
2932
+ x,
2933
+ y
2934
+ }, {
2935
+ x: points[0][0],
2936
+ y: points[0][1]
2937
+ });
2938
+ }
2939
+ return {
2940
+ type: "L",
2941
+ x,
2942
+ y
2943
+ };
2944
+ }
2945
+
2946
+ // src/interpolate-path/de-casteljau.ts
2947
+ function decasteljau(points, t) {
2948
+ const left = [];
2949
+ const right = [];
2950
+ function decasteljauRecurse(_points, _t) {
2951
+ if (_points.length === 1) {
2952
+ left.push(_points[0]);
2953
+ right.push(_points[0]);
2954
+ } else {
2955
+ const newPoints = Array(_points.length - 1);
2956
+ for (let i = 0;i < newPoints.length; i++) {
2957
+ if (i === 0) {
2958
+ left.push(_points[0]);
2959
+ }
2960
+ if (i === newPoints.length - 1) {
2961
+ right.push(_points[i + 1]);
2962
+ }
2963
+ newPoints[i] = [
2964
+ (1 - _t) * _points[i][0] + _t * _points[i + 1][0],
2965
+ (1 - _t) * _points[i][1] + _t * _points[i + 1][1]
2966
+ ];
2967
+ }
2968
+ decasteljauRecurse(newPoints, _t);
2969
+ }
2970
+ }
2971
+ if (points.length) {
2972
+ decasteljauRecurse(points, t);
2973
+ }
2974
+ return { left, right: right.reverse() };
2975
+ }
2976
+
2977
+ // src/interpolate-path/split-curve-as-points.ts
2978
+ function splitCurveAsPoints(points, segmentCount = 2) {
2979
+ const segments = [];
2980
+ let remainingCurve = points;
2981
+ const tIncrement = 1 / segmentCount;
2982
+ for (let i = 0;i < segmentCount - 1; i++) {
2983
+ const tRelative = tIncrement / (1 - tIncrement * i);
2984
+ const split = decasteljau(remainingCurve, tRelative);
2985
+ segments.push(split.left);
2986
+ remainingCurve = split.right;
2987
+ }
2988
+ segments.push(remainingCurve);
2989
+ return segments;
2990
+ }
2991
+
2992
+ // src/interpolate-path/split-curve.ts
2993
+ var splitCurveInstructions = (instructionStartX, instructionStartY, instructionEnd, segmentCount) => {
2994
+ const points = [[instructionStartX, instructionStartY]];
2995
+ if (instructionEnd.type === "Q") {
2996
+ points.push([instructionEnd.cpx, instructionEnd.cpy]);
2997
+ }
2998
+ if (instructionEnd.type === "C") {
2999
+ points.push([instructionEnd.cp1x, instructionEnd.cp1y]);
3000
+ points.push([instructionEnd.cp2x, instructionEnd.cp2y]);
3001
+ }
3002
+ points.push([instructionEnd.x, instructionEnd.y]);
3003
+ return splitCurveAsPoints(points, segmentCount).map((p) => {
3004
+ return pointsToInstruction(p);
3005
+ });
3006
+ };
3007
+
3008
+ // src/interpolate-path/split-segment.ts
3009
+ function splitSegmentInstructions(commandStart, commandEnd, segmentCount) {
3010
+ let segments = [];
3011
+ if (commandEnd.type === "L" || commandEnd.type === "C") {
3012
+ if (commandStart.type !== "Z") {
3013
+ segments = segments.concat(splitCurveInstructions(commandStart.x, commandStart.y, commandEnd, segmentCount));
3014
+ }
3015
+ } else {
3016
+ const copyCommand = commandStart.type === "M" ? {
3017
+ type: "L",
3018
+ x: commandStart.x,
3019
+ y: commandStart.y
3020
+ } : commandStart;
3021
+ segments = segments.concat(new Array(segmentCount - 1).fill(true).map(() => copyCommand));
3022
+ segments.push(commandEnd);
3023
+ }
3024
+ return segments;
3025
+ }
3026
+
3027
+ // src/interpolate-path/extend-command.ts
3028
+ function extendInstruction(commandsToExtend, referenceCommands) {
3029
+ const numSegmentsToExtend = commandsToExtend.length - 1;
3030
+ const numReferenceSegments = referenceCommands.length - 1;
3031
+ const segmentRatio = numSegmentsToExtend / numReferenceSegments;
3032
+ const countPointsPerSegment = new Array(numReferenceSegments).fill(undefined).reduce((accum, _d, i) => {
3033
+ const insertIndex = Math.floor(segmentRatio * i);
3034
+ accum[insertIndex] = (accum[insertIndex] || 0) + 1;
3035
+ return accum;
3036
+ }, []);
3037
+ const extended = countPointsPerSegment.reduce((_extended, segmentCount, i) => {
3038
+ if (i === commandsToExtend.length - 1) {
3039
+ const lastCommandCopies = new Array(segmentCount).fill({
3040
+ ...commandsToExtend[commandsToExtend.length - 1]
3041
+ });
3042
+ if (lastCommandCopies[0].type === "M") {
3043
+ lastCommandCopies.forEach((d) => {
3044
+ d.type = "L";
3045
+ });
3046
+ }
3047
+ return _extended.concat(lastCommandCopies);
3048
+ }
3049
+ return _extended.concat(splitSegmentInstructions(commandsToExtend[i], commandsToExtend[i + 1], segmentCount));
3050
+ }, []);
3051
+ extended.unshift(commandsToExtend[0]);
3052
+ return extended;
3053
+ }
3054
+
3055
+ // src/interpolate-path/interpolate-instruction-of-same-kind.ts
3056
+ var interpolateLInstruction = (t, first, second) => {
3057
+ return {
3058
+ type: "L",
3059
+ x: (1 - t) * first.x + t * second.x,
3060
+ y: (1 - t) * first.y + t * second.y
3061
+ };
3062
+ };
3063
+ var interpolateCInstructions = (t, first, second) => {
3064
+ return {
3065
+ type: "C",
3066
+ cp1x: (1 - t) * first.cp1x + t * second.cp1x,
3067
+ cp2x: (1 - t) * first.cp2x + t * second.cp2x,
3068
+ cp1y: (1 - t) * first.cp1y + t * second.cp1y,
3069
+ cp2y: (1 - t) * first.cp2y + t * second.cp2y,
3070
+ x: (1 - t) * first.x + t * second.x,
3071
+ y: (1 - t) * first.y + t * second.y
3072
+ };
3073
+ };
3074
+ var interpolateMInstructions = (t, first, second) => {
3075
+ return {
3076
+ type: "M",
3077
+ x: (1 - t) * first.x + t * second.x,
3078
+ y: (1 - t) * first.y + t * second.y
3079
+ };
3080
+ };
3081
+ var interpolateInstructionOfSameKind = (t, first, second) => {
3082
+ if (first.type === "L") {
3083
+ if (second.type !== "L") {
3084
+ throw new Error("mismatch");
3085
+ }
3086
+ return interpolateLInstruction(t, first, second);
3087
+ }
3088
+ if (first.type === "C") {
3089
+ if (second.type !== "C") {
3090
+ throw new Error("mismatch");
3091
+ }
3092
+ return interpolateCInstructions(t, first, second);
3093
+ }
3094
+ if (first.type === "M") {
3095
+ if (second.type !== "M") {
3096
+ throw new Error("mismatch");
3097
+ }
3098
+ return interpolateMInstructions(t, first, second);
3099
+ }
3100
+ if (first.type === "Z") {
3101
+ if (second.type !== "Z") {
3102
+ throw new Error("mismatch");
3103
+ }
3104
+ return {
3105
+ type: "Z"
3106
+ };
3107
+ }
3108
+ throw new Error("mismatch");
3109
+ };
3110
+
3111
+ // src/interpolate-path/interpolate-instructions.ts
3112
+ function interpolateInstructions(aCommandsInput, bCommandsInput) {
3113
+ let aCommands = aCommandsInput.slice();
3114
+ let bCommands = bCommandsInput.slice();
3115
+ if (!aCommands.length && !bCommands.length) {
3116
+ return function() {
3117
+ return [];
3118
+ };
3119
+ }
3120
+ const addZ = (aCommands.length === 0 || aCommands[aCommands.length - 1].type === "Z") && (bCommands.length === 0 || bCommands[bCommands.length - 1].type === "Z");
3121
+ if (aCommands.length > 0 && aCommands[aCommands.length - 1].type === "Z") {
3122
+ aCommands.pop();
3123
+ }
3124
+ if (bCommands.length > 0 && bCommands[bCommands.length - 1].type === "Z") {
3125
+ bCommands.pop();
3126
+ }
3127
+ if (!aCommands.length) {
3128
+ aCommands.push(bCommands[0]);
3129
+ } else if (!bCommands.length) {
3130
+ bCommands.push(aCommands[0]);
3131
+ }
3132
+ const numPointsToExtend = Math.abs(bCommands.length - aCommands.length);
3133
+ if (numPointsToExtend !== 0) {
3134
+ if (bCommands.length > aCommands.length) {
3135
+ aCommands = extendInstruction(aCommands, bCommands);
3136
+ } else if (bCommands.length < aCommands.length) {
3137
+ bCommands = extendInstruction(bCommands, aCommands);
3138
+ }
3139
+ }
3140
+ const aSameType = aCommands.map((aCommand, i) => {
3141
+ const commandsUntilNow = aCommands.slice(0, i);
3142
+ const point = getEndPosition(commandsUntilNow);
3143
+ return convertToSameInstructionType(aCommand, bCommands[i], point);
3144
+ });
3145
+ const interpolatedCommands = [];
3146
+ if (addZ) {
3147
+ aSameType.push({ type: "Z" });
3148
+ bCommands.push({ type: "Z" });
3149
+ }
3150
+ return function(t) {
3151
+ if (t === 1) {
3152
+ return bCommandsInput;
3153
+ }
3154
+ if (t === 0) {
3155
+ return aSameType;
3156
+ }
3157
+ for (let i = 0;i < aSameType.length; ++i) {
3158
+ interpolatedCommands.push(interpolateInstructionOfSameKind(t, aSameType[i], bCommands[i]));
3159
+ }
3160
+ return interpolatedCommands;
3161
+ };
3162
+ }
3163
+
3164
+ // src/interpolate-path/interpolate-path.ts
3165
+ var interpolatePath = (value, firstPath, secondPath) => {
3166
+ if (value === 1) {
3167
+ return secondPath;
3168
+ }
3169
+ if (value === 0) {
3170
+ return firstPath;
3171
+ }
3172
+ const aCommands = reduceInstructions(parsePath(firstPath));
3173
+ if (aCommands.length === 0) {
3174
+ throw new TypeError(`SVG Path "${firstPath}" is not valid`);
3175
+ }
3176
+ const bCommands = reduceInstructions(parsePath(secondPath));
3177
+ if (bCommands.length === 0) {
3178
+ throw new TypeError(`SVG Path "${secondPath}" is not valid`);
3179
+ }
3180
+ const commandInterpolator = interpolateInstructions(aCommands, bCommands);
3181
+ return serializeInstructions(commandInterpolator(value));
3182
+ };
3183
+ // src/translate-path.ts
3184
+ var translateSegments = (segments, x, y) => {
3185
+ return segments.map((segment) => {
3186
+ if (segment.type === "a" || segment.type === "c" || segment.type === "v" || segment.type === "s" || segment.type === "h" || segment.type === "l" || segment.type === "m" || segment.type === "q" || segment.type === "t") {
3187
+ return segment;
3188
+ }
3189
+ if (segment.type === "V") {
3190
+ return {
3191
+ type: "V",
3192
+ y: segment.y + y
3193
+ };
3194
+ }
3195
+ if (segment.type === "H") {
3196
+ return {
3197
+ type: "H",
3198
+ x: segment.x + x
3199
+ };
3200
+ }
3201
+ if (segment.type === "A") {
3202
+ return {
3203
+ type: "A",
3204
+ rx: segment.rx,
3205
+ ry: segment.ry,
3206
+ largeArcFlag: segment.largeArcFlag,
3207
+ sweepFlag: segment.sweepFlag,
3208
+ xAxisRotation: segment.xAxisRotation,
3209
+ x: segment.x + x,
3210
+ y: segment.y + y
3211
+ };
3212
+ }
3213
+ if (segment.type === "Z") {
3214
+ return segment;
3215
+ }
3216
+ if (segment.type === "C") {
3217
+ return {
3218
+ type: "C",
3219
+ cp1x: segment.cp1x + x,
3220
+ cp1y: segment.cp1y + y,
3221
+ cp2x: segment.cp2x + x,
3222
+ cp2y: segment.cp2y + y,
3223
+ x: segment.x + x,
3224
+ y: segment.y + y
3225
+ };
3226
+ }
3227
+ if (segment.type === "Q") {
3228
+ return {
3229
+ type: "Q",
3230
+ cpx: segment.cpx + x,
3231
+ cpy: segment.cpy + y,
3232
+ x: segment.x + x,
3233
+ y: segment.y + y
3234
+ };
3235
+ }
3236
+ if (segment.type === "S") {
3237
+ return {
3238
+ type: "S",
3239
+ cpx: segment.cpx + x,
3240
+ cpy: segment.cpy + y,
3241
+ x: segment.x + x,
3242
+ y: segment.y + y
3243
+ };
3244
+ }
3245
+ if (segment.type === "T") {
3246
+ return {
3247
+ type: "T",
3248
+ x: segment.x + x,
3249
+ y: segment.y + y
3250
+ };
3251
+ }
3252
+ if (segment.type === "L") {
3253
+ return {
3254
+ type: "L",
3255
+ x: segment.x + x,
3256
+ y: segment.y + y
3257
+ };
3258
+ }
3259
+ if (segment.type === "M") {
3260
+ return {
3261
+ type: "M",
3262
+ x: segment.x + x,
3263
+ y: segment.y + y
3264
+ };
3265
+ }
3266
+ throw new Error(`Unknown segment type: ${segment.type}`);
3267
+ });
3268
+ };
3269
+ var translatePath = (path, x, y) => {
3270
+ return serializeInstructions(translateSegments(parsePath(path), x, y));
3271
+ };
3272
+
3273
+ // src/reset-path.ts
3274
+ var resetPath = (d) => {
3275
+ const box = getBoundingBox(d);
3276
+ return translatePath(d, -box.x1, -box.y1);
3277
+ };
3278
+ // src/reverse-path.ts
3279
+ function reverseNormalizedPath(instructions) {
3280
+ const reversed = [];
3281
+ let nextX = 0;
3282
+ let nextY = 0;
3283
+ for (const term of instructions) {
3284
+ if (term.type === "A") {
3285
+ reversed.unshift({
3286
+ type: "A",
3287
+ largeArcFlag: term.largeArcFlag,
3288
+ rx: term.rx,
3289
+ ry: term.ry,
3290
+ xAxisRotation: term.xAxisRotation,
3291
+ sweepFlag: !term.sweepFlag,
3292
+ x: nextX,
3293
+ y: nextY
3294
+ });
3295
+ } else if (term.type === "C") {
3296
+ reversed.unshift({
3297
+ type: "C",
3298
+ cp1x: term.cp2x,
3299
+ cp1y: term.cp2y,
3300
+ cp2x: term.cp1x,
3301
+ cp2y: term.cp1y,
3302
+ x: nextX,
3303
+ y: nextY
3304
+ });
3305
+ } else if (term.type === "Q") {
3306
+ reversed.unshift({
3307
+ type: "Q",
3308
+ cpx: term.cpx,
3309
+ cpy: term.cpy,
3310
+ x: nextX,
3311
+ y: nextY
3312
+ });
3313
+ } else if (term.type === "L") {
3314
+ reversed.unshift({
3315
+ type: "L",
3316
+ x: nextX,
3317
+ y: nextY
3318
+ });
3319
+ } else if (term.type === "M") {
3320
+ } else if (term.type === "Z") {
3321
+ } else {
3322
+ throw new Error("unnormalized instruction " + term.type);
3323
+ }
3324
+ if (term.type !== "Z") {
3325
+ nextX = term.x;
3326
+ nextY = term.y;
3327
+ }
3328
+ }
3329
+ reversed.unshift({
3330
+ type: "M",
3331
+ x: nextX,
3332
+ y: nextY
3333
+ });
3334
+ let revstring = serializeInstructions(reversed);
3335
+ if (instructions[instructions.length - 1].type === "Z")
3336
+ revstring += "Z";
3337
+ revstring = revstring.replace(/M M/g, "Z M");
3338
+ return revstring;
3339
+ }
3340
+ var reversePath = (path) => {
3341
+ const parsed = parsePath(path);
3342
+ const normalized = normalizeInstructions(parsed);
3343
+ const reduced = reduceInstructions(normalized);
3344
+ const { segments } = constructFromInstructions(reduced);
3345
+ return segments.map((spath) => {
3346
+ return reverseNormalizedPath(spath);
3347
+ }).join(" ").replace(/ +/g, " ").trim();
3348
+ };
3349
+ // src/scale-path.ts
3350
+ var scalePath = (d, scaleX, scaleY) => {
3351
+ const reduced = reduceInstructions(parsePath(d));
3352
+ const bounded = getBoundingBoxFromInstructions(reduced);
3353
+ const zeroed = translateSegments(reduced, -bounded.x1, -bounded.y1);
3354
+ const mapped = zeroed.map((instruction) => {
3355
+ if (instruction.type === "L") {
3356
+ return {
3357
+ type: "L",
3358
+ x: scaleX * instruction.x,
3359
+ y: scaleY * instruction.y
3360
+ };
3361
+ }
3362
+ if (instruction.type === "C") {
3363
+ return {
3364
+ type: "C",
3365
+ x: scaleX * instruction.x,
3366
+ y: scaleY * instruction.y,
3367
+ cp1x: scaleX * instruction.cp1x,
3368
+ cp1y: scaleY * instruction.cp1y,
3369
+ cp2x: scaleX * instruction.cp2x,
3370
+ cp2y: scaleY * instruction.cp2y
3371
+ };
3372
+ }
3373
+ if (instruction.type === "M") {
3374
+ return {
3375
+ type: "M",
3376
+ x: scaleX * instruction.x,
3377
+ y: scaleY * instruction.y
3378
+ };
3379
+ }
3380
+ if (instruction.type === "Q") {
3381
+ return {
3382
+ type: "Q",
3383
+ x: scaleX * instruction.x,
3384
+ y: scaleY * instruction.y,
3385
+ cpx: scaleX * instruction.cpx,
3386
+ cpy: scaleY * instruction.cpy
3387
+ };
3388
+ }
3389
+ if (instruction.type === "Z") {
3390
+ return {
3391
+ type: "Z"
3392
+ };
3393
+ }
3394
+ if (instruction.type === "A") {
3395
+ return {
3396
+ type: "A",
3397
+ largeArcFlag: instruction.largeArcFlag,
3398
+ rx: scaleX * instruction.rx,
3399
+ ry: scaleY * instruction.ry,
3400
+ sweepFlag: instruction.sweepFlag,
3401
+ xAxisRotation: instruction.xAxisRotation,
3402
+ x: scaleX * instruction.x,
3403
+ y: scaleY * instruction.y
3404
+ };
3405
+ }
3406
+ if (instruction.type === "H") {
3407
+ return {
3408
+ type: "H",
3409
+ x: scaleX * instruction.x
3410
+ };
3411
+ }
3412
+ if (instruction.type === "S") {
3413
+ return {
3414
+ type: "S",
3415
+ cpx: scaleX * instruction.cpx,
3416
+ cpy: scaleY * instruction.cpy,
3417
+ x: scaleX * instruction.x,
3418
+ y: scaleY * instruction.y
3419
+ };
3420
+ }
3421
+ if (instruction.type === "T") {
3422
+ return {
3423
+ type: "T",
3424
+ x: scaleX * instruction.x,
3425
+ y: scaleY * instruction.y
3426
+ };
3427
+ }
3428
+ if (instruction.type === "V") {
3429
+ return {
3430
+ type: "V",
3431
+ y: scaleY * instruction.y
3432
+ };
3433
+ }
3434
+ if (instruction.type === "a") {
3435
+ return {
3436
+ type: "a",
3437
+ dx: scaleX * instruction.dx,
3438
+ dy: scaleY * instruction.dy,
3439
+ largeArcFlag: instruction.largeArcFlag,
3440
+ rx: scaleX * instruction.rx,
3441
+ ry: scaleY * instruction.ry,
3442
+ sweepFlag: instruction.sweepFlag,
3443
+ xAxisRotation: instruction.xAxisRotation
3444
+ };
3445
+ }
3446
+ if (instruction.type === "c") {
3447
+ return {
3448
+ type: "c",
3449
+ cp1dx: scaleX * instruction.cp1dx,
3450
+ cp1dy: scaleY * instruction.cp1dy,
3451
+ cp2dx: scaleX * instruction.cp2dx,
3452
+ cp2dy: scaleY * instruction.cp2dy,
3453
+ dx: scaleX * instruction.dx,
3454
+ dy: scaleY * instruction.dy
3455
+ };
3456
+ }
3457
+ if (instruction.type === "h") {
3458
+ return {
3459
+ type: "h",
3460
+ dx: scaleX * instruction.dx
3461
+ };
3462
+ }
3463
+ if (instruction.type === "l") {
3464
+ return {
3465
+ type: "l",
3466
+ dx: scaleX * instruction.dx,
3467
+ dy: scaleY * instruction.dy
3468
+ };
3469
+ }
3470
+ if (instruction.type === "m") {
3471
+ return {
3472
+ type: "m",
3473
+ dx: scaleX * instruction.dx,
3474
+ dy: scaleY * instruction.dy
3475
+ };
3476
+ }
3477
+ if (instruction.type === "q") {
3478
+ return {
3479
+ type: "q",
3480
+ cpdx: scaleX * instruction.cpdx,
3481
+ cpdy: scaleY * instruction.cpdy,
3482
+ dx: scaleX * instruction.dx,
3483
+ dy: scaleY * instruction.dy
3484
+ };
3485
+ }
3486
+ if (instruction.type === "s") {
3487
+ return {
3488
+ type: "s",
3489
+ cpdx: scaleX * instruction.cpdx,
3490
+ cpdy: scaleY * instruction.cpdy,
3491
+ dx: scaleX * instruction.dx,
3492
+ dy: scaleY * instruction.dy
3493
+ };
3494
+ }
3495
+ if (instruction.type === "t") {
3496
+ return {
3497
+ type: "t",
3498
+ dx: scaleX * instruction.dx,
3499
+ dy: scaleY * instruction.dy
3500
+ };
3501
+ }
3502
+ if (instruction.type === "v") {
3503
+ return {
3504
+ type: "v",
3505
+ dy: scaleY * instruction.dy
3506
+ };
3507
+ }
3508
+ throw new Error("unexpected function");
3509
+ });
3510
+ return serializeInstructions(translateSegments(mapped, bounded.x1, bounded.y1));
3511
+ };
3512
+ // src/warp-path/warp-helpers.ts
3513
+ var euclideanDistance = (points) => {
3514
+ const startPoint = points[0];
3515
+ const endPoint = points[points.length - 1];
3516
+ let d2 = 0;
3517
+ for (let i = 0;i < startPoint.length; i++) {
3518
+ const d = endPoint[i] - startPoint[i];
3519
+ d2 += d ** 2;
3520
+ }
3521
+ return Math.sqrt(d2);
3522
+ };
3523
+ function split(p, t = 0.5) {
3524
+ const seg0 = [];
3525
+ const seg1 = [];
3526
+ const orders = [p];
3527
+ while (orders.length < p.length) {
3528
+ const q = orders[orders.length - 1];
3529
+ const r = [];
3530
+ for (let i = 1;i < q.length; i++) {
3531
+ const q0 = q[i - 1];
3532
+ const q1 = q[i];
3533
+ const s = [];
3534
+ const dim = Math.max(q0.length, q1.length);
3535
+ for (let j = 0;j < dim; j++) {
3536
+ const s0 = q0[j] || 0;
3537
+ const s1 = q1[j] || 0;
3538
+ s.push(s0 + (s1 - s0) * t);
3539
+ }
3540
+ r.push(s);
3541
+ }
3542
+ orders.push(r);
3543
+ }
3544
+ for (let i = 0;i < orders.length; i++) {
3545
+ seg0.push(orders[i][0]);
3546
+ seg1.push(orders[orders.length - 1 - i][i]);
3547
+ }
3548
+ return [seg0, seg1];
3549
+ }
3550
+ function interpolateUntil(points, threshold, deltaFunction = euclideanDistance) {
3551
+ const stack = [points];
3552
+ const segments = [];
3553
+ while (stack.length > 0) {
3554
+ const currentPoints = stack.pop();
3555
+ if (deltaFunction(currentPoints) > threshold) {
3556
+ const newPoints = split(currentPoints);
3557
+ for (let i = newPoints.length - 1;i >= 0; i--) {
3558
+ stack.push(newPoints[i]);
3559
+ }
3560
+ } else {
3561
+ segments.push(currentPoints);
3562
+ }
3563
+ }
3564
+ return segments;
3565
+ }
3566
+ function createLineSegment(points) {
3567
+ switch (points.length) {
3568
+ case 2:
3569
+ return {
3570
+ type: "L",
3571
+ x: points[1][0],
3572
+ y: points[1][1]
3573
+ };
3574
+ case 3:
3575
+ return convertQToCInstruction({
3576
+ type: "Q",
3577
+ cpx: points[1][0],
3578
+ cpy: points[1][1],
3579
+ x: points[2][0],
3580
+ y: points[2][1]
3581
+ }, {
3582
+ x: points[0][0],
3583
+ y: points[0][1]
3584
+ });
3585
+ case 4:
3586
+ return {
3587
+ type: "C",
3588
+ cp1x: points[1][0],
3589
+ cp1y: points[1][1],
3590
+ cp2x: points[2][0],
3591
+ cp2y: points[2][1],
3592
+ x: points[3][0],
3593
+ y: points[3][1]
3594
+ };
3595
+ default:
3596
+ throw new Error("Expected 2, 3 or 4 points for a line segment, got " + points.length);
3597
+ }
3598
+ }
3599
+ function warpInterpolate(path, threshold, deltaFunction) {
3600
+ let prexX = 0;
3601
+ let prexY = 0;
3602
+ return path.map((segment) => {
3603
+ const points = [[prexX, prexY]];
3604
+ if (segment.type !== "Z") {
3605
+ prexX = segment.x;
3606
+ prexY = segment.y;
3607
+ }
3608
+ if (segment.type === "C") {
3609
+ points.push([segment.cp1x, segment.cp1y]);
3610
+ points.push([segment.cp2x, segment.cp2y]);
3611
+ points.push([segment.x, segment.y]);
3612
+ }
3613
+ if (segment.type === "L") {
3614
+ points.push([segment.x, segment.y]);
3615
+ }
3616
+ if (segment.type === "C" || segment.type === "L") {
3617
+ return interpolateUntil(points, threshold, deltaFunction).map((rawSegment) => createLineSegment(rawSegment));
3618
+ }
3619
+ return [segment];
3620
+ }).flat(1);
3621
+ }
3622
+ function svgPathInterpolate(path, threshold) {
3623
+ let didWork = false;
3624
+ const deltaFunction = (points) => {
3625
+ const linearPoints = [
3626
+ points[0].slice(0, 2),
3627
+ points[points.length - 1].slice(0, 2)
3628
+ ];
3629
+ const delta = euclideanDistance(linearPoints);
3630
+ didWork = didWork || delta > threshold;
3631
+ return delta;
3632
+ };
3633
+ return warpInterpolate(path, threshold, deltaFunction);
3634
+ }
3635
+ var warpTransform = (path, transformer) => {
3636
+ return path.map((segment) => {
3637
+ if (segment.type === "L") {
3638
+ const { x, y } = transformer({ x: segment.x, y: segment.y });
3639
+ return [
3640
+ {
3641
+ type: "L",
3642
+ x,
3643
+ y
3644
+ }
3645
+ ];
3646
+ }
3647
+ if (segment.type === "C") {
3648
+ const { x, y } = transformer({ x: segment.x, y: segment.y });
3649
+ const { x: cp1x, y: cp1y } = transformer({
3650
+ x: segment.cp1x,
3651
+ y: segment.cp1y
3652
+ });
3653
+ const { x: cp2x, y: cp2y } = transformer({
3654
+ x: segment.cp2x,
3655
+ y: segment.cp2y
3656
+ });
3657
+ return [
3658
+ {
3659
+ type: "C",
3660
+ x,
3661
+ y,
3662
+ cp1x,
3663
+ cp1y,
3664
+ cp2x,
3665
+ cp2y
3666
+ }
3667
+ ];
3668
+ }
3669
+ if (segment.type === "M") {
3670
+ const { x, y } = transformer({ x: segment.x, y: segment.y });
3671
+ return [
3672
+ {
3673
+ type: "M",
3674
+ x,
3675
+ y
3676
+ }
3677
+ ];
3678
+ }
3679
+ return [segment];
3680
+ }).flat(1);
3681
+ };
3682
+ var fixZInstruction = (instructions) => {
3683
+ let prevX = 0;
3684
+ let prevY = 0;
3685
+ return instructions.map((instruction) => {
3686
+ if (instruction.type === "Z") {
3687
+ return [
3688
+ {
3689
+ type: "L",
3690
+ x: prevX,
3691
+ y: prevY
3692
+ },
3693
+ {
3694
+ type: "Z"
3695
+ }
3696
+ ];
3697
+ }
3698
+ if (instruction.type === "M") {
3699
+ prevX = instruction.x;
3700
+ prevY = instruction.y;
3701
+ }
3702
+ return [instruction];
3703
+ }).flat(1);
3704
+ };
3705
+
3706
+ // src/warp-path/index.ts
3707
+ var getDefaultInterpolationThreshold = (instructions) => {
3708
+ const boundingBox = getBoundingBoxFromInstructions(instructions);
3709
+ const longer = Math.max(boundingBox.y2 - boundingBox.y1, boundingBox.x2 - boundingBox.x1);
3710
+ return longer * 0.01;
3711
+ };
3712
+ var warpPath = (path, transformer, options) => {
3713
+ const reduced = reduceInstructions(parsePath(path));
3714
+ const withZFix = fixZInstruction(reduced);
3715
+ const interpolated = svgPathInterpolate(withZFix, options?.interpolationThreshold ?? getDefaultInterpolationThreshold(withZFix));
3716
+ return serializeInstructions(warpTransform(interpolated, transformer));
3717
+ };
3718
+
3719
+ // src/index.ts
3720
+ var PathInternals = {
3721
+ getBoundingBoxFromInstructions,
3722
+ debugPath,
3723
+ cutPath
3724
+ };
3725
+ export {
3726
+ warpPath,
3727
+ translatePath,
3728
+ serializeInstructions,
3729
+ scalePath,
3730
+ reversePath,
3731
+ resetPath,
3732
+ reduceInstructions,
3733
+ parsePath,
3734
+ normalizePath,
3735
+ interpolatePath,
3736
+ getTangentAtLength,
3737
+ getSubpaths,
3738
+ getPointAtLength,
3739
+ getLength,
3740
+ getInstructionIndexAtLength,
3741
+ getBoundingBox,
3742
+ extendViewBox,
3743
+ evolvePath,
3744
+ PathInternals
3745
+ };