@heyramzi/ui 2.11.1 → 2.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/helpers.js +38 -38
- package/dist/agents/page-state.js +49 -50
- package/dist/agents/vendor/color.js +146 -127
- package/dist/agents/vendor/draw.js +617 -508
- package/dist/agents/vendor/engine.js +698 -599
- package/dist/agents/vendor/mesh.js +653 -683
- package/dist/agents/vendor/plastic.js +3913 -3112
- package/dist/agents/vendor/presets.js +163 -164
- package/dist/agents/vendor/shapes.js +21 -20
- package/dist/agents/vendor/ticker.js +41 -42
- package/dist/agents/vendor/types.js +1 -0
- package/dist/agents/vendor/wear.js +1421 -1448
- package/dist/ai/confirmation/confirmation-context.svelte.js +6 -6
- package/dist/ai/confirmation/index.js +3 -1
- package/dist/ai/index.js +33 -0
- package/dist/ai/prompt-input/index.js +3 -1
- package/dist/ai/reasoning/index.js +3 -1
- package/dist/ai/reasoning/reasoning-context.svelte.js +6 -6
- package/dist/ai/suggestion/index.js +3 -1
- package/dist/ai/typing-dots/index.js +3 -1
- package/dist/animations/text-swap.js +24 -24
- package/dist/brand/index.js +54 -48
- package/dist/canvas/card/resize.js +5 -3
- package/dist/canvas/edges/edge-path.js +255 -242
- package/dist/canvas/editor/context-menu.js +39 -36
- package/dist/canvas/editor/dispatch.svelte.js +154 -151
- package/dist/canvas/editor/editor-context.js +7 -2
- package/dist/canvas/editor/editor-mode.js +1 -0
- package/dist/canvas/editor/frame.js +73 -76
- package/dist/canvas/editor/hand-context.js +5 -2
- package/dist/canvas/editor/history-core.js +163 -191
- package/dist/canvas/editor/keymap.js +95 -169
- package/dist/canvas/editor/layout-actions.js +143 -144
- package/dist/canvas/editor/lock.js +52 -51
- package/dist/canvas/editor/rebase.js +217 -240
- package/dist/canvas/editor/style.js +132 -137
- package/dist/canvas/editor/text-field-context.js +7 -2
- package/dist/canvas/editor/z-order.js +65 -70
- package/dist/canvas/headless/alignment.js +22 -16
- package/dist/canvas/headless/break-apart-find.js +286 -279
- package/dist/canvas/headless/break-apart-pieces.js +62 -58
- package/dist/canvas/headless/break-apart-plan.js +299 -325
- package/dist/canvas/headless/break-apart-style.js +75 -70
- package/dist/canvas/headless/break-apart.js +188 -181
- package/dist/canvas/headless/canvas-cleanup.js +78 -58
- package/dist/canvas/headless/edge-anchors.js +115 -116
- package/dist/canvas/headless/edge-memo.js +24 -22
- package/dist/canvas/headless/edge-serialization.js +17 -27
- package/dist/canvas/headless/figure-geometry.js +232 -264
- package/dist/canvas/headless/fit-viewport.js +84 -67
- package/dist/canvas/headless/grid.js +88 -86
- package/dist/canvas/headless/icon-node.js +44 -36
- package/dist/canvas/headless/index.js +1 -0
- package/dist/canvas/headless/linkify.js +17 -19
- package/dist/canvas/headless/pen-marks.js +101 -95
- package/dist/canvas/headless/sketch.js +231 -209
- package/dist/canvas/headless/snap-guides.js +99 -83
- package/dist/canvas/headless/svg-figure.js +133 -117
- package/dist/canvas/headless/table-layout.js +146 -107
- package/dist/canvas/index.js +2 -0
- package/dist/canvas/lod/lod-mode.svelte.js +20 -18
- package/dist/canvas/lod/render-all.svelte.js +36 -39
- package/dist/canvas/ops/arrange.js +78 -71
- package/dist/canvas/ops/ops.js +260 -255
- package/dist/canvas/pen/colors.js +37 -35
- package/dist/canvas/pen/eraser.js +28 -27
- package/dist/canvas/pen/geometry.js +120 -130
- package/dist/canvas/pen/index.js +1 -0
- package/dist/canvas/pen/ops.js +11 -11
- package/dist/canvas/pen/pen-session.js +150 -159
- package/dist/canvas/pen/plugin.js +107 -104
- package/dist/canvas/pen/shapes.js +73 -68
- package/dist/canvas/pen/stroke-path.js +32 -30
- package/dist/canvas/pen/types.js +21 -21
- package/dist/canvas/pen/ui.js +10 -8
- package/dist/canvas/plugin.js +46 -46
- package/dist/canvas/screen/glyphs.js +12 -11
- package/dist/canvas/screen/labels.js +22 -22
- package/dist/canvas/screen/parts.js +98 -111
- package/dist/canvas/screen/plugin.js +47 -56
- package/dist/canvas/screen/types.js +30 -35
- package/dist/canvas/screen/ui.js +7 -7
- package/dist/canvas/test-utils.js +14 -14
- package/dist/canvas/types.js +1 -0
- package/dist/canvas/ui/forward-wheel.js +24 -25
- package/dist/canvas/ui/icons.js +64 -131
- package/dist/canvas/ui/place-panel.js +58 -49
- package/dist/canvas/ui/shortcut-tip.js +14 -12
- package/dist/canvas/ui/tools.js +300 -385
- package/dist/charts/dashboard/chart.js +4 -0
- package/dist/charts/dashboard/data-table.js +11 -0
- package/dist/charts/dashboard/windows.js +8 -3
- package/dist/charts/edge-fade.js +10 -5
- package/dist/charts/hover-band.js +16 -11
- package/dist/charts/index.js +0 -1
- package/dist/charts/motion.js +11 -7
- package/dist/charts/primitives/chart-utils.js +12 -12
- package/dist/components/copy/clipboard.js +32 -32
- package/dist/components/copy/copied.svelte.js +31 -23
- package/dist/components/data-table/data-table.js +39 -39
- package/dist/components/docs/index.js +4 -0
- package/dist/components/docs/scroll-spy.svelte.js +73 -68
- package/dist/components/list-page/filter-section.js +4 -1
- package/dist/components/list-page/index.js +2 -0
- package/dist/components/list-page/list-table.js +7 -2
- package/dist/components/list-page/queue-rail.js +14 -0
- package/dist/components/list-page/section-host.js +4 -2
- package/dist/components/list-page/step.js +4 -3
- package/dist/components/list-page/types.js +1 -0
- package/dist/components/picker/trigger.js +48 -30
- package/dist/components/picker/types.js +1 -0
- package/dist/components/segmented/collapse.js +38 -27
- package/dist/components/segmented/index.js +8 -0
- package/dist/components/segmented/segmented.js +67 -42
- package/dist/components/star-rating-input/index.js +3 -1
- package/dist/components/table-view/types.js +1 -0
- package/dist/components/tags-input/tags.js +81 -69
- package/dist/components/theme/index.js +4 -0
- package/dist/components/toolbar/index.js +4 -0
- package/dist/components/toolbar/toolbar-trigger.js +14 -1
- package/dist/editor/anchors.js +17 -13
- package/dist/editor/block-id.js +52 -51
- package/dist/editor/block-ops.js +108 -80
- package/dist/editor/doc-blocks.js +155 -166
- package/dist/editor/extensions.js +139 -180
- package/dist/editor/index.js +4 -0
- package/dist/editor/markdown-test-helpers.js +4 -2
- package/dist/editor/markdown.js +420 -408
- package/dist/editor/serializer.js +204 -200
- package/dist/editor/slash-items.js +89 -101
- package/dist/editor/youtube-url.js +25 -20
- package/dist/effects/animated-beam/path-calculator.svelte.js +43 -38
- package/dist/effects/animated-beam/types.js +1 -0
- package/dist/effects/border-beam/css.js +92 -78
- package/dist/effects/border-beam/presets.js +1705 -1720
- package/dist/effects/border-beam/register-properties.js +43 -33
- package/dist/effects/border-beam/types.js +1 -0
- package/dist/effects/image-comparison/compare.js +3 -2
- package/dist/effects/image-reveal/types.js +1 -0
- package/dist/effects/magnetic/magnetic.js +58 -52
- package/dist/effects/reveal/observe.js +50 -40
- package/dist/effects/reveal/types.js +1 -0
- package/dist/effects/shader-gradient/color.js +36 -29
- package/dist/effects/shader-gradient/renderer.js +384 -295
- package/dist/effects/shader-gradient/shaders.js +31 -0
- package/dist/effects/shader-gradient/types.js +1 -0
- package/dist/icons/apple-symbol-exports.js +99 -124
- package/dist/icons/sf-symbols.js +357 -461
- package/dist/icons/trades.js +43 -28
- package/dist/inbox/index.js +1 -0
- package/dist/inbox/logic.js +126 -122
- package/dist/inbox/types.js +43 -43
- package/dist/lib/arrive.js +19 -12
- package/dist/lib/icon-types.js +1 -0
- package/dist/lib/initials.js +16 -10
- package/dist/lib/layout.js +5 -0
- package/dist/lib/panel.js +13 -0
- package/dist/lib/result.js +22 -22
- package/dist/lib/sliding-pill.js +59 -44
- package/dist/lib/theme-transition.js +43 -43
- package/dist/lib/tone.js +31 -24
- package/dist/lib/utils.js +3 -1
- package/dist/onboarding/define-tours.js +24 -23
- package/dist/onboarding/onboarding.svelte.js +16 -12
- package/dist/onboarding/pick.js +10 -6
- package/dist/onboarding/stores.js +40 -41
- package/dist/onboarding/wait.js +24 -23
- package/dist/panel/side-panel-types.js +1 -0
- package/dist/record/demo-data.js +459 -486
- package/dist/record/fields.js +129 -131
- package/dist/record/format.js +70 -82
- package/dist/record/gutter.js +1 -0
- package/dist/record/kinds.js +95 -105
- package/dist/record/logic.js +238 -219
- package/dist/record/types.js +49 -48
- package/dist/shadcn/accordion/index.js +3 -1
- package/dist/shadcn/alert/index.js +3 -1
- package/dist/shadcn/alert-dialog/index.js +3 -1
- package/dist/shadcn/attachment/index.js +3 -1
- package/dist/shadcn/avatar/index.js +3 -1
- package/dist/shadcn/breadcrumb/index.js +3 -1
- package/dist/shadcn/bubble/index.js +3 -1
- package/dist/shadcn/button/index.js +3 -1
- package/dist/shadcn/calendar/index.js +3 -1
- package/dist/shadcn/card/index.js +3 -1
- package/dist/shadcn/checkbox/index.js +3 -1
- package/dist/shadcn/code-block/index.js +3 -1
- package/dist/shadcn/collapsible/index.js +3 -1
- package/dist/shadcn/command/index.js +4 -1
- package/dist/shadcn/context-menu/index.js +3 -1
- package/dist/shadcn/dialog/index.js +3 -1
- package/dist/shadcn/dropdown-menu/menu-item.js +40 -20
- package/dist/shadcn/empty/index.js +3 -1
- package/dist/shadcn/field/index.js +3 -1
- package/dist/shadcn/hooks/highlighter.js +77 -75
- package/dist/shadcn/hooks/is-mobile.svelte.js +3 -3
- package/dist/shadcn/hooks/use-highlighted-code.svelte.js +62 -62
- package/dist/shadcn/input/index.js +3 -1
- package/dist/shadcn/kbd/index.js +3 -1
- package/dist/shadcn/label/index.js +3 -1
- package/dist/shadcn/marker/index.js +3 -1
- package/dist/shadcn/message/index.js +3 -1
- package/dist/shadcn/message-scroller/index.js +3 -1
- package/dist/shadcn/popover/index.js +3 -1
- package/dist/shadcn/progress/index.js +3 -1
- package/dist/shadcn/progress/tone.js +8 -7
- package/dist/shadcn/radio-group/index.js +3 -1
- package/dist/shadcn/scroll-area/index.js +3 -1
- package/dist/shadcn/select/index.js +3 -1
- package/dist/shadcn/separator/index.js +3 -1
- package/dist/shadcn/sheet/index.js +3 -1
- package/dist/shadcn/sidebar/context.svelte.js +42 -28
- package/dist/shadcn/sidebar/index.js +3 -1
- package/dist/shadcn/skeleton/index.js +3 -1
- package/dist/shadcn/slider/index.js +3 -1
- package/dist/shadcn/switch/index.js +3 -1
- package/dist/shadcn/table/index.js +3 -1
- package/dist/shadcn/tabs/index.js +3 -1
- package/dist/shadcn/textarea/index.js +3 -1
- package/dist/shadcn/toggle/index.js +3 -1
- package/dist/shadcn/toggle-group/index.js +3 -1
- package/dist/shadcn/tooltip/context.js +7 -2
- package/dist/shadcn/tooltip/index.js +3 -1
- package/dist/shadcn/trace/index.js +3 -1
- package/dist/slides/bridges.js +65 -59
- package/dist/slides/deck-controller.svelte.js +210 -207
- package/dist/slides/export/capture.js +66 -71
- package/dist/slides/export/ffmpeg.js +76 -72
- package/dist/slides/export/index.js +3 -0
- package/dist/slides/export/launch.js +9 -6
- package/dist/slides/export/pdf.js +60 -54
- package/dist/slides/export/types.js +1 -0
- package/dist/slides/labels.js +24 -24
- package/dist/slides/layout.js +39 -41
- package/dist/slides/model.js +9 -7
- package/dist/slides/navigation.js +78 -73
- package/dist/slides/types.js +2 -2
- package/dist/status/define-statuses.js +18 -14
- package/dist/status/status-types.js +1 -0
- package/dist/test-setup.js +24 -20
- package/dist/thread/logic.js +73 -77
- package/dist/thread/types.js +21 -21
- package/dist/work/board-order.js +94 -90
- package/dist/work/dates.js +16 -9
- package/dist/work/detail/detail-types.js +18 -18
- package/dist/work/docs/edited.js +32 -29
- package/dist/work/docs/index.js +4 -0
- package/dist/work/docs/labels.js +34 -34
- package/dist/work/docs/menu.js +113 -106
- package/dist/work/docs/outline.js +39 -29
- package/dist/work/gantt/logic.js +211 -235
- package/dist/work/inbox/inbox-logic.js +71 -75
- package/dist/work/inbox/inbox-statuses.js +75 -72
- package/dist/work/inbox/inbox-types.js +1 -0
- package/dist/work/kanban-drag.js +27 -22
- package/dist/work/kanban-types.js +1 -0
- package/dist/work/presets/sales.js +36 -32
- package/dist/work/reorder.js +9 -8
- package/dist/work/task-types.js +1 -0
- package/dist/work/time/duration.js +51 -46
- package/dist/work/time/time-types.js +23 -23
- package/dist/work/use-kanban-dnd.svelte.js +126 -125
- package/package.json +3 -1
- package/src/components/list-page/master-detail.svelte +3 -1
- package/src/components/list-page/rail-row.svelte +4 -4
- package/src/editor/markdown.ts +30 -35
|
@@ -1,331 +1,299 @@
|
|
|
1
1
|
const FALLBACK_FONT = 16;
|
|
2
2
|
const ORIGIN = {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
x: 0,
|
|
4
|
+
y: 0
|
|
5
5
|
};
|
|
6
6
|
export function isEl(child) {
|
|
7
|
-
|
|
7
|
+
return typeof child !== "string";
|
|
8
8
|
}
|
|
9
9
|
export function num(value, fallback = 0) {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const parsed = Number.parseFloat(value ?? "");
|
|
11
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
12
12
|
}
|
|
13
|
+
/** A paint that draws: set, and not `none`. */
|
|
13
14
|
export function solid(value) {
|
|
14
|
-
|
|
15
|
+
return Boolean(value) && value !== "none";
|
|
15
16
|
}
|
|
16
17
|
export function plus(a, b) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
return {
|
|
19
|
+
x: a.x + b.x,
|
|
20
|
+
y: a.y + b.y
|
|
21
|
+
};
|
|
21
22
|
}
|
|
23
|
+
/** `translate(a b)` and nothing else. Any other transform makes the geometry unreadable: null. */
|
|
22
24
|
export function translateOf(el) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
const raw = el.attrs.transform?.trim();
|
|
26
|
+
if (!raw) return {
|
|
27
|
+
x: 0,
|
|
28
|
+
y: 0
|
|
29
|
+
};
|
|
30
|
+
const match = raw.match(/^translate\(\s*(-?[\d.]+)[\s,]*(-?[\d.]+)?\s*\)$/);
|
|
31
|
+
return match ? {
|
|
32
|
+
x: Number(match[1]),
|
|
33
|
+
y: Number(match[2] ?? 0)
|
|
34
|
+
} : null;
|
|
33
35
|
}
|
|
34
36
|
export function union(a, b) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
if (!a) return b;
|
|
38
|
+
if (!b) return a;
|
|
39
|
+
return {
|
|
40
|
+
x1: Math.min(a.x1, b.x1),
|
|
41
|
+
y1: Math.min(a.y1, b.y1),
|
|
42
|
+
x2: Math.max(a.x2, b.x2),
|
|
43
|
+
y2: Math.max(a.y2, b.y2)
|
|
44
|
+
};
|
|
43
45
|
}
|
|
44
46
|
export function boxOf(points) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
if (points.length === 0) return null;
|
|
48
|
+
return {
|
|
49
|
+
x1: Math.min(...points.map((p) => p.x)),
|
|
50
|
+
y1: Math.min(...points.map((p) => p.y)),
|
|
51
|
+
x2: Math.max(...points.map((p) => p.x)),
|
|
52
|
+
y2: Math.max(...points.map((p) => p.y))
|
|
53
|
+
};
|
|
52
54
|
}
|
|
53
55
|
export function within(inner, outer, tolerance = 1) {
|
|
54
|
-
|
|
56
|
+
return inner.x1 >= outer.x1 - tolerance && inner.y1 >= outer.y1 - tolerance && inner.x2 <= outer.x2 + tolerance && inner.y2 <= outer.y2 + tolerance;
|
|
55
57
|
}
|
|
56
58
|
export function contains(box, point, tolerance) {
|
|
57
|
-
|
|
59
|
+
return point.x >= box.x1 - tolerance && point.x <= box.x2 + tolerance && point.y >= box.y1 - tolerance && point.y <= box.y2 + tolerance;
|
|
58
60
|
}
|
|
59
|
-
export const areaOf = (b)=>(b.x2 - b.x1) * (b.y2 - b.y1);
|
|
60
|
-
export const centerOf = (b)=>({
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
export const areaOf = (b) => (b.x2 - b.x1) * (b.y2 - b.y1);
|
|
62
|
+
export const centerOf = (b) => ({
|
|
63
|
+
x: (b.x1 + b.x2) / 2,
|
|
64
|
+
y: (b.y1 + b.y2) / 2
|
|
65
|
+
});
|
|
64
66
|
export function distanceToBox(box, p) {
|
|
65
|
-
|
|
67
|
+
return Math.hypot(Math.max(box.x1 - p.x, 0, p.x - box.x2), Math.max(box.y1 - p.y, 0, p.y - box.y2));
|
|
66
68
|
}
|
|
67
69
|
export function distanceToSegment(a, b, p) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
const dx = b.x - a.x;
|
|
71
|
+
const dy = b.y - a.y;
|
|
72
|
+
const len = dx * dx + dy * dy;
|
|
73
|
+
const t = len === 0 ? 0 : Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / len));
|
|
74
|
+
return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy));
|
|
73
75
|
}
|
|
76
|
+
// Numbers per path command; the last two (or the one for H and V) are the end point.
|
|
74
77
|
const PATH_ARITY = {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
M: 2,
|
|
79
|
+
L: 2,
|
|
80
|
+
H: 1,
|
|
81
|
+
V: 1,
|
|
82
|
+
C: 6,
|
|
83
|
+
S: 4,
|
|
84
|
+
Q: 4,
|
|
85
|
+
T: 2,
|
|
86
|
+
A: 7,
|
|
87
|
+
Z: 0
|
|
85
88
|
};
|
|
89
|
+
/** Where one command ends, given its arguments and where the pen was. */
|
|
86
90
|
function pathEnd(upper, rel, args, cur) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
91
|
+
const at = (from, value) => rel ? from + value : value;
|
|
92
|
+
if (upper === "H") return {
|
|
93
|
+
x: at(cur.x, args[0]),
|
|
94
|
+
y: cur.y
|
|
95
|
+
};
|
|
96
|
+
if (upper === "V") return {
|
|
97
|
+
x: cur.x,
|
|
98
|
+
y: at(cur.y, args[0])
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
x: at(cur.x, args[args.length - 2]),
|
|
102
|
+
y: at(cur.y, args[args.length - 1])
|
|
103
|
+
};
|
|
100
104
|
}
|
|
105
|
+
/** The vertices a path passes through. Curve control points are skipped: the ends bound it well enough. */
|
|
101
106
|
export function pathPoints(d) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
107
|
+
const out = [];
|
|
108
|
+
let cur = {
|
|
109
|
+
x: 0,
|
|
110
|
+
y: 0
|
|
111
|
+
};
|
|
112
|
+
let start = {
|
|
113
|
+
x: 0,
|
|
114
|
+
y: 0
|
|
115
|
+
};
|
|
116
|
+
for (const part of d.matchAll(/([a-zA-Z])([^a-zA-Z]*)/g)) {
|
|
117
|
+
const cmd = part[1];
|
|
118
|
+
const upper = cmd.toUpperCase();
|
|
119
|
+
const size = PATH_ARITY[upper];
|
|
120
|
+
if (size === undefined) continue;
|
|
121
|
+
const nums = (part[2].match(/-?(?:\d+\.?\d*|\.\d+)(?:e-?\d+)?/gi) ?? []).map(Number);
|
|
122
|
+
if (upper === "Z") {
|
|
123
|
+
cur = start;
|
|
124
|
+
out.push(cur);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
for (let i = 0; i + size <= nums.length; i += size) {
|
|
128
|
+
cur = pathEnd(upper, cmd !== upper, nums.slice(i, i + size), cur);
|
|
129
|
+
if (upper === "M" && i === 0) start = cur;
|
|
130
|
+
out.push(cur);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
129
134
|
}
|
|
130
135
|
export function pointList(raw) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
const nums = (raw ?? "").match(/-?(?:\d+\.?\d*|\.\d+)/g)?.map(Number) ?? [];
|
|
137
|
+
const out = [];
|
|
138
|
+
for (let i = 0; i + 1 < nums.length; i += 2) out.push({
|
|
139
|
+
x: nums[i],
|
|
140
|
+
y: nums[i + 1]
|
|
141
|
+
});
|
|
142
|
+
return out;
|
|
138
143
|
}
|
|
139
144
|
export function textLines(el) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
145
|
+
const lines = [];
|
|
146
|
+
let line = "";
|
|
147
|
+
const flush = () => {
|
|
148
|
+
const clean = line.replace(/\s+/g, " ").trim();
|
|
149
|
+
if (clean) lines.push(clean);
|
|
150
|
+
line = "";
|
|
151
|
+
};
|
|
152
|
+
for (const child of el.children) {
|
|
153
|
+
if (typeof child === "string") line += child;
|
|
154
|
+
else if (child.tag === "tspan") {
|
|
155
|
+
if ("dy" in child.attrs || "y" in child.attrs) flush();
|
|
156
|
+
line += child.children.map((c) => typeof c === "string" ? c : "").join("");
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
flush();
|
|
160
|
+
return lines;
|
|
156
161
|
}
|
|
157
162
|
export function isBold(el) {
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
const weight = el.attrs["font-weight"];
|
|
164
|
+
return num(weight) >= 600 || weight === "bold";
|
|
160
165
|
}
|
|
161
166
|
export function fontSize(el) {
|
|
162
|
-
|
|
167
|
+
return num(el.attrs["font-size"], FALLBACK_FONT);
|
|
163
168
|
}
|
|
164
169
|
function rectBox({ attrs: a }) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
170
|
+
return {
|
|
171
|
+
x1: num(a.x),
|
|
172
|
+
y1: num(a.y),
|
|
173
|
+
x2: num(a.x) + num(a.width),
|
|
174
|
+
y2: num(a.y) + num(a.height)
|
|
175
|
+
};
|
|
171
176
|
}
|
|
172
177
|
function ellipseBox({ attrs: a }) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
178
|
+
const rx = num(a.rx, num(a.r));
|
|
179
|
+
const ry = num(a.ry, num(a.r));
|
|
180
|
+
return {
|
|
181
|
+
x1: num(a.cx) - rx,
|
|
182
|
+
y1: num(a.cy) - ry,
|
|
183
|
+
x2: num(a.cx) + rx,
|
|
184
|
+
y2: num(a.cy) + ry
|
|
185
|
+
};
|
|
181
186
|
}
|
|
182
187
|
function lineBox({ attrs: a }) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
y: num(a.y2)
|
|
191
|
-
}
|
|
192
|
-
]);
|
|
188
|
+
return boxOf([{
|
|
189
|
+
x: num(a.x1),
|
|
190
|
+
y: num(a.y1)
|
|
191
|
+
}, {
|
|
192
|
+
x: num(a.x2),
|
|
193
|
+
y: num(a.y2)
|
|
194
|
+
}]);
|
|
193
195
|
}
|
|
194
196
|
function polyBox({ attrs: a }) {
|
|
195
|
-
|
|
197
|
+
return boxOf(pointList(a.points));
|
|
196
198
|
}
|
|
197
199
|
function pathBox({ attrs: a }) {
|
|
198
|
-
|
|
200
|
+
return boxOf(pathPoints(a.d ?? ""));
|
|
199
201
|
}
|
|
200
202
|
function textLeft(x, width, anchor) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
+
if (anchor === "middle") return x - width / 2;
|
|
204
|
+
return anchor === "end" ? x - width : x;
|
|
203
205
|
}
|
|
204
206
|
function textBox(el) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
207
|
+
const lines = textLines(el);
|
|
208
|
+
const size = fontSize(el);
|
|
209
|
+
const width = Math.max(0, ...lines.map((l) => l.length)) * size * (isBold(el) ? .6 : .55);
|
|
210
|
+
const left = textLeft(num(el.attrs.x), width, el.attrs["text-anchor"]);
|
|
211
|
+
const y = num(el.attrs.y);
|
|
212
|
+
return {
|
|
213
|
+
x1: left,
|
|
214
|
+
y1: y - size * .8,
|
|
215
|
+
x2: left + width,
|
|
216
|
+
y2: y + size * .2 + Math.max(0, lines.length - 1) * size * 1.2
|
|
217
|
+
};
|
|
216
218
|
}
|
|
217
219
|
function groupBox(el) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
220
|
+
let box = null;
|
|
221
|
+
for (const child of el.children) {
|
|
222
|
+
if (isEl(child)) box = union(box, boxOfEl(child, ORIGIN));
|
|
223
|
+
}
|
|
224
|
+
return box;
|
|
223
225
|
}
|
|
224
226
|
const MEASURE = new Map([
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
ellipseBox
|
|
236
|
-
],
|
|
237
|
-
[
|
|
238
|
-
"line",
|
|
239
|
-
lineBox
|
|
240
|
-
],
|
|
241
|
-
[
|
|
242
|
-
"polyline",
|
|
243
|
-
polyBox
|
|
244
|
-
],
|
|
245
|
-
[
|
|
246
|
-
"polygon",
|
|
247
|
-
polyBox
|
|
248
|
-
],
|
|
249
|
-
[
|
|
250
|
-
"path",
|
|
251
|
-
pathBox
|
|
252
|
-
],
|
|
253
|
-
[
|
|
254
|
-
"text",
|
|
255
|
-
textBox
|
|
256
|
-
],
|
|
257
|
-
[
|
|
258
|
-
"g",
|
|
259
|
-
groupBox
|
|
260
|
-
],
|
|
261
|
-
[
|
|
262
|
-
"svg",
|
|
263
|
-
groupBox
|
|
264
|
-
]
|
|
227
|
+
["rect", rectBox],
|
|
228
|
+
["circle", ellipseBox],
|
|
229
|
+
["ellipse", ellipseBox],
|
|
230
|
+
["line", lineBox],
|
|
231
|
+
["polyline", polyBox],
|
|
232
|
+
["polygon", polyBox],
|
|
233
|
+
["path", pathBox],
|
|
234
|
+
["text", textBox],
|
|
235
|
+
["g", groupBox],
|
|
236
|
+
["svg", groupBox]
|
|
265
237
|
]);
|
|
238
|
+
/** The ink a shape takes, in the figure's own units. Text is estimated: no DOM here to measure it. */
|
|
266
239
|
export function boxOfEl(el, offset) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
240
|
+
const box = MEASURE.get(el.tag)?.(el);
|
|
241
|
+
if (!box) return null;
|
|
242
|
+
const at = plus(offset, translateOf(el) ?? ORIGIN);
|
|
243
|
+
return {
|
|
244
|
+
x1: box.x1 + at.x,
|
|
245
|
+
y1: box.y1 + at.y,
|
|
246
|
+
x2: box.x2 + at.x,
|
|
247
|
+
y2: box.y2 + at.y
|
|
248
|
+
};
|
|
276
249
|
}
|
|
277
250
|
export function visible(el) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
251
|
+
const fill = el.attrs.fill;
|
|
252
|
+
const stroke = el.attrs.stroke;
|
|
253
|
+
return fill !== undefined && fill !== "none" || stroke !== undefined && stroke !== "none";
|
|
281
254
|
}
|
|
282
255
|
export function viewBoxOf(root) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
256
|
+
const raw = root.attrs.viewBox ?? root.attrs.viewbox;
|
|
257
|
+
if (raw) {
|
|
258
|
+
const [x, y, w, h] = raw.trim().split(/[\s,]+/).map(Number);
|
|
259
|
+
if (w > 0 && h > 0) return {
|
|
260
|
+
x1: x,
|
|
261
|
+
y1: y,
|
|
262
|
+
x2: x + w,
|
|
263
|
+
y2: y + h
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
const w = num(root.attrs.width);
|
|
267
|
+
const h = num(root.attrs.height);
|
|
268
|
+
return w > 0 && h > 0 ? {
|
|
269
|
+
x1: 0,
|
|
270
|
+
y1: 0,
|
|
271
|
+
x2: w,
|
|
272
|
+
y2: h
|
|
273
|
+
} : null;
|
|
301
274
|
}
|
|
302
275
|
export function hasText(el) {
|
|
303
|
-
|
|
276
|
+
return el.tag === "text" && textLines(el).length > 0;
|
|
304
277
|
}
|
|
278
|
+
/** Where a line, polyline or path starts and stops, on the figure. Null for one with a transform we can't read. */
|
|
305
279
|
export function strokeEnds(el, offset) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
const first = pts[0];
|
|
326
|
-
const last = pts[pts.length - 1];
|
|
327
|
-
return [
|
|
328
|
-
plus(first, at),
|
|
329
|
-
plus(last, at)
|
|
330
|
-
];
|
|
280
|
+
const shift = translateOf(el);
|
|
281
|
+
if (!shift) return null;
|
|
282
|
+
const a = el.attrs;
|
|
283
|
+
let pts = [];
|
|
284
|
+
if (el.tag === "line") {
|
|
285
|
+
pts = [{
|
|
286
|
+
x: num(a.x1),
|
|
287
|
+
y: num(a.y1)
|
|
288
|
+
}, {
|
|
289
|
+
x: num(a.x2),
|
|
290
|
+
y: num(a.y2)
|
|
291
|
+
}];
|
|
292
|
+
} else if (el.tag === "polyline") pts = pointList(a.points);
|
|
293
|
+
else if (el.tag === "path") pts = pathPoints(a.d ?? "");
|
|
294
|
+
if (pts.length < 2) return null;
|
|
295
|
+
const at = plus(offset, shift);
|
|
296
|
+
const first = pts[0];
|
|
297
|
+
const last = pts[pts.length - 1];
|
|
298
|
+
return [plus(first, at), plus(last, at)];
|
|
331
299
|
}
|