@kitlangton/knobs 0.4.0-next.2 → 0.4.0-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -8
- package/dist/dev/{chunk-ayb292zj.js → chunk-j6zmtens.js} +1 -1
- package/dist/dev/{chunk-1qzffbpa.js → chunk-zwj6yngd.js} +66 -33
- package/dist/dev/index.js +3 -3
- package/dist/panel.js +66 -33
- package/dist/types/ui/compare-css.d.ts +1 -1
- package/dist/types/ui/compare-gpu.d.ts +0 -5
- package/dist/types/ui/compare-model.d.ts +31 -2
- package/dist/types/ui/compare.d.ts +17 -4
- package/dist/types/ui/icons.d.ts +40 -0
- package/dist/types/ui/index.d.ts +4 -2
- package/dist/types/ui/selection-pill-css.d.ts +1 -0
- package/dist/types/ui/selection-pill.d.ts +103 -0
- package/dist/types/ui/timeline-model.d.ts +23 -0
- package/dist/types/ui/timeline.d.ts +11 -1
- package/dist/types/ui/tree.d.ts +3 -2
- package/dist/ui-react.js +696 -270
- package/dist/ui-solid.js +696 -270
- package/dist/ui.js +716 -270
- package/package.json +1 -1
package/dist/ui.js
CHANGED
|
@@ -570,12 +570,20 @@ var compareCss = `
|
|
|
570
570
|
display:flex;flex-direction:column;gap:6px;width:100%;height:100%;min-height:160px;outline:none;user-select:none;-webkit-user-select:none;
|
|
571
571
|
font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left}
|
|
572
572
|
:where(.knobs-ui) :is(.knobs-cmp-mode,.knobs-cmp-toggle){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;margin:0;padding:0;outline:none;box-shadow:none}
|
|
573
|
-
.knobs-cmp-bar{flex:none;display:flex;align-items:center;gap:
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
.knobs-
|
|
578
|
-
.knobs-ui .knobs-cmp-mode
|
|
573
|
+
.knobs-cmp-bar{flex:none;display:flex;align-items:center;gap:var(--_k-gap);height:var(--_k-control-h)}
|
|
574
|
+
/* The modes: one fill, the selection pill on the one picked; a mode isn't brighter for being
|
|
575
|
+
picked: the pill's bright copy is. */
|
|
576
|
+
.knobs-cmp-modes{position:relative;display:inline-flex;height:var(--_k-control-h);border-radius:var(--_k-radius);background:var(--_k-fill)}
|
|
577
|
+
.knobs-cmp-modes[hidden]{display:none}
|
|
578
|
+
.knobs-ui .knobs-cmp-mode{display:inline-flex;align-items:center;height:100%;padding:0 8px;border-radius:var(--_k-radius);color:var(--_k-fg-2);cursor:pointer;white-space:nowrap;
|
|
579
|
+
transition:color calc(var(--_k-hover-out) * 1ms)}
|
|
580
|
+
.knobs-ui .knobs-cmp-mode:is(:hover,:focus-visible){color:var(--_k-fg)}
|
|
581
|
+
/* Toggles: icon buttons, the accent's wash when on. */
|
|
582
|
+
.knobs-ui .knobs-cmp-toggle{display:inline-flex;align-items:center;justify-content:center;width:var(--_k-control-h);height:var(--_k-control-h);border-radius:var(--_k-radius);color:var(--_k-fg-3);cursor:pointer;
|
|
583
|
+
transition:color calc(var(--_k-hover-out) * 1ms),background calc(var(--_k-hover-out) * 1ms)}
|
|
584
|
+
.knobs-ui .knobs-cmp-toggle:is(:hover,:focus-visible){color:var(--_k-fg);background:var(--_ku-wash)}
|
|
585
|
+
.knobs-ui .knobs-cmp-toggle[aria-pressed="true"]{color:var(--_k-accent-fg);background:var(--_k-accent-soft)}
|
|
586
|
+
.knobs-cmp-toggle svg{display:block}
|
|
579
587
|
.knobs-cmp-fill{flex:1}
|
|
580
588
|
.knobs-cmp-toggle[hidden]{display:none}
|
|
581
589
|
/* One surface: on a card (a walkthrough's step, a split's pane, anything .knobs-surface) or marked
|
|
@@ -590,7 +598,8 @@ var compareCss = `
|
|
|
590
598
|
/* Unzoomed, a finger still scrolls the page up and down; zoomed, the stage takes every gesture. */
|
|
591
599
|
.knobs-compare[data-zoomed] .knobs-cmp-stage{cursor:grab;touch-action:none}
|
|
592
600
|
.knobs-compare[data-panning],.knobs-compare[data-panning] *{cursor:grabbing!important}
|
|
593
|
-
.
|
|
601
|
+
/* Wiping, the grip stands in for the cursor. */
|
|
602
|
+
.knobs-compare[data-dragging],.knobs-compare[data-dragging] *{cursor:none!important}
|
|
594
603
|
.knobs-cmp-sizer{position:absolute;left:0;right:0;top:0;height:0;visibility:hidden;pointer-events:none}
|
|
595
604
|
.knobs-cmp-canvas{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none}
|
|
596
605
|
.knobs-cmp-media{position:absolute;left:0;top:0;display:block;max-width:none;margin:0;padding:0;border:0;object-fit:fill;transform-origin:0 0;pointer-events:none;will-change:transform}
|
|
@@ -598,18 +607,21 @@ var compareCss = `
|
|
|
598
607
|
/* Glass: what's behind shows through, blurred, on the knobs tokens. */
|
|
599
608
|
.knobs-cmp-label,.knobs-cmp-zoom{background:color-mix(in srgb,var(--_k-bg) 52%,transparent);-webkit-backdrop-filter:blur(14px) saturate(1.6);backdrop-filter:blur(14px) saturate(1.6);
|
|
600
609
|
box-shadow:inset 0 0 0 .5px var(--_k-border),inset 0 1px 0 var(--_k-rim),0 2px 10px rgba(0,0,0,calc(.18 * var(--_k-shadow-k,1)))}
|
|
601
|
-
.knobs-cmp-label{position:absolute;left:0;top:0;padding:1px 7px;border-radius:999px;font-size:var(--_k-text-meta);line-height:16px;color:var(--_k-fg-2);white-space:nowrap;pointer-events:none;will-change:transform;transition:color
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
/* The wipe: a hairline down the line with a grip at its middle; a wider strip takes the hand and
|
|
605
|
-
the keys (a slider). It fades with the mode. */
|
|
610
|
+
.knobs-cmp-label{position:absolute;left:0;top:0;padding:1px 7px;border-radius:999px;font-size:var(--_k-text-meta);line-height:16px;color:var(--_k-fg-2);white-space:nowrap;pointer-events:none;will-change:transform;transition:color calc(var(--_k-hover-out) * 1ms)}
|
|
611
|
+
/* The wipe: a hairline down the line with a raised grip at the pointer's height; a wider strip
|
|
612
|
+
takes the hand and the keys (a slider). It fades with the mode; wiping, line and grip brighten. */
|
|
606
613
|
.knobs-cmp-handle{cursor:ew-resize;position:absolute;left:-12px;top:0;width:24px;height:0;opacity:0;pointer-events:none;outline:none;will-change:transform;transition:opacity .18s cubic-bezier(.4,0,1,1)}
|
|
607
614
|
.knobs-cmp-handle[data-on]{opacity:1;pointer-events:auto;transition:opacity .22s cubic-bezier(.2,.8,.2,1)}
|
|
608
|
-
.knobs-cmp-handle::before{content:"";position:absolute;top:0;bottom:0;left:11.5px;width:1px;background:var(--_ku-cmp-line);box-shadow:0 0 0 .5px rgba(0,0,0,.28),0 0 6px rgba(0,0,0,.25)}
|
|
609
|
-
.knobs-cmp-handle::
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
.knobs-cmp-
|
|
615
|
+
.knobs-cmp-handle::before{content:"";position:absolute;top:0;bottom:0;left:11.5px;width:1px;background:color-mix(in srgb,var(--_ku-cmp-line) 72%,transparent);box-shadow:0 0 0 .5px rgba(0,0,0,.28),0 0 6px rgba(0,0,0,.25)}
|
|
616
|
+
.knobs-compare[data-dragging] .knobs-cmp-handle::before{background:var(--_ku-cmp-line)}
|
|
617
|
+
.knobs-cmp-grip{position:absolute;top:0;left:4px;width:16px;height:28px;border-radius:min(8px,calc(var(--_k-radius) * 999));background:var(--_k-bg-overlay);
|
|
618
|
+
box-shadow:var(--_k-shadow-overlay),inset 0 0 0 1px var(--_k-border),inset 0 1px 0 var(--_k-rim);will-change:transform;transition:box-shadow calc(var(--_k-hover-out) * 1ms)}
|
|
619
|
+
.knobs-cmp-grip::before,.knobs-cmp-grip::after{content:"";position:absolute;top:10px;width:1px;height:8px;background:var(--_k-fg-3);transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
620
|
+
.knobs-cmp-grip::before{left:6px}
|
|
621
|
+
.knobs-cmp-grip::after{left:9px}
|
|
622
|
+
.knobs-compare[data-dragging] .knobs-cmp-grip{box-shadow:var(--_k-shadow-overlay),inset 0 0 0 1px var(--_k-border-strong),inset 0 1px 0 var(--_k-rim)}
|
|
623
|
+
.knobs-compare[data-dragging] .knobs-cmp-grip::before,.knobs-compare[data-dragging] .knobs-cmp-grip::after{background:var(--_k-fg)}
|
|
624
|
+
.knobs-cmp-handle:focus-visible .knobs-cmp-grip,.knobs-compare[data-keyboard] .knobs-cmp-handle:focus .knobs-cmp-grip{box-shadow:var(--_k-shadow-overlay),0 0 0 2px var(--_k-accent)}
|
|
613
625
|
/* The split's hairline, down the middle side by side. */
|
|
614
626
|
.knobs-cmp-split{position:absolute;left:0;top:0;width:1px;height:0;margin-left:-.5px;background:color-mix(in srgb,var(--_k-bg) 72%,transparent);pointer-events:none;will-change:transform,opacity}
|
|
615
627
|
/* Zoomed: how far, and a way back, in the stage's corner; it fades in and out, nothing shifts. */
|
|
@@ -618,12 +630,12 @@ var compareCss = `
|
|
|
618
630
|
opacity:0;scale:.96;pointer-events:none;transition:opacity .16s cubic-bezier(.4,0,1,1),scale .16s cubic-bezier(.4,0,1,1)}
|
|
619
631
|
.knobs-cmp-zoom[data-on]{opacity:1;scale:1;pointer-events:auto;transition:opacity .2s cubic-bezier(.2,.8,.2,1),scale .2s cubic-bezier(.2,.8,.2,1)}
|
|
620
632
|
:where(.knobs-ui) .knobs-cmp-zoom-reset{all:revert;box-sizing:border-box;font:inherit;letter-spacing:inherit;margin:0;border:0;outline:none;box-shadow:none;
|
|
621
|
-
height:20px;padding:0
|
|
633
|
+
display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border-radius:999px;background:transparent;color:var(--_k-fg-2);cursor:pointer;transition:color .15s,background .15s}
|
|
622
634
|
:where(.knobs-ui) .knobs-cmp-zoom-reset:is(:hover,:focus-visible){color:var(--_k-fg);background:color-mix(in srgb,var(--_k-fg) 12%,transparent)}
|
|
623
635
|
.knobs-cmp-note{position:absolute;left:50%;top:50%;translate:-50% -50%;color:var(--_k-fg-3);font-size:var(--_k-text-meta);pointer-events:none}
|
|
624
636
|
.knobs-cmp-note:empty{display:none}
|
|
625
637
|
.knobs-cmp-strip-host{flex:none;height:60px;min-height:0}
|
|
626
|
-
.knobs-cmp-timeline-host{flex:none;
|
|
638
|
+
.knobs-cmp-timeline-host{flex:none;min-height:0}
|
|
627
639
|
/* The frame strip: Before over After per column, a difference bar under them, a dot where it peaks. */
|
|
628
640
|
.knobs-ui.knobs-cmp-strip{--_ku-cmp-diff:var(--k-compare-diff,var(--_k-ok));position:relative;width:100%;height:100%;min-height:40px;overflow:hidden;cursor:col-resize;touch-action:none;
|
|
629
641
|
font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg)}
|
|
@@ -766,7 +778,7 @@ var init_picker_css = __esm(() => {
|
|
|
766
778
|
.knobs-picker-suggested{flex:none;color:var(--_k-fg-3);font-size:var(--_k-text-meta)}
|
|
767
779
|
.knobs-picker-check{flex:none;display:flex;width:14px;height:14px;color:var(--_k-accent);opacity:0;scale:.6;filter:blur(2px);
|
|
768
780
|
transition:opacity .11s ease-in,scale .11s ease-in,filter .11s ease-in}
|
|
769
|
-
.knobs-picker-check svg{display:block;width:
|
|
781
|
+
.knobs-picker-check svg{display:block;width:12px;height:12px}
|
|
770
782
|
.knobs-picker-option[data-chosen] .knobs-picker-check{opacity:1;scale:1;filter:none;transition:opacity .15s ease-out,scale var(--kp-snappy-ms) var(--kp-snappy),filter .15s ease-out}
|
|
771
783
|
.knobs-picker-body{position:relative;overflow:visible}
|
|
772
784
|
.knobs-picker-body[data-moving]{overflow:hidden}
|
|
@@ -870,6 +882,15 @@ var readoutCss = `
|
|
|
870
882
|
@media(prefers-reduced-motion:reduce){.knobs-rd :where(*){transition:none!important}}
|
|
871
883
|
`;
|
|
872
884
|
|
|
885
|
+
// src/ui/selection-pill-css.ts
|
|
886
|
+
var selectionPillCss = `
|
|
887
|
+
.knobs-pick-pill,.knobs-pick-copy{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;transition:opacity .1s linear}
|
|
888
|
+
.knobs-pick-pill{background:var(--_k-fill-selected);will-change:transform}
|
|
889
|
+
.knobs-pick-copy{overflow:hidden;will-change:transform}
|
|
890
|
+
.knobs-pick-copy-rows{position:absolute;left:0;top:0;width:0;height:0}
|
|
891
|
+
:is(.knobs-pick-pill,.knobs-pick-copy)[data-off]{opacity:0}
|
|
892
|
+
`;
|
|
893
|
+
|
|
873
894
|
// src/tokens/color.ts
|
|
874
895
|
function linearToOklch([r, g, b, a]) {
|
|
875
896
|
const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
|
|
@@ -2797,11 +2818,9 @@ var css2 = `
|
|
|
2797
2818
|
.knobs-tree:focus .knobs-tree-row[data-active][aria-selected="true"]::before{background:var(--_ku-select-focus)}
|
|
2798
2819
|
.knobs-tree-row[data-drop="into"]::before{opacity:1;background:color-mix(in srgb,var(--_k-accent) 30%,transparent)}
|
|
2799
2820
|
.knobs-tree-row[data-dragged]{opacity:.38}
|
|
2800
|
-
/* glide:
|
|
2801
|
-
.knobs-tree-
|
|
2802
|
-
|
|
2803
|
-
.knobs-tree-cursor[data-on]{opacity:1}
|
|
2804
|
-
.knobs-tree:focus .knobs-tree-cursor{background:var(--_ku-select-focus)}
|
|
2821
|
+
/* glide: the selection pill on the selected row, in the selection's colour (the row's own stays off). */
|
|
2822
|
+
.knobs-tree>.knobs-pick-pill{background:var(--_ku-select)}
|
|
2823
|
+
.knobs-tree:focus>.knobs-pick-pill{background:var(--_ku-select-focus)}
|
|
2805
2824
|
.knobs-tree[data-glide] .knobs-tree-row[aria-selected="true"]::before{opacity:0!important}
|
|
2806
2825
|
.knobs-tree-row>*{position:relative}
|
|
2807
2826
|
.knobs-tree-caret{flex:none;display:flex;align-items:center;justify-content:center;width:16px;height:100%;color:var(--_k-fg-3);transition:transform var(--_ku-ease-ms) var(--_ku-ease)}
|
|
@@ -2833,22 +2852,20 @@ var css2 = `
|
|
|
2833
2852
|
box-shadow:0 0 0 1px var(--_k-border-strong),0 6px 18px rgba(0,0,0,calc(.35 * var(--_k-shadow-k,1)));pointer-events:none;white-space:nowrap;font:var(--_k-weight) var(--_k-font-size)/1.6 var(--_k-font)}
|
|
2834
2853
|
.knobs-tree-empty{padding:10px var(--_k-inset);color:var(--_k-fg-3)}
|
|
2835
2854
|
|
|
2836
|
-
/* Timeline:
|
|
2837
|
-
|
|
2855
|
+
/* Timeline: play beside a track: the ruler's canvas over a lane of markers, ranges as soft bands,
|
|
2856
|
+
and the playhead, a hairline in the accent with a cap. No clock: the time shows under the
|
|
2857
|
+
pointer on the track (the tag), in seconds, while hovering or scrubbing. */
|
|
2838
2858
|
:where(.knobs-timeline,.knobs-timeline *){box-sizing:border-box}
|
|
2839
2859
|
.knobs-ui.knobs-timeline{display:flex;align-items:stretch;gap:10px;width:100%;height:100%;min-height:52px;padding:6px var(--_k-inset) 8px 8px;outline:none;user-select:none;-webkit-user-select:none;
|
|
2840
2860
|
font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left}
|
|
2841
2861
|
:where(.knobs-ui) :is(.knobs-tl-play,.knobs-tl-edit){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;margin:0;padding:0;outline:none;box-shadow:none}
|
|
2842
|
-
.knobs-tl-transport{flex:none;display:flex;align-items:center
|
|
2862
|
+
.knobs-tl-transport{flex:none;display:flex;align-items:center}
|
|
2843
2863
|
.knobs-ui .knobs-tl-play{flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--_k-control-h);height:var(--_k-control-h);min-width:22px;min-height:22px;border-radius:calc(var(--_k-radius) * 999);
|
|
2844
2864
|
background:var(--_k-fill-selected);color:var(--_k-fg);cursor:pointer;transition:background .15s,transform .15s var(--_ku-ease)}
|
|
2845
2865
|
.knobs-ui .knobs-tl-play:hover{background:color-mix(in srgb,var(--_k-fg) 16%,transparent)}
|
|
2846
2866
|
.knobs-ui .knobs-tl-play:active{transform:scale(.94)}
|
|
2847
2867
|
.knobs-tl-play svg{width:12px;height:12px}
|
|
2848
2868
|
.knobs-timeline[data-playing] .knobs-tl-play{background:var(--_k-accent);color:var(--_k-bg)}
|
|
2849
|
-
.knobs-tl-time{display:flex;flex-direction:column;line-height:1.2;font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
|
|
2850
|
-
.knobs-tl-now{font:var(--_k-weight) var(--_k-value-size)/1.2 var(--_k-value-font);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";color:var(--_k-fg);white-space:nowrap}
|
|
2851
|
-
.knobs-tl-sub{font-size:var(--_k-text-meta);color:var(--_k-fg-3);white-space:nowrap}
|
|
2852
2869
|
.knobs-tl-track{position:relative;flex:1;min-width:0;overflow:hidden;border-radius:var(--_k-radius);background:var(--_k-fill);cursor:col-resize;touch-action:none;
|
|
2853
2870
|
transition:background calc(var(--_k-hover-out) * 1ms)}
|
|
2854
2871
|
.knobs-timeline:focus-visible .knobs-tl-track,.knobs-timeline[data-keyboard]:focus .knobs-tl-track{background:color-mix(in srgb,var(--_k-fill-selected) 80%,transparent)}
|
|
@@ -2872,7 +2889,8 @@ var css2 = `
|
|
|
2872
2889
|
.knobs-tl-pin{position:absolute;top:13px;left:-5px;width:10px;height:10px;pointer-events:auto;cursor:grab}
|
|
2873
2890
|
.knobs-tl-pin::after{content:"";position:absolute;inset:1.5px;border-radius:min(2px,var(--_k-radius));background:var(--knobs-tl-c);rotate:45deg;transition:background .15s,scale .2s var(--_ku-ease)}
|
|
2874
2891
|
.knobs-tl-mlabel{position:absolute;top:26px;left:3px;max-width:140px;padding:0 6px;border-radius:max(0px,calc(var(--_k-radius) - 3px));background:var(--_k-fill-selected);color:var(--_k-fg);
|
|
2875
|
-
font-size:var(--_k-text-meta);line-height:17px;white-space:nowrap;
|
|
2892
|
+
font-size:var(--_k-text-meta);line-height:17px;white-space:nowrap;pointer-events:auto;cursor:grab;transition:background .15s,color .15s}
|
|
2893
|
+
.knobs-tl-mtext{display:block;overflow:hidden;white-space:nowrap}
|
|
2876
2894
|
.knobs-tl-marker[data-selected]{--knobs-tl-c:var(--_k-accent)}
|
|
2877
2895
|
.knobs-tl-marker[data-selected] .knobs-tl-mlabel{background:color-mix(in srgb,var(--_k-accent) 24%,var(--_k-fill-selected))}
|
|
2878
2896
|
.knobs-tl-marker[data-selected] .knobs-tl-pin::after{scale:1.2}
|
|
@@ -2893,7 +2911,22 @@ var css2 = `
|
|
|
2893
2911
|
.knobs-timeline[data-scrubbing] .knobs-tl-hover{opacity:0}
|
|
2894
2912
|
@media(prefers-reduced-motion:reduce){.knobs-timeline :where(*,::before,::after){transition:none!important}}
|
|
2895
2913
|
@media(prefers-reduced-motion:reduce){:is(.knobs-tree,.knobs-split>.knobs-divider,.knobs-pane-head,.knobs-pane-rail) :where(*,::before,::after){transition:none!important}}
|
|
2896
|
-
|
|
2914
|
+
.knobs-tl-tag{position:absolute;left:0;bottom:2px;font-size:var(--_k-text-meta);line-height:16px;color:var(--_k-fg);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap;pointer-events:none;opacity:0}
|
|
2915
|
+
.knobs-tl-tag[data-on]{opacity:1}
|
|
2916
|
+
/* The lane (variant: "lane"): one slim track of ticks under a compare or a video; markers are
|
|
2917
|
+
faint chapter ticks, the current one in text colour; nothing to edit. */
|
|
2918
|
+
.knobs-ui.knobs-timeline[data-variant="lane"]{height:auto;min-height:0;padding:0;gap:var(--_k-gap)}
|
|
2919
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-track{height:var(--_k-control-h)}
|
|
2920
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-ruler{height:100%}
|
|
2921
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-lane{top:0}
|
|
2922
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-marker{top:0}
|
|
2923
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-marker::before{top:0;bottom:50%;left:-.75px;width:1.5px;background:var(--_k-fg-3)}
|
|
2924
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-marker[data-current]::before{background:var(--_k-fg)}
|
|
2925
|
+
.knobs-timeline[data-variant="lane"] :is(.knobs-tl-pin,.knobs-tl-mlabel,.knobs-tl-rlabel){display:none}
|
|
2926
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-head::before{top:0}
|
|
2927
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-head::after{content:none}
|
|
2928
|
+
.knobs-timeline[data-variant="lane"] .knobs-tl-tag{top:2px;bottom:auto}
|
|
2929
|
+
`, uiCss = () => aliased(css2 + readoutCss + overlayCss + bentoCss + activityCss + pickerCss + compareCss + selectionPillCss) + rolling_css_default, RESTYLED = ".knobs-ui,.knobs-panel,.knobs-chip,.knobs-notice", lookDefaults, tune = (s, m) => {
|
|
2897
2930
|
s.omega = m.omega;
|
|
2898
2931
|
s.zeta = m.zeta;
|
|
2899
2932
|
return s;
|
|
@@ -4659,6 +4692,283 @@ var init_tree_model = __esm(() => {
|
|
|
4659
4692
|
};
|
|
4660
4693
|
});
|
|
4661
4694
|
|
|
4695
|
+
// src/ui/icons.ts
|
|
4696
|
+
function icon(name, options = {}) {
|
|
4697
|
+
const size = options.small ? 12 : 16;
|
|
4698
|
+
return `<svg class="knobs-icon" viewBox="0 0 256 256" width="${size}" height="${size}" fill="currentColor" aria-hidden="true" focusable="false"><path d="${PATHS[name]}"/></svg>`;
|
|
4699
|
+
}
|
|
4700
|
+
var PATHS, ICON_NAMES;
|
|
4701
|
+
var init_icons = __esm(() => {
|
|
4702
|
+
PATHS = {
|
|
4703
|
+
arrowLeft: "M224,128a8,8,0,0,1-8,8H59.31l58.35,58.34a8,8,0,0,1-11.32,11.32l-72-72a8,8,0,0,1,0-11.32l72-72a8,8,0,0,1,11.32,11.32L59.31,120H216A8,8,0,0,1,224,128Z",
|
|
4704
|
+
arrowUpRight: "M200,64V168a8,8,0,0,1-16,0V83.31L69.66,197.66a8,8,0,0,1-11.32-11.32L172.69,72H88a8,8,0,0,1,0-16H192A8,8,0,0,1,200,64Z",
|
|
4705
|
+
arrowSquareOut: "M224,104a8,8,0,0,1-16,0V59.32l-66.33,66.34a8,8,0,0,1-11.32-11.32L196.68,48H152a8,8,0,0,1,0-16h64a8,8,0,0,1,8,8Zm-40,24a8,8,0,0,0-8,8v72H48V80h72a8,8,0,0,0,0-16H48A16,16,0,0,0,32,80V208a16,16,0,0,0,16,16H176a16,16,0,0,0,16-16V136A8,8,0,0,0,184,128Z",
|
|
4706
|
+
arrowCounterClockwise: "M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z",
|
|
4707
|
+
arrowUDownLeft: "M232,112a64.07,64.07,0,0,1-64,64H51.31l34.35,34.34a8,8,0,0,1-11.32,11.32l-48-48a8,8,0,0,1,0-11.32l48-48a8,8,0,0,1,11.32,11.32L51.31,160H168a48,48,0,0,0,0-96H80a8,8,0,0,1,0-16h88A64.07,64.07,0,0,1,232,112Z",
|
|
4708
|
+
arrowsHorizontal: "M136,40V216a8,8,0,0,1-16,0V40a8,8,0,0,1,16,0ZM96,120H35.31l18.35-18.34A8,8,0,0,0,42.34,90.34l-32,32a8,8,0,0,0,0,11.32l32,32a8,8,0,0,0,11.32-11.32L35.31,136H96a8,8,0,0,0,0-16Zm149.66,2.34-32-32a8,8,0,0,0-11.32,11.32L220.69,120H160a8,8,0,0,0,0,16h60.69l-18.35,18.34a8,8,0,0,0,11.32,11.32l32-32A8,8,0,0,0,245.66,122.34Z",
|
|
4709
|
+
caretDown: "M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z",
|
|
4710
|
+
caretLeft: "M165.66,202.34a8,8,0,0,1-11.32,11.32l-80-80a8,8,0,0,1,0-11.32l80-80a8,8,0,0,1,11.32,11.32L91.31,128Z",
|
|
4711
|
+
caretRight: "M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z",
|
|
4712
|
+
caretUp: "M213.66,165.66a8,8,0,0,1-11.32,0L128,91.31,53.66,165.66a8,8,0,0,1-11.32-11.32l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,213.66,165.66Z",
|
|
4713
|
+
check: "M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z",
|
|
4714
|
+
checkCircle: "M173.66,98.34a8,8,0,0,1,0,11.32l-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35A8,8,0,0,1,173.66,98.34ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z",
|
|
4715
|
+
circle: "M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Z",
|
|
4716
|
+
copy: "M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z",
|
|
4717
|
+
cornersIn: "M152,96V48a8,8,0,0,1,16,0V88h40a8,8,0,0,1,0,16H160A8,8,0,0,1,152,96ZM96,152H48a8,8,0,0,0,0,16H88v40a8,8,0,0,0,16,0V160A8,8,0,0,0,96,152Zm112,0H160a8,8,0,0,0-8,8v48a8,8,0,0,0,16,0V168h40a8,8,0,0,0,0-16ZM96,40a8,8,0,0,0-8,8V88H48a8,8,0,0,0,0,16H96a8,8,0,0,0,8-8V48A8,8,0,0,0,96,40Z",
|
|
4718
|
+
cornersOut: "M216,48V88a8,8,0,0,1-16,0V56H168a8,8,0,0,1,0-16h40A8,8,0,0,1,216,48ZM88,200H56V168a8,8,0,0,0-16,0v40a8,8,0,0,0,8,8H88a8,8,0,0,0,0-16Zm120-40a8,8,0,0,0-8,8v32H168a8,8,0,0,0,0,16h40a8,8,0,0,0,8-8V168A8,8,0,0,0,208,160ZM88,40H48a8,8,0,0,0-8,8V88a8,8,0,0,0,16,0V56H88a8,8,0,0,0,0-16Z",
|
|
4719
|
+
folder: "M216,72H130.67L102.93,51.2a16.12,16.12,0,0,0-9.6-3.2H40A16,16,0,0,0,24,64V200a16,16,0,0,0,16,16H216.89A15.13,15.13,0,0,0,232,200.89V88A16,16,0,0,0,216,72Zm0,128H40V64H93.33L123.2,86.4A8,8,0,0,0,128,88h88Z",
|
|
4720
|
+
keyboard: "M224,48H32A16,16,0,0,0,16,64V192a16,16,0,0,0,16,16H224a16,16,0,0,0,16-16V64A16,16,0,0,0,224,48Zm0,144H32V64H224V192Zm-16-64a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16H200A8,8,0,0,1,208,128Zm0-32a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16H200A8,8,0,0,1,208,96ZM72,160a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16h8A8,8,0,0,1,72,160Zm96,0a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,160Zm40,0a8,8,0,0,1-8,8h-8a8,8,0,0,1,0-16h8A8,8,0,0,1,208,160Z",
|
|
4721
|
+
magnifyingGlass: "M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z",
|
|
4722
|
+
magnifyingGlassMinus: "M152,112a8,8,0,0,1-8,8H80a8,8,0,0,1,0-16h64A8,8,0,0,1,152,112Zm77.66,117.66a8,8,0,0,1-11.32,0l-50.06-50.07a88.11,88.11,0,1,1,11.31-11.31l50.07,50.06A8,8,0,0,1,229.66,229.66ZM112,184a72,72,0,1,0-72-72A72.08,72.08,0,0,0,112,184Z",
|
|
4723
|
+
magnifyingGlassPlus: "M152,112a8,8,0,0,1-8,8H120v24a8,8,0,0,1-16,0V120H80a8,8,0,0,1,0-16h24V80a8,8,0,0,1,16,0v24h24A8,8,0,0,1,152,112Zm77.66,117.66a8,8,0,0,1-11.32,0l-50.06-50.07a88.11,88.11,0,1,1,11.31-11.31l50.07,50.06A8,8,0,0,1,229.66,229.66ZM112,184a72,72,0,1,0-72-72A72.08,72.08,0,0,0,112,184Z",
|
|
4724
|
+
microphone: "M128,176a48.05,48.05,0,0,0,48-48V64a48,48,0,0,0-96,0v64A48.05,48.05,0,0,0,128,176ZM96,64a32,32,0,0,1,64,0v64a32,32,0,0,1-64,0Zm40,143.6V240a8,8,0,0,1-16,0V207.6A80.11,80.11,0,0,1,48,128a8,8,0,0,1,16,0,64,64,0,0,0,128,0,8,8,0,0,1,16,0A80.11,80.11,0,0,1,136,207.6Z",
|
|
4725
|
+
paperPlaneRight: "M231.87,114l-168-95.89A16,16,0,0,0,40.92,37.34L71.55,128,40.92,218.67A16,16,0,0,0,56,240a16.15,16.15,0,0,0,7.93-2.1l167.92-96.05a16,16,0,0,0,.05-27.89ZM56,224a.56.56,0,0,0,0-.12L85.74,136H144a8,8,0,0,0,0-16H85.74L56.06,32.16A.46.46,0,0,0,56,32l168,95.83Z",
|
|
4726
|
+
pencilSimple: "M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM92.69,208H48V163.31l88-88L180.69,120ZM192,108.68,147.31,64l24-24L216,84.68Z",
|
|
4727
|
+
repeat: "M24,128A72.08,72.08,0,0,1,96,56H204.69L194.34,45.66a8,8,0,0,1,11.32-11.32l24,24a8,8,0,0,1,0,11.32l-24,24a8,8,0,0,1-11.32-11.32L204.69,72H96a56.06,56.06,0,0,0-56,56,8,8,0,0,1-16,0Zm200-8a8,8,0,0,0-8,8,56.06,56.06,0,0,1-56,56H51.31l10.35-10.34a8,8,0,0,0-11.32-11.32l-24,24a8,8,0,0,0,0,11.32l24,24a8,8,0,0,0,11.32-11.32L51.31,200H160a72.08,72.08,0,0,0,72-72A8,8,0,0,0,224,120Z",
|
|
4728
|
+
sidebar: "M216,40H40A16,16,0,0,0,24,56V200a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A16,16,0,0,0,216,40ZM40,56H80V200H40ZM216,200H96V56H216V200Z",
|
|
4729
|
+
x: "M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"
|
|
4730
|
+
};
|
|
4731
|
+
ICON_NAMES = Object.keys(PATHS);
|
|
4732
|
+
});
|
|
4733
|
+
|
|
4734
|
+
// src/ui/selection-pill.ts
|
|
4735
|
+
function pillSpring(distance, base = SPRINGS.default) {
|
|
4736
|
+
return distance > 400 ? { duration: base.duration * 1.4, bounce: base.bounce } : base;
|
|
4737
|
+
}
|
|
4738
|
+
function pillBoxOf(row, container) {
|
|
4739
|
+
return {
|
|
4740
|
+
x: row.left - container.left - container.clientLeft + container.scrollLeft,
|
|
4741
|
+
y: row.top - container.top - container.clientTop + container.scrollTop,
|
|
4742
|
+
w: row.width,
|
|
4743
|
+
h: row.height
|
|
4744
|
+
};
|
|
4745
|
+
}
|
|
4746
|
+
function pillRadius(from, to, h, k) {
|
|
4747
|
+
const t = Math.abs(to.h - from.h) > 0.5 ? (h - from.h) / (to.h - from.h) : Number.isFinite(k) ? k : 1;
|
|
4748
|
+
return from.r + (to.r - from.r) * Math.min(1, Math.max(0, t));
|
|
4749
|
+
}
|
|
4750
|
+
function pillProgress(from, to, at) {
|
|
4751
|
+
const d = Math.hypot(to.x - from.x, to.y - from.y);
|
|
4752
|
+
if (d < 0.5)
|
|
4753
|
+
return 1;
|
|
4754
|
+
const p = ((at.x - from.x) * (to.x - from.x) + (at.y - from.y) * (to.y - from.y)) / (d * d);
|
|
4755
|
+
return Math.min(1, Math.max(0, p));
|
|
4756
|
+
}
|
|
4757
|
+
function planPill(state, next, flags = {}) {
|
|
4758
|
+
if (!next)
|
|
4759
|
+
return { kind: "hide" };
|
|
4760
|
+
if (!state.shown || !state.at || flags.first || flags.reduced || flags.snap)
|
|
4761
|
+
return { kind: "land", box: next };
|
|
4762
|
+
const t = state.target;
|
|
4763
|
+
if (t && t.x === next.x && t.y === next.y && t.w === next.w && t.h === next.h)
|
|
4764
|
+
return { kind: "stay" };
|
|
4765
|
+
const d = Math.hypot(next.x - state.at.x, next.y - state.at.y);
|
|
4766
|
+
return { kind: "travel", box: next, spring: pillSpring(d) };
|
|
4767
|
+
}
|
|
4768
|
+
function selectionPill(container, options) {
|
|
4769
|
+
const doc = container.ownerDocument;
|
|
4770
|
+
const win = doc.defaultView;
|
|
4771
|
+
injectUiStyles(doc);
|
|
4772
|
+
if (win.getComputedStyle(container).position === "static")
|
|
4773
|
+
container.style.position = "relative";
|
|
4774
|
+
const pill = doc.createElement("i");
|
|
4775
|
+
pill.className = "knobs-pick-pill";
|
|
4776
|
+
pill.setAttribute("aria-hidden", "true");
|
|
4777
|
+
pill.dataset.off = "";
|
|
4778
|
+
const copyOn = options.copy !== false;
|
|
4779
|
+
const copy = doc.createElement("div");
|
|
4780
|
+
copy.className = "knobs-pick-copy";
|
|
4781
|
+
copy.setAttribute("aria-hidden", "true");
|
|
4782
|
+
copy.inert = true;
|
|
4783
|
+
copy.dataset.off = "";
|
|
4784
|
+
const copyRows = doc.createElement("div");
|
|
4785
|
+
copyRows.className = "knobs-pick-copy-rows";
|
|
4786
|
+
copy.append(copyRows);
|
|
4787
|
+
container.prepend(pill);
|
|
4788
|
+
if (copyOn)
|
|
4789
|
+
container.append(copy);
|
|
4790
|
+
const { omega, zeta } = springMotion(SPRINGS.default);
|
|
4791
|
+
const springs = [0, 0, 0, 0].map(() => new Spring(0, omega, zeta, 0.01));
|
|
4792
|
+
const [sx, sy, sw, sh] = springs;
|
|
4793
|
+
let shown = false;
|
|
4794
|
+
let first = true;
|
|
4795
|
+
let target = null;
|
|
4796
|
+
let from = { x: 0, y: 0, w: 0, h: 0 };
|
|
4797
|
+
let fromR = 0;
|
|
4798
|
+
let toR = 0;
|
|
4799
|
+
let rowBoxes = [];
|
|
4800
|
+
const clones = new Map;
|
|
4801
|
+
let disposed = false;
|
|
4802
|
+
const radiusOf = (row) => options.radius?.(row) ?? (Number.parseFloat(win.getComputedStyle(row).borderTopLeftRadius) || 0);
|
|
4803
|
+
const rowsNow = () => options.rows ? [...options.rows()] : [...container.children].filter((n) => n !== pill && n !== copy);
|
|
4804
|
+
const measure = (row) => {
|
|
4805
|
+
const c = container.getBoundingClientRect();
|
|
4806
|
+
const r = row.getBoundingClientRect();
|
|
4807
|
+
return pillBoxOf(r, {
|
|
4808
|
+
left: c.left,
|
|
4809
|
+
top: c.top,
|
|
4810
|
+
scrollLeft: container.scrollLeft,
|
|
4811
|
+
scrollTop: container.scrollTop,
|
|
4812
|
+
clientLeft: container.clientLeft,
|
|
4813
|
+
clientTop: container.clientTop
|
|
4814
|
+
});
|
|
4815
|
+
};
|
|
4816
|
+
const at = () => ({ x: sx.x, y: sy.x, w: sw.x, h: sh.x });
|
|
4817
|
+
const syncCopy = (span) => {
|
|
4818
|
+
if (!copyOn)
|
|
4819
|
+
return;
|
|
4820
|
+
const keep = new Set;
|
|
4821
|
+
for (const { row, box } of rowBoxes) {
|
|
4822
|
+
if (!boxesMeet(box, span))
|
|
4823
|
+
continue;
|
|
4824
|
+
keep.add(row);
|
|
4825
|
+
let n = clones.get(row);
|
|
4826
|
+
if (!n) {
|
|
4827
|
+
n = row.cloneNode(true);
|
|
4828
|
+
n.removeAttribute("id");
|
|
4829
|
+
for (const d of n.querySelectorAll("[id]"))
|
|
4830
|
+
d.removeAttribute("id");
|
|
4831
|
+
clones.set(row, n);
|
|
4832
|
+
copyRows.append(n);
|
|
4833
|
+
}
|
|
4834
|
+
const s = n.style;
|
|
4835
|
+
s.position = "absolute";
|
|
4836
|
+
s.inset = "auto";
|
|
4837
|
+
s.left = `${box.x}px`;
|
|
4838
|
+
s.top = `${box.y}px`;
|
|
4839
|
+
s.width = `${box.w}px`;
|
|
4840
|
+
s.height = `${box.h}px`;
|
|
4841
|
+
s.margin = "0";
|
|
4842
|
+
s.transform = "none";
|
|
4843
|
+
s.clipPath = "";
|
|
4844
|
+
s.opacity = "";
|
|
4845
|
+
s.boxSizing = "border-box";
|
|
4846
|
+
s.color = options.color ?? "var(--_k-fg)";
|
|
4847
|
+
}
|
|
4848
|
+
for (const [row, n] of clones)
|
|
4849
|
+
if (!keep.has(row)) {
|
|
4850
|
+
n.remove();
|
|
4851
|
+
clones.delete(row);
|
|
4852
|
+
}
|
|
4853
|
+
};
|
|
4854
|
+
const paint = () => {
|
|
4855
|
+
const b = at();
|
|
4856
|
+
const x0 = grid(b.x);
|
|
4857
|
+
const y0 = grid(b.y);
|
|
4858
|
+
const w = grid(b.x + b.w) - x0;
|
|
4859
|
+
const h = grid(b.y + b.h) - y0;
|
|
4860
|
+
const r = target ? pillRadius({ h: from.h, r: fromR }, { h: target.h, r: toR }, b.h, pillProgress(from, target, b)) : toR;
|
|
4861
|
+
const radius = `${Math.max(0, Math.min(r, h / 2, w / 2)).toFixed(2)}px`;
|
|
4862
|
+
for (const n of copyOn ? [pill, copy] : [pill]) {
|
|
4863
|
+
n.style.transform = `translate3d(${x0}px,${y0}px,0)`;
|
|
4864
|
+
n.style.width = `${w}px`;
|
|
4865
|
+
n.style.height = `${h}px`;
|
|
4866
|
+
n.style.borderRadius = radius;
|
|
4867
|
+
}
|
|
4868
|
+
if (copyOn)
|
|
4869
|
+
copyRows.style.transform = `translate3d(${-x0}px,${-y0}px,0)`;
|
|
4870
|
+
};
|
|
4871
|
+
const loop = frameLoop(win, (dt) => {
|
|
4872
|
+
for (const s of springs)
|
|
4873
|
+
s.step(dt);
|
|
4874
|
+
paint();
|
|
4875
|
+
return springs.some((s) => !s.resting);
|
|
4876
|
+
});
|
|
4877
|
+
const show = (on) => {
|
|
4878
|
+
shown = on;
|
|
4879
|
+
pill.toggleAttribute("data-off", !on);
|
|
4880
|
+
copy.toggleAttribute("data-off", !on);
|
|
4881
|
+
container.toggleAttribute("data-pick-empty", !on);
|
|
4882
|
+
};
|
|
4883
|
+
const update = (o) => {
|
|
4884
|
+
if (disposed)
|
|
4885
|
+
return;
|
|
4886
|
+
const row = options.selected();
|
|
4887
|
+
const next = row?.isConnected ? measure(row) : null;
|
|
4888
|
+
const plan = planPill({ shown, at: shown ? at() : null, target }, next, {
|
|
4889
|
+
first,
|
|
4890
|
+
reduced: reducedMotion(win),
|
|
4891
|
+
...o?.snap ? { snap: true } : {}
|
|
4892
|
+
});
|
|
4893
|
+
first = false;
|
|
4894
|
+
for (const n of clones.values())
|
|
4895
|
+
n.remove();
|
|
4896
|
+
clones.clear();
|
|
4897
|
+
rowBoxes = copyOn ? rowsNow().filter((r) => r.isConnected).map((r) => ({ row: r, box: measure(r) })) : [];
|
|
4898
|
+
if (plan.kind === "hide") {
|
|
4899
|
+
if (shown)
|
|
4900
|
+
show(false);
|
|
4901
|
+
return;
|
|
4902
|
+
}
|
|
4903
|
+
if (plan.kind === "stay") {
|
|
4904
|
+
syncCopy(boxUnion(at(), target));
|
|
4905
|
+
return;
|
|
4906
|
+
}
|
|
4907
|
+
const r = radiusOf(row);
|
|
4908
|
+
if (plan.kind === "land") {
|
|
4909
|
+
sx.snap(plan.box.x);
|
|
4910
|
+
sy.snap(plan.box.y);
|
|
4911
|
+
sw.snap(plan.box.w);
|
|
4912
|
+
sh.snap(plan.box.h);
|
|
4913
|
+
from = plan.box;
|
|
4914
|
+
fromR = r;
|
|
4915
|
+
toR = r;
|
|
4916
|
+
target = plan.box;
|
|
4917
|
+
syncCopy(plan.box);
|
|
4918
|
+
paint();
|
|
4919
|
+
loop.stop();
|
|
4920
|
+
if (!shown)
|
|
4921
|
+
show(true);
|
|
4922
|
+
return;
|
|
4923
|
+
}
|
|
4924
|
+
const m = springMotion(plan.spring);
|
|
4925
|
+
for (const s of springs) {
|
|
4926
|
+
s.omega = m.omega;
|
|
4927
|
+
s.zeta = m.zeta;
|
|
4928
|
+
}
|
|
4929
|
+
const now = at();
|
|
4930
|
+
fromR = target ? pillRadius({ h: from.h, r: fromR }, { h: target.h, r: toR }, now.h, pillProgress(from, target, now)) : r;
|
|
4931
|
+
from = now;
|
|
4932
|
+
toR = r;
|
|
4933
|
+
target = plan.box;
|
|
4934
|
+
sx.set(plan.box.x);
|
|
4935
|
+
sy.set(plan.box.y);
|
|
4936
|
+
sw.set(plan.box.w);
|
|
4937
|
+
sh.set(plan.box.h);
|
|
4938
|
+
syncCopy(boxUnion(now, plan.box));
|
|
4939
|
+
loop.wake();
|
|
4940
|
+
};
|
|
4941
|
+
const ro = "ResizeObserver" in win ? new win.ResizeObserver(() => update({ snap: true })) : null;
|
|
4942
|
+
ro?.observe(container);
|
|
4943
|
+
update();
|
|
4944
|
+
return {
|
|
4945
|
+
element: pill,
|
|
4946
|
+
update,
|
|
4947
|
+
dispose() {
|
|
4948
|
+
disposed = true;
|
|
4949
|
+
loop.stop();
|
|
4950
|
+
ro?.disconnect();
|
|
4951
|
+
pill.remove();
|
|
4952
|
+
copy.remove();
|
|
4953
|
+
container.removeAttribute("data-pick-empty");
|
|
4954
|
+
}
|
|
4955
|
+
};
|
|
4956
|
+
}
|
|
4957
|
+
var boxesMeet = (a, b) => a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h, boxUnion = (a, b) => {
|
|
4958
|
+
const x = Math.min(a.x, b.x);
|
|
4959
|
+
const y = Math.min(a.y, b.y);
|
|
4960
|
+
return {
|
|
4961
|
+
x,
|
|
4962
|
+
y,
|
|
4963
|
+
w: Math.max(a.x + a.w, b.x + b.w) - x,
|
|
4964
|
+
h: Math.max(a.y + a.h, b.y + b.h) - y
|
|
4965
|
+
};
|
|
4966
|
+
}, grid = (v) => Math.round(v * 64) / 64;
|
|
4967
|
+
var init_selection_pill = __esm(() => {
|
|
4968
|
+
init_motion();
|
|
4969
|
+
init_look();
|
|
4970
|
+
});
|
|
4971
|
+
|
|
4662
4972
|
// src/core/storage.ts
|
|
4663
4973
|
function browserStorage() {
|
|
4664
4974
|
return typeof window === "undefined" ? null : window.localStorage;
|
|
@@ -4981,10 +5291,25 @@ function advance(t, dt, o) {
|
|
|
4981
5291
|
}
|
|
4982
5292
|
return { t: hi, ended: true, wrapped: false };
|
|
4983
5293
|
}
|
|
4984
|
-
|
|
5294
|
+
function moveHead(head, t, motion, catching, minGap = 0) {
|
|
5295
|
+
if (motion === "jump" && Math.abs(t - head.x) > minGap)
|
|
5296
|
+
return { x: head.x, target: t, catching: true };
|
|
5297
|
+
if (catching)
|
|
5298
|
+
return { x: head.x + (t - head.target), target: t, catching: true };
|
|
5299
|
+
return { x: t, target: t, catching: false };
|
|
5300
|
+
}
|
|
5301
|
+
function currentMarker(markers, t, fps) {
|
|
5302
|
+
let best = null;
|
|
5303
|
+
for (const m of markers)
|
|
5304
|
+
if (m.time <= t + 0.5 / fps && (!best || m.time >= best.time))
|
|
5305
|
+
best = m;
|
|
5306
|
+
return best;
|
|
5307
|
+
}
|
|
5308
|
+
var SECOND_STEPS, FRAME_STEPS, toFrame = (t, fps) => Math.round(t * fps), frameTime = (t, fps) => Math.round(t * fps) / fps, round = (t) => Math.round(t * 1e6) / 1e6, CATCH_UP;
|
|
4985
5309
|
var init_timeline_model = __esm(() => {
|
|
4986
5310
|
SECOND_STEPS = [0.1, 0.2, 0.25, 0.5, 1, 2, 5, 10, 15, 30, 60, 120, 300, 600, 900, 1800, 3600];
|
|
4987
5311
|
FRAME_STEPS = [1, 2, 5, 10, 15, 30, 60, 120, 300, 600, 900, 1800, 3600, 9000, 18000];
|
|
5312
|
+
CATCH_UP = { duration: 0.15, bounce: 0 };
|
|
4988
5313
|
});
|
|
4989
5314
|
|
|
4990
5315
|
// src/ui/timeline.ts
|
|
@@ -4997,6 +5322,7 @@ function timeline(container, options) {
|
|
|
4997
5322
|
let speed = options.speed ?? 1;
|
|
4998
5323
|
let repeat = options.repeat ?? true;
|
|
4999
5324
|
const arrows = options.arrows ?? "frames";
|
|
5325
|
+
const lane = options.variant === "lane";
|
|
5000
5326
|
let time = Math.min(duration, Math.max(0, options.time ?? 0));
|
|
5001
5327
|
let playing = false;
|
|
5002
5328
|
let markers = [...options.markers ?? []];
|
|
@@ -5030,27 +5356,27 @@ function timeline(container, options) {
|
|
|
5030
5356
|
root.setAttribute("aria-label", options.label ?? "Timeline");
|
|
5031
5357
|
root.setAttribute("aria-keyshortcuts", "Space ArrowLeft ArrowRight , . Home End [ ] I O M");
|
|
5032
5358
|
applyLook2(root, options);
|
|
5359
|
+
if (lane)
|
|
5360
|
+
root.dataset.variant = "lane";
|
|
5033
5361
|
const transport = el("div", "knobs-tl-transport");
|
|
5034
5362
|
const playBtn = el("button", "knobs-tl-play");
|
|
5035
5363
|
playBtn.type = "button";
|
|
5036
5364
|
playBtn.tabIndex = -1;
|
|
5037
|
-
|
|
5038
|
-
const now = el("span", "knobs-tl-now");
|
|
5039
|
-
const sub = el("span", "knobs-tl-sub");
|
|
5040
|
-
readout.append(now, sub);
|
|
5041
|
-
transport.append(playBtn, readout);
|
|
5365
|
+
transport.append(playBtn);
|
|
5042
5366
|
const track = el("div", "knobs-tl-track");
|
|
5043
5367
|
const canvas = el("canvas", "knobs-tl-ruler");
|
|
5044
5368
|
canvas.setAttribute("aria-hidden", "true");
|
|
5045
|
-
const
|
|
5369
|
+
const markerLane = el("div", "knobs-tl-lane");
|
|
5046
5370
|
const hover = el("div", "knobs-tl-hover");
|
|
5371
|
+
const tag = el("span", "knobs-tl-tag");
|
|
5372
|
+
tag.setAttribute("aria-hidden", "true");
|
|
5047
5373
|
const head = el("div", "knobs-tl-head");
|
|
5048
5374
|
head.id = `${id}-head`;
|
|
5049
5375
|
head.setAttribute("role", "slider");
|
|
5050
5376
|
head.setAttribute("aria-label", "Playhead");
|
|
5051
5377
|
head.setAttribute("aria-valuemin", "0");
|
|
5052
5378
|
head.setAttribute("aria-valuemax", String(duration));
|
|
5053
|
-
track.append(canvas,
|
|
5379
|
+
track.append(canvas, markerLane, hover, head, tag);
|
|
5054
5380
|
root.append(transport, track);
|
|
5055
5381
|
container.append(root);
|
|
5056
5382
|
let width = 1;
|
|
@@ -5097,13 +5423,14 @@ function timeline(container, options) {
|
|
|
5097
5423
|
let drawn = "";
|
|
5098
5424
|
const drawRuler = () => {
|
|
5099
5425
|
const v = view();
|
|
5100
|
-
const key = `${v.start.toFixed(6)}:${v.span.toFixed(6)}:${width}:${units}:${fps}`;
|
|
5426
|
+
const key = `${v.start.toFixed(6)}:${v.span.toFixed(6)}:${width}:${height}:${units}:${fps}`;
|
|
5101
5427
|
if (key === drawn)
|
|
5102
5428
|
return;
|
|
5103
5429
|
drawn = key;
|
|
5104
5430
|
const dpr = win.devicePixelRatio || 1;
|
|
5105
5431
|
const w = Math.max(1, Math.round(width * dpr));
|
|
5106
|
-
const
|
|
5432
|
+
const rh = lane ? height : RULER;
|
|
5433
|
+
const h = Math.round(rh * dpr);
|
|
5107
5434
|
if (canvas.width !== w || canvas.height !== h) {
|
|
5108
5435
|
canvas.width = w;
|
|
5109
5436
|
canvas.height = h;
|
|
@@ -5112,8 +5439,19 @@ function timeline(container, options) {
|
|
|
5112
5439
|
if (!ctx)
|
|
5113
5440
|
return;
|
|
5114
5441
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
5115
|
-
ctx.clearRect(0, 0, width,
|
|
5442
|
+
ctx.clearRect(0, 0, width, rh);
|
|
5116
5443
|
const ticks = rulerTicks(v, width, { fps, units });
|
|
5444
|
+
if (lane) {
|
|
5445
|
+
ctx.fillStyle = colors.tick;
|
|
5446
|
+
for (const t of ticks.minor)
|
|
5447
|
+
if (t >= -0.000000001 && t <= duration + 0.000000001)
|
|
5448
|
+
ctx.fillRect(xOf(t) - 0.5, rh - 4, 1, 4);
|
|
5449
|
+
ctx.fillStyle = colors.major;
|
|
5450
|
+
for (const m of ticks.major)
|
|
5451
|
+
if (m.t >= -0.000000001 && m.t <= duration + 0.000000001)
|
|
5452
|
+
ctx.fillRect(xOf(m.t) - 0.5, rh - 7, 1, 7);
|
|
5453
|
+
return;
|
|
5454
|
+
}
|
|
5117
5455
|
const px = (t) => Math.round(xOf(t)) + 0.5;
|
|
5118
5456
|
ctx.fillStyle = colors.line;
|
|
5119
5457
|
ctx.fillRect(0, RULER - 1, width, 1);
|
|
@@ -5153,18 +5491,21 @@ function timeline(container, options) {
|
|
|
5153
5491
|
n.dataset.id = m.id;
|
|
5154
5492
|
const pin = el("span", "knobs-tl-pin");
|
|
5155
5493
|
const label = el("span", "knobs-tl-mlabel");
|
|
5494
|
+
label.append(el("span", "knobs-tl-mtext knobs-scroll-fade-x"));
|
|
5156
5495
|
n.append(pin, label);
|
|
5157
|
-
|
|
5496
|
+
markerLane.append(n);
|
|
5158
5497
|
markerEls.set(m.id, n);
|
|
5159
5498
|
if (built)
|
|
5160
5499
|
enter(n);
|
|
5161
5500
|
}
|
|
5162
5501
|
const label = n.querySelector(".knobs-tl-mlabel");
|
|
5163
|
-
|
|
5164
|
-
|
|
5502
|
+
const text = label.firstElementChild;
|
|
5503
|
+
if (text.textContent !== (m.label ?? ""))
|
|
5504
|
+
text.textContent = m.label ?? "";
|
|
5165
5505
|
label.hidden = !m.label;
|
|
5166
5506
|
n.style.setProperty("--knobs-tl-color", m.color ?? "");
|
|
5167
5507
|
n.toggleAttribute("data-selected", selected?.kind === "marker" && selected.id === m.id);
|
|
5508
|
+
n.toggleAttribute("data-current", m.id === currentId);
|
|
5168
5509
|
n.title = `${m.label ? `${m.label} · ` : ""}${clock(m.time)}`;
|
|
5169
5510
|
}
|
|
5170
5511
|
placeMarkers();
|
|
@@ -5192,7 +5533,7 @@ function timeline(container, options) {
|
|
|
5192
5533
|
b.dataset.edge = "end";
|
|
5193
5534
|
const label = el("span", "knobs-tl-rlabel");
|
|
5194
5535
|
n.append(label, a, b);
|
|
5195
|
-
track.insertBefore(n,
|
|
5536
|
+
track.insertBefore(n, markerLane);
|
|
5196
5537
|
rangeEls.set(r.id, n);
|
|
5197
5538
|
if (built)
|
|
5198
5539
|
enter(n);
|
|
@@ -5241,16 +5582,17 @@ function timeline(container, options) {
|
|
|
5241
5582
|
};
|
|
5242
5583
|
const clock = (t) => units === "frames" ? `f${toFrame(t, fps)}` : `${timeLabel(t, "seconds", fps, 0.01)}`;
|
|
5243
5584
|
let shownHead = time;
|
|
5585
|
+
let currentId = null;
|
|
5244
5586
|
const renderHead = () => {
|
|
5245
5587
|
head.style.transform = `translateX(${xOf(shownHead).toFixed(2)}px)`;
|
|
5246
|
-
const main = units === "frames" ? `f${toFrame(time, fps)}` : `${time.toFixed(2)}s`;
|
|
5247
|
-
const minor = units === "frames" ? `${time.toFixed(2)}s` : `f${toFrame(time, fps)}`;
|
|
5248
|
-
if (now.textContent !== main)
|
|
5249
|
-
now.textContent = main;
|
|
5250
|
-
if (sub.textContent !== minor)
|
|
5251
|
-
sub.textContent = minor;
|
|
5252
5588
|
head.setAttribute("aria-valuenow", time.toFixed(3));
|
|
5253
5589
|
head.setAttribute("aria-valuetext", `${time.toFixed(2)} seconds, frame ${toFrame(time, fps)}`);
|
|
5590
|
+
const cur = currentMarker(markers, time, fps)?.id ?? null;
|
|
5591
|
+
if (cur !== currentId) {
|
|
5592
|
+
markerEls.get(currentId ?? "")?.removeAttribute("data-current");
|
|
5593
|
+
currentId = cur;
|
|
5594
|
+
markerEls.get(cur ?? "")?.setAttribute("data-current", "");
|
|
5595
|
+
}
|
|
5254
5596
|
};
|
|
5255
5597
|
let viewSent = "";
|
|
5256
5598
|
const render = () => {
|
|
@@ -5276,18 +5618,27 @@ function timeline(container, options) {
|
|
|
5276
5618
|
};
|
|
5277
5619
|
const caret = new Spring(time, GLIDE.omega, GLIDE.zeta, 0.00001);
|
|
5278
5620
|
let gliding = false;
|
|
5279
|
-
const
|
|
5280
|
-
const
|
|
5281
|
-
|
|
5621
|
+
const headTo = (shown, motion) => {
|
|
5622
|
+
const from = gliding ? { x: caret.x, target: caret.target } : { x: shownHead, target: shownHead };
|
|
5623
|
+
const jump = motion === "jump" && !reducedMotion(win);
|
|
5624
|
+
const next = moveHead(from, shown, jump ? "jump" : "follow", gliding, 2 / pxPerSec());
|
|
5625
|
+
if (next.catching) {
|
|
5282
5626
|
if (!gliding)
|
|
5283
|
-
caret.snap(
|
|
5284
|
-
caret.
|
|
5627
|
+
caret.snap(from.x);
|
|
5628
|
+
caret.x = next.x;
|
|
5629
|
+
caret.target = next.target;
|
|
5285
5630
|
gliding = true;
|
|
5631
|
+
shownHead = caret.x;
|
|
5286
5632
|
loop.wake();
|
|
5287
5633
|
} else {
|
|
5288
5634
|
gliding = false;
|
|
5289
|
-
|
|
5635
|
+
caret.snap(next.x);
|
|
5636
|
+
shownHead = next.x;
|
|
5290
5637
|
}
|
|
5638
|
+
};
|
|
5639
|
+
const setTime = (t, source, shown = t, glide = false) => {
|
|
5640
|
+
const next = Math.min(duration, Math.max(0, t));
|
|
5641
|
+
headTo(Math.min(duration, Math.max(0, shown)), glide ? "jump" : "follow");
|
|
5291
5642
|
const moved = next !== time;
|
|
5292
5643
|
time = next;
|
|
5293
5644
|
renderHead();
|
|
@@ -5328,8 +5679,7 @@ function timeline(container, options) {
|
|
|
5328
5679
|
options.onCross?.(m);
|
|
5329
5680
|
}
|
|
5330
5681
|
time = step.t;
|
|
5331
|
-
|
|
5332
|
-
gliding = false;
|
|
5682
|
+
headTo(time, step.wrapped ? "jump" : "follow");
|
|
5333
5683
|
emitSeek(time, "play");
|
|
5334
5684
|
keepInView();
|
|
5335
5685
|
if (step.ended) {
|
|
@@ -5342,7 +5692,7 @@ function timeline(container, options) {
|
|
|
5342
5692
|
shownHead = caret.step(dt);
|
|
5343
5693
|
if (caret.resting) {
|
|
5344
5694
|
gliding = false;
|
|
5345
|
-
shownHead =
|
|
5695
|
+
shownHead = caret.target;
|
|
5346
5696
|
}
|
|
5347
5697
|
}
|
|
5348
5698
|
vStart.step(dt);
|
|
@@ -5355,9 +5705,9 @@ function timeline(container, options) {
|
|
|
5355
5705
|
return;
|
|
5356
5706
|
const r = loopRange();
|
|
5357
5707
|
if (r && (time < r.start || time >= r.end - 0.5 / fps))
|
|
5358
|
-
setTime(r.start, "code");
|
|
5708
|
+
setTime(r.start, "code", r.start, true);
|
|
5359
5709
|
else if (!r && time >= duration - 0.5 / fps)
|
|
5360
|
-
setTime(0, "code");
|
|
5710
|
+
setTime(0, "code", 0, true);
|
|
5361
5711
|
playing = true;
|
|
5362
5712
|
syncPlay();
|
|
5363
5713
|
emitPlay(true);
|
|
@@ -5486,24 +5836,35 @@ function timeline(container, options) {
|
|
|
5486
5836
|
};
|
|
5487
5837
|
const localX = (e) => e.clientX - track.getBoundingClientRect().left;
|
|
5488
5838
|
let drag = null;
|
|
5489
|
-
const scrubTo = (x) => {
|
|
5839
|
+
const scrubTo = (x, press = false) => {
|
|
5490
5840
|
const shownX = softClamp(x, xOf(0), xOf(duration), 10);
|
|
5491
5841
|
const s = scrubTime(tOf(shownX), {
|
|
5492
5842
|
duration,
|
|
5493
5843
|
fps,
|
|
5494
5844
|
pxPerSec: pxPerSec(),
|
|
5495
|
-
stops: snapMarkers ? markers.map((m) => m.time) : [],
|
|
5845
|
+
stops: snapMarkers && !lane ? markers.map((m) => m.time) : [],
|
|
5496
5846
|
frames: snapFrames
|
|
5497
5847
|
});
|
|
5498
|
-
setTime(s.t, "scrub", s.shown);
|
|
5848
|
+
setTime(s.t, "scrub", s.shown, press);
|
|
5499
5849
|
root.toggleAttribute("data-stuck", s.stop !== null);
|
|
5500
5850
|
};
|
|
5851
|
+
const showTag = (x) => {
|
|
5852
|
+
const at = Math.min(duration, Math.max(0, tOf(x)));
|
|
5853
|
+
const text = `${at.toFixed(2)} s`;
|
|
5854
|
+
if (tag.textContent !== text)
|
|
5855
|
+
tag.textContent = text;
|
|
5856
|
+
const cx = Math.min(width, Math.max(0, x));
|
|
5857
|
+
const flip = cx > width - tag.offsetWidth - 12;
|
|
5858
|
+
tag.style.transform = `translateX(${cx.toFixed(1)}px) translateX(${flip ? "calc(-100% - 4px)" : "4px"})`;
|
|
5859
|
+
tag.dataset.on = "";
|
|
5860
|
+
};
|
|
5861
|
+
const hideTag = () => delete tag.dataset.on;
|
|
5501
5862
|
track.addEventListener("pointerdown", (e) => {
|
|
5502
5863
|
if (e.button !== 0 || editing)
|
|
5503
5864
|
return;
|
|
5504
5865
|
root.focus({ preventScroll: true });
|
|
5505
5866
|
const t = e.target;
|
|
5506
|
-
const markerEl = t.closest(".knobs-tl-marker");
|
|
5867
|
+
const markerEl = lane ? null : t.closest(".knobs-tl-marker");
|
|
5507
5868
|
const edgeEl = t.closest(".knobs-tl-edge");
|
|
5508
5869
|
const rangeEl = t.closest(".knobs-tl-range");
|
|
5509
5870
|
track.setPointerCapture(e.pointerId);
|
|
@@ -5548,13 +5909,16 @@ function timeline(container, options) {
|
|
|
5548
5909
|
root.dataset.scrubbing = "";
|
|
5549
5910
|
for (const l of listeners)
|
|
5550
5911
|
l.onScrub?.(true);
|
|
5551
|
-
scrubTo(localX(e));
|
|
5912
|
+
scrubTo(localX(e), true);
|
|
5913
|
+
showTag(localX(e));
|
|
5552
5914
|
}
|
|
5553
5915
|
e.preventDefault();
|
|
5554
5916
|
});
|
|
5555
5917
|
track.addEventListener("pointermove", (e) => {
|
|
5556
5918
|
const x = localX(e);
|
|
5557
5919
|
hover.style.transform = `translateX(${x.toFixed(1)}px)`;
|
|
5920
|
+
if (!drag || drag.kind === "scrub")
|
|
5921
|
+
showTag(x);
|
|
5558
5922
|
if (!drag)
|
|
5559
5923
|
return;
|
|
5560
5924
|
if (drag.kind === "scrub")
|
|
@@ -5600,8 +5964,10 @@ function timeline(container, options) {
|
|
|
5600
5964
|
delete root.dataset.dragging;
|
|
5601
5965
|
root.removeAttribute("data-stuck");
|
|
5602
5966
|
if (d.kind === "scrub") {
|
|
5603
|
-
|
|
5967
|
+
headTo(time, "follow");
|
|
5604
5968
|
renderHead();
|
|
5969
|
+
if (!track.matches(":hover"))
|
|
5970
|
+
hideTag();
|
|
5605
5971
|
for (const l of listeners)
|
|
5606
5972
|
l.onScrub?.(false);
|
|
5607
5973
|
if (d.wasPlaying)
|
|
@@ -5614,7 +5980,7 @@ function timeline(container, options) {
|
|
|
5614
5980
|
} else {
|
|
5615
5981
|
const m = markers.find((x) => x.id === d.id);
|
|
5616
5982
|
if (m)
|
|
5617
|
-
setTime(m.time, "marker");
|
|
5983
|
+
setTime(m.time, "marker", m.time, true);
|
|
5618
5984
|
}
|
|
5619
5985
|
} else if (d.kind === "edge" || d.moved)
|
|
5620
5986
|
emitRanges();
|
|
@@ -5623,10 +5989,14 @@ function timeline(container, options) {
|
|
|
5623
5989
|
track.addEventListener("pointercancel", endDrag);
|
|
5624
5990
|
track.addEventListener("lostpointercapture", endDrag);
|
|
5625
5991
|
track.addEventListener("pointerleave", () => {
|
|
5626
|
-
if (
|
|
5627
|
-
|
|
5992
|
+
if (drag)
|
|
5993
|
+
return;
|
|
5994
|
+
hover.style.transform = "translateX(-100px)";
|
|
5995
|
+
hideTag();
|
|
5628
5996
|
});
|
|
5629
5997
|
track.addEventListener("dblclick", (e) => {
|
|
5998
|
+
if (lane)
|
|
5999
|
+
return;
|
|
5630
6000
|
const markerEl = e.target.closest(".knobs-tl-marker");
|
|
5631
6001
|
if (markerEl)
|
|
5632
6002
|
return rename(markerEl.dataset.id);
|
|
@@ -5637,6 +6007,8 @@ function timeline(container, options) {
|
|
|
5637
6007
|
rename(m.id);
|
|
5638
6008
|
});
|
|
5639
6009
|
track.addEventListener("wheel", (e) => {
|
|
6010
|
+
if (lane)
|
|
6011
|
+
return;
|
|
5640
6012
|
e.preventDefault();
|
|
5641
6013
|
const scale = e.deltaMode === 1 ? 16 : e.deltaMode === 2 ? height : 1;
|
|
5642
6014
|
if (e.ctrlKey || e.metaKey) {
|
|
@@ -5700,7 +6072,7 @@ function timeline(container, options) {
|
|
|
5700
6072
|
if (!m)
|
|
5701
6073
|
return;
|
|
5702
6074
|
select({ kind: "marker", id: m.id });
|
|
5703
|
-
return setTime(m.time, "marker");
|
|
6075
|
+
return setTime(m.time, "marker", m.time, true);
|
|
5704
6076
|
}
|
|
5705
6077
|
case "i":
|
|
5706
6078
|
case "I":
|
|
@@ -5712,11 +6084,13 @@ function timeline(container, options) {
|
|
|
5712
6084
|
return setEdge("end", time);
|
|
5713
6085
|
case "m":
|
|
5714
6086
|
case "M":
|
|
6087
|
+
if (lane)
|
|
6088
|
+
return;
|
|
5715
6089
|
claim();
|
|
5716
6090
|
addMarker(time);
|
|
5717
6091
|
return;
|
|
5718
6092
|
case "Enter":
|
|
5719
|
-
if (selected?.kind === "marker") {
|
|
6093
|
+
if (selected?.kind === "marker" && !lane) {
|
|
5720
6094
|
claim();
|
|
5721
6095
|
rename(selected.id);
|
|
5722
6096
|
}
|
|
@@ -5734,19 +6108,25 @@ function timeline(container, options) {
|
|
|
5734
6108
|
return;
|
|
5735
6109
|
case "=":
|
|
5736
6110
|
case "+":
|
|
6111
|
+
if (lane)
|
|
6112
|
+
return;
|
|
5737
6113
|
claim();
|
|
5738
6114
|
return zoom(1.5);
|
|
5739
6115
|
case "-":
|
|
6116
|
+
if (lane)
|
|
6117
|
+
return;
|
|
5740
6118
|
claim();
|
|
5741
6119
|
return zoom(1 / 1.5);
|
|
5742
6120
|
case "0":
|
|
6121
|
+
if (lane)
|
|
6122
|
+
return;
|
|
5743
6123
|
claim();
|
|
5744
6124
|
return fit();
|
|
5745
6125
|
}
|
|
5746
6126
|
});
|
|
5747
6127
|
const unregisterHints = options.hints === false ? undefined : hints.register(root, () => [
|
|
5748
6128
|
{ el: playBtn, label: playing ? "Pause" : "Play", activate: toggle },
|
|
5749
|
-
...markers.flatMap((m) => {
|
|
6129
|
+
...(lane ? [] : markers).flatMap((m) => {
|
|
5750
6130
|
const n = markerEls.get(m.id);
|
|
5751
6131
|
if (!n || n.dataset.leaving !== undefined)
|
|
5752
6132
|
return [];
|
|
@@ -5758,7 +6138,7 @@ function timeline(container, options) {
|
|
|
5758
6138
|
...label && !label.hidden ? { labelEl: label } : {},
|
|
5759
6139
|
activate: () => {
|
|
5760
6140
|
select({ kind: "marker", id: m.id });
|
|
5761
|
-
setTime(m.time, "marker");
|
|
6141
|
+
setTime(m.time, "marker", m.time, true);
|
|
5762
6142
|
root.focus({ preventScroll: true });
|
|
5763
6143
|
}
|
|
5764
6144
|
}
|
|
@@ -5770,7 +6150,7 @@ function timeline(container, options) {
|
|
|
5770
6150
|
activate: () => root.focus({ preventScroll: true })
|
|
5771
6151
|
}
|
|
5772
6152
|
], { listen: false, rank: 1 });
|
|
5773
|
-
const menu = contextMenu(track, (e) => {
|
|
6153
|
+
const menu = lane ? null : contextMenu(track, (e) => {
|
|
5774
6154
|
const t = e?.target ?? null;
|
|
5775
6155
|
const markerEl = t?.closest(".knobs-tl-marker");
|
|
5776
6156
|
const rangeEl = t?.closest(".knobs-tl-range");
|
|
@@ -5785,7 +6165,7 @@ function timeline(container, options) {
|
|
|
5785
6165
|
run: () => {
|
|
5786
6166
|
const m = markers.find((x) => x.id === mid);
|
|
5787
6167
|
if (m)
|
|
5788
|
-
setTime(m.time, "marker");
|
|
6168
|
+
setTime(m.time, "marker", m.time, true);
|
|
5789
6169
|
}
|
|
5790
6170
|
},
|
|
5791
6171
|
{ label: "Rename…", shortcut: "Enter", run: () => rename(mid) },
|
|
@@ -5949,7 +6329,7 @@ function timeline(container, options) {
|
|
|
5949
6329
|
listeners.clear();
|
|
5950
6330
|
loop.stop();
|
|
5951
6331
|
ro.disconnect();
|
|
5952
|
-
menu
|
|
6332
|
+
menu?.dispose();
|
|
5953
6333
|
root.remove();
|
|
5954
6334
|
}
|
|
5955
6335
|
};
|
|
@@ -5966,10 +6346,21 @@ var init_timeline = __esm(() => {
|
|
|
5966
6346
|
init_timeline_model();
|
|
5967
6347
|
INSTANT = springMotion(SPRINGS.instant);
|
|
5968
6348
|
CALM = springMotion(SPRINGS.calm);
|
|
5969
|
-
GLIDE = springMotion(
|
|
6349
|
+
GLIDE = springMotion(CATCH_UP);
|
|
5970
6350
|
});
|
|
5971
6351
|
|
|
5972
6352
|
// src/ui/compare-model.ts
|
|
6353
|
+
function compareModes(modes, mode) {
|
|
6354
|
+
const list = [...new Set((modes ?? ["side", "wipe"]).filter((m) => ALL_MODES.includes(m)))];
|
|
6355
|
+
const offered = list.length ? list : ["side", "wipe"];
|
|
6356
|
+
return { modes: offered, mode: mode && offered.includes(mode) ? mode : offered[0] };
|
|
6357
|
+
}
|
|
6358
|
+
function modeForKey(key, modes) {
|
|
6359
|
+
const k = key.toLowerCase();
|
|
6360
|
+
if (/^[1-9]$/.test(k))
|
|
6361
|
+
return modes[Number(k) - 1] ?? null;
|
|
6362
|
+
return modes.find((m) => MODE_KEYS[m] === k) ?? null;
|
|
6363
|
+
}
|
|
5973
6364
|
function mediaKind(src, kind) {
|
|
5974
6365
|
if (kind)
|
|
5975
6366
|
return kind;
|
|
@@ -6048,6 +6439,18 @@ function wipeGrab(x, rect, wipe, slop = 12) {
|
|
|
6048
6439
|
const onLine = Math.abs(x - line) <= slop;
|
|
6049
6440
|
return { onLine, offset: onLine ? x - line : 0 };
|
|
6050
6441
|
}
|
|
6442
|
+
function seamLabels(x, left, right, wb, wa, gap = 8) {
|
|
6443
|
+
const room = (space, w) => Math.min(1, Math.max(0, (space - w - 2 * gap) / gap));
|
|
6444
|
+
return {
|
|
6445
|
+
before: { x: x - gap - wb, opacity: room(x - left, wb) },
|
|
6446
|
+
after: { x: x + gap, opacity: room(right - x, wa) }
|
|
6447
|
+
};
|
|
6448
|
+
}
|
|
6449
|
+
function gripTop(y, rect, grip, margin = 8) {
|
|
6450
|
+
const lo = rect.y + margin;
|
|
6451
|
+
const hi = rect.y + rect.h - margin - grip;
|
|
6452
|
+
return hi < lo ? rect.y + (rect.h - grip) / 2 : Math.min(hi, Math.max(lo, y - grip / 2));
|
|
6453
|
+
}
|
|
6051
6454
|
function stripColumns(view, width, o) {
|
|
6052
6455
|
const { fps } = o;
|
|
6053
6456
|
const total = Math.max(1, Math.round(o.duration * fps));
|
|
@@ -6098,7 +6501,7 @@ function stripPeaks(diffs, o = {}) {
|
|
|
6098
6501
|
});
|
|
6099
6502
|
return out;
|
|
6100
6503
|
}
|
|
6101
|
-
var VIDEO, frameOf = (t, fps) => Math.max(0, Math.floor(t * fps + 0.0001)), lastFrame = (duration, fps) => Math.max(0, Math.ceil(duration * fps - 0.0001) - 1), seekTime = (t, fps, duration) => frameMidpoint(frameOf(t, fps), fps, duration), sameFrame = (a, b, fps) => frameOf(a, fps) === frameOf(b, fps), SEEK_IDLE, splitHeight = (w, media) => media.w > 0 && media.h > 0 ? w / 2 * (media.h / media.w) : w / 2 * (9 / 16), ZOOM_FIT, ZOOM_MAX = 16, panBy = (r, dx, dy, base) => clampZoom({
|
|
6504
|
+
var ALL_MODES, MODE_KEYS, modeKey = (mode) => MODE_KEYS[mode].toUpperCase(), VIDEO, frameOf = (t, fps) => Math.max(0, Math.floor(t * fps + 0.0001)), lastFrame = (duration, fps) => Math.max(0, Math.ceil(duration * fps - 0.0001) - 1), seekTime = (t, fps, duration) => frameMidpoint(frameOf(t, fps), fps, duration), sameFrame = (a, b, fps) => frameOf(a, fps) === frameOf(b, fps), SEEK_IDLE, splitHeight = (w, media) => media.w > 0 && media.h > 0 ? w / 2 * (media.h / media.w) : w / 2 * (9 / 16), ZOOM_FIT, ZOOM_MAX = 16, panBy = (r, dx, dy, base) => clampZoom({
|
|
6102
6505
|
u: r.u - dx / Math.max(1, base.w) * r.w,
|
|
6103
6506
|
v: r.v - dy / Math.max(1, base.h) * r.h,
|
|
6104
6507
|
w: r.w
|
|
@@ -6117,6 +6520,8 @@ var VIDEO, frameOf = (t, fps) => Math.max(0, Math.floor(t * fps + 0.0001)), last
|
|
|
6117
6520
|
h: a.h + (b.h - a.h) * k
|
|
6118
6521
|
}), wipeX = (rect, wipe) => rect.x + Math.min(1, Math.max(0, wipe)) * rect.w, wipeAt = (x, rect, offset = 0) => rect.w <= 0 ? 0.5 : Math.min(1, Math.max(0, (x - offset - rect.x) / rect.w)), wipeKey = (wipe, dir, big = false) => Math.min(1, Math.max(0, Math.round((wipe + dir * (big ? 0.1 : 0.01)) * 1000) / 1000));
|
|
6119
6522
|
var init_compare_model = __esm(() => {
|
|
6523
|
+
ALL_MODES = ["side", "wipe", "difference"];
|
|
6524
|
+
MODE_KEYS = { side: "s", wipe: "w", difference: "d" };
|
|
6120
6525
|
VIDEO = /\.(mp4|m4v|mov|webm|ogv|mkv)$/i;
|
|
6121
6526
|
SEEK_IDLE = { seeking: false, pending: null };
|
|
6122
6527
|
ZOOM_FIT = { u: 0, v: 0, w: 1, h: 1 };
|
|
@@ -6916,8 +7321,8 @@ async function createCompareGpu(canvas, onLost) {
|
|
|
6916
7321
|
r(0, f.before);
|
|
6917
7322
|
r(4, f.after);
|
|
6918
7323
|
data.set([f.width, f.height, f.dpr, 0], 8);
|
|
6919
|
-
data.set([f.wipeX, f.soft, 0,
|
|
6920
|
-
data.set([f.from, f.to, f.mix,
|
|
7324
|
+
data.set([f.wipeX, f.soft, 0, 0], 12);
|
|
7325
|
+
data.set([f.from, f.to, f.mix, 0], 16);
|
|
6921
7326
|
data.set([f.threshold, f.gain, ready[0], ready[1]], 20);
|
|
6922
7327
|
data.set([f.accent[0], f.accent[1], f.accent[2], 1], 24);
|
|
6923
7328
|
const l = f.loupe;
|
|
@@ -6959,8 +7364,8 @@ var MODE_INDEX, WGSL = `
|
|
|
6959
7364
|
struct U {
|
|
6960
7365
|
ra: vec4f, rb: vec4f,
|
|
6961
7366
|
view: vec4f, // w, h, dpr, _
|
|
6962
|
-
wipe: vec4f, // x, soft, _,
|
|
6963
|
-
modes: vec4f, // from, to, mix,
|
|
7367
|
+
wipe: vec4f, // x, soft, _, _
|
|
7368
|
+
modes: vec4f, // from, to, mix, _
|
|
6964
7369
|
diff: vec4f, // threshold, gain, readyA, readyB
|
|
6965
7370
|
accent: vec4f,
|
|
6966
7371
|
loupe: vec4f, // x, y, r, zoom (0: none)
|
|
@@ -7011,21 +7416,14 @@ fn takeB(p: vec2f, r: vec4f, c0: vec4f, near: bool) -> vec4f {
|
|
|
7011
7416
|
|
|
7012
7417
|
fn pm(c: vec4f) -> vec4f { return vec4f(c.rgb * c.a, c.a); }
|
|
7013
7418
|
|
|
7014
|
-
fn composite(mode: u32, p: vec2f, a: vec4f, b: vec4f
|
|
7015
|
-
let flick = u.modes.w > 0.5;
|
|
7419
|
+
fn composite(mode: u32, p: vec2f, a: vec4f, b: vec4f) -> vec4f {
|
|
7016
7420
|
switch mode {
|
|
7017
|
-
case 0u: {
|
|
7018
|
-
let bb = select(b, vec4f(a2.rgb, b.a), flick);
|
|
7019
|
-
return vec4f(a.rgb * a.a + bb.rgb * bb.a * (1.0 - a.a), a.a + bb.a * (1.0 - a.a));
|
|
7020
|
-
}
|
|
7021
7421
|
case 1u: {
|
|
7022
|
-
if (flick) { return pm(a); }
|
|
7023
7422
|
let s = max(u.wipe.y, 0.5);
|
|
7024
7423
|
let m = smoothstep(u.wipe.x - s, u.wipe.x + s, p.x);
|
|
7025
7424
|
return pm(vec4f(mix(a.rgb, b.rgb, m), mix(a.a, b.a, m)));
|
|
7026
7425
|
}
|
|
7027
7426
|
case 2u: {
|
|
7028
|
-
if (flick) { return pm(a); }
|
|
7029
7427
|
let d = abs(a.rgb - b.rgb);
|
|
7030
7428
|
let h = smoothstep(u.diff.x, u.diff.x + 0.06, max(d.r, max(d.g, d.b)) * u.diff.y) * min(a.a, b.a);
|
|
7031
7429
|
let c = mix(vec3f(luma(b.rgb) * 0.35), u.accent.rgb, h);
|
|
@@ -7033,8 +7431,8 @@ fn composite(mode: u32, p: vec2f, a: vec4f, b: vec4f, a2: vec4f) -> vec4f {
|
|
|
7033
7431
|
}
|
|
7034
7432
|
default: {}
|
|
7035
7433
|
}
|
|
7036
|
-
//
|
|
7037
|
-
return
|
|
7434
|
+
// Side by side: each side in its own place, Before over After where they meet.
|
|
7435
|
+
return vec4f(a.rgb * a.a + b.rgb * b.a * (1.0 - a.a), a.a + b.a * (1.0 - a.a));
|
|
7038
7436
|
}
|
|
7039
7437
|
|
|
7040
7438
|
@fragment fn fs(@builtin(position) q: vec4f) -> @location(0) vec4f {
|
|
@@ -7052,16 +7450,14 @@ fn composite(mode: u32, p: vec2f, a: vec4f, b: vec4f, a2: vec4f) -> vec4f {
|
|
|
7052
7450
|
}
|
|
7053
7451
|
let a = takeA(p, u.ra, u.ca, near);
|
|
7054
7452
|
let b = takeB(p, u.rb, u.cb, near);
|
|
7055
|
-
|
|
7056
|
-
let a2 = takeA(p, u.rb, u.cb, near);
|
|
7057
|
-
var o = mix(composite(u32(u.modes.x), p, a, b, a2), composite(u32(u.modes.y), p, a, b, a2), u.modes.z);
|
|
7453
|
+
var o = mix(composite(u32(u.modes.x), p, a, b), composite(u32(u.modes.y), p, a, b), u.modes.z);
|
|
7058
7454
|
if (near) { o = o + vec4f(0.05, 0.05, 0.06, 1.0) * (1.0 - o.a); }
|
|
7059
7455
|
o = mix(o, vec4f(0.92), ring * 0.9);
|
|
7060
7456
|
return o;
|
|
7061
7457
|
}
|
|
7062
7458
|
`, TEXTURE_BINDING = 4, COPY_DST = 2, RENDER_ATTACHMENT = 16, shared = null, lostListeners;
|
|
7063
7459
|
var init_compare_gpu = __esm(() => {
|
|
7064
|
-
MODE_INDEX = { side: 0, wipe: 1, difference: 2
|
|
7460
|
+
MODE_INDEX = { side: 0, wipe: 1, difference: 2 };
|
|
7065
7461
|
lostListeners = new Set;
|
|
7066
7462
|
});
|
|
7067
7463
|
|
|
@@ -7447,7 +7843,9 @@ function compare(container, options) {
|
|
|
7447
7843
|
...options.theme ? { theme: options.theme } : {},
|
|
7448
7844
|
...options.appearance ? { appearance: options.appearance } : {}
|
|
7449
7845
|
};
|
|
7450
|
-
|
|
7846
|
+
const offered = compareModes(options.modes, options.mode);
|
|
7847
|
+
const modeList = offered.modes;
|
|
7848
|
+
let mode = offered.mode;
|
|
7451
7849
|
let wipe = Math.min(1, Math.max(0, options.wipe ?? 0.5));
|
|
7452
7850
|
let loupeOn = options.loupe ?? false;
|
|
7453
7851
|
let threshold = options.threshold ?? 4 / 255;
|
|
@@ -7465,7 +7863,7 @@ function compare(container, options) {
|
|
|
7465
7863
|
root.setAttribute("role", "group");
|
|
7466
7864
|
root.setAttribute("aria-roledescription", "compare");
|
|
7467
7865
|
root.setAttribute("aria-label", options.label ?? "Compare");
|
|
7468
|
-
root.setAttribute("aria-keyshortcuts",
|
|
7866
|
+
root.setAttribute("aria-keyshortcuts", `Space ArrowLeft ArrowRight Shift+ArrowLeft Shift+ArrowRight , . ${modeList.map((m, i) => `${i + 1} ${modeKey(m)}`).join(" ")} Z L 0 = -`);
|
|
7469
7867
|
applyLook2(root, options);
|
|
7470
7868
|
root.dataset.mode = mode;
|
|
7471
7869
|
if (auto)
|
|
@@ -7474,35 +7872,37 @@ function compare(container, options) {
|
|
|
7474
7872
|
const modes = el("div", "knobs-cmp-modes");
|
|
7475
7873
|
modes.setAttribute("role", "radiogroup");
|
|
7476
7874
|
modes.setAttribute("aria-label", "Mode");
|
|
7477
|
-
|
|
7875
|
+
modes.hidden = modeList.length < 2;
|
|
7876
|
+
const modeBtns = modeList.map((m, i) => {
|
|
7478
7877
|
const b = el("button", "knobs-cmp-mode");
|
|
7479
7878
|
b.type = "button";
|
|
7480
7879
|
b.tabIndex = -1;
|
|
7481
|
-
b.textContent = m.
|
|
7482
|
-
b.title = `${m.
|
|
7880
|
+
b.textContent = MODE_LABEL[m].short;
|
|
7881
|
+
b.title = `${MODE_LABEL[m].long} · ${i + 1} or ${modeKey(m)}`;
|
|
7483
7882
|
b.setAttribute("role", "radio");
|
|
7484
|
-
b.setAttribute("aria-keyshortcuts",
|
|
7883
|
+
b.setAttribute("aria-keyshortcuts", `${i + 1} ${modeKey(m)}`);
|
|
7485
7884
|
b.addEventListener("click", () => {
|
|
7486
|
-
setMode(m
|
|
7885
|
+
setMode(m);
|
|
7487
7886
|
root.focus({ preventScroll: true });
|
|
7488
7887
|
});
|
|
7489
7888
|
modes.append(b);
|
|
7490
7889
|
return b;
|
|
7491
7890
|
});
|
|
7492
|
-
const
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7891
|
+
const toggleBtn = (name, label, title) => {
|
|
7892
|
+
const b = el("button", "knobs-cmp-toggle");
|
|
7893
|
+
b.type = "button";
|
|
7894
|
+
b.tabIndex = -1;
|
|
7895
|
+
b.innerHTML = icon(name);
|
|
7896
|
+
b.setAttribute("aria-label", label);
|
|
7897
|
+
b.title = title;
|
|
7898
|
+
return b;
|
|
7899
|
+
};
|
|
7900
|
+
const loupeBtn = toggleBtn("magnifyingGlass", "Loupe", "Loupe · hold Z");
|
|
7497
7901
|
loupeBtn.addEventListener("click", () => {
|
|
7498
7902
|
setLoupe(!loupeOn);
|
|
7499
7903
|
root.focus({ preventScroll: true });
|
|
7500
7904
|
});
|
|
7501
|
-
const loopBtn =
|
|
7502
|
-
loopBtn.type = "button";
|
|
7503
|
-
loopBtn.tabIndex = -1;
|
|
7504
|
-
loopBtn.textContent = "Loop";
|
|
7505
|
-
loopBtn.title = "Loop · L (drag its ends on the timeline)";
|
|
7905
|
+
const loopBtn = toggleBtn("repeat", "Loop", "Loop · L (drag its ends on the timeline)");
|
|
7506
7906
|
loopBtn.setAttribute("aria-keyshortcuts", "L");
|
|
7507
7907
|
loopBtn.addEventListener("click", () => {
|
|
7508
7908
|
api.setLoop(!loopNow());
|
|
@@ -7519,7 +7919,8 @@ function compare(container, options) {
|
|
|
7519
7919
|
const zoomReset = el("button", "knobs-cmp-zoom-reset");
|
|
7520
7920
|
zoomReset.type = "button";
|
|
7521
7921
|
zoomReset.tabIndex = -1;
|
|
7522
|
-
zoomReset.
|
|
7922
|
+
zoomReset.innerHTML = icon("arrowCounterClockwise", { small: true });
|
|
7923
|
+
zoomReset.setAttribute("aria-label", "Reset zoom");
|
|
7523
7924
|
zoomReset.title = "Fit · 0 or double-click";
|
|
7524
7925
|
zoomReset.addEventListener("click", () => {
|
|
7525
7926
|
api.setZoom(null);
|
|
@@ -7534,6 +7935,9 @@ function compare(container, options) {
|
|
|
7534
7935
|
handle.setAttribute("aria-label", "Wipe");
|
|
7535
7936
|
handle.setAttribute("aria-valuemin", "0");
|
|
7536
7937
|
handle.setAttribute("aria-valuemax", "100");
|
|
7938
|
+
const grip = el("span", "knobs-cmp-grip");
|
|
7939
|
+
grip.setAttribute("aria-hidden", "true");
|
|
7940
|
+
handle.append(grip);
|
|
7537
7941
|
const note = el("div", "knobs-cmp-note");
|
|
7538
7942
|
stage.append(canvas, split, labels[0], labels[1], handle, zoomPill, note);
|
|
7539
7943
|
root.append(bar, stage);
|
|
@@ -7550,6 +7954,7 @@ function compare(container, options) {
|
|
|
7550
7954
|
root.append(host);
|
|
7551
7955
|
tl = timeline(host, {
|
|
7552
7956
|
...look,
|
|
7957
|
+
variant: "lane",
|
|
7553
7958
|
duration: 1,
|
|
7554
7959
|
fps: fps(),
|
|
7555
7960
|
arrows: { step: 0.5, shift: 2 },
|
|
@@ -7568,9 +7973,9 @@ function compare(container, options) {
|
|
|
7568
7973
|
const fade = new Spring(1, FADE2.omega, FADE2.zeta, 0.001);
|
|
7569
7974
|
let fromMode = mode;
|
|
7570
7975
|
let toMode = mode;
|
|
7571
|
-
|
|
7572
|
-
let
|
|
7573
|
-
let
|
|
7976
|
+
const wipeLine = new Spring(wipe, WIPE_CATCH.omega, WIPE_CATCH.zeta, 0.0001);
|
|
7977
|
+
let wipeCatching = false;
|
|
7978
|
+
let gripY = null;
|
|
7574
7979
|
let loupeHeld = false;
|
|
7575
7980
|
let pointer = null;
|
|
7576
7981
|
let drag = null;
|
|
@@ -7888,25 +8293,16 @@ function compare(container, options) {
|
|
|
7888
8293
|
gpu = g;
|
|
7889
8294
|
setRenderer("gpu");
|
|
7890
8295
|
};
|
|
7891
|
-
const syncFlicker = () => {
|
|
7892
|
-
win.clearInterval(flickerTimer);
|
|
7893
|
-
flickerTimer = 0;
|
|
7894
|
-
phase = false;
|
|
7895
|
-
if (mode === "flicker")
|
|
7896
|
-
flickerTimer = win.setInterval(() => {
|
|
7897
|
-
phase = !phase;
|
|
7898
|
-
requestDraw();
|
|
7899
|
-
}, FLICKER_MS);
|
|
7900
|
-
};
|
|
7901
8296
|
const syncModeUi = () => {
|
|
7902
8297
|
root.dataset.mode = mode;
|
|
7903
|
-
|
|
7904
|
-
modeBtns[i].setAttribute("aria-checked", String(m
|
|
8298
|
+
modeList.forEach((m, i) => {
|
|
8299
|
+
modeBtns[i].setAttribute("aria-checked", String(m === mode));
|
|
7905
8300
|
});
|
|
7906
8301
|
handle.tabIndex = mode === "wipe" ? 0 : -1;
|
|
8302
|
+
modePill?.update();
|
|
7907
8303
|
};
|
|
7908
8304
|
const setMode = (next, emit = true) => {
|
|
7909
|
-
if (next === mode)
|
|
8305
|
+
if (next === mode || !modeList.includes(next))
|
|
7910
8306
|
return;
|
|
7911
8307
|
mode = next;
|
|
7912
8308
|
const reduced = reducedMotion(win);
|
|
@@ -7922,19 +8318,29 @@ function compare(container, options) {
|
|
|
7922
8318
|
else
|
|
7923
8319
|
lay.set(next === "side" ? 0 : 1);
|
|
7924
8320
|
syncModeUi();
|
|
7925
|
-
syncFlicker();
|
|
7926
8321
|
if (emit)
|
|
7927
8322
|
options.onMode?.(next);
|
|
7928
8323
|
requestDraw();
|
|
7929
8324
|
};
|
|
7930
|
-
const setWipe = (next, emit = true) => {
|
|
8325
|
+
const setWipe = (next, emit = true, jump = false) => {
|
|
7931
8326
|
const w = Math.min(1, Math.max(0, next));
|
|
7932
|
-
if (w === wipe)
|
|
8327
|
+
if (w === wipe && !jump)
|
|
7933
8328
|
return;
|
|
7934
8329
|
wipe = w;
|
|
8330
|
+
const minGap = 2 / Math.max(1, wipeRect(layoutNow().L.overlay).w);
|
|
8331
|
+
const head = moveHead({ x: wipeLine.x, target: wipeLine.target }, w, jump && !reducedMotion(win) ? "jump" : "follow", wipeCatching, minGap);
|
|
8332
|
+
wipeCatching = head.catching;
|
|
8333
|
+
if (head.catching) {
|
|
8334
|
+
wipeLine.x = head.x;
|
|
8335
|
+
wipeLine.target = head.target;
|
|
8336
|
+
} else
|
|
8337
|
+
wipeLine.snap(head.x);
|
|
7935
8338
|
if (emit)
|
|
7936
8339
|
options.onWipe?.(w);
|
|
7937
|
-
|
|
8340
|
+
if (head.catching)
|
|
8341
|
+
requestDraw();
|
|
8342
|
+
else
|
|
8343
|
+
drawNow();
|
|
7938
8344
|
};
|
|
7939
8345
|
const setLoupe = (on) => {
|
|
7940
8346
|
loupeOn = on;
|
|
@@ -8087,28 +8493,44 @@ function compare(container, options) {
|
|
|
8087
8493
|
viewSent = key;
|
|
8088
8494
|
options.onView({ zoom: clampZoom(z), loop: l });
|
|
8089
8495
|
};
|
|
8496
|
+
const labelsIn = (m, r, wr, wx) => {
|
|
8497
|
+
if (m === "wipe") {
|
|
8498
|
+
const at = seamLabels(wx, wr.x, wr.x + wr.w, labelW[0], labelW[1], INSET);
|
|
8499
|
+
return [at.before, at.after];
|
|
8500
|
+
}
|
|
8501
|
+
const ax = r.after.x + INSET + (r.after.w - labelW[1] - INSET * 2) * lay.x;
|
|
8502
|
+
return [
|
|
8503
|
+
{ x: r.before.x + INSET, opacity: 1 },
|
|
8504
|
+
{ x: ax, opacity: 1 }
|
|
8505
|
+
];
|
|
8506
|
+
};
|
|
8507
|
+
const placeGrip = (wr) => {
|
|
8508
|
+
const gy = gripTop(gripY ?? wr.y + wr.h / 2, wr, GRIP.h) - wr.y;
|
|
8509
|
+
grip.style.transform = `translate3d(0,${gy.toFixed(2)}px,0)`;
|
|
8510
|
+
};
|
|
8090
8511
|
const draw = () => {
|
|
8091
8512
|
dirty = false;
|
|
8092
8513
|
const r = layoutNow();
|
|
8093
8514
|
const wr = wipeRect(r.L.overlay);
|
|
8094
|
-
const wx = wipeX(wr,
|
|
8515
|
+
const wx = wipeX(wr, wipeLine.x);
|
|
8095
8516
|
const k = lay.x;
|
|
8096
|
-
const
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
const
|
|
8100
|
-
const
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
|
|
8104
|
-
|
|
8517
|
+
const a = labelsIn(fromMode, r, wr, wx);
|
|
8518
|
+
const b = labelsIn(toMode, r, wr, wx);
|
|
8519
|
+
const f = Math.min(1, Math.max(0, fade.x));
|
|
8520
|
+
const ys = [r.before.y + INSET, r.after.y + INSET];
|
|
8521
|
+
for (const i of [0, 1]) {
|
|
8522
|
+
const x = a[i].x + (b[i].x - a[i].x) * f;
|
|
8523
|
+
labels[i].style.transform = `translate(${x.toFixed(2)}px,${ys[i].toFixed(2)}px)`;
|
|
8524
|
+
labels[i].style.opacity = (a[i].opacity + (b[i].opacity - a[i].opacity) * f).toFixed(3);
|
|
8525
|
+
}
|
|
8105
8526
|
const top = Math.min(r.L.side.before.y, r.L.side.after.y);
|
|
8106
8527
|
split.style.transform = `translate(${r.L.side.split.toFixed(2)}px,${top.toFixed(2)}px)`;
|
|
8107
8528
|
split.style.height = `${Math.max(0, r.L.side.after.h).toFixed(2)}px`;
|
|
8108
8529
|
split.style.opacity = String(Math.max(0, 1 - k * 2));
|
|
8109
|
-
handle.toggleAttribute("data-on", mode === "wipe"
|
|
8530
|
+
handle.toggleAttribute("data-on", mode === "wipe");
|
|
8110
8531
|
handle.style.transform = `translate(${wx.toFixed(2)}px,${wr.y.toFixed(2)}px)`;
|
|
8111
8532
|
handle.style.height = `${Math.max(0, wr.h).toFixed(2)}px`;
|
|
8533
|
+
placeGrip(wr);
|
|
8112
8534
|
handle.setAttribute("aria-valuenow", String(Math.round(wipe * 100)));
|
|
8113
8535
|
handle.setAttribute("aria-valuetext", `${Math.round(wipe * 100)}% Before`);
|
|
8114
8536
|
const pct = `${Math.round(100 / zw.x)}%`;
|
|
@@ -8131,7 +8553,7 @@ function compare(container, options) {
|
|
|
8131
8553
|
const right = Math.max(0, rect.x + rect.w - Math.min(clip.x + clip.w, cutAt));
|
|
8132
8554
|
st.clipPath = t + l + b + right > 0.01 ? `inset(${t.toFixed(2)}px ${right.toFixed(2)}px ${b.toFixed(2)}px ${l.toFixed(2)}px)` : "";
|
|
8133
8555
|
};
|
|
8134
|
-
const cut = mode === "wipe"
|
|
8556
|
+
const cut = mode === "wipe" ? wx : Number.POSITIVE_INFINITY;
|
|
8135
8557
|
for (const s of sides) {
|
|
8136
8558
|
const rect = s.index === 0 ? r.zBefore : r.zAfter;
|
|
8137
8559
|
const clip = s.index === 0 ? r.before : r.after;
|
|
@@ -8140,10 +8562,8 @@ function compare(container, options) {
|
|
|
8140
8562
|
place(s.preview, rect, clip, at);
|
|
8141
8563
|
if (s.index !== 0)
|
|
8142
8564
|
continue;
|
|
8143
|
-
for (const n of [s.el, s.preview])
|
|
8144
|
-
n.style.mixBlendMode = mode === "difference"
|
|
8145
|
-
n.style.opacity = mode === "flicker" && !showsBefore ? "0" : "";
|
|
8146
|
-
}
|
|
8565
|
+
for (const n of [s.el, s.preview])
|
|
8566
|
+
n.style.mixBlendMode = mode === "difference" ? "difference" : "";
|
|
8147
8567
|
}
|
|
8148
8568
|
return;
|
|
8149
8569
|
}
|
|
@@ -8164,8 +8584,6 @@ function compare(container, options) {
|
|
|
8164
8584
|
from: MODE_INDEX[fromMode],
|
|
8165
8585
|
to: MODE_INDEX[toMode],
|
|
8166
8586
|
mix: Math.min(1, Math.max(0, fade.x)),
|
|
8167
|
-
flick: flickHeld,
|
|
8168
|
-
phase,
|
|
8169
8587
|
threshold,
|
|
8170
8588
|
gain: 1,
|
|
8171
8589
|
accent,
|
|
@@ -8181,6 +8599,11 @@ function compare(container, options) {
|
|
|
8181
8599
|
const loop = frameLoop(win, (dt) => {
|
|
8182
8600
|
lay.step(dt);
|
|
8183
8601
|
fade.step(dt);
|
|
8602
|
+
if (wipeCatching) {
|
|
8603
|
+
wipeLine.step(dt);
|
|
8604
|
+
if (wipeLine.resting)
|
|
8605
|
+
wipeCatching = false;
|
|
8606
|
+
}
|
|
8184
8607
|
zu.step(dt);
|
|
8185
8608
|
zv.step(dt);
|
|
8186
8609
|
zw.step(dt);
|
|
@@ -8214,7 +8637,7 @@ function compare(container, options) {
|
|
|
8214
8637
|
pushFrame(s);
|
|
8215
8638
|
}
|
|
8216
8639
|
}
|
|
8217
|
-
const moving = !lay.resting || !fade.resting || !zoomResting();
|
|
8640
|
+
const moving = !lay.resting || !fade.resting || !zoomResting() || wipeCatching;
|
|
8218
8641
|
if (moving)
|
|
8219
8642
|
dirty = true;
|
|
8220
8643
|
if (auto && !lay.resting)
|
|
@@ -8357,16 +8780,19 @@ function compare(container, options) {
|
|
|
8357
8780
|
e.preventDefault();
|
|
8358
8781
|
return startPinch();
|
|
8359
8782
|
}
|
|
8360
|
-
if (mode === "wipe"
|
|
8783
|
+
if (mode === "wipe") {
|
|
8361
8784
|
const wr = wipeRect(layoutNow().L.overlay);
|
|
8362
8785
|
const inside = p.x >= wr.x - SLOP && p.x <= wr.x + wr.w + SLOP && p.y >= wr.y && p.y <= wr.y + wr.h;
|
|
8363
|
-
const grab = wipeGrab(p.x, wr,
|
|
8786
|
+
const grab = wipeGrab(p.x, wr, wipeLine.x, SLOP);
|
|
8364
8787
|
if (inside && (grab.onLine || !zoomed())) {
|
|
8365
8788
|
drag = { kind: "wipe", offset: grab.offset };
|
|
8366
8789
|
root.dataset.dragging = "";
|
|
8790
|
+
gripY = p.y;
|
|
8367
8791
|
e.preventDefault();
|
|
8368
8792
|
if (!grab.onLine)
|
|
8369
|
-
setWipe(wipeAt(p.x, wr));
|
|
8793
|
+
setWipe(wipeAt(p.x, wr), true, true);
|
|
8794
|
+
else
|
|
8795
|
+
drawNow();
|
|
8370
8796
|
return;
|
|
8371
8797
|
}
|
|
8372
8798
|
}
|
|
@@ -8392,6 +8818,11 @@ function compare(container, options) {
|
|
|
8392
8818
|
pinch = { d, x: mid.x, y: mid.y };
|
|
8393
8819
|
return handZoom(zoomAbout(panned, k, q.pu, q.pv));
|
|
8394
8820
|
}
|
|
8821
|
+
if (mode === "wipe" && drag?.kind !== "pan") {
|
|
8822
|
+
gripY = p.y;
|
|
8823
|
+
if (!drag)
|
|
8824
|
+
placeGrip(wipeRect(layoutNow().L.overlay));
|
|
8825
|
+
}
|
|
8395
8826
|
if (drag?.kind === "wipe")
|
|
8396
8827
|
setWipe(wipeAt(p.x, wipeRect(layoutNow().L.overlay), drag.offset));
|
|
8397
8828
|
else if (drag?.kind === "pan") {
|
|
@@ -8464,12 +8895,6 @@ function compare(container, options) {
|
|
|
8464
8895
|
const z = { u: zu.target, v: zv.target, w: zw.target, h: zw.target };
|
|
8465
8896
|
glideZoom(zoomAbout(z, factor, 0.5, 0.5));
|
|
8466
8897
|
};
|
|
8467
|
-
const holdFlick = (on) => {
|
|
8468
|
-
if (flickHeld === on)
|
|
8469
|
-
return;
|
|
8470
|
-
flickHeld = on;
|
|
8471
|
-
drawNow();
|
|
8472
|
-
};
|
|
8473
8898
|
const holdLoupe = (on) => {
|
|
8474
8899
|
if (loupeHeld === on)
|
|
8475
8900
|
return;
|
|
@@ -8515,25 +8940,17 @@ function compare(container, options) {
|
|
|
8515
8940
|
case "s":
|
|
8516
8941
|
case "w":
|
|
8517
8942
|
case "d":
|
|
8518
|
-
if (e.altKey || e.shiftKey || key === "s" && claimsHintKey(doc, key))
|
|
8519
|
-
return;
|
|
8520
|
-
claim();
|
|
8521
|
-
return setMode(KEY_MODE[key]);
|
|
8522
8943
|
case "1":
|
|
8523
8944
|
case "2":
|
|
8524
|
-
case "3":
|
|
8525
|
-
|
|
8526
|
-
if (e.altKey || e.shiftKey)
|
|
8945
|
+
case "3": {
|
|
8946
|
+
if (e.altKey || e.shiftKey || key === "s" && claimsHintKey(doc, key))
|
|
8527
8947
|
return;
|
|
8528
|
-
|
|
8529
|
-
|
|
8530
|
-
case "x":
|
|
8531
|
-
if (e.altKey)
|
|
8948
|
+
const m = modeForKey(key, modeList);
|
|
8949
|
+
if (!m)
|
|
8532
8950
|
return;
|
|
8533
8951
|
claim();
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
return;
|
|
8952
|
+
return setMode(m);
|
|
8953
|
+
}
|
|
8537
8954
|
case "z":
|
|
8538
8955
|
if (e.altKey)
|
|
8539
8956
|
return;
|
|
@@ -8589,8 +9006,11 @@ function compare(container, options) {
|
|
|
8589
9006
|
labels[1].textContent = labelOf(1);
|
|
8590
9007
|
loupeBtn.setAttribute("aria-pressed", String(loupeOn));
|
|
8591
9008
|
loopBtn.setAttribute("aria-pressed", String(loopNow() !== null));
|
|
9009
|
+
const modePill = modeList.length > 1 ? selectionPill(modes, {
|
|
9010
|
+
rows: () => modeBtns,
|
|
9011
|
+
selected: () => modeBtns[modeList.indexOf(mode)] ?? null
|
|
9012
|
+
}) : null;
|
|
8592
9013
|
syncModeUi();
|
|
8593
|
-
syncFlicker();
|
|
8594
9014
|
const unlisten = tl?.listen({
|
|
8595
9015
|
onSeek: (t, source) => {
|
|
8596
9016
|
if (source === "play") {
|
|
@@ -8648,24 +9068,20 @@ function compare(container, options) {
|
|
|
8648
9068
|
});
|
|
8649
9069
|
root.addEventListener("keydown", onKey);
|
|
8650
9070
|
root.addEventListener("keyup", (e) => {
|
|
8651
|
-
|
|
8652
|
-
if (key === "x")
|
|
8653
|
-
holdFlick(false);
|
|
8654
|
-
else if (key === "z")
|
|
9071
|
+
if (e.key.toLowerCase() === "z")
|
|
8655
9072
|
holdLoupe(false);
|
|
8656
9073
|
});
|
|
8657
9074
|
root.addEventListener("focusout", (e) => {
|
|
8658
9075
|
if (root.contains(e.relatedTarget))
|
|
8659
9076
|
return;
|
|
8660
|
-
holdFlick(false);
|
|
8661
9077
|
holdLoupe(false);
|
|
8662
9078
|
});
|
|
8663
9079
|
const unregisterHints = options.hints === false ? undefined : hints.register(root, () => [
|
|
8664
|
-
...
|
|
9080
|
+
...modeList.length > 1 ? modeList.map((m, i) => ({
|
|
8665
9081
|
el: modeBtns[i],
|
|
8666
|
-
label: m.
|
|
8667
|
-
activate: () => setMode(m
|
|
8668
|
-
})),
|
|
9082
|
+
label: MODE_LABEL[m].long,
|
|
9083
|
+
activate: () => setMode(m)
|
|
9084
|
+
})) : [],
|
|
8669
9085
|
{ el: loopBtn, label: "Loop", activate: () => api.setLoop(!loopNow()) },
|
|
8670
9086
|
...loupeBtn.hidden ? [] : [{ el: loupeBtn, label: "Loupe", activate: () => setLoupe(!loupeOn) }],
|
|
8671
9087
|
...zoomed() ? [{ el: zoomReset, label: "Reset zoom", activate: () => api.setZoom(null) }] : [],
|
|
@@ -8690,6 +9106,7 @@ function compare(container, options) {
|
|
|
8690
9106
|
get mode() {
|
|
8691
9107
|
return mode;
|
|
8692
9108
|
},
|
|
9109
|
+
modes: modeList,
|
|
8693
9110
|
get wipe() {
|
|
8694
9111
|
return wipe;
|
|
8695
9112
|
},
|
|
@@ -8745,7 +9162,7 @@ function compare(container, options) {
|
|
|
8745
9162
|
tl?.update({ fps: next.fps });
|
|
8746
9163
|
requestDraw();
|
|
8747
9164
|
},
|
|
8748
|
-
seek: (t) => tl ? tl.seek(t) : ownSeek(t),
|
|
9165
|
+
seek: (t, o) => tl ? tl.seek(t, o?.glide ? { glide: true } : undefined) : ownSeek(t),
|
|
8749
9166
|
seekBy(d) {
|
|
8750
9167
|
const total = duration || tl?.duration || 0;
|
|
8751
9168
|
const t = Math.min(total, Math.max(0, now() + d));
|
|
@@ -8786,7 +9203,7 @@ function compare(container, options) {
|
|
|
8786
9203
|
dispose() {
|
|
8787
9204
|
disposed = true;
|
|
8788
9205
|
loop.stop();
|
|
8789
|
-
|
|
9206
|
+
modePill?.dispose();
|
|
8790
9207
|
win.clearTimeout(releaseTimer);
|
|
8791
9208
|
ro.disconnect();
|
|
8792
9209
|
nearIo?.disconnect();
|
|
@@ -8816,7 +9233,7 @@ function compare(container, options) {
|
|
|
8816
9233
|
wake();
|
|
8817
9234
|
return api;
|
|
8818
9235
|
}
|
|
8819
|
-
var COMPARE_FFMPEG = "ffmpeg -i in.mov -vf fps=30 -fps_mode cfr -c:v libx264 -preset slow -crf 18 -g 15 -keyint_min 15 -pix_fmt yuv420p -movflags +faststart -an out.mp4", LAYOUT, FADE2, FADE_REDUCED, ZOOM,
|
|
9236
|
+
var COMPARE_FFMPEG = "ffmpeg -i in.mov -vf fps=30 -fps_mode cfr -c:v libx264 -preset slow -crf 18 -g 15 -keyint_min 15 -pix_fmt yuv420p -movflags +faststart -an out.mp4", LAYOUT, FADE2, FADE_REDUCED, ZOOM, WIPE_CATCH, SLOP = 12, INSET = 8, GRIP, LOUPE, FAST_SEEK_FRAMES = 15, RELEASE_MS = 3000, MODE_LABEL;
|
|
8820
9237
|
var init_compare = __esm(() => {
|
|
8821
9238
|
init_motion();
|
|
8822
9239
|
init_page_hints();
|
|
@@ -8824,21 +9241,24 @@ var init_compare = __esm(() => {
|
|
|
8824
9241
|
init_compare_gpu();
|
|
8825
9242
|
init_compare_model();
|
|
8826
9243
|
init_compare_strip();
|
|
9244
|
+
init_icons();
|
|
8827
9245
|
init_look();
|
|
8828
9246
|
init_rgba();
|
|
9247
|
+
init_selection_pill();
|
|
8829
9248
|
init_timeline();
|
|
9249
|
+
init_timeline_model();
|
|
8830
9250
|
LAYOUT = springMotion({ duration: 0.35, bounce: 0 });
|
|
8831
9251
|
FADE2 = springMotion(SPRINGS.snappy);
|
|
8832
9252
|
FADE_REDUCED = springMotion(FADE);
|
|
8833
9253
|
ZOOM = springMotion({ duration: 0.35, bounce: 0 });
|
|
9254
|
+
WIPE_CATCH = springMotion(CATCH_UP);
|
|
9255
|
+
GRIP = { w: 16, h: 28 };
|
|
8834
9256
|
LOUPE = { r: 88, zoom: 4 };
|
|
8835
|
-
|
|
8836
|
-
{
|
|
8837
|
-
|
|
8838
|
-
|
|
8839
|
-
|
|
8840
|
-
];
|
|
8841
|
-
KEY_MODE = { s: "side", w: "wipe", d: "difference" };
|
|
9257
|
+
MODE_LABEL = {
|
|
9258
|
+
side: { short: "Side", long: "Side by side" },
|
|
9259
|
+
wipe: { short: "Wipe", long: "Wipe" },
|
|
9260
|
+
difference: { short: "Difference", long: "Difference" }
|
|
9261
|
+
};
|
|
8842
9262
|
});
|
|
8843
9263
|
|
|
8844
9264
|
// src/ui/scrollbar.ts
|
|
@@ -8960,34 +9380,27 @@ function tree(container, options) {
|
|
|
8960
9380
|
const empty = doc.createElement("div");
|
|
8961
9381
|
empty.className = "knobs-tree-empty";
|
|
8962
9382
|
empty.hidden = true;
|
|
8963
|
-
|
|
8964
|
-
|
|
8965
|
-
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
9383
|
+
root.append(space, line, empty);
|
|
9384
|
+
let pill = null;
|
|
9385
|
+
let picked = null;
|
|
9386
|
+
let travelUntil = 0;
|
|
9387
|
+
const pickedRow = () => {
|
|
9388
|
+
const id = sel.ids.length === 1 ? sel.ids[0] : null;
|
|
9389
|
+
const v = id === null ? undefined : views.get(id);
|
|
9390
|
+
return v && !v.leaving && rowIndex.has(v.id) ? v : null;
|
|
8970
9391
|
};
|
|
8971
9392
|
const placeCursor = (animate) => {
|
|
8972
|
-
if (!
|
|
9393
|
+
if (!pill)
|
|
8973
9394
|
return;
|
|
8974
9395
|
const id = sel.ids.length === 1 ? sel.ids[0] : null;
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
}
|
|
8982
|
-
|
|
8983
|
-
cursorY.set(i * h);
|
|
8984
|
-
else
|
|
8985
|
-
cursorY.snap(i * h);
|
|
8986
|
-
cursorOn = true;
|
|
8987
|
-
cursor.setAttribute("data-on", "");
|
|
8988
|
-
drawCursor();
|
|
8989
|
-
if (!cursorY.resting)
|
|
8990
|
-
loop.wake();
|
|
9396
|
+
root.toggleAttribute("data-glide", id !== null && rowIndex.has(id));
|
|
9397
|
+
const fresh = id !== picked;
|
|
9398
|
+
picked = id;
|
|
9399
|
+
if (animate && fresh) {
|
|
9400
|
+
travelUntil = performance.now() + 450;
|
|
9401
|
+
pill.update();
|
|
9402
|
+
} else if (performance.now() >= travelUntil)
|
|
9403
|
+
pill.update({ snap: true });
|
|
8991
9404
|
};
|
|
8992
9405
|
container.append(root);
|
|
8993
9406
|
const scrollbar = overlayScrollbar(root, space);
|
|
@@ -9016,6 +9429,12 @@ function tree(container, options) {
|
|
|
9016
9429
|
};
|
|
9017
9430
|
const views = new Map;
|
|
9018
9431
|
const pool = [];
|
|
9432
|
+
if (options.glide)
|
|
9433
|
+
pill = selectionPill(root, {
|
|
9434
|
+
rows: () => [...views.values()].filter((v) => !v.leaving).map((v) => v.el),
|
|
9435
|
+
selected: () => pickedRow()?.el ?? null,
|
|
9436
|
+
radius: (row) => Number.parseFloat(win.getComputedStyle(row, "::before").borderTopLeftRadius) || 0
|
|
9437
|
+
});
|
|
9019
9438
|
const makeView = (id) => {
|
|
9020
9439
|
const v = pool.pop() ?? createView();
|
|
9021
9440
|
v.id = id;
|
|
@@ -9196,12 +9615,6 @@ function tree(container, options) {
|
|
|
9196
9615
|
function frame(dt) {
|
|
9197
9616
|
let moving = false;
|
|
9198
9617
|
let bottom = rows.length * h;
|
|
9199
|
-
if (options.glide && !cursorY.resting) {
|
|
9200
|
-
cursorY.step(dt);
|
|
9201
|
-
drawCursor();
|
|
9202
|
-
if (!cursorY.resting)
|
|
9203
|
-
moving = true;
|
|
9204
|
-
}
|
|
9205
9618
|
for (const v of views.values()) {
|
|
9206
9619
|
v.y.step(dt);
|
|
9207
9620
|
if (!v.y.resting)
|
|
@@ -9221,6 +9634,8 @@ function tree(container, options) {
|
|
|
9221
9634
|
}
|
|
9222
9635
|
setSpace(moving ? bottom : rows.length * h);
|
|
9223
9636
|
trim();
|
|
9637
|
+
if (pill && moving && performance.now() >= travelUntil)
|
|
9638
|
+
pill.update({ snap: true });
|
|
9224
9639
|
return moving;
|
|
9225
9640
|
}
|
|
9226
9641
|
const trim = () => {
|
|
@@ -9849,6 +10264,7 @@ function tree(container, options) {
|
|
|
9849
10264
|
autoScroll.stop();
|
|
9850
10265
|
ro.disconnect();
|
|
9851
10266
|
scrollbar.dispose();
|
|
10267
|
+
pill?.dispose();
|
|
9852
10268
|
dragging?.ghost.remove();
|
|
9853
10269
|
root.remove();
|
|
9854
10270
|
}
|
|
@@ -9867,6 +10283,7 @@ var init_tree = __esm(() => {
|
|
|
9867
10283
|
init_motion();
|
|
9868
10284
|
init_page_hints();
|
|
9869
10285
|
init_look();
|
|
10286
|
+
init_selection_pill();
|
|
9870
10287
|
init_tree_model();
|
|
9871
10288
|
MOVE = springMotion(SPRINGS.default);
|
|
9872
10289
|
});
|
|
@@ -9916,33 +10333,29 @@ var init_diff_css = __esm(() => {
|
|
|
9916
10333
|
.knobs-diff-fill{flex:1}
|
|
9917
10334
|
.knobs-diff-nav{flex:none;display:inline-flex;align-items:center;gap:1px;color:var(--_k-fg-3);font-size:var(--_k-text-meta);font-variant-numeric:tabular-nums}
|
|
9918
10335
|
.knobs-diff-nav>span{min-width:3.6em;text-align:center}
|
|
9919
|
-
:where(.knobs-ui) :is(.knobs-diff-btn,.knobs-diff-
|
|
10336
|
+
:where(.knobs-ui) :is(.knobs-diff-btn,.knobs-diff-choice,.knobs-diff-viewed,.knobs-diff-filter>input,.knobs-diff-filter>button){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;border-radius:0;
|
|
9920
10337
|
margin:0;padding:0;min-width:0;box-shadow:none;outline:none}
|
|
9921
|
-
.knobs-ui .knobs-diff-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:
|
|
10338
|
+
.knobs-ui .knobs-diff-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--_k-control-h);height:var(--_k-control-h);border-radius:calc(var(--_k-radius) * 999);color:var(--_k-fg-3);cursor:pointer;
|
|
9922
10339
|
transition:background .15s,color .15s,opacity .15s}
|
|
9923
10340
|
.knobs-ui .knobs-diff-btn:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
|
|
9924
10341
|
.knobs-ui .knobs-diff-btn[aria-pressed="true"]{color:var(--_k-fg);background:var(--_ku-wash)}
|
|
9925
10342
|
.knobs-ui .knobs-diff-btn:disabled{opacity:.35;cursor:default;background:transparent}
|
|
9926
|
-
.knobs-diff-btn svg{width:
|
|
10343
|
+
.knobs-diff-btn svg{width:16px;height:16px}
|
|
9927
10344
|
/* Viewed: a check with its word, as on GitHub; the path dims once it's ticked. */
|
|
9928
10345
|
.knobs-ui .knobs-diff-viewed{flex:none;display:inline-flex;align-items:center;gap:5px;height:var(--_k-control-h);padding:0 8px 0 6px;border-radius:var(--kd-ctl);color:var(--_k-fg-2);
|
|
9929
10346
|
font-size:var(--_k-text-meta);font-weight:var(--_k-weight-label);white-space:nowrap;cursor:pointer;transition:background .15s,color .15s}
|
|
9930
10347
|
.knobs-ui .knobs-diff-viewed:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
|
|
9931
10348
|
.knobs-ui .knobs-diff-viewed[aria-pressed="true"]{color:var(--_k-fg);background:var(--_ku-wash)}
|
|
9932
|
-
.knobs-diff-viewed svg{width:
|
|
10349
|
+
.knobs-diff-viewed svg{width:16px;height:16px}
|
|
9933
10350
|
.knobs-diff-viewed[aria-pressed="true"] svg{color:var(--kd-add)}
|
|
9934
10351
|
.knobs-diff-path{transition:opacity .2s}
|
|
9935
10352
|
.knobs-diff[data-viewed]>.knobs-diff-head .knobs-diff-path,.knobs-diff-part[data-viewed] .knobs-diff-path{opacity:.6}
|
|
9936
|
-
/* Split | Unified:
|
|
9937
|
-
|
|
9938
|
-
.knobs-diff-seg{position:relative;flex:none;display:grid;grid-template-columns:1fr 1fr;height:var(--_k-control-h);padding:2px;border-radius:var(--kd-ctl);background:var(--_k-
|
|
9939
|
-
.knobs-ui .knobs-diff-
|
|
9940
|
-
font-weight:var(--_k-weight-label);white-space:nowrap;cursor:pointer;transition:color
|
|
9941
|
-
.knobs-ui .knobs-diff-
|
|
9942
|
-
.knobs-diff-pill{position:absolute;top:2px;bottom:2px;left:2px;width:calc(50% - 2px);border-radius:max(0px,calc(var(--kd-ctl) - 2px));background:color-mix(in srgb,var(--_k-accent) 18%,var(--_k-segmented-active));
|
|
9943
|
-
box-shadow:0 1px 2px rgba(0,0,0,calc(.16 * var(--k-lift,1)));transition:transform var(--_ku-ease-ms) var(--_ku-ease)}
|
|
9944
|
-
.knobs-diff-seg[data-value="unified"]>.knobs-diff-pill{transform:translateX(100%)}
|
|
9945
|
-
.knobs-diff[data-frame="flat"] .knobs-diff-pill{box-shadow:none}
|
|
10353
|
+
/* Split | Unified: the selection pill on the one picked, its bright copy the picked one's text; a
|
|
10354
|
+
choice isn't brighter for being picked. Choices are styled by class, as the copy holds them too. */
|
|
10355
|
+
.knobs-diff-seg{position:relative;flex:none;display:grid;grid-template-columns:1fr 1fr;height:var(--_k-control-h);padding:2px;border-radius:var(--kd-ctl);background:var(--_k-fill)}
|
|
10356
|
+
.knobs-ui .knobs-diff-choice{padding:0 9px;border-radius:max(0px,calc(var(--kd-ctl) - 2px));color:var(--_k-fg-2);font-size:var(--_k-text-meta);
|
|
10357
|
+
font-weight:var(--_k-weight-label);white-space:nowrap;cursor:pointer;transition:color calc(var(--_k-hover-out) * 1ms)}
|
|
10358
|
+
.knobs-ui .knobs-diff-choice:is(:hover,:focus-visible){color:var(--_k-fg)}
|
|
9946
10359
|
/* The diff: one layer per file or layout on show, the old fading under the new. */
|
|
9947
10360
|
.knobs-diff-body{position:relative;flex:1;min-height:0}
|
|
9948
10361
|
.knobs-diff-probe{position:absolute;left:0;top:0;width:0;height:var(--kd-line);visibility:hidden;pointer-events:none}
|
|
@@ -10037,7 +10450,7 @@ var init_diff_css = __esm(() => {
|
|
|
10037
10450
|
.knobs-ui .knobs-diff-filter>input::placeholder{color:var(--_k-fg-3)}
|
|
10038
10451
|
.knobs-ui .knobs-diff-filter>button{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;color:var(--_k-fg-3);cursor:pointer;transition:background .12s,color .12s,opacity .12s}
|
|
10039
10452
|
.knobs-ui .knobs-diff-filter>button:hover{background:var(--_ku-wash-hi);color:var(--_k-fg)}
|
|
10040
|
-
.knobs-diff-filter>button svg{width:
|
|
10453
|
+
.knobs-diff-filter>button svg{width:12px;height:12px}
|
|
10041
10454
|
.knobs-diff-list{position:relative;flex:1;min-height:0}
|
|
10042
10455
|
.knobs-diff-files .knobs-diff-counts{font-size:var(--_k-text-meta);align-items:center}
|
|
10043
10456
|
.knobs-diff-files .knobs-diff-counts{gap:5px}
|
|
@@ -10843,7 +11256,7 @@ function codeDiff(container, options) {
|
|
|
10843
11256
|
};
|
|
10844
11257
|
const nav = make("span", "knobs-diff-nav");
|
|
10845
11258
|
const prev = button("Previous file", PREV);
|
|
10846
|
-
const next = button("Next file",
|
|
11259
|
+
const next = button("Next file", NEXT);
|
|
10847
11260
|
const place = make("span", "");
|
|
10848
11261
|
nav.append(prev, place, next);
|
|
10849
11262
|
const wrapButton = button("Wrap lines", WRAP);
|
|
@@ -10864,9 +11277,8 @@ function codeDiff(container, options) {
|
|
|
10864
11277
|
const seg = make("div", "knobs-diff-seg");
|
|
10865
11278
|
seg.setAttribute("role", "radiogroup");
|
|
10866
11279
|
seg.setAttribute("aria-label", "Layout");
|
|
10867
|
-
const pill = make("i", "knobs-diff-pill");
|
|
10868
11280
|
const choice = (value, label) => {
|
|
10869
|
-
const b = make("button", "");
|
|
11281
|
+
const b = make("button", "knobs-diff-choice");
|
|
10870
11282
|
b.type = "button";
|
|
10871
11283
|
b.setAttribute("role", "radio");
|
|
10872
11284
|
b.dataset.value = value;
|
|
@@ -10875,7 +11287,7 @@ function codeDiff(container, options) {
|
|
|
10875
11287
|
};
|
|
10876
11288
|
const splitButton = choice("split", "Split");
|
|
10877
11289
|
const unifiedButton = choice("unified", "Unified");
|
|
10878
|
-
seg.append(
|
|
11290
|
+
seg.append(splitButton, unifiedButton);
|
|
10879
11291
|
if (options.lead)
|
|
10880
11292
|
head.append(options.lead);
|
|
10881
11293
|
head.append(path, stat, make("span", "knobs-diff-fill"), nav, wrapButton, seg, viewedButton);
|
|
@@ -10886,6 +11298,11 @@ function codeDiff(container, options) {
|
|
|
10886
11298
|
body.append(note, probe);
|
|
10887
11299
|
root.append(head, body);
|
|
10888
11300
|
container.append(root);
|
|
11301
|
+
const segPill = selectionPill(seg, {
|
|
11302
|
+
rows: () => [splitButton, unifiedButton],
|
|
11303
|
+
selected: () => layout === "split" ? splitButton : unifiedButton
|
|
11304
|
+
});
|
|
11305
|
+
let pilled = layout;
|
|
10889
11306
|
const fileNow = () => files.find((f) => f.name === current) ?? null;
|
|
10890
11307
|
const paintHead = () => {
|
|
10891
11308
|
const file = fileNow();
|
|
@@ -10918,6 +11335,10 @@ function codeDiff(container, options) {
|
|
|
10918
11335
|
next.disabled = at >= files.length - 1;
|
|
10919
11336
|
wrapButton.setAttribute("aria-pressed", String(wrap));
|
|
10920
11337
|
seg.dataset.value = layout;
|
|
11338
|
+
if (pilled !== layout) {
|
|
11339
|
+
pilled = layout;
|
|
11340
|
+
segPill.update();
|
|
11341
|
+
}
|
|
10921
11342
|
splitButton.setAttribute("aria-checked", String(layout === "split"));
|
|
10922
11343
|
unifiedButton.setAttribute("aria-checked", String(layout === "unified"));
|
|
10923
11344
|
splitButton.tabIndex = layout === "split" ? 0 : -1;
|
|
@@ -11752,6 +12173,7 @@ function codeDiff(container, options) {
|
|
|
11752
12173
|
dispose() {
|
|
11753
12174
|
disposed = true;
|
|
11754
12175
|
loop.stop();
|
|
12176
|
+
segPill.dispose();
|
|
11755
12177
|
sizes.disconnect();
|
|
11756
12178
|
attaching.disconnect();
|
|
11757
12179
|
resized.disconnect();
|
|
@@ -12107,7 +12529,7 @@ function diffReview(container, options) {
|
|
|
12107
12529
|
}
|
|
12108
12530
|
};
|
|
12109
12531
|
}
|
|
12110
|
-
var lib, load = () => lib ??= import("@pierre/diffs"), SYNTAX, IN, OUT, FADE3, HEIGHT, DRAWER, BLUR = 3, WRAP, PREV, UNVIEWED, VIEWED, SEARCH, CLEAR, SIDEBAR, SEPARATOR = 32;
|
|
12532
|
+
var lib, load = () => lib ??= import("@pierre/diffs"), SYNTAX, IN, OUT, FADE3, HEIGHT, DRAWER, BLUR = 3, WRAP, PREV, NEXT, UNVIEWED, VIEWED, SEARCH, CLEAR, SIDEBAR, SEPARATOR = 32;
|
|
12111
12533
|
var init_diff = __esm(() => {
|
|
12112
12534
|
init_glide();
|
|
12113
12535
|
init_motion();
|
|
@@ -12115,6 +12537,8 @@ var init_diff = __esm(() => {
|
|
|
12115
12537
|
init_diff_model();
|
|
12116
12538
|
init_look();
|
|
12117
12539
|
init_rgba();
|
|
12540
|
+
init_icons();
|
|
12541
|
+
init_selection_pill();
|
|
12118
12542
|
init_tree();
|
|
12119
12543
|
SYNTAX = { dark: "pierre-dark", light: "pierre-light" };
|
|
12120
12544
|
IN = springMotion(SPRINGS.default);
|
|
@@ -12122,13 +12546,14 @@ var init_diff = __esm(() => {
|
|
|
12122
12546
|
FADE3 = springMotion(FADE);
|
|
12123
12547
|
HEIGHT = springMotion(SPRINGS.calm);
|
|
12124
12548
|
DRAWER = springMotion(SPRINGS.calm);
|
|
12125
|
-
WRAP =
|
|
12126
|
-
PREV =
|
|
12127
|
-
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12549
|
+
WRAP = icon("arrowUDownLeft");
|
|
12550
|
+
PREV = icon("caretLeft");
|
|
12551
|
+
NEXT = icon("caretRight");
|
|
12552
|
+
UNVIEWED = icon("circle");
|
|
12553
|
+
VIEWED = icon("checkCircle");
|
|
12554
|
+
SEARCH = icon("magnifyingGlass", { small: true });
|
|
12555
|
+
CLEAR = icon("x", { small: true });
|
|
12556
|
+
SIDEBAR = icon("sidebar");
|
|
12132
12557
|
});
|
|
12133
12558
|
|
|
12134
12559
|
// src/ui/index.ts
|
|
@@ -14629,6 +15054,11 @@ function readout(field, options = {}) {
|
|
|
14629
15054
|
dispose: () => view.dispose()
|
|
14630
15055
|
};
|
|
14631
15056
|
}
|
|
15057
|
+
|
|
15058
|
+
// src/ui/index.ts
|
|
15059
|
+
init_icons();
|
|
15060
|
+
init_selection_pill();
|
|
15061
|
+
|
|
14632
15062
|
// src/ui/tooltip.ts
|
|
14633
15063
|
init_keys();
|
|
14634
15064
|
init_layer();
|
|
@@ -18390,6 +18820,7 @@ function activity(container, options) {
|
|
|
18390
18820
|
// src/ui/picker.ts
|
|
18391
18821
|
init_motion();
|
|
18392
18822
|
init_look();
|
|
18823
|
+
init_icons();
|
|
18393
18824
|
|
|
18394
18825
|
// src/ui/picker-model.ts
|
|
18395
18826
|
function digitPick(ids, key) {
|
|
@@ -18444,7 +18875,7 @@ var CLOSE3 = springMotion(CLOSE);
|
|
|
18444
18875
|
var CARD = springMotion(SPRINGS.default);
|
|
18445
18876
|
var FADE6 = springMotion(FADE);
|
|
18446
18877
|
var DRIFT = 6;
|
|
18447
|
-
var CHECK2 =
|
|
18878
|
+
var CHECK2 = icon("check", { small: true });
|
|
18448
18879
|
function optionPicker(container, options) {
|
|
18449
18880
|
const doc = container.ownerDocument;
|
|
18450
18881
|
const win = doc.defaultView;
|
|
@@ -20262,7 +20693,7 @@ function mountTable(host, m, steps) {
|
|
|
20262
20693
|
context: () => ({ kind: "table" })
|
|
20263
20694
|
};
|
|
20264
20695
|
}
|
|
20265
|
-
var
|
|
20696
|
+
var grid2 = (v) => Math.round(v * 64) / 64;
|
|
20266
20697
|
function chapterPills(host, chapters, io) {
|
|
20267
20698
|
const doc = host.ownerDocument;
|
|
20268
20699
|
const win = doc.defaultView;
|
|
@@ -20290,9 +20721,9 @@ function chapterPills(host, chapters, io) {
|
|
|
20290
20721
|
const y = new Spring(0, MOTION.calm.omega, MOTION.calm.zeta, 0.25);
|
|
20291
20722
|
const w = new Spring(0, MOTION.calm.omega, MOTION.calm.zeta, 0.25);
|
|
20292
20723
|
const draw = () => {
|
|
20293
|
-
const left =
|
|
20294
|
-
mark.style.transform = `translate(${left}px,${
|
|
20295
|
-
mark.style.width = `${
|
|
20724
|
+
const left = grid2(x.x);
|
|
20725
|
+
mark.style.transform = `translate(${left}px,${grid2(y.x)}px)`;
|
|
20726
|
+
mark.style.width = `${grid2(x.x + w.x) - left}px`;
|
|
20296
20727
|
};
|
|
20297
20728
|
const loop = frameLoop(win, (dt) => {
|
|
20298
20729
|
x.step(dt);
|
|
@@ -20896,7 +21327,7 @@ var lookOf2 = (o) => ({
|
|
|
20896
21327
|
...o.preset ? { preset: o.preset } : {},
|
|
20897
21328
|
...o.theme ? { theme: o.theme } : {}
|
|
20898
21329
|
});
|
|
20899
|
-
var
|
|
21330
|
+
var grid3 = (v) => Math.round(v * 64) / 64;
|
|
20900
21331
|
var ICON = {
|
|
20901
21332
|
full: svg('<path d="M3 6.5V3h3.5M13 6.5V3H9.5M3 9.5V13h3.5M13 9.5V13H9.5"/>'),
|
|
20902
21333
|
exit: svg('<path d="M6.5 3v3.5H3M9.5 3v3.5H13M6.5 13V9.5H3M9.5 13V9.5H13"/>'),
|
|
@@ -21076,8 +21507,8 @@ function walkthrough(container, options) {
|
|
|
21076
21507
|
if (mark) {
|
|
21077
21508
|
pillY.step(dt);
|
|
21078
21509
|
pillH.step(dt);
|
|
21079
|
-
mark.style.transform = `translateY(${
|
|
21080
|
-
mark.style.height = `${
|
|
21510
|
+
mark.style.transform = `translateY(${grid3(pillY.x)}px)`;
|
|
21511
|
+
mark.style.height = `${grid3(pillY.x + pillH.x) - grid3(pillY.x)}px`;
|
|
21081
21512
|
more ||= !pillY.resting || !pillH.resting;
|
|
21082
21513
|
}
|
|
21083
21514
|
if (scroll.to && scroll.el) {
|
|
@@ -21237,10 +21668,10 @@ function walkthrough(container, options) {
|
|
|
21237
21668
|
const a = f.hold.getBoundingClientRect();
|
|
21238
21669
|
const b = fullRect();
|
|
21239
21670
|
const k = reduced() ? Math.round(f.p.target) : f.p.x;
|
|
21240
|
-
const left =
|
|
21241
|
-
const top =
|
|
21242
|
-
const right =
|
|
21243
|
-
const bottom =
|
|
21671
|
+
const left = grid3(a.left + (b.x - a.left) * k);
|
|
21672
|
+
const top = grid3(a.top + (b.y - a.top) * k);
|
|
21673
|
+
const right = grid3(a.right + (b.x + b.w - a.right) * k);
|
|
21674
|
+
const bottom = grid3(a.bottom + (b.y + b.h - a.bottom) * k);
|
|
21244
21675
|
const s = f.v.card.style;
|
|
21245
21676
|
s.left = `${left}px`;
|
|
21246
21677
|
s.top = `${top}px`;
|
|
@@ -22104,9 +22535,11 @@ function walkthrough(container, options) {
|
|
|
22104
22535
|
return api;
|
|
22105
22536
|
}
|
|
22106
22537
|
export {
|
|
22538
|
+
CATCH_UP,
|
|
22107
22539
|
COLLAPSE_PAST,
|
|
22108
22540
|
COMPARE_FFMPEG,
|
|
22109
22541
|
FIT_MAX,
|
|
22542
|
+
ICON_NAMES,
|
|
22110
22543
|
activity,
|
|
22111
22544
|
adjacentMarker,
|
|
22112
22545
|
advance,
|
|
@@ -22123,12 +22556,14 @@ export {
|
|
|
22123
22556
|
commandsFrom,
|
|
22124
22557
|
compare,
|
|
22125
22558
|
compareLayout,
|
|
22559
|
+
compareModes,
|
|
22126
22560
|
comparePaths,
|
|
22127
22561
|
compareStrip,
|
|
22128
22562
|
compareText,
|
|
22129
22563
|
confirm,
|
|
22130
22564
|
contextMenu,
|
|
22131
22565
|
countChanges,
|
|
22566
|
+
currentMarker,
|
|
22132
22567
|
diffActivity,
|
|
22133
22568
|
diffBar,
|
|
22134
22569
|
diffCounts,
|
|
@@ -22153,7 +22588,9 @@ export {
|
|
|
22153
22588
|
frameOf,
|
|
22154
22589
|
frameTime,
|
|
22155
22590
|
fuzzy,
|
|
22591
|
+
gripTop,
|
|
22156
22592
|
hints,
|
|
22593
|
+
icon,
|
|
22157
22594
|
inTriangle,
|
|
22158
22595
|
indexActivity,
|
|
22159
22596
|
indexTree,
|
|
@@ -22172,7 +22609,9 @@ export {
|
|
|
22172
22609
|
mediaKind,
|
|
22173
22610
|
mediaSlot,
|
|
22174
22611
|
menu,
|
|
22612
|
+
modeForKey,
|
|
22175
22613
|
motionBlur,
|
|
22614
|
+
moveHead,
|
|
22176
22615
|
navigate,
|
|
22177
22616
|
navigateActivity,
|
|
22178
22617
|
normalizeWalkthrough,
|
|
@@ -22181,9 +22620,14 @@ export {
|
|
|
22181
22620
|
pageHints,
|
|
22182
22621
|
parseLayout,
|
|
22183
22622
|
parsePatch,
|
|
22623
|
+
pillBoxOf,
|
|
22624
|
+
pillProgress,
|
|
22625
|
+
pillRadius,
|
|
22626
|
+
pillSpring,
|
|
22184
22627
|
place,
|
|
22185
22628
|
plainAccess,
|
|
22186
22629
|
planBento,
|
|
22630
|
+
planPill,
|
|
22187
22631
|
popover,
|
|
22188
22632
|
railSegments,
|
|
22189
22633
|
rank,
|
|
@@ -22195,9 +22639,11 @@ export {
|
|
|
22195
22639
|
rulerTicks,
|
|
22196
22640
|
safeTriangle,
|
|
22197
22641
|
scrubTime,
|
|
22642
|
+
seamLabels,
|
|
22198
22643
|
seekTime,
|
|
22199
22644
|
seeked,
|
|
22200
22645
|
select,
|
|
22646
|
+
selectionPill,
|
|
22201
22647
|
showsSelection,
|
|
22202
22648
|
softClamp,
|
|
22203
22649
|
solve2 as solveSplit,
|