@ixfx/components 0.4.2 → 0.4.4
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/bundle/index.d.ts +435 -1193
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +7765 -20670
- package/bundle/index.js.map +1 -1
- package/dist/ac-text.d.ts +12 -7
- package/dist/ac-text.d.ts.map +1 -1
- package/dist/ac-text.js +2 -3
- package/dist/ac-text.js.map +1 -1
- package/dist/{button-C3fLMKUv.js → button-DxYee1ZH.js} +2 -2
- package/dist/{button-C3fLMKUv.js.map → button-DxYee1ZH.js.map} +1 -1
- package/dist/button.d.ts +1 -2
- package/dist/button.d.ts.map +1 -1
- package/dist/button.js +1 -2
- package/dist/checkbox.d.ts +0 -1
- package/dist/checkbox.d.ts.map +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/{colour-picker-0sgAha1T.js → colour-picker-BacNRabo.js} +14 -16
- package/dist/colour-picker-BacNRabo.js.map +1 -0
- package/dist/colour-picker.d.ts +1 -1
- package/dist/colour-picker.js +1 -1
- package/dist/crumbs.d.ts +5 -2
- package/dist/crumbs.d.ts.map +1 -1
- package/dist/crumbs.js +45 -20
- package/dist/crumbs.js.map +1 -1
- package/dist/data-display.d.ts +1 -2
- package/dist/data-display.d.ts.map +1 -1
- package/dist/data-display.js +25 -23
- package/dist/data-display.js.map +1 -1
- package/dist/{data-provider-DgI909FP.js → data-provider-35TyWclX.js} +2 -2
- package/dist/data-provider-35TyWclX.js.map +1 -0
- package/dist/{decorate-DdjvVHS-.js → decorate-VRK8rslU.js} +2 -2
- package/dist/{decorate-DdjvVHS-.js.map → decorate-VRK8rslU.js.map} +1 -1
- package/dist/editable-label.d.ts +1 -2
- package/dist/editable-label.d.ts.map +1 -1
- package/dist/editable-label.js +1 -1
- package/dist/editable-label.js.map +1 -1
- package/dist/{hex-editor-WZrjRtvL.js → hex-editor-Bk6rxhfg.js} +9 -11
- package/dist/hex-editor-Bk6rxhfg.js.map +1 -0
- package/dist/{hex-editor-CMIxtNgT.d.ts → hex-editor-Caq8vNQk.d.ts} +2 -3
- package/dist/hex-editor-Caq8vNQk.d.ts.map +1 -0
- package/dist/hex.d.ts +1 -1
- package/dist/hex.js +1 -1
- package/dist/highlight-B-eQrhhb.js.map +1 -1
- package/dist/{icon-Ndo40kNO.js → icon-B22XVlCt.js} +6 -4
- package/dist/{icon-Ndo40kNO.js.map → icon-B22XVlCt.js.map} +1 -1
- package/dist/{icon-epZd-JIO.d.ts → icon-DpA9x2Ve.d.ts} +3 -4
- package/dist/icon-DpA9x2Ve.d.ts.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +1 -1
- package/dist/{incr-search-CeERfijK.js → incr-search-2pz21xtR.js} +9 -6
- package/dist/incr-search-2pz21xtR.js.map +1 -0
- package/dist/incr-search.d.ts +1 -1
- package/dist/incr-search.js +1 -1
- package/dist/{index-CowKi2mo.d.ts → index-BeuCXtiO.d.ts} +3 -4
- package/dist/index-BeuCXtiO.d.ts.map +1 -0
- package/dist/{index-D87kRcEs.d.ts → index-BtGFYfaK.d.ts} +2 -1
- package/dist/index-BtGFYfaK.d.ts.map +1 -0
- package/dist/{index-JuEVfmr-.d.ts → index-CoqtMSd9.d.ts} +6 -4
- package/dist/index-CoqtMSd9.d.ts.map +1 -0
- package/dist/{index-9fGVAg1d.d.ts → index-Cxwxtj6g.d.ts} +3 -3
- package/dist/index-Cxwxtj6g.d.ts.map +1 -0
- package/dist/index-D_ftz_IT.d.ts +184 -0
- package/dist/index-D_ftz_IT.d.ts.map +1 -0
- package/dist/{index-_RTQSKHi.d.ts → index-DfEkTGvT.d.ts} +11 -11
- package/dist/index-DfEkTGvT.d.ts.map +1 -0
- package/dist/index.d.ts +45 -30
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +304 -3075
- package/dist/index.js.map +1 -1
- package/dist/keyboard-B5xD7Fz-.js +36 -0
- package/dist/keyboard-B5xD7Fz-.js.map +1 -0
- package/dist/{labelled-input-base-Cz6qE6Dk.d.ts → labelled-input-base-DiTme1JO.d.ts} +2 -3
- package/dist/labelled-input-base-DiTme1JO.d.ts.map +1 -0
- package/dist/{labelled-input-base-9K_w3oLj.js → labelled-input-base-hoKGwyKT.js} +2 -2
- package/dist/{labelled-input-base-9K_w3oLj.js.map → labelled-input-base-hoKGwyKT.js.map} +1 -1
- package/dist/labelled-radial-input.d.ts +6 -5
- package/dist/labelled-radial-input.d.ts.map +1 -1
- package/dist/labelled-radial-input.js +7 -3
- package/dist/labelled-radial-input.js.map +1 -1
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/labelled-range-input.js +27 -3
- package/dist/labelled-range-input.js.map +1 -1
- package/dist/led.d.ts +1 -2
- package/dist/led.d.ts.map +1 -1
- package/dist/led.js +1 -1
- package/dist/led.js.map +1 -1
- package/dist/{menu-vjoiHZ13.js → menu-g6yd7ddN.js} +8 -9
- package/dist/menu-g6yd7ddN.js.map +1 -0
- package/dist/{menu-item-COx-Azgj.d.ts → menu-item-DSyf9f_L.d.ts} +4 -4
- package/dist/menu-item-DSyf9f_L.d.ts.map +1 -0
- package/dist/{menu-item-BrIuORYD.js → menu-item-NUKwJ4s5.js} +3 -4
- package/dist/{menu-item-BrIuORYD.js.map → menu-item-NUKwJ4s5.js.map} +1 -1
- package/dist/menu.d.ts +2 -2
- package/dist/menu.js +2 -2
- package/dist/miller.d.ts +8 -5
- package/dist/miller.d.ts.map +1 -1
- package/dist/miller.js +22 -24
- package/dist/miller.js.map +1 -1
- package/dist/narrowed-text.d.ts +7 -3
- package/dist/narrowed-text.d.ts.map +1 -1
- package/dist/narrowed-text.js +73 -47
- package/dist/narrowed-text.js.map +1 -1
- package/dist/panel.d.ts +1 -1
- package/dist/panel.d.ts.map +1 -1
- package/dist/panel.js +2 -2
- package/dist/panel.js.map +1 -1
- package/dist/plots.d.ts +2 -2
- package/dist/plots.js +1 -1
- package/dist/polar-pad.d.ts +15 -3
- package/dist/polar-pad.d.ts.map +1 -1
- package/dist/polar-pad.js +64 -11
- package/dist/polar-pad.js.map +1 -1
- package/dist/{radial-input-CpQPs1Mp.d.ts → radial-input-DXMN55Nz.d.ts} +6 -4
- package/dist/radial-input-DXMN55Nz.d.ts.map +1 -0
- package/dist/{radial-input-DZ7eQCcM.js → radial-input-DxCrt_NE.js} +41 -19
- package/dist/radial-input-DxCrt_NE.js.map +1 -0
- package/dist/radial-input.d.ts +1 -1
- package/dist/radial-input.js +1 -1
- package/dist/range-input.d.ts +15 -4
- package/dist/range-input.d.ts.map +1 -1
- package/dist/range-input.js +23 -2
- package/dist/range-input.js.map +1 -1
- package/dist/range.d.ts +15 -4
- package/dist/range.d.ts.map +1 -1
- package/dist/range.js +23 -2
- package/dist/range.js.map +1 -1
- package/dist/selecthorizontal.d.ts +1 -2
- package/dist/selecthorizontal.d.ts.map +1 -1
- package/dist/selecthorizontal.js +1 -1
- package/dist/selecthorizontal.js.map +1 -1
- package/dist/slider-input-DFpG23bS.js +1592 -0
- package/dist/slider-input-DFpG23bS.js.map +1 -0
- package/dist/slider-input-XppH3vcy.d.ts +160 -0
- package/dist/slider-input-XppH3vcy.d.ts.map +1 -0
- package/dist/slider-input.d.ts +2 -0
- package/dist/slider-input.js +2 -0
- package/dist/snap-container.d.ts +1 -2
- package/dist/snap-container.d.ts.map +1 -1
- package/dist/snap-container.js +6 -5
- package/dist/snap-container.js.map +1 -1
- package/dist/split-layout.d.ts +1 -2
- package/dist/split-layout.d.ts.map +1 -1
- package/dist/split-layout.js +6 -4
- package/dist/split-layout.js.map +1 -1
- package/dist/swipe.d.ts +12 -2
- package/dist/swipe.d.ts.map +1 -1
- package/dist/swipe.js +22 -3
- package/dist/swipe.js.map +1 -1
- package/dist/{tab-list-DLzb-m-I.d.ts → tab-list-BohmbvqF.d.ts} +14 -5
- package/dist/tab-list-BohmbvqF.d.ts.map +1 -0
- package/dist/tab-list-DzknpdSo.js +592 -0
- package/dist/tab-list-DzknpdSo.js.map +1 -0
- package/dist/tabs.d.ts +2 -2
- package/dist/tabs.js +1 -208
- package/dist/{tickled-controller-BjYCzGrU.d.ts → tickled-controller-BF2Ea0DE.d.ts} +2 -31
- package/dist/tickled-controller-BF2Ea0DE.d.ts.map +1 -0
- package/dist/tickled-styles-fNDdqf6l.js.map +1 -1
- package/dist/{timeline-2OFtN4Ta.js → timeline-B2fgDL4U.js} +37 -1438
- package/dist/timeline-B2fgDL4U.js.map +1 -0
- package/dist/timeline.d.ts +1 -1
- package/dist/timeline.js +1 -1
- package/dist/{tooltip-RGVIwHrZ.d.ts → tooltip-BlvBUQxx.d.ts} +3 -3
- package/dist/tooltip-BlvBUQxx.d.ts.map +1 -0
- package/dist/{tree-D84RUgFC.js → tree-BnvzhsAw.js} +8 -9
- package/dist/tree-BnvzhsAw.js.map +1 -0
- package/dist/{tree-component-BaCSPWg1.d.ts → tree-component-DCmmKZ4j.d.ts} +8 -124
- package/dist/tree-component-DCmmKZ4j.d.ts.map +1 -0
- package/dist/tree.d.ts +10 -4
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +1 -1
- package/dist/types-DO3gt5vg.d.ts +130 -0
- package/dist/types-DO3gt5vg.d.ts.map +1 -0
- package/dist/wheel-nudge-BlSCe_hD.js +86 -0
- package/dist/wheel-nudge-BlSCe_hD.js.map +1 -0
- package/dist/wheel-nudge-DGrNzWuE.d.ts +29 -0
- package/dist/wheel-nudge-DGrNzWuE.d.ts.map +1 -0
- package/dist/{xy-axis-CEI7ojks.d.ts → xy-axis-5KhVTNoX.d.ts} +75 -29
- package/dist/xy-axis-5KhVTNoX.d.ts.map +1 -0
- package/dist/xy-axis-CxHC8z5E.js +1849 -0
- package/dist/xy-axis-CxHC8z5E.js.map +1 -0
- package/dist/xy-pad.d.ts +13 -2
- package/dist/xy-pad.d.ts.map +1 -1
- package/dist/xy-pad.js +47 -6
- package/dist/xy-pad.js.map +1 -1
- package/docs-user/radial-input.md +2 -2
- package/package.json +22 -21
- package/dist/colour-C3MQIjFJ-vRCdr8W-.js +0 -3732
- package/dist/colour-C3MQIjFJ-vRCdr8W-.js.map +0 -1
- package/dist/colour-picker-0sgAha1T.js.map +0 -1
- package/dist/data-provider-DgI909FP.js.map +0 -1
- package/dist/dist-CA13FvMn.js +0 -980
- package/dist/dist-CA13FvMn.js.map +0 -1
- package/dist/hex-editor-CMIxtNgT.d.ts.map +0 -1
- package/dist/hex-editor-WZrjRtvL.js.map +0 -1
- package/dist/icon-epZd-JIO.d.ts.map +0 -1
- package/dist/incr-search-CeERfijK.js.map +0 -1
- package/dist/index-9fGVAg1d.d.ts.map +0 -1
- package/dist/index-CowKi2mo.d.ts.map +0 -1
- package/dist/index-D87kRcEs.d.ts.map +0 -1
- package/dist/index-DgXpCg_G.d.ts +0 -1244
- package/dist/index-DgXpCg_G.d.ts.map +0 -1
- package/dist/index-JuEVfmr-.d.ts.map +0 -1
- package/dist/index-_RTQSKHi.d.ts.map +0 -1
- package/dist/keyboard-CimiEskD.js +0 -20
- package/dist/keyboard-CimiEskD.js.map +0 -1
- package/dist/labelled-input-base-Cz6qE6Dk.d.ts.map +0 -1
- package/dist/menu-item-COx-Azgj.d.ts.map +0 -1
- package/dist/menu-vjoiHZ13.js.map +0 -1
- package/dist/radial-input-CpQPs1Mp.d.ts.map +0 -1
- package/dist/radial-input-DZ7eQCcM.js.map +0 -1
- package/dist/tab-list-DLzb-m-I.d.ts.map +0 -1
- package/dist/tabs.js.map +0 -1
- package/dist/tickled-controller-BjYCzGrU.d.ts.map +0 -1
- package/dist/timeline-2OFtN4Ta.js.map +0 -1
- package/dist/tooltip-RGVIwHrZ.d.ts.map +0 -1
- package/dist/tree-D84RUgFC.js.map +0 -1
- package/dist/tree-component-BaCSPWg1.d.ts.map +0 -1
- package/dist/types-DSfbtHs3.d.ts +0 -8
- package/dist/types-DSfbtHs3.d.ts.map +0 -1
- package/dist/xy-axis-CEI7ojks.d.ts.map +0 -1
- package/dist/xy-axis-DbPezP6A.js +0 -7849
- package/dist/xy-axis-DbPezP6A.js.map +0 -1
- /package/bundle/{chunk-D7D4PA-g.js → rolldown-runtime-D7D4PA-g.js} +0 -0
- /package/dist/{chunk-D7D4PA-g.js → rolldown-runtime-D7D4PA-g.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,52 +1,54 @@
|
|
|
1
1
|
import { n as buildHighlightTargets, r as clearHighlights, t as applyHighlights } from "./highlight-B-eQrhhb.js";
|
|
2
2
|
import { n as tickledStyles, r as TickledController, t as tickledItemStyles } from "./tickled-styles-fNDdqf6l.js";
|
|
3
3
|
import { t as themeFallbacks } from "./fallbacks-pNMOMx38.js";
|
|
4
|
-
import { n as safeCustomElement, t as __decorate } from "./decorate-
|
|
4
|
+
import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
|
|
5
5
|
import { a as svgToDataUri, i as registerIcon, n as hasIcon, r as iconBus, t as getIcon } from "./registry-CkW7q09Q.js";
|
|
6
|
-
import { t as IxfxIconElement } from "./icon-
|
|
6
|
+
import { t as IxfxIconElement } from "./icon-B22XVlCt.js";
|
|
7
7
|
import { AcTextElement } from "./ac-text.js";
|
|
8
|
-
import { a as createFuzzySearch, i as createAcCompletionProvider, n as IncrSearchTreeController, r as createIncrSearch, t as createElementIncrSearch } from "./incr-search-
|
|
8
|
+
import { a as createFuzzySearch, i as createAcCompletionProvider, n as IncrSearchTreeController, r as createIncrSearch, t as createElementIncrSearch } from "./incr-search-2pz21xtR.js";
|
|
9
9
|
import { i as ICON_CLOSE, n as ICON_CHECK, r as ICON_CHEVRON_DOWN, t as ICON_CARET_RIGHT } from "./defaults-C3b9OWJD.js";
|
|
10
10
|
import "./icons.js";
|
|
11
11
|
import { t as prominenceStyles } from "./prominence-DlFShic3.js";
|
|
12
|
-
import { n as buttonStyles, t as ButtonElement } from "./button-
|
|
12
|
+
import { n as buttonStyles, t as ButtonElement } from "./button-DxYee1ZH.js";
|
|
13
13
|
import { t as popupSurfaceStyles } from "./popup-DiWMxsWj.js";
|
|
14
|
-
import "./menu-item-
|
|
14
|
+
import "./menu-item-NUKwJ4s5.js";
|
|
15
15
|
import { Checkbox } from "./checkbox.js";
|
|
16
|
-
import {
|
|
17
|
-
import { C as resultThrow, T as throwIfFailed, d as scaler, h as without, n as clamper, p as containsDuplicateInstances, y as nullUndefTest } from "./dist-CA13FvMn.js";
|
|
18
|
-
import { n as ColourPicker, t as ColourPickerPopup } from "./colour-picker-0sgAha1T.js";
|
|
16
|
+
import { n as ColourPicker, t as ColourPickerPopup } from "./colour-picker-BacNRabo.js";
|
|
19
17
|
import { LabelledRangeInput } from "./labelled-range-input.js";
|
|
20
|
-
import { t as collectDataResult } from "./data-provider-
|
|
21
|
-
import { i as TreeDataModel, n as TreeListElement, r as TreeBaseElement, t as TreeController } from "./tree-
|
|
18
|
+
import { t as collectDataResult } from "./data-provider-35TyWclX.js";
|
|
19
|
+
import { i as TreeDataModel, n as TreeListElement, r as TreeBaseElement, t as TreeController } from "./tree-BnvzhsAw.js";
|
|
22
20
|
import { NarrowedTextElement } from "./narrowed-text.js";
|
|
23
21
|
import { CrumbNavigationElement } from "./crumbs.js";
|
|
24
22
|
import { DataDisplayComponent } from "./data-display.js";
|
|
25
23
|
import { EditableLabel } from "./editable-label.js";
|
|
26
|
-
import { t as
|
|
24
|
+
import { t as resolveAxisStep } from "./keyboard-B5xD7Fz-.js";
|
|
25
|
+
import { t as WheelNudgeMixin } from "./wheel-nudge-BlSCe_hD.js";
|
|
27
26
|
import { PanelElement } from "./panel.js";
|
|
28
|
-
import { t as IxfxHexEditorElement } from "./hex-editor-
|
|
29
|
-
import { t as RadialInputElement } from "./radial-input-
|
|
27
|
+
import { t as IxfxHexEditorElement } from "./hex-editor-Bk6rxhfg.js";
|
|
28
|
+
import { t as RadialInputElement } from "./radial-input-DxCrt_NE.js";
|
|
30
29
|
import { LabelledRadialInput } from "./labelled-radial-input.js";
|
|
31
30
|
import { LedElement } from "./led.js";
|
|
32
|
-
import { t as menu_exports } from "./menu-
|
|
31
|
+
import { t as menu_exports } from "./menu-g6yd7ddN.js";
|
|
33
32
|
import { MillerBaseElement, MillerListElement, MillerTreeController } from "./miller.js";
|
|
33
|
+
import { a as TooltipElement, c as computeColour, i as PlotMultiAxis, l as parseColourScaleAttr, n as PlotSingleAxis, o as PlotDataSeries, r as PlotHistogram, s as applyAgeModification, t as PlotXyAxis, u as readBaseColour } from "./xy-axis-CxHC8z5E.js";
|
|
34
34
|
import { PolarPad } from "./polar-pad.js";
|
|
35
35
|
import { t as tooltipValueStyles } from "./tooltip-CJt3WLmN.js";
|
|
36
36
|
import { RangeInput } from "./range-input.js";
|
|
37
37
|
import { RangeElement } from "./range.js";
|
|
38
38
|
import { SelectHorizontalElement } from "./selecthorizontal.js";
|
|
39
|
+
import { t as SliderInputElement } from "./slider-input-DFpG23bS.js";
|
|
39
40
|
import { SnapContainer } from "./snap-container.js";
|
|
40
41
|
import { SplitLayoutElement } from "./split-layout.js";
|
|
41
42
|
import { SwipeElement } from "./swipe.js";
|
|
42
|
-
import { TabListElement } from "./
|
|
43
|
-
import { a as resolveCssVars, i as attachTimelineInteractions, n as TimelineTrackTabElement, o as resolveGrid, r as timelineStyles, s as TimelineController, t as IxfxTimelineElement } from "./timeline-
|
|
43
|
+
import { t as TabListElement } from "./tab-list-DzknpdSo.js";
|
|
44
|
+
import { a as resolveCssVars, i as attachTimelineInteractions, n as TimelineTrackTabElement, o as resolveGrid, r as timelineStyles, s as TimelineController, t as IxfxTimelineElement } from "./timeline-B2fgDL4U.js";
|
|
44
45
|
import { XyPad } from "./xy-pad.js";
|
|
45
46
|
import { LitElement, css, html, nothing } from "lit";
|
|
46
47
|
import { eventOptions, property, query, queryAssignedElements, state } from "lit/decorators.js";
|
|
47
48
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
49
|
+
import { Trees } from "@ixfx/collections";
|
|
50
|
+
import { clamper, scaler } from "@ixfx/numbers";
|
|
48
51
|
import { repeat } from "lit/directives/repeat.js";
|
|
49
|
-
import { classMap } from "lit/directives/class-map.js";
|
|
50
52
|
import { keyed } from "lit/directives/keyed.js";
|
|
51
53
|
//#region src/common/data-controller.ts
|
|
52
54
|
function isAsyncIterable(v) {
|
|
@@ -451,7 +453,6 @@ let AcTokenElement = class AcTokenElement extends LitElement {
|
|
|
451
453
|
e.preventDefault();
|
|
452
454
|
this.#closePopup();
|
|
453
455
|
this._selectedTokenIndex = void 0;
|
|
454
|
-
break;
|
|
455
456
|
}
|
|
456
457
|
}
|
|
457
458
|
#onPaste;
|
|
@@ -569,9 +570,10 @@ let AcTokenElement = class AcTokenElement extends LitElement {
|
|
|
569
570
|
});
|
|
570
571
|
}
|
|
571
572
|
#renderChip(item, index) {
|
|
573
|
+
const isSelected = this._selectedTokenIndex === index;
|
|
572
574
|
return html`
|
|
573
575
|
<span
|
|
574
|
-
class="token-chip ${
|
|
576
|
+
class="token-chip ${isSelected ? `selected` : ``}"
|
|
575
577
|
title=${item.subLabel ?? nothing}
|
|
576
578
|
@pointerdown=${(e) => this.#onChipPointerDown(e, index)}
|
|
577
579
|
>
|
|
@@ -1410,2887 +1412,158 @@ let SplitButton = class SplitButton extends ButtonElement {
|
|
|
1410
1412
|
@keydown=${this._handlePrimaryKeyDown}
|
|
1411
1413
|
@click=${this._handleSwitcherPrimaryClick}
|
|
1412
1414
|
>
|
|
1413
|
-
${primaryIcon}${primaryLabel}
|
|
1414
|
-
</button>
|
|
1415
|
-
<ixfx-menu-trigger .registry=${this.registry} .keyboardManager=${this.keyboardManager}>
|
|
1416
|
-
${this._renderCaret(`chevron-right`, `Choose action`)}
|
|
1417
|
-
<ixfx-menu-container slot="menu">
|
|
1418
|
-
${popupItems}
|
|
1419
|
-
</ixfx-menu-container>
|
|
1420
|
-
</ixfx-menu-trigger>
|
|
1421
|
-
</div>
|
|
1422
|
-
`;
|
|
1423
|
-
}
|
|
1424
|
-
static {
|
|
1425
|
-
this.styles = [
|
|
1426
|
-
themeFallbacks,
|
|
1427
|
-
prominenceStyles,
|
|
1428
|
-
buttonStyles,
|
|
1429
|
-
css`
|
|
1430
|
-
:host {
|
|
1431
|
-
display: inline-flex;
|
|
1432
|
-
max-width: 100%;
|
|
1433
|
-
vertical-align: middle;
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
slot.switcher-data {
|
|
1437
|
-
display: none;
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
.split {
|
|
1441
|
-
display: inline-flex;
|
|
1442
|
-
width: 100%;
|
|
1443
|
-
background: var(--surface-3, #ccc);
|
|
1444
|
-
color: var(--surface-3-text, #000);
|
|
1445
|
-
border: var(--border, 1px solid #999);
|
|
1446
|
-
border-radius: var(--radius-xl, 8px);
|
|
1447
|
-
corner-shape: superellipse(1);
|
|
1448
|
-
box-shadow:
|
|
1449
|
-
inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-4) 30%, transparent),
|
|
1450
|
-
inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 20%, transparent),
|
|
1451
|
-
2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 30%, transparent);
|
|
1452
|
-
overflow: hidden;
|
|
1453
|
-
transition: background var(--transition, 0.2s), border-color var(--transition, 0.2s);
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
/* Switcher: accent the caret separator to signal "this changes the default" */
|
|
1457
|
-
.split.switcher button.caret {
|
|
1458
|
-
border-inline-start-color: var(--accent, #666);
|
|
1459
|
-
opacity: 0.7;
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
|
-
.split.switcher button.caret:hover:not(:disabled) {
|
|
1463
|
-
opacity: 1;
|
|
1464
|
-
}
|
|
1465
|
-
|
|
1466
|
-
/* Caret is dimmed when there is no popup content */
|
|
1467
|
-
button.caret[data-empty] {
|
|
1468
|
-
opacity: 0.3;
|
|
1469
|
-
pointer-events: none;
|
|
1470
|
-
}
|
|
1471
|
-
|
|
1472
|
-
.split:has(button:hover:not(:disabled)) {
|
|
1473
|
-
border-color: var(--accent, #666);
|
|
1474
|
-
box-shadow:
|
|
1475
|
-
inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-5) 70%, transparent),
|
|
1476
|
-
inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 60%, transparent),
|
|
1477
|
-
2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 90%, transparent);
|
|
1478
|
-
}
|
|
1479
|
-
|
|
1480
|
-
.split:has(button:active:not(:disabled)) {
|
|
1481
|
-
transform: translateY(1px);
|
|
1482
|
-
box-shadow: inset 1px 1px 0px 0.5px color-mix(in oklch, var(--surface-1), transparent);
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
|
-
button.primary,
|
|
1486
|
-
button.caret {
|
|
1487
|
-
border: none;
|
|
1488
|
-
border-radius: 0;
|
|
1489
|
-
background: none;
|
|
1490
|
-
box-shadow: none;
|
|
1491
|
-
color: inherit;
|
|
1492
|
-
margin: 0;
|
|
1493
|
-
cursor: pointer;
|
|
1494
|
-
display: inline-flex;
|
|
1495
|
-
align-items: center;
|
|
1496
|
-
justify-content: center;
|
|
1497
|
-
transition: background var(--transition, 0.2s), opacity var(--transition, 0.2s);
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
|
-
button.primary {
|
|
1501
|
-
flex: 1;
|
|
1502
|
-
padding: var(--space-m, 8px) var(--space-l, 12px);
|
|
1503
|
-
gap: 0.5em;
|
|
1504
|
-
overflow: hidden;
|
|
1505
|
-
white-space: nowrap;
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
|
-
button.caret {
|
|
1509
|
-
padding: var(--space-m, 8px) var(--space-s, 6px);
|
|
1510
|
-
border-inline-start: var(--border, 1px solid #999);
|
|
1511
|
-
flex-shrink: 0;
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
button.primary:hover:not(:disabled),
|
|
1515
|
-
button.caret:hover:not(:disabled) {
|
|
1516
|
-
background: color-mix(in oklch, var(--surface-4) 80%, transparent);
|
|
1517
|
-
}
|
|
1518
|
-
|
|
1519
|
-
button.primary:active:not(:disabled),
|
|
1520
|
-
button.caret:active:not(:disabled) {
|
|
1521
|
-
background: var(--surface-2, #aaa);
|
|
1522
|
-
transform: none;
|
|
1523
|
-
box-shadow: none;
|
|
1524
|
-
}
|
|
1525
|
-
|
|
1526
|
-
button.primary:disabled,
|
|
1527
|
-
button.caret:disabled {
|
|
1528
|
-
opacity: 0.5;
|
|
1529
|
-
cursor: not-allowed;
|
|
1530
|
-
}
|
|
1531
|
-
|
|
1532
|
-
button.primary:focus-visible,
|
|
1533
|
-
button.caret:focus-visible {
|
|
1534
|
-
outline: 2px solid var(--accent, #666);
|
|
1535
|
-
outline-offset: -2px;
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
ixfx-menu-trigger {
|
|
1539
|
-
display: inline-flex;
|
|
1540
|
-
align-items: stretch;
|
|
1541
|
-
}
|
|
1542
|
-
`
|
|
1543
|
-
];
|
|
1544
|
-
}
|
|
1545
|
-
};
|
|
1546
|
-
__decorate([property({ attribute: false })], SplitButton.prototype, "registry", void 0);
|
|
1547
|
-
__decorate([property({ attribute: false })], SplitButton.prototype, "keyboardManager", void 0);
|
|
1548
|
-
__decorate([property({ type: String })], SplitButton.prototype, "mode", void 0);
|
|
1549
|
-
__decorate([property({
|
|
1550
|
-
type: String,
|
|
1551
|
-
attribute: `default-value`
|
|
1552
|
-
})], SplitButton.prototype, "defaultValue", void 0);
|
|
1553
|
-
__decorate([property({ attribute: false })], SplitButton.prototype, "itemsProvider", void 0);
|
|
1554
|
-
__decorate([property({ attribute: false })], SplitButton.prototype, "items", void 0);
|
|
1555
|
-
__decorate([query(`ixfx-menu-trigger`)], SplitButton.prototype, "_menuTrigger", void 0);
|
|
1556
|
-
__decorate([state()], SplitButton.prototype, "_compact", void 0);
|
|
1557
|
-
__decorate([state()], SplitButton.prototype, "_selectedCommand", void 0);
|
|
1558
|
-
__decorate([state()], SplitButton.prototype, "_selectedLabel", void 0);
|
|
1559
|
-
__decorate([state()], SplitButton.prototype, "_selectedIcon", void 0);
|
|
1560
|
-
__decorate([state()], SplitButton.prototype, "_switcherItems", void 0);
|
|
1561
|
-
__decorate([state()], SplitButton.prototype, "_dynamicItems", void 0);
|
|
1562
|
-
__decorate([state()], SplitButton.prototype, "_loadingItems", void 0);
|
|
1563
|
-
__decorate([state()], SplitButton.prototype, "_menuHasItems", void 0);
|
|
1564
|
-
SplitButton = __decorate([safeCustomElement(`ixfx-split-button`)], SplitButton);
|
|
1565
|
-
//#endregion
|
|
1566
|
-
//#region node_modules/.pnpm/@ixfx+collections@0.56.13/node_modules/@ixfx/collections/dist/StackMutable-B9Qm32K8.js
|
|
1567
|
-
const trimStack = (opts, stack, toAdd) => {
|
|
1568
|
-
const potentialLength = stack.length + toAdd.length;
|
|
1569
|
-
const policy = opts.discardPolicy ?? `additions`;
|
|
1570
|
-
const capacity = opts.capacity ?? potentialLength;
|
|
1571
|
-
const toRemove = potentialLength - capacity;
|
|
1572
|
-
if (opts.debug) console.log(`Stack.push: stackLen: ${stack.length} potentialLen: ${potentialLength} toRemove: ${toRemove} policy: ${policy}`);
|
|
1573
|
-
switch (policy) {
|
|
1574
|
-
case `additions`:
|
|
1575
|
-
if (opts.debug) console.log(`Stack.push:DiscardAdditions: stackLen: ${stack.length} slice: ${potentialLength - capacity} toAddLen: ${toAdd.length}`);
|
|
1576
|
-
if (stack.length === opts.capacity) return stack;
|
|
1577
|
-
else return [...stack, ...toAdd.slice(0, toAdd.length - toRemove)];
|
|
1578
|
-
case `newer`: {
|
|
1579
|
-
if (toAdd.length >= capacity) return toAdd.slice(toAdd.length - capacity);
|
|
1580
|
-
const keepFromOld = capacity - toAdd.length;
|
|
1581
|
-
return [...stack.slice(0, keepFromOld), ...toAdd];
|
|
1582
|
-
}
|
|
1583
|
-
case `older`: return [...stack, ...toAdd].slice(toRemove);
|
|
1584
|
-
default: throw new Error(`Unknown discard policy ${policy}`);
|
|
1585
|
-
}
|
|
1586
|
-
};
|
|
1587
|
-
const push = (opts, stack, ...toAdd) => {
|
|
1588
|
-
const potentialLength = stack.length + toAdd.length;
|
|
1589
|
-
return opts.capacity && potentialLength > opts.capacity ? trimStack(opts, stack, toAdd) : [...stack, ...toAdd];
|
|
1590
|
-
};
|
|
1591
|
-
const pop = (opts, stack) => {
|
|
1592
|
-
if (stack.length === 0) throw new Error(`Stack is empty`);
|
|
1593
|
-
return stack.slice(0, -1);
|
|
1594
|
-
};
|
|
1595
|
-
/**
|
|
1596
|
-
* Peek at the top of the stack (end of array)
|
|
1597
|
-
*
|
|
1598
|
-
* @typeParam V - Type of stored items
|
|
1599
|
-
* @param {StackOpts} opts
|
|
1600
|
-
* @param {V[]} stack
|
|
1601
|
-
* @returns {(V | undefined)}
|
|
1602
|
-
*/
|
|
1603
|
-
const peek = (opts, stack) => stack.at(-1);
|
|
1604
|
-
const isEmpty = (opts, stack) => stack.length === 0;
|
|
1605
|
-
const isFull = (opts, stack) => {
|
|
1606
|
-
if (opts.capacity) return stack.length >= opts.capacity;
|
|
1607
|
-
return false;
|
|
1608
|
-
};
|
|
1609
|
-
/**
|
|
1610
|
-
* Creates a stack. Mutable. Use {@link StackImmutable} for an immutable alternative.
|
|
1611
|
-
*
|
|
1612
|
-
* @example Basic usage
|
|
1613
|
-
* ```js
|
|
1614
|
-
* // Create
|
|
1615
|
-
* const s = new StackMutable();
|
|
1616
|
-
* // Add one or more items
|
|
1617
|
-
* s.push(1, 2, 3, 4);
|
|
1618
|
-
*
|
|
1619
|
-
* // See what's on top
|
|
1620
|
-
* s.peek; // 4
|
|
1621
|
-
*
|
|
1622
|
-
* // Remove the top-most, and return it
|
|
1623
|
-
* s.pop(); // 4
|
|
1624
|
-
*
|
|
1625
|
-
* // Now there's a new top-most element
|
|
1626
|
-
* s.peek; // 3
|
|
1627
|
-
* ```
|
|
1628
|
-
*/
|
|
1629
|
-
var StackMutable = class {
|
|
1630
|
-
opts;
|
|
1631
|
-
data;
|
|
1632
|
-
/**
|
|
1633
|
-
* Create a new StackMutable.
|
|
1634
|
-
*
|
|
1635
|
-
* @param opts Options
|
|
1636
|
-
* @param data Initial data to use
|
|
1637
|
-
*/
|
|
1638
|
-
constructor(opts = {}, data = []) {
|
|
1639
|
-
this.opts = opts;
|
|
1640
|
-
this.data = data;
|
|
1641
|
-
}
|
|
1642
|
-
/**
|
|
1643
|
-
* Push data onto the stack.
|
|
1644
|
-
* If `toAdd` is empty, nothing happens
|
|
1645
|
-
* @param toAdd Data to add
|
|
1646
|
-
* @returns Length of stack
|
|
1647
|
-
*/
|
|
1648
|
-
push(...toAdd) {
|
|
1649
|
-
if (toAdd.length === 0) return this.data.length;
|
|
1650
|
-
this.data = push(this.opts, this.data, ...toAdd);
|
|
1651
|
-
return this.data.length;
|
|
1652
|
-
}
|
|
1653
|
-
/**
|
|
1654
|
-
* Iterate from bottom to top. Note that `forEachFromTop` iterates from top to bottom, so this is the reverse.
|
|
1655
|
-
* @param fn
|
|
1656
|
-
*/
|
|
1657
|
-
forEach(fn) {
|
|
1658
|
-
this.data.forEach(fn);
|
|
1659
|
-
}
|
|
1660
|
-
/**
|
|
1661
|
-
* Iterate from top to bottom. Note that `forEach` iterates from bottom to top, so this is the reverse.
|
|
1662
|
-
* @param fn
|
|
1663
|
-
*/
|
|
1664
|
-
forEachFromTop(fn) {
|
|
1665
|
-
[...this.data].reverse().forEach(fn);
|
|
1666
|
-
}
|
|
1667
|
-
/**
|
|
1668
|
-
* Pop the top-most item from the stack, and return it. If the stack is empty, returns _undefined_.
|
|
1669
|
-
* @returns
|
|
1670
|
-
*/
|
|
1671
|
-
pop() {
|
|
1672
|
-
const v = peek(this.opts, this.data);
|
|
1673
|
-
this.data = pop(this.opts, this.data);
|
|
1674
|
-
return v;
|
|
1675
|
-
}
|
|
1676
|
-
/**
|
|
1677
|
-
* Returns _true_ if the stack is empty, _false_ otherwise.
|
|
1678
|
-
*/
|
|
1679
|
-
get isEmpty() {
|
|
1680
|
-
return isEmpty(this.opts, this.data);
|
|
1681
|
-
}
|
|
1682
|
-
/**
|
|
1683
|
-
* Returns _true_ if the stack is full, _false_ otherwise. Note that a stack is only full if a `maxSize` option was provided at construction time.
|
|
1684
|
-
*/
|
|
1685
|
-
get isFull() {
|
|
1686
|
-
return isFull(this.opts, this.data);
|
|
1687
|
-
}
|
|
1688
|
-
/**
|
|
1689
|
-
* Returns the top-most item on the stack, without modifying the stack. If the stack is empty, returns _undefined_.
|
|
1690
|
-
*/
|
|
1691
|
-
get peek() {
|
|
1692
|
-
return peek(this.opts, this.data);
|
|
1693
|
-
}
|
|
1694
|
-
/**
|
|
1695
|
-
* Returns the number of items currently on the stack.
|
|
1696
|
-
*/
|
|
1697
|
-
get length() {
|
|
1698
|
-
return this.data.length;
|
|
1699
|
-
}
|
|
1700
|
-
};
|
|
1701
|
-
//#endregion
|
|
1702
|
-
//#region node_modules/.pnpm/@ixfx+collections@0.56.13/node_modules/@ixfx/collections/dist/tree-C6jGRTgK.js
|
|
1703
|
-
const compare$1 = (a, b, eq = isEqualValueIgnoreOrder, parent) => {
|
|
1704
|
-
const valueEqual = valueOrIdentityEqual(a, b, eq);
|
|
1705
|
-
const childrenCompare = compareChildren(a, b, eq);
|
|
1706
|
-
const diff = {
|
|
1707
|
-
valueChanged: !valueEqual,
|
|
1708
|
-
a,
|
|
1709
|
-
b,
|
|
1710
|
-
added: childrenCompare.added,
|
|
1711
|
-
removed: childrenCompare.removed,
|
|
1712
|
-
childChanged: false
|
|
1713
|
-
};
|
|
1714
|
-
const diffNode = {
|
|
1715
|
-
value: diff,
|
|
1716
|
-
childrenStore: [],
|
|
1717
|
-
parent
|
|
1718
|
-
};
|
|
1719
|
-
const childrenDiff = childrenCompare.identical.map((c) => compare$1(c[0], c[1], eq, diffNode));
|
|
1720
|
-
const someChildChange = hasChange(diff) || childrenDiff.some((v) => hasChange(v.value));
|
|
1721
|
-
setChildren(diffNode, childrenDiff);
|
|
1722
|
-
diffNode.toString = () => toString$1(diffNode, 0);
|
|
1723
|
-
diffNode.value.childChanged = someChildChange;
|
|
1724
|
-
throwTreeTest(diffNode);
|
|
1725
|
-
return diffNode;
|
|
1726
|
-
};
|
|
1727
|
-
const hasChange = (vv) => {
|
|
1728
|
-
if (vv === void 0) return false;
|
|
1729
|
-
if (vv.valueChanged) return true;
|
|
1730
|
-
if (vv.childChanged) return true;
|
|
1731
|
-
if (vv.added.length > 0) return true;
|
|
1732
|
-
if (vv.removed.length > 0) return true;
|
|
1733
|
-
return false;
|
|
1734
|
-
};
|
|
1735
|
-
const compareChildren = (a, b, eq = isEqualValueIgnoreOrder) => {
|
|
1736
|
-
const childrenOfA = [...a.children()];
|
|
1737
|
-
const childrenOfB = [...b.children()];
|
|
1738
|
-
const identical = [];
|
|
1739
|
-
const removed = [];
|
|
1740
|
-
for (const childA of childrenOfA) {
|
|
1741
|
-
let foundIndex = -1;
|
|
1742
|
-
for (const [index, childOfB] of childrenOfB.entries()) if (valueOrIdentityEqual(childA, childOfB, eq)) {
|
|
1743
|
-
identical.push([childA, childOfB]);
|
|
1744
|
-
foundIndex = index;
|
|
1745
|
-
break;
|
|
1746
|
-
}
|
|
1747
|
-
if (foundIndex === -1) removed.push(childA);
|
|
1748
|
-
else childrenOfB.splice(foundIndex, 1);
|
|
1749
|
-
}
|
|
1750
|
-
return {
|
|
1751
|
-
added: [...childrenOfB],
|
|
1752
|
-
identical,
|
|
1753
|
-
removed
|
|
1754
|
-
};
|
|
1755
|
-
};
|
|
1756
|
-
const valueOrIdentityEqual = (a, b, eq) => {
|
|
1757
|
-
if (a.getIdentity() === b.getIdentity()) return true;
|
|
1758
|
-
if (eq(a.getValue(), b.getValue())) return true;
|
|
1759
|
-
return false;
|
|
1760
|
-
};
|
|
1761
|
-
const toStringSingle = (n) => {
|
|
1762
|
-
return JSON.stringify(n.getValue());
|
|
1763
|
-
};
|
|
1764
|
-
const toString$1 = (n, indent = 0) => {
|
|
1765
|
-
if (n === void 0) return `(undefined)`;
|
|
1766
|
-
let t = toStringDiff(n.value, indent);
|
|
1767
|
-
for (const c of n.childrenStore) t += toString$1(c, indent + 2);
|
|
1768
|
-
return t;
|
|
1769
|
-
};
|
|
1770
|
-
const toStringDiff = (n, indent) => {
|
|
1771
|
-
const spaces = ` `.repeat(indent);
|
|
1772
|
-
if (n === void 0) return `${spaces}(undefined)`;
|
|
1773
|
-
const t = [];
|
|
1774
|
-
t.push(`a: ${toStringSingle(n.a)} b: ${toStringSingle(n.b)}`);
|
|
1775
|
-
if (n.valueChanged) t.push(`Value changed. Child changed: ${n.childChanged}`);
|
|
1776
|
-
else t.push(`Value unchanged. Child changed: ${n.childChanged}`);
|
|
1777
|
-
if (n.added.length > 0) {
|
|
1778
|
-
t.push(`Added:`);
|
|
1779
|
-
for (const c of n.added) t.push(` - ` + toStringSingle(c));
|
|
1780
|
-
}
|
|
1781
|
-
if (n.removed.length > 0) {
|
|
1782
|
-
t.push(`Removed: ${n.removed.length}`);
|
|
1783
|
-
for (const c of n.removed) t.push(` - ` + toStringSingle(c));
|
|
1784
|
-
}
|
|
1785
|
-
t.push(`----\n`);
|
|
1786
|
-
return t.map((line) => spaces + line).join(`\n`);
|
|
1787
|
-
};
|
|
1788
|
-
var tree_mutable_exports = /* @__PURE__ */ __exportAll({
|
|
1789
|
-
add: () => add,
|
|
1790
|
-
addValue: () => addValue,
|
|
1791
|
-
asDynamicTraversable: () => asDynamicTraversable$1,
|
|
1792
|
-
breadthFirst: () => breadthFirst$2,
|
|
1793
|
-
children: () => children$2,
|
|
1794
|
-
childrenLength: () => childrenLength$1,
|
|
1795
|
-
childrenValues: () => childrenValues,
|
|
1796
|
-
compare: () => compare,
|
|
1797
|
-
computeMaxDepth: () => computeMaxDepth,
|
|
1798
|
-
createNode: () => createNode$1,
|
|
1799
|
-
depthFirst: () => depthFirst$3,
|
|
1800
|
-
findAnyChildByValue: () => findAnyChildByValue$2,
|
|
1801
|
-
findChildByValue: () => findChildByValue$1,
|
|
1802
|
-
findParentsValue: () => findParentsValue,
|
|
1803
|
-
followValue: () => followValue$1,
|
|
1804
|
-
fromPlainObject: () => fromPlainObject,
|
|
1805
|
-
getRoot: () => getRoot,
|
|
1806
|
-
hasAnyChild: () => hasAnyChild$1,
|
|
1807
|
-
hasAnyParent: () => hasAnyParent$1,
|
|
1808
|
-
hasChild: () => hasChild$1,
|
|
1809
|
-
hasParent: () => hasParent$1,
|
|
1810
|
-
nodeDepth: () => nodeDepth,
|
|
1811
|
-
parents: () => parents$1,
|
|
1812
|
-
parentsValues: () => parentsValues,
|
|
1813
|
-
queryByValue: () => queryByValue,
|
|
1814
|
-
queryParentsValue: () => queryParentsValue,
|
|
1815
|
-
remove: () => remove$1,
|
|
1816
|
-
removeValuelessNodesFromChild: () => removeValuelessNodesFromChild,
|
|
1817
|
-
root: () => root$2,
|
|
1818
|
-
rootWrapped: () => rootWrapped$1,
|
|
1819
|
-
setChildren: () => setChildren,
|
|
1820
|
-
siblings: () => siblings$2,
|
|
1821
|
-
stripParentage: () => stripParentage,
|
|
1822
|
-
throwTreeTest: () => throwTreeTest,
|
|
1823
|
-
toStringDeep: () => toStringDeep$4,
|
|
1824
|
-
treeTest: () => treeTest,
|
|
1825
|
-
value: () => value,
|
|
1826
|
-
wrap: () => wrap$1
|
|
1827
|
-
});
|
|
1828
|
-
/**
|
|
1829
|
-
* Compares two nodes.
|
|
1830
|
-
*
|
|
1831
|
-
* By default uses `isEqualValueIgnoreOrder` to compare nodes. This means
|
|
1832
|
-
* values of nodes will be compared, ignoring the order of fields.
|
|
1833
|
-
* @param a
|
|
1834
|
-
* @param b
|
|
1835
|
-
* @param eq Comparison function. Uses `isEqualValueIgnoreOrder` by default.
|
|
1836
|
-
* @returns Compare results
|
|
1837
|
-
*/
|
|
1838
|
-
function compare(a, b, eq) {
|
|
1839
|
-
return compare$1(asDynamicTraversable$1(a), asDynamicTraversable$1(b), eq);
|
|
1840
|
-
}
|
|
1841
|
-
/**
|
|
1842
|
-
* Converts {@link Trees.TreeNode} to {@link Trees.SimplifiedNode}, removing the 'parent' fields.
|
|
1843
|
-
* This can be useful because if you have the whole tree, the parent field
|
|
1844
|
-
* is redundant and because it makes circular references can make dumping to console etc more troublesome.
|
|
1845
|
-
*
|
|
1846
|
-
* Recursive: strips parentage of all children and so on too.
|
|
1847
|
-
* @param node
|
|
1848
|
-
*/
|
|
1849
|
-
function stripParentage(node) {
|
|
1850
|
-
return {
|
|
1851
|
-
value: node.value,
|
|
1852
|
-
childrenStore: node.childrenStore.map((c) => stripParentage(c))
|
|
1853
|
-
};
|
|
1854
|
-
}
|
|
1855
|
-
const unwrapped = (node) => `wraps` in node ? node.wraps : node;
|
|
1856
|
-
const wrapped = (node) => `wraps` in node ? node : wrap$1(node);
|
|
1857
|
-
/**
|
|
1858
|
-
* Wraps node `n` for a more object-oriented means of access.
|
|
1859
|
-
* It will wrap child nodes on demand. For this reason, WrappedNode object
|
|
1860
|
-
* identity is not stable
|
|
1861
|
-
* @param n Node to wrap
|
|
1862
|
-
*/
|
|
1863
|
-
function wrap$1(n) {
|
|
1864
|
-
return {
|
|
1865
|
-
*children() {
|
|
1866
|
-
for (const c of n.childrenStore) yield wrap$1(c);
|
|
1867
|
-
},
|
|
1868
|
-
getValue: () => n.value,
|
|
1869
|
-
getIdentity: () => n,
|
|
1870
|
-
*queryValue(value) {
|
|
1871
|
-
for (const v of queryByValue(value, unwrapped(n))) yield wrap$1(v);
|
|
1872
|
-
},
|
|
1873
|
-
*queryParentsValue(child, value, eq) {
|
|
1874
|
-
for (const v of queryParentsValue(unwrapped(child), value, eq)) yield wrap$1(v);
|
|
1875
|
-
},
|
|
1876
|
-
*parentsValues(child) {
|
|
1877
|
-
yield* parentsValues(unwrapped(child));
|
|
1878
|
-
},
|
|
1879
|
-
findParentsValue(child, value, eq) {
|
|
1880
|
-
const n = findParentsValue(child, value, eq);
|
|
1881
|
-
if (n !== void 0) return wrap$1(n);
|
|
1882
|
-
},
|
|
1883
|
-
getParent: () => n.parent === void 0 ? void 0 : wrap$1(n.parent),
|
|
1884
|
-
hasParent: (parent) => {
|
|
1885
|
-
return hasParent$1(n, unwrapped(parent));
|
|
1886
|
-
},
|
|
1887
|
-
hasAnyParent: (parent) => {
|
|
1888
|
-
return hasAnyParent$1(n, unwrapped(parent));
|
|
1889
|
-
},
|
|
1890
|
-
hasChild: (child) => {
|
|
1891
|
-
return hasChild$1(unwrapped(child), n);
|
|
1892
|
-
},
|
|
1893
|
-
hasAnyChild: (child) => {
|
|
1894
|
-
return hasAnyChild$1(unwrapped(child), n);
|
|
1895
|
-
},
|
|
1896
|
-
remove: () => {
|
|
1897
|
-
remove$1(n);
|
|
1898
|
-
},
|
|
1899
|
-
addValue: (value) => {
|
|
1900
|
-
return wrap$1(addValue(value, n));
|
|
1901
|
-
},
|
|
1902
|
-
add: (child) => {
|
|
1903
|
-
add(unwrapped(child), n);
|
|
1904
|
-
return wrapped(child);
|
|
1905
|
-
},
|
|
1906
|
-
wraps: n
|
|
1907
|
-
};
|
|
1908
|
-
}
|
|
1909
|
-
/**
|
|
1910
|
-
* Removes `child` from the tree structure it is in.
|
|
1911
|
-
* It removes `child` from its parent. Any sub-children of `child` still remain connected.
|
|
1912
|
-
* @param child
|
|
1913
|
-
*/
|
|
1914
|
-
function remove$1(child) {
|
|
1915
|
-
const p = child.parent;
|
|
1916
|
-
if (p === void 0) return false;
|
|
1917
|
-
child.parent = void 0;
|
|
1918
|
-
const count = p.childrenStore.length;
|
|
1919
|
-
p.childrenStore = without(p.childrenStore, child);
|
|
1920
|
-
return count !== p.childrenStore.length;
|
|
1921
|
-
}
|
|
1922
|
-
/**
|
|
1923
|
-
* Starting from a child node, work backwards, removing it and ancestors that have no value
|
|
1924
|
-
*
|
|
1925
|
-
* If `child` is an only child, it will recursively call the same function on the parent.
|
|
1926
|
-
* @param child Child to start from
|
|
1927
|
-
*/
|
|
1928
|
-
function removeValuelessNodesFromChild(child) {
|
|
1929
|
-
if (typeof child.value !== `undefined`) return false;
|
|
1930
|
-
const parent = child.parent;
|
|
1931
|
-
if (!parent) return false;
|
|
1932
|
-
const sibs = [...siblings$2(child)];
|
|
1933
|
-
remove$1(child);
|
|
1934
|
-
if (sibs.length === 0) return removeValuelessNodesFromChild(parent);
|
|
1935
|
-
return true;
|
|
1936
|
-
}
|
|
1937
|
-
/**
|
|
1938
|
-
* Enumeate all siblings of `child`. This won't include `child` itself.
|
|
1939
|
-
* If `child` is not part of a tree (ie has no parent) no values are yielded.
|
|
1940
|
-
*/
|
|
1941
|
-
function* siblings$2(child, eq = isEqualDefault) {
|
|
1942
|
-
const parent = child.parent;
|
|
1943
|
-
if (typeof parent === `undefined`) return;
|
|
1944
|
-
for (const c of parent.childrenStore) {
|
|
1945
|
-
if (eq(c, child)) continue;
|
|
1946
|
-
yield c;
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
|
-
/**
|
|
1950
|
-
* Depth-first iteration of the children of `node`
|
|
1951
|
-
* @param node
|
|
1952
|
-
*/
|
|
1953
|
-
function* depthFirst$3(node) {
|
|
1954
|
-
if (!root$2) return;
|
|
1955
|
-
const stack = new StackMutable();
|
|
1956
|
-
stack.push(...node.childrenStore);
|
|
1957
|
-
let entry = stack.pop();
|
|
1958
|
-
while (entry) {
|
|
1959
|
-
yield entry;
|
|
1960
|
-
if (entry) stack.push(...entry.childrenStore);
|
|
1961
|
-
if (stack.isEmpty) break;
|
|
1962
|
-
entry = stack.pop();
|
|
1963
|
-
}
|
|
1964
|
-
}
|
|
1965
|
-
/**
|
|
1966
|
-
* Breadth-first iteration of the children of `node`
|
|
1967
|
-
* @param node
|
|
1968
|
-
*/
|
|
1969
|
-
function* breadthFirst$2(node) {
|
|
1970
|
-
if (!node) return;
|
|
1971
|
-
const queue = new QueueMutable();
|
|
1972
|
-
queue.enqueue(...node.childrenStore);
|
|
1973
|
-
let entry = queue.dequeue();
|
|
1974
|
-
while (entry) {
|
|
1975
|
-
yield entry;
|
|
1976
|
-
if (entry) queue.enqueue(...entry.childrenStore);
|
|
1977
|
-
if (queue.isEmpty) break;
|
|
1978
|
-
entry = queue.dequeue();
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
|
-
/**
|
|
1982
|
-
* Validates the tree from `root` downwards.
|
|
1983
|
-
* @param root
|
|
1984
|
-
* @param seen
|
|
1985
|
-
*/
|
|
1986
|
-
function treeTest(root, seen = []) {
|
|
1987
|
-
if (root.parent === root) return [
|
|
1988
|
-
false,
|
|
1989
|
-
`Root has itself as parent`,
|
|
1990
|
-
root
|
|
1991
|
-
];
|
|
1992
|
-
if (seen.includes(root)) return [
|
|
1993
|
-
false,
|
|
1994
|
-
`Same node instance is appearing further in tree`,
|
|
1995
|
-
root
|
|
1996
|
-
];
|
|
1997
|
-
seen.push(root);
|
|
1998
|
-
if (containsDuplicateInstances(root.childrenStore)) return [
|
|
1999
|
-
false,
|
|
2000
|
-
`Children list contains duplicates`,
|
|
2001
|
-
root
|
|
2002
|
-
];
|
|
2003
|
-
for (const c of root.childrenStore) {
|
|
2004
|
-
if (c.parent !== root) return [
|
|
2005
|
-
false,
|
|
2006
|
-
`Member of childrenStore does not have .parent set`,
|
|
2007
|
-
c
|
|
2008
|
-
];
|
|
2009
|
-
if (hasAnyChild$1(root, c)) return [
|
|
2010
|
-
false,
|
|
2011
|
-
`Child has parent as its own child`,
|
|
2012
|
-
c
|
|
2013
|
-
];
|
|
2014
|
-
const v = treeTest(c, seen);
|
|
2015
|
-
if (!v[0]) return v;
|
|
2016
|
-
}
|
|
2017
|
-
return [
|
|
2018
|
-
true,
|
|
2019
|
-
``,
|
|
2020
|
-
root
|
|
2021
|
-
];
|
|
2022
|
-
}
|
|
2023
|
-
/**
|
|
2024
|
-
* Throws an exception if `root` fails tree validation
|
|
2025
|
-
* @param root
|
|
2026
|
-
*/
|
|
2027
|
-
function throwTreeTest(root) {
|
|
2028
|
-
const v = treeTest(root);
|
|
2029
|
-
if (v[0]) return;
|
|
2030
|
-
throw new Error(`${v[1]} Node: ${toStringAbbreviate(v[2].value, 30)}`, { cause: v[2] });
|
|
2031
|
-
}
|
|
2032
|
-
/**
|
|
2033
|
-
* Iterate over direct children of `root`, yielding {@link TreeNode} instances.
|
|
2034
|
-
* Use {@link childrenValues} to iterate over child values
|
|
2035
|
-
* @param root
|
|
2036
|
-
*/
|
|
2037
|
-
function* children$2(root) {
|
|
2038
|
-
for (const c of root.childrenStore) yield c;
|
|
2039
|
-
}
|
|
2040
|
-
/**
|
|
2041
|
-
* Iterate over the value of direct children of `root`.
|
|
2042
|
-
* Use {@link children} if you want to iterate over {@link TreeNode} instances instead.
|
|
2043
|
-
* @param root
|
|
2044
|
-
*/
|
|
2045
|
-
function* childrenValues(root) {
|
|
2046
|
-
for (const c of root.childrenStore) if (typeof c.value !== `undefined`) yield c.value;
|
|
2047
|
-
}
|
|
2048
|
-
/**
|
|
2049
|
-
* Iterate over all parents of `child`. First result is the immediate parent.
|
|
2050
|
-
* @param child
|
|
2051
|
-
*/
|
|
2052
|
-
function* parents$1(child) {
|
|
2053
|
-
let p = child.parent;
|
|
2054
|
-
while (p) {
|
|
2055
|
-
yield p;
|
|
2056
|
-
p = p.parent;
|
|
2057
|
-
}
|
|
2058
|
-
}
|
|
2059
|
-
/**
|
|
2060
|
-
* Returns the depth of `node`. A root node (ie. with no parents) has a depth of 0.
|
|
2061
|
-
* @param node
|
|
2062
|
-
*/
|
|
2063
|
-
function nodeDepth(node) {
|
|
2064
|
-
return [...parents$1(node)].length;
|
|
2065
|
-
}
|
|
2066
|
-
/**
|
|
2067
|
-
* Returns _true_ if `child` is an immediate child of `parent`.
|
|
2068
|
-
* @param child
|
|
2069
|
-
* @param parent
|
|
2070
|
-
* @param eq Equality function to compare nodes. Uses `isEqualDefault` by default, which compares by reference.
|
|
2071
|
-
*/
|
|
2072
|
-
function hasChild$1(child, parent, eq = isEqualDefault) {
|
|
2073
|
-
for (const c of parent.childrenStore) if (eq(c, child)) return true;
|
|
2074
|
-
return false;
|
|
2075
|
-
}
|
|
2076
|
-
/**
|
|
2077
|
-
* Returns the first immediate child of `parent` that matches `value`.
|
|
2078
|
-
*
|
|
2079
|
-
* Use {@link queryByValue} if you want all matching children.
|
|
2080
|
-
* @param value
|
|
2081
|
-
* @param parent
|
|
2082
|
-
* @param eq
|
|
2083
|
-
*/
|
|
2084
|
-
function findChildByValue$1(value, parent, eq = isEqualDefault) {
|
|
2085
|
-
for (const c of parent.childrenStore) if (eq(value, c.value)) return c;
|
|
2086
|
-
}
|
|
2087
|
-
/**
|
|
2088
|
-
* Yield all immediate children of `parent` that match `value`.
|
|
2089
|
-
*
|
|
2090
|
-
* Use {@link findChildByValue} if you only want the first matching child.
|
|
2091
|
-
* @param value
|
|
2092
|
-
* @param parent
|
|
2093
|
-
* @param eq
|
|
2094
|
-
*/
|
|
2095
|
-
function* queryByValue(value, parent, eq = isEqualDefault) {
|
|
2096
|
-
for (const c of parent.childrenStore) if (eq(value, c.value)) yield c;
|
|
2097
|
-
}
|
|
2098
|
-
/**
|
|
2099
|
-
* Returns _true_ if `prospectiveChild` is some child node of `parent`,
|
|
2100
|
-
* anywhere in the tree structure.
|
|
2101
|
-
*
|
|
2102
|
-
* Use {@link hasChild} to only check immediate children.
|
|
2103
|
-
* @param prospectiveChild
|
|
2104
|
-
* @param parent
|
|
2105
|
-
*/
|
|
2106
|
-
function hasAnyChild$1(prospectiveChild, parent) {
|
|
2107
|
-
for (const c of breadthFirst$2(parent)) if (c === prospectiveChild) return true;
|
|
2108
|
-
return false;
|
|
2109
|
-
}
|
|
2110
|
-
/**
|
|
2111
|
-
* Using a breadth-first search, return the first child of `parent` that has `value`.
|
|
2112
|
-
* @param value Value being sought
|
|
2113
|
-
* @param parent Parent node
|
|
2114
|
-
* @param eq Equality function to compare values. Uses `isEqualDefault` by default, which compares by reference.
|
|
2115
|
-
*/
|
|
2116
|
-
function findAnyChildByValue$2(value, parent, eq = isEqualDefault) {
|
|
2117
|
-
for (const c of breadthFirst$2(parent)) if (eq(c.value, value)) return c;
|
|
2118
|
-
}
|
|
2119
|
-
/**
|
|
2120
|
-
* Traverses up a node to find the root.
|
|
2121
|
-
* @param node
|
|
2122
|
-
*/
|
|
2123
|
-
function getRoot(node) {
|
|
2124
|
-
if (node.parent) return getRoot(node.parent);
|
|
2125
|
-
return node;
|
|
2126
|
-
}
|
|
2127
|
-
/**
|
|
2128
|
-
* Returns _true_ if `prospectiveParent` is any ancestor
|
|
2129
|
-
* parent of `child`.
|
|
2130
|
-
*
|
|
2131
|
-
* Use {@link hasParent} to only check immediate parent.
|
|
2132
|
-
* @param child
|
|
2133
|
-
* @param prospectiveParent
|
|
2134
|
-
*/
|
|
2135
|
-
function hasAnyParent$1(child, prospectiveParent) {
|
|
2136
|
-
for (const p of parents$1(child)) if (p === prospectiveParent) return true;
|
|
2137
|
-
return false;
|
|
2138
|
-
}
|
|
2139
|
-
/**
|
|
2140
|
-
* Yields the node value of each parent of `child`.
|
|
2141
|
-
* _undefined_ values are not returned.
|
|
2142
|
-
*
|
|
2143
|
-
* Use {@link queryParentsValue} to search for a particular value
|
|
2144
|
-
* @param child
|
|
2145
|
-
*/
|
|
2146
|
-
function* parentsValues(child) {
|
|
2147
|
-
for (const p of parents$1(child)) if (typeof p.value !== `undefined`) yield p.value;
|
|
2148
|
-
return false;
|
|
2149
|
-
}
|
|
2150
|
-
/**
|
|
2151
|
-
* Yields all parents of `child` that have a given value.
|
|
2152
|
-
* Use {@link findParentsValue} to find the first match only.
|
|
2153
|
-
* @param child
|
|
2154
|
-
* @param value
|
|
2155
|
-
* @param eq
|
|
2156
|
-
*/
|
|
2157
|
-
function* queryParentsValue(child, value, eq = isEqualDefault) {
|
|
2158
|
-
for (const p of parents$1(child)) if (typeof p.value !== `undefined`) {
|
|
2159
|
-
if (eq(p.value, value)) yield p;
|
|
2160
|
-
}
|
|
2161
|
-
return false;
|
|
2162
|
-
}
|
|
2163
|
-
/**
|
|
2164
|
-
* Returns the first parent that has a given value.
|
|
2165
|
-
* @param child
|
|
2166
|
-
* @param value
|
|
2167
|
-
* @param eq
|
|
2168
|
-
*/
|
|
2169
|
-
function findParentsValue(child, value, eq = isEqualDefault) {
|
|
2170
|
-
return [...queryParentsValue(child, value, eq)][0];
|
|
2171
|
-
}
|
|
2172
|
-
/**
|
|
2173
|
-
* Returns _true_ if `prospectiveParent` is the immediate
|
|
2174
|
-
* parent of `child`.
|
|
2175
|
-
*
|
|
2176
|
-
* Use {@link hasAnyParent} to check for any ancestor parent.
|
|
2177
|
-
* @param child
|
|
2178
|
-
* @param prospectiveParent
|
|
2179
|
-
*/
|
|
2180
|
-
function hasParent$1(child, prospectiveParent) {
|
|
2181
|
-
return child.parent === prospectiveParent;
|
|
2182
|
-
}
|
|
2183
|
-
/**
|
|
2184
|
-
* Computes the maximum depth of the tree.
|
|
2185
|
-
* That is, how many steps down from `node` it can go.
|
|
2186
|
-
* If a tree is: root -> childA -> subChildB
|
|
2187
|
-
* ```js
|
|
2188
|
-
* // Yields 2, since there are at max two steps down from root
|
|
2189
|
-
* computeMaxDepth(root);
|
|
2190
|
-
* ```
|
|
2191
|
-
* @param node
|
|
2192
|
-
*/
|
|
2193
|
-
function computeMaxDepth(node) {
|
|
2194
|
-
return computeMaxDepthImpl(node, 0);
|
|
2195
|
-
}
|
|
2196
|
-
function computeMaxDepthImpl(node, startingDepth = 0) {
|
|
2197
|
-
let depth = startingDepth;
|
|
2198
|
-
for (const c of node.childrenStore) depth = Math.max(depth, computeMaxDepthImpl(c, startingDepth + 1));
|
|
2199
|
-
return depth;
|
|
2200
|
-
}
|
|
2201
|
-
/**
|
|
2202
|
-
* Adds a child node to `parent`.
|
|
2203
|
-
* If `child` already has a parent, it is removed from that parent.
|
|
2204
|
-
* @param child
|
|
2205
|
-
* @param parent
|
|
2206
|
-
* @throws Error if adding a child would break tree structure
|
|
2207
|
-
*/
|
|
2208
|
-
function add(child, parent) {
|
|
2209
|
-
throwAttemptedChild(child, parent);
|
|
2210
|
-
const p = child.parent;
|
|
2211
|
-
parent.childrenStore = [...parent.childrenStore, child];
|
|
2212
|
-
child.parent = parent;
|
|
2213
|
-
if (p) p.childrenStore = without(p.childrenStore, child);
|
|
2214
|
-
}
|
|
2215
|
-
/**
|
|
2216
|
-
* Adds a new child node based on a value
|
|
2217
|
-
*/
|
|
2218
|
-
function addValue(value, parent) {
|
|
2219
|
-
return createNode$1(value, parent);
|
|
2220
|
-
}
|
|
2221
|
-
/**
|
|
2222
|
-
* Creates the root for a tree, with an optional `value`.
|
|
2223
|
-
* Use {@link rootWrapped} if you want a more object-oriented mode of access.
|
|
2224
|
-
* @param value
|
|
2225
|
-
*/
|
|
2226
|
-
function root$2(value) {
|
|
2227
|
-
return createNode$1(value);
|
|
2228
|
-
}
|
|
2229
|
-
function fromPlainObject(value, label = ``, parent, seen = []) {
|
|
2230
|
-
const entries = Object.entries(value);
|
|
2231
|
-
parent = parent === void 0 ? root$2() : addValue({
|
|
2232
|
-
label,
|
|
2233
|
-
value
|
|
2234
|
-
}, parent);
|
|
2235
|
-
for (const entry of entries) {
|
|
2236
|
-
const value = entry[1];
|
|
2237
|
-
if (seen.includes(value)) continue;
|
|
2238
|
-
seen.push(value);
|
|
2239
|
-
if (typeof entry[1] === `object`) fromPlainObject(value, entry[0], parent, seen);
|
|
2240
|
-
else addValue({
|
|
2241
|
-
label: entry[0],
|
|
2242
|
-
value
|
|
2243
|
-
}, parent);
|
|
2244
|
-
}
|
|
2245
|
-
return parent;
|
|
2246
|
-
}
|
|
2247
|
-
/**
|
|
2248
|
-
* Creates a tree, returning it as a {@link WrappedNode} for object-oriented access.
|
|
2249
|
-
* Use {@link Trees.Mutable.root} alternatively.
|
|
2250
|
-
* @param value
|
|
2251
|
-
*/
|
|
2252
|
-
function rootWrapped$1(value) {
|
|
2253
|
-
return wrap$1(createNode$1(value));
|
|
2254
|
-
}
|
|
2255
|
-
/**
|
|
2256
|
-
* Creates a `TreeNode` instance with a given value and parent.
|
|
2257
|
-
* Parent node, if specified, has its `childrenStore` property changed to include new child.
|
|
2258
|
-
* @param value
|
|
2259
|
-
* @param parent
|
|
2260
|
-
*/
|
|
2261
|
-
function createNode$1(value, parent) {
|
|
2262
|
-
const n = {
|
|
2263
|
-
childrenStore: [],
|
|
2264
|
-
parent,
|
|
2265
|
-
value
|
|
2266
|
-
};
|
|
2267
|
-
if (parent !== void 0) parent.childrenStore = [...parent.childrenStore, n];
|
|
2268
|
-
return n;
|
|
2269
|
-
}
|
|
2270
|
-
function childrenLength$1(node) {
|
|
2271
|
-
return node.childrenStore.length;
|
|
2272
|
-
}
|
|
2273
|
-
function value(node) {
|
|
2274
|
-
return node.value;
|
|
2275
|
-
}
|
|
2276
|
-
/**
|
|
2277
|
-
* Projects `node` as a dynamic traversable.
|
|
2278
|
-
* Dynamic in the sense that it creates the traversable project for nodes on demand.
|
|
2279
|
-
* A consequence is that node identities are not stable.
|
|
2280
|
-
* @param node
|
|
2281
|
-
*/
|
|
2282
|
-
function asDynamicTraversable$1(node) {
|
|
2283
|
-
return {
|
|
2284
|
-
*children() {
|
|
2285
|
-
for (const c of node.childrenStore) yield asDynamicTraversable$1(c);
|
|
2286
|
-
},
|
|
2287
|
-
getParent() {
|
|
2288
|
-
if (node.parent === void 0) return;
|
|
2289
|
-
return asDynamicTraversable$1(node.parent);
|
|
2290
|
-
},
|
|
2291
|
-
getValue() {
|
|
2292
|
-
return node.value;
|
|
2293
|
-
},
|
|
2294
|
-
getIdentity() {
|
|
2295
|
-
return node;
|
|
2296
|
-
}
|
|
2297
|
-
};
|
|
2298
|
-
}
|
|
2299
|
-
/**
|
|
2300
|
-
* Throws an error if:
|
|
2301
|
-
* 1. `child` is the same node as `parent`
|
|
2302
|
-
* 2. `child` is already an immediate child of `parent`
|
|
2303
|
-
* 3. `child` is an ancestor parent of `parent`
|
|
2304
|
-
* 4. `child` has `parent` as its own child
|
|
2305
|
-
* @param c
|
|
2306
|
-
* @param parent
|
|
2307
|
-
*/
|
|
2308
|
-
function throwAttemptedChild(c, parent) {
|
|
2309
|
-
if (parent === c) throw new Error(`Cannot add self as child`);
|
|
2310
|
-
if (c.parent === parent) return;
|
|
2311
|
-
if (hasAnyParent$1(parent, c)) throw new Error(`Child contains parent (1)`, { cause: c });
|
|
2312
|
-
if (hasAnyParent$1(c, parent)) throw new Error(`Parent already contains child`, { cause: c });
|
|
2313
|
-
if (hasAnyChild$1(parent, c)) throw new Error(`Child contains parent (2)`, { cause: c });
|
|
2314
|
-
}
|
|
2315
|
-
/**
|
|
2316
|
-
* Sets the children of `parent` to a list of `children`.
|
|
2317
|
-
*
|
|
2318
|
-
* Any previous children are disconnected from this parent.
|
|
2319
|
-
* All new children have their parent set to `parent`.
|
|
2320
|
-
*
|
|
2321
|
-
* There is some validation to ensure that adding the children doesn't break the tree.
|
|
2322
|
-
*/
|
|
2323
|
-
function setChildren(parent, children) {
|
|
2324
|
-
for (const c of children) throwAttemptedChild(c, parent);
|
|
2325
|
-
parent.childrenStore = [...children];
|
|
2326
|
-
for (const c of children) c.parent = parent;
|
|
2327
|
-
}
|
|
2328
|
-
function toStringDeep$4(node, indent = 0) {
|
|
2329
|
-
const t = `${` `.repeat(indent)} + ${node.value ? JSON.stringify(node.value) : `-`}`;
|
|
2330
|
-
return node.childrenStore.length > 0 ? `${t}\n${node.childrenStore.map((d) => toStringDeep$4(d, indent + 1)).join(`\n`)}` : t;
|
|
2331
|
-
}
|
|
2332
|
-
function* followValue$1(root, continuePredicate, depth = 1) {
|
|
2333
|
-
for (const c of root.childrenStore) {
|
|
2334
|
-
const value = c.value;
|
|
2335
|
-
if (value === void 0) continue;
|
|
2336
|
-
if (continuePredicate(value, depth)) {
|
|
2337
|
-
yield c.value;
|
|
2338
|
-
yield* followValue$1(c, continuePredicate, depth + 1);
|
|
2339
|
-
}
|
|
2340
|
-
}
|
|
2341
|
-
}
|
|
2342
|
-
var traverse_object_exports = /* @__PURE__ */ __exportAll({
|
|
2343
|
-
asDynamicTraversable: () => asDynamicTraversable,
|
|
2344
|
-
children: () => children$1,
|
|
2345
|
-
create: () => create$1,
|
|
2346
|
-
createSimplified: () => createSimplified,
|
|
2347
|
-
createWrapped: () => createWrapped,
|
|
2348
|
-
depthFirst: () => depthFirst$2,
|
|
2349
|
-
getByPath: () => getByPath,
|
|
2350
|
-
prettyPrint: () => prettyPrint,
|
|
2351
|
-
prettyPrintEntries: () => prettyPrintEntries,
|
|
2352
|
-
toStringDeep: () => toStringDeep$3,
|
|
2353
|
-
traceByPath: () => traceByPath
|
|
2354
|
-
});
|
|
2355
|
-
/**
|
|
2356
|
-
* Helper function to get a 'friendly' string representation of an array of {@link TraverseObjectEntry}.
|
|
2357
|
-
* @param entries
|
|
2358
|
-
* @returns
|
|
2359
|
-
*/
|
|
2360
|
-
function prettyPrintEntries(entries) {
|
|
2361
|
-
if (entries.length === 0) return `(empty)`;
|
|
2362
|
-
let t = ``;
|
|
2363
|
-
for (const [index, entry] of entries.entries()) {
|
|
2364
|
-
t += ` `.repeat(index);
|
|
2365
|
-
t += entry.name + ` = ` + JSON.stringify(entry.leafValue) + `\n`;
|
|
2366
|
-
}
|
|
2367
|
-
return t;
|
|
2368
|
-
}
|
|
2369
|
-
/**
|
|
2370
|
-
* Returns a human-friendly debug string for a tree-like structure
|
|
2371
|
-
* ```js
|
|
2372
|
-
* console.log(Trees.prettyPrint(obj));
|
|
2373
|
-
* ```
|
|
2374
|
-
* @param indent
|
|
2375
|
-
* @param node
|
|
2376
|
-
* @param options
|
|
2377
|
-
* @returns
|
|
2378
|
-
*/
|
|
2379
|
-
const prettyPrint = (node, indent = 0, options = {}) => {
|
|
2380
|
-
resultThrow(nullUndefTest(node, `node`));
|
|
2381
|
-
const entry = getNamedEntry(node, options.name ?? `node`);
|
|
2382
|
-
const t = `${` `.repeat(indent)} + name: ${entry.name} value: ${JSON.stringify(entry.leafValue)}`;
|
|
2383
|
-
const childrenAsArray = [...children$1(node, options)];
|
|
2384
|
-
return childrenAsArray.length > 0 ? t + `\n` + childrenAsArray.map((d) => prettyPrint(d.leafValue, indent + 1, {
|
|
2385
|
-
...options,
|
|
2386
|
-
name: d.name
|
|
2387
|
-
})).join(`\n`) : t;
|
|
2388
|
-
};
|
|
2389
|
-
/**
|
|
2390
|
-
* Returns a debug string representation of the node (recursive)
|
|
2391
|
-
* @param node
|
|
2392
|
-
* @param indent
|
|
2393
|
-
* @returns
|
|
2394
|
-
*/
|
|
2395
|
-
const toStringDeep$3 = (node, indent = 0) => {
|
|
2396
|
-
let t = ` `.repeat(indent) + ` ${node.value?.name}`;
|
|
2397
|
-
if (node.value !== void 0) {
|
|
2398
|
-
if (`sourceValue` in node.value && `leafValue` in node.value) {
|
|
2399
|
-
let sourceValue = toStringAbbreviate(node.value.sourceValue, 20);
|
|
2400
|
-
const leafValue = toStringAbbreviate(node.value.leafValue, 20);
|
|
2401
|
-
sourceValue = sourceValue === leafValue ? `` : `source: ` + sourceValue;
|
|
2402
|
-
t += ` = ${leafValue} ${sourceValue}`;
|
|
2403
|
-
} else if (`sourceValue` in node.value && node.value.sourceValue !== void 0) t += ` = ${node.value.sourceValue}`;
|
|
2404
|
-
if (`ancestors` in node.value) t += ` (ancestors: ${node.value.ancestors.join(`, `)})`;
|
|
2405
|
-
}
|
|
2406
|
-
t += `\n`;
|
|
2407
|
-
for (const c of node.childrenStore) t += toStringDeep$3(c, indent + 1);
|
|
2408
|
-
return t;
|
|
2409
|
-
};
|
|
2410
|
-
/**
|
|
2411
|
-
* Yields the direct (ie. non-recursive) children of a tree-like object as a pairing
|
|
2412
|
-
* of node name and value. Supports basic objects, Maps and arrays.
|
|
2413
|
-
*
|
|
2414
|
-
* To iterate recursively, consider {@link depthFirst}
|
|
2415
|
-
*
|
|
2416
|
-
* Each child is returned in an {@link TraverseObjectEntry} structure:
|
|
2417
|
-
* ```typescript
|
|
2418
|
-
* type Entry = Readonly<{
|
|
2419
|
-
* // Property name
|
|
2420
|
-
* name: string,
|
|
2421
|
-
* // Value of property, as if you called `object[propertyName]`
|
|
2422
|
-
* sourceValue: any,
|
|
2423
|
-
* // Branch nodes will have _undefined_, leaf nodes will contain the value
|
|
2424
|
-
* leafValue: any
|
|
2425
|
-
* }>;
|
|
2426
|
-
* ```
|
|
2427
|
-
*
|
|
2428
|
-
* For example, iterating over a flat object:
|
|
2429
|
-
* ```js
|
|
2430
|
-
* const verySimpleObject = { field: `hello`, flag: true }
|
|
2431
|
-
* const kids = [ ...children(verySimpleObject) ];
|
|
2432
|
-
* // Yields:
|
|
2433
|
-
* // [ { name: "field", sourceValue: `hello`, leafValue: `hello` },
|
|
2434
|
-
* // { name: "flag", sourceValue: true, leafValue: true } ]
|
|
2435
|
-
* ```
|
|
2436
|
-
*
|
|
2437
|
-
* For objects containing objects:
|
|
2438
|
-
* ```js
|
|
2439
|
-
* const lessSimpleObject = { field: `hello`, flag: true, colour: { `red`, opacity: 0.5 } }
|
|
2440
|
-
* const kids = [ ...children(verySimpleObject) ];
|
|
2441
|
-
* // Yields as before, plus:
|
|
2442
|
-
* // { name: "colour", sourceValue: { name: 'red', opacity: 0.5 }, leafValue: undefined }
|
|
2443
|
-
* ```
|
|
2444
|
-
*
|
|
2445
|
-
* Note that 'sourceValue' always contains the property value, as if you
|
|
2446
|
-
* access it via `object[propName]`. 'leafValue' only contains the value if it's a leaf
|
|
2447
|
-
* node.
|
|
2448
|
-
*
|
|
2449
|
-
* Arrays are assigned a name based on index.
|
|
2450
|
-
* @example Arrays
|
|
2451
|
-
* ```js
|
|
2452
|
-
* const colours = [ { r: 1, g: 0, b: 0 }, { r: 0, g: 1, b: 0 }, { r: 0, g: 0, b: 1 } ];
|
|
2453
|
-
* // Children:
|
|
2454
|
-
* // [
|
|
2455
|
-
* // { name: "array[0]", value: {r:1,g:0,b:0} },
|
|
2456
|
-
* // { name: "array[1]", value: {r:0,g:1,b:0} },
|
|
2457
|
-
* // { name: "array[2]", value: {r:0,g:0,b:1} },
|
|
2458
|
-
* // ]
|
|
2459
|
-
* ```
|
|
2460
|
-
*
|
|
2461
|
-
* Pass in `options.name` (eg 'colours') to have names generated as 'colours[0]', etc.
|
|
2462
|
-
* Options can also be used to filter children. By default all direct children are returned.
|
|
2463
|
-
* @param node
|
|
2464
|
-
* @param options
|
|
2465
|
-
*/
|
|
2466
|
-
function* children$1(node, options = {}) {
|
|
2467
|
-
resultThrow(nullUndefTest(node, `node`));
|
|
2468
|
-
const filteringOption = options.filter ?? `none`;
|
|
2469
|
-
const filterByValue = (v) => {
|
|
2470
|
-
if (filteringOption === `none`) return [true, isPrimitive(v)];
|
|
2471
|
-
else if (filteringOption === `leaves` && isPrimitive(v)) return [true, true];
|
|
2472
|
-
else if (filteringOption === `branches` && !isPrimitive(v)) return [true, false];
|
|
2473
|
-
return [false, isPrimitive(v)];
|
|
2474
|
-
};
|
|
2475
|
-
if (Array.isArray(node)) for (const [index, element] of node.entries()) {
|
|
2476
|
-
const f = filterByValue(element);
|
|
2477
|
-
if (f[0]) yield {
|
|
2478
|
-
name: index.toString(),
|
|
2479
|
-
_kind: `entry`,
|
|
2480
|
-
sourceValue: element,
|
|
2481
|
-
leafValue: f[1] ? element : void 0
|
|
2482
|
-
};
|
|
2483
|
-
}
|
|
2484
|
-
else if (typeof node === `object`) {
|
|
2485
|
-
const entriesIter = `entries` in node ? node.entries() : Object.entries(node);
|
|
2486
|
-
for (const [name, value] of entriesIter) {
|
|
2487
|
-
const [filter, isPrimitive] = filterByValue(value);
|
|
2488
|
-
if (filter) yield {
|
|
2489
|
-
name,
|
|
2490
|
-
_kind: `entry`,
|
|
2491
|
-
sourceValue: value,
|
|
2492
|
-
leafValue: isPrimitive ? value : void 0
|
|
2493
|
-
};
|
|
2494
|
-
}
|
|
2495
|
-
}
|
|
2496
|
-
}
|
|
2497
|
-
function* depthFirst$2(node, options = {}, ancestors = []) {
|
|
2498
|
-
for (const c of children$1(node, options)) {
|
|
2499
|
-
yield {
|
|
2500
|
-
...c,
|
|
2501
|
-
ancestors: [...ancestors],
|
|
2502
|
-
_kind: `entry-ancestors`
|
|
2503
|
-
};
|
|
2504
|
-
yield* depthFirst$2(c.sourceValue, options, [...ancestors, c.name]);
|
|
2505
|
-
}
|
|
2506
|
-
}
|
|
2507
|
-
/**
|
|
2508
|
-
* Finds a given direct child by name
|
|
2509
|
-
* @param name
|
|
2510
|
-
* @param node
|
|
2511
|
-
* @returns
|
|
2512
|
-
*/
|
|
2513
|
-
function childByName(name, node) {
|
|
2514
|
-
for (const d of children$1(node)) if (d.name === name) return d;
|
|
2515
|
-
}
|
|
2516
|
-
/**
|
|
2517
|
-
* Returns the closest matching entry, tracing `path` in an array, Map or simple object.
|
|
2518
|
-
* Returns an entry with _undefined_ value at the point where tracing stopped.
|
|
2519
|
-
* Use {@link traceByPath} to step through all the segments.
|
|
2520
|
-
*
|
|
2521
|
-
* ```js
|
|
2522
|
-
* const people = {
|
|
2523
|
-
* jane: {
|
|
2524
|
-
* address: {
|
|
2525
|
-
* postcode: 1000,
|
|
2526
|
-
* street: 'West St',
|
|
2527
|
-
* city: 'Blahville'
|
|
2528
|
-
* },
|
|
2529
|
-
* colour: 'red'
|
|
2530
|
-
* }
|
|
2531
|
-
* }
|
|
2532
|
-
* Trees.getByPath('jane.address.postcode', people); // '.' default separator
|
|
2533
|
-
* // ['postcode', 1000]
|
|
2534
|
-
* Trees.getByPath('jane.address.country.state', people);
|
|
2535
|
-
* // ['country', undefined] - since full path could not be resolved.
|
|
2536
|
-
* ```
|
|
2537
|
-
* @param path Path, eg `jane.address.postcode`
|
|
2538
|
-
* @param node Node to look within
|
|
2539
|
-
* @param options Options for parsing path. By default '.' is used as a separator
|
|
2540
|
-
* @returns
|
|
2541
|
-
*/
|
|
2542
|
-
function getByPath(path, node, options = {}) {
|
|
2543
|
-
const v = last(traceByPath(path, node, options));
|
|
2544
|
-
if (!v) throw new Error(`Could not trace path: ${path} `);
|
|
2545
|
-
return v;
|
|
2546
|
-
}
|
|
2547
|
-
/**
|
|
2548
|
-
* Enumerates over children of `node` towards the node named in `path`.
|
|
2549
|
-
* This is useful if you want to get the interim steps to the target node.
|
|
2550
|
-
*
|
|
2551
|
-
* Use {@link getByPath} if you don't care about interim steps.
|
|
2552
|
-
*
|
|
2553
|
-
* ```js
|
|
2554
|
-
* const people = {
|
|
2555
|
-
* jane: {
|
|
2556
|
-
* address: {
|
|
2557
|
-
* postcode: 1000,
|
|
2558
|
-
* street: 'West St',
|
|
2559
|
-
* city: 'Blahville'
|
|
2560
|
-
* },
|
|
2561
|
-
* colour: 'red'
|
|
2562
|
-
* }
|
|
2563
|
-
* }
|
|
2564
|
-
* for (const p of Trees.traceByPath('jane.address.street', people)) {
|
|
2565
|
-
* // { name: "jane", value: { address: { postcode: 1000,street: 'West St', city: 'Blahville' }, colour: 'red'} },
|
|
2566
|
-
* // { name: "address", value: { postcode: 1000, street: 'West St', city: 'Blahville' } },
|
|
2567
|
-
* // { name: "street", value: "West St" } }
|
|
2568
|
-
* }
|
|
2569
|
-
* ```
|
|
2570
|
-
*
|
|
2571
|
-
* Results stop when the path can't be followed any further.
|
|
2572
|
-
* The last entry will have a name of the last sought path segment, and _undefined_ as its value.
|
|
2573
|
-
*
|
|
2574
|
-
* @param path Path to traverse
|
|
2575
|
-
* @param node Starting node
|
|
2576
|
-
* @param options Options for path traversal logic
|
|
2577
|
-
* @returns
|
|
2578
|
-
*/
|
|
2579
|
-
function* traceByPath(path, node, options = {}) {
|
|
2580
|
-
resultThrow(nullUndefTest(path, `path`), nullUndefTest(node, `node`));
|
|
2581
|
-
const separator = options.separator ?? `.`;
|
|
2582
|
-
const pathSplit = path.split(separator);
|
|
2583
|
-
const ancestors = [];
|
|
2584
|
-
for (const p of pathSplit) {
|
|
2585
|
-
const entry = childByName(p, node);
|
|
2586
|
-
if (!entry) {
|
|
2587
|
-
yield {
|
|
2588
|
-
name: p,
|
|
2589
|
-
sourceValue: void 0,
|
|
2590
|
-
leafValue: void 0,
|
|
2591
|
-
ancestors,
|
|
2592
|
-
_kind: `entry-ancestors`
|
|
2593
|
-
};
|
|
2594
|
-
return;
|
|
2595
|
-
}
|
|
2596
|
-
node = entry.sourceValue;
|
|
2597
|
-
yield {
|
|
2598
|
-
...entry,
|
|
2599
|
-
ancestors: [...ancestors],
|
|
2600
|
-
_kind: `entry-ancestors`
|
|
2601
|
-
};
|
|
2602
|
-
ancestors.push(p);
|
|
2603
|
-
}
|
|
2604
|
-
}
|
|
2605
|
-
/**
|
|
2606
|
-
* Returns a projection of `node` as a dynamic traversable.
|
|
2607
|
-
* This means that the tree structure is dynamically created as last-minute as possible.
|
|
2608
|
-
*
|
|
2609
|
-
* The type when calling `getValue()` is {@link TraverseObjectEntryStatic}:
|
|
2610
|
-
* ```typescript
|
|
2611
|
-
* type EntryStatic = Readonly<{
|
|
2612
|
-
* name: string,
|
|
2613
|
-
* value: any
|
|
2614
|
-
* ancestors: string[]
|
|
2615
|
-
* }>
|
|
2616
|
-
* ```
|
|
2617
|
-
*
|
|
2618
|
-
* Note that the object identity of TraversableTree return results is not stable.
|
|
2619
|
-
* This is because they are created on-the-fly by reading fields of `node`.
|
|
2620
|
-
*
|
|
2621
|
-
* ```js
|
|
2622
|
-
* const c1 = [ ...asDynamicTraversable(someObject).children() ];
|
|
2623
|
-
* const c2 = [ ...asDynamicTraversable(someObject).children() ];
|
|
2624
|
-
*
|
|
2625
|
-
* // Object identity is not the same
|
|
2626
|
-
* c1[ 0 ] === c1[ 0 ]; // false
|
|
2627
|
-
*
|
|
2628
|
-
* // ...even though its referring to the same value
|
|
2629
|
-
* c1[ 0 ].getValue() === c1[ 0 ].getValue(); // true
|
|
2630
|
-
* ```
|
|
2631
|
-
*
|
|
2632
|
-
* Instead .getIdentity() to get a stable identity:
|
|
2633
|
-
* ```js
|
|
2634
|
-
* c1[ 0 ].getIdentity() === c2[ 0 ].getIdentity(); // true
|
|
2635
|
-
* ```
|
|
2636
|
-
*
|
|
2637
|
-
* @example
|
|
2638
|
-
* ```js
|
|
2639
|
-
* const myObj = { name: `Pedro`, size: 45, colour: `orange` };
|
|
2640
|
-
* const root = Trees.FromObject.asDynamicTraversable(myObj);
|
|
2641
|
-
* for (const v of Trees.Traverse.breadthFirst(root)) {
|
|
2642
|
-
* // v.getValue() yields:
|
|
2643
|
-
* // { name: 'name', sourceValue: 'Pedro' ...},
|
|
2644
|
-
* // { name: 'size', sourceValue: 45 ... }
|
|
2645
|
-
* // ...
|
|
2646
|
-
* }
|
|
2647
|
-
* ```
|
|
2648
|
-
* @param node Object to read
|
|
2649
|
-
* @param options Options when creating traversable
|
|
2650
|
-
* @param ancestors Do not use
|
|
2651
|
-
* @param parent Do not use
|
|
2652
|
-
* @returns
|
|
2653
|
-
*/
|
|
2654
|
-
const asDynamicTraversable = (node, options = {}, ancestors = [], parent) => {
|
|
2655
|
-
const name = options.name ?? `object`;
|
|
2656
|
-
const t = {
|
|
2657
|
-
*children() {
|
|
2658
|
-
for (const { name: childName, sourceValue, leafValue } of children$1(node, options)) yield asDynamicTraversable(sourceValue, {
|
|
2659
|
-
...options,
|
|
2660
|
-
name: childName
|
|
2661
|
-
}, [...ancestors, name], t);
|
|
2662
|
-
},
|
|
2663
|
-
getParent() {
|
|
2664
|
-
return parent;
|
|
2665
|
-
},
|
|
2666
|
-
getValue() {
|
|
2667
|
-
return {
|
|
2668
|
-
name,
|
|
2669
|
-
sourceValue: node,
|
|
2670
|
-
ancestors,
|
|
2671
|
-
_kind: `entry-static`
|
|
2672
|
-
};
|
|
2673
|
-
},
|
|
2674
|
-
getIdentity() {
|
|
2675
|
-
return node;
|
|
2676
|
-
}
|
|
2677
|
-
};
|
|
2678
|
-
return t;
|
|
2679
|
-
};
|
|
2680
|
-
/**
|
|
2681
|
-
* Reads all fields and sub-fields of `node`, returning as a 'wrapped' tree structure.
|
|
2682
|
-
* Is a snapshot of `node`, and won't update if it mutates.
|
|
2683
|
-
* @param node
|
|
2684
|
-
* @param options
|
|
2685
|
-
* @returns
|
|
2686
|
-
*/
|
|
2687
|
-
const createWrapped = (node, options) => {
|
|
2688
|
-
return wrap$1(create$1(node, options));
|
|
2689
|
-
};
|
|
2690
|
-
/**
|
|
2691
|
-
* Reads all fields and sub-fields of `node`, returning as a basic tree structure.
|
|
2692
|
-
* The structure is a snapshot of the object. If the object changes afterwards, the tree will
|
|
2693
|
-
* remain the same.
|
|
2694
|
-
*
|
|
2695
|
-
* Alternatively, consider {@link asDynamicTraversable} which reads the object dynamically.
|
|
2696
|
-
* @example
|
|
2697
|
-
* ```js
|
|
2698
|
-
* const myObj = { name: `Pedro`, size: 45, colour: `orange` };
|
|
2699
|
-
* const root = Trees.FromObject.create(myObj);
|
|
2700
|
-
* for (const v of Trees.Traverse.breadthFirst(root)) {
|
|
2701
|
-
* // v.getValue() yields:
|
|
2702
|
-
* // { name: 'name', sourceValue: 'Pedro' ...},
|
|
2703
|
-
* // { name: 'size', sourceValue: 45 ... }
|
|
2704
|
-
* // ...
|
|
2705
|
-
* }
|
|
2706
|
-
* ```
|
|
2707
|
-
* @param node
|
|
2708
|
-
* @param options
|
|
2709
|
-
* @returns
|
|
2710
|
-
*/
|
|
2711
|
-
const create$1 = (node, options = {}) => {
|
|
2712
|
-
return createImpl(node, (options.valuesAtLeaves ?? false ? (v) => {
|
|
2713
|
-
if (isPrimitive(v)) return v;
|
|
2714
|
-
} : (v) => v)(node), options, []);
|
|
2715
|
-
};
|
|
2716
|
-
const createImpl = (sourceValue, leafValue, options = {}, ancestors) => {
|
|
2717
|
-
const defaultName = options.name ?? `object_ci`;
|
|
2718
|
-
const r = root$2({
|
|
2719
|
-
name: defaultName,
|
|
2720
|
-
sourceValue: leafValue,
|
|
2721
|
-
ancestors: [...ancestors],
|
|
2722
|
-
_kind: `entry-static`
|
|
2723
|
-
});
|
|
2724
|
-
ancestors = [...ancestors, defaultName];
|
|
2725
|
-
for (const c of children$1(sourceValue, options)) {
|
|
2726
|
-
const v = options.valuesAtLeaves ? c.leafValue : c.sourceValue;
|
|
2727
|
-
add(createImpl(c.sourceValue, v, {
|
|
2728
|
-
...options,
|
|
2729
|
-
name: c.name
|
|
2730
|
-
}, ancestors), r);
|
|
2731
|
-
}
|
|
2732
|
-
return r;
|
|
2733
|
-
};
|
|
2734
|
-
/**
|
|
2735
|
-
* Returns a copy of `node` with its (and all its childrens') parent information removed.
|
|
2736
|
-
*
|
|
2737
|
-
* Under the hood:
|
|
2738
|
-
* ```js
|
|
2739
|
-
* TreeArrayBacked.stripParentage(create(node, options));
|
|
2740
|
-
* ```
|
|
2741
|
-
* @param node
|
|
2742
|
-
* @param options
|
|
2743
|
-
* @returns
|
|
2744
|
-
*/
|
|
2745
|
-
const createSimplified = (node, options = {}) => {
|
|
2746
|
-
return stripParentage(create$1(node, options));
|
|
2747
|
-
};
|
|
2748
|
-
/**
|
|
2749
|
-
* Generates a name for a node.
|
|
2750
|
-
* Uses the 'name' property if it exists, otherwise uses `defaultName`
|
|
2751
|
-
* @param node
|
|
2752
|
-
* @param defaultName
|
|
2753
|
-
* @returns
|
|
2754
|
-
*/
|
|
2755
|
-
function getNamedEntry(node, defaultName = ``) {
|
|
2756
|
-
if (`name` in node && `leafValue` in node && `sourceValue` in node) return {
|
|
2757
|
-
name: node.name,
|
|
2758
|
-
_kind: `entry`,
|
|
2759
|
-
leafValue: node.leafValue,
|
|
2760
|
-
sourceValue: node.sourceValue
|
|
2761
|
-
};
|
|
2762
|
-
if (`name` in node) return {
|
|
2763
|
-
name: node.name,
|
|
2764
|
-
leafValue: node,
|
|
2765
|
-
sourceValue: node,
|
|
2766
|
-
_kind: `entry`
|
|
2767
|
-
};
|
|
2768
|
-
return {
|
|
2769
|
-
name: defaultName,
|
|
2770
|
-
leafValue: node,
|
|
2771
|
-
sourceValue: node,
|
|
2772
|
-
_kind: `entry`
|
|
2773
|
-
};
|
|
2774
|
-
}
|
|
2775
|
-
function isSingleValue(v) {
|
|
2776
|
-
if (`value` in v) return true;
|
|
2777
|
-
return false;
|
|
2778
|
-
}
|
|
2779
|
-
function isMultiValue(v) {
|
|
2780
|
-
if (`values` in v) return Array.isArray(v.values);
|
|
2781
|
-
return false;
|
|
2782
|
-
}
|
|
2783
|
-
var pathed_exports = /* @__PURE__ */ __exportAll({
|
|
2784
|
-
Pathed: () => Pathed,
|
|
2785
|
-
addValueByPath: () => addValueByPath,
|
|
2786
|
-
children: () => children,
|
|
2787
|
-
childrenLengthByPath: () => childrenLengthByPath,
|
|
2788
|
-
clearValuesByPath: () => clearValuesByPath,
|
|
2789
|
-
findAnyChildByValue: () => findAnyChildByValue$1,
|
|
2790
|
-
hasValue: () => hasValue,
|
|
2791
|
-
parent: () => parent,
|
|
2792
|
-
parentValues: () => parentValues,
|
|
2793
|
-
removeValueByPath: () => removeValueByPath,
|
|
2794
|
-
siblings: () => siblings$1,
|
|
2795
|
-
siblingsValues: () => siblingsValues,
|
|
2796
|
-
toStringDeep: () => toStringDeep$2,
|
|
2797
|
-
valueByPath: () => valueByPath,
|
|
2798
|
-
valuesByPath: () => valuesByPath
|
|
2799
|
-
});
|
|
2800
|
-
/**
|
|
2801
|
-
* Creates a wrapper for working with 'pathed' trees.
|
|
2802
|
-
* An example is a filesystem.
|
|
2803
|
-
*
|
|
2804
|
-
* ```js
|
|
2805
|
-
* const t = new Pathed();
|
|
2806
|
-
* // Store a value. Path implies a structure of
|
|
2807
|
-
* // c -> users -> admin
|
|
2808
|
-
* // ...which is automatically created
|
|
2809
|
-
* t.add({x:10}, `c.users.admin`);
|
|
2810
|
-
*
|
|
2811
|
-
* t.add({x:20}, `c.users.guest`);
|
|
2812
|
-
* // Tree will now be:
|
|
2813
|
-
* // c-> users -> admin
|
|
2814
|
-
* // -> guest
|
|
2815
|
-
*
|
|
2816
|
-
* t.getValue(`c.users.guest`); // { x:20 }
|
|
2817
|
-
* ```
|
|
2818
|
-
*
|
|
2819
|
-
* By default only a single value can be stored at a path.
|
|
2820
|
-
* Set options to allow this:
|
|
2821
|
-
* ```js
|
|
2822
|
-
* const t = new Pathed({ duplicates: `allow` });
|
|
2823
|
-
* t.add({x:10}, `c.users.admin`);
|
|
2824
|
-
* t.add({x:20}, `c.users.admin`);
|
|
2825
|
-
* t.getValue(`c.users.admin`); // Throws an error because there are multiple values
|
|
2826
|
-
* t.getValues(`c.users.admin`); // [ {x:10}, {x:20 } ]
|
|
2827
|
-
* ```
|
|
2828
|
-
* @param pathOpts
|
|
2829
|
-
* @returns
|
|
2830
|
-
*/
|
|
2831
|
-
var Pathed = class {
|
|
2832
|
-
#root;
|
|
2833
|
-
#pathOpts;
|
|
2834
|
-
/**
|
|
2835
|
-
* Create, using default options
|
|
2836
|
-
* @param pathOpts
|
|
2837
|
-
*/
|
|
2838
|
-
constructor(pathOpts = {}) {
|
|
2839
|
-
this.#pathOpts = {
|
|
2840
|
-
separator: `.`,
|
|
2841
|
-
startsWithSeparator: false,
|
|
2842
|
-
duplicates: `overwrite`,
|
|
2843
|
-
...pathOpts
|
|
2844
|
-
};
|
|
2845
|
-
}
|
|
2846
|
-
/**
|
|
2847
|
-
* Adds a value at the string path, automatically creating intermediate nodes as needed.
|
|
2848
|
-
* By default, if a value already exists at the path, it will be overwritten. Set options to change this.
|
|
2849
|
-
* @param value Value to associate with path
|
|
2850
|
-
* @param path Path
|
|
2851
|
-
*/
|
|
2852
|
-
add(value, path) {
|
|
2853
|
-
throwIfFailed(this.validate(path));
|
|
2854
|
-
const n = addValueByPath(value, path, this.#pathOpts, this.#root);
|
|
2855
|
-
if (this.#root === void 0) this.#root = getRoot(n);
|
|
2856
|
-
}
|
|
2857
|
-
validate(path) {
|
|
2858
|
-
if (this.#pathOpts.startsWithSeparator && !path.startsWith(this.#pathOpts.separator)) return {
|
|
2859
|
-
success: false,
|
|
2860
|
-
error: `Path must start with separator when 'startsWithSeparator' is enabled. Got: ${path}`
|
|
2861
|
-
};
|
|
2862
|
-
return {
|
|
2863
|
-
success: true,
|
|
2864
|
-
value: path
|
|
2865
|
-
};
|
|
2866
|
-
}
|
|
2867
|
-
/**
|
|
2868
|
-
* Returns a string representation of tree
|
|
2869
|
-
* @returns Returns a string representation of tree
|
|
2870
|
-
*/
|
|
2871
|
-
prettyPrint() {
|
|
2872
|
-
if (this.#root === void 0) return `(empty)`;
|
|
2873
|
-
return toStringDeep$4(this.#root);
|
|
2874
|
-
}
|
|
2875
|
-
/**
|
|
2876
|
-
* Removes the value at the given path, returning _true_
|
|
2877
|
-
* if there was a value. This will delete tree nodes if they become empty
|
|
2878
|
-
* @param path
|
|
2879
|
-
* @returns _true_ if value was removed
|
|
2880
|
-
*/
|
|
2881
|
-
remove(path) {
|
|
2882
|
-
throwIfFailed(this.validate(path));
|
|
2883
|
-
if (this.#root === void 0) return false;
|
|
2884
|
-
return removeValueByPath(path, this.#root, this.#pathOpts);
|
|
2885
|
-
}
|
|
2886
|
-
/**
|
|
2887
|
-
* Returns _true_ if we have a value at `path`
|
|
2888
|
-
* @param path
|
|
2889
|
-
* @returns _true_ if value exists at path
|
|
2890
|
-
*/
|
|
2891
|
-
hasPath(path) {
|
|
2892
|
-
throwIfFailed(this.validate(path));
|
|
2893
|
-
if (this.#root === void 0) return false;
|
|
2894
|
-
return findChildByPath(path, this.#root, this.#pathOpts) !== void 0;
|
|
2895
|
-
}
|
|
2896
|
-
/**
|
|
2897
|
-
* Returns a tree node for a given path, or _undefined_
|
|
2898
|
-
* if path does not exist.
|
|
2899
|
-
*
|
|
2900
|
-
* Use {@link getValue} to get the value at a node instead.
|
|
2901
|
-
* @param path
|
|
2902
|
-
* @returns The tree node for the given path, or _undefined_ if not found
|
|
2903
|
-
*/
|
|
2904
|
-
getNode(path) {
|
|
2905
|
-
throwIfFailed(this.validate(path));
|
|
2906
|
-
if (this.#root === void 0) return;
|
|
2907
|
-
return findChildByPath(path, this.#root, this.#pathOpts);
|
|
2908
|
-
}
|
|
2909
|
-
/**
|
|
2910
|
-
* Returns the value at the path, or _undefined_ if path is not found.
|
|
2911
|
-
* Use {@link getNode} to get the tree node instead.
|
|
2912
|
-
* @param path
|
|
2913
|
-
* @returns The value at the path, or _undefined_ if path is not found
|
|
2914
|
-
*/
|
|
2915
|
-
getValue(path) {
|
|
2916
|
-
throwIfFailed(this.validate(path));
|
|
2917
|
-
if (this.#root === void 0) return;
|
|
2918
|
-
return valueByPath(path, this.#root, this.#pathOpts);
|
|
2919
|
-
}
|
|
2920
|
-
/**
|
|
2921
|
-
* Gets the containing path to `node`. If _includeNode_ is true, we also include the
|
|
2922
|
-
* node's own label.
|
|
2923
|
-
*/
|
|
2924
|
-
getPath(node, includeNode) {
|
|
2925
|
-
if (this.#root === void 0) return ``;
|
|
2926
|
-
const segments = [];
|
|
2927
|
-
if (includeNode && node.value) segments.push(node.value?.label);
|
|
2928
|
-
for (const p of parentValues(node)) segments.unshift(p.label);
|
|
2929
|
-
let path = segments.join(this.#pathOpts.separator);
|
|
2930
|
-
if (this.#pathOpts.startsWithSeparator) {
|
|
2931
|
-
if (!path.startsWith(this.#pathOpts.separator)) path = this.#pathOpts.separator + path;
|
|
2932
|
-
if (!path.endsWith(this.#pathOpts.separator) && (node.childrenStore.length > 0 || !includeNode)) path += this.#pathOpts.separator;
|
|
2933
|
-
}
|
|
2934
|
-
return path;
|
|
2935
|
-
}
|
|
2936
|
-
/**
|
|
2937
|
-
* Gets the number of children at a given path.
|
|
2938
|
-
* Returns NaN if path does not exist or has no children.
|
|
2939
|
-
* @param path
|
|
2940
|
-
* @returns The number of children at the path, or NaN if path is not found
|
|
2941
|
-
*/
|
|
2942
|
-
childrenLength(path) {
|
|
2943
|
-
throwIfFailed(this.validate(path));
|
|
2944
|
-
if (this.#root === void 0) return NaN;
|
|
2945
|
-
const c = findChildByPath(path, this.#root, this.#pathOpts);
|
|
2946
|
-
if (c === void 0) return NaN;
|
|
2947
|
-
return c.childrenStore.length;
|
|
2948
|
-
}
|
|
2949
|
-
/**
|
|
2950
|
-
* Get all the values stored at a path, if multiple values are allowed. Returns an empty array if path does not exist or has no value.
|
|
2951
|
-
* @param path
|
|
2952
|
-
* @returns An array of values at the path, or an empty array if path is not found
|
|
2953
|
-
*/
|
|
2954
|
-
getValues(path) {
|
|
2955
|
-
throwIfFailed(this.validate(path));
|
|
2956
|
-
if (this.#root === void 0) return void 0;
|
|
2957
|
-
return valuesByPath(path, this.#root, this.#pathOpts);
|
|
2958
|
-
}
|
|
2959
|
-
/**
|
|
2960
|
-
* Removes all values at the given path, but leaves the structure of the tree intact. Returns _true_ if there was a value to clear.
|
|
2961
|
-
* @param path
|
|
2962
|
-
* @returns _true_ if there was a value to clear at the path
|
|
2963
|
-
*/
|
|
2964
|
-
clearValues(path) {
|
|
2965
|
-
throwIfFailed(this.validate(path));
|
|
2966
|
-
if (this.#root === void 0) return false;
|
|
2967
|
-
return clearValuesByPath(path, this.#root, this.#pathOpts);
|
|
2968
|
-
}
|
|
2969
|
-
/**
|
|
2970
|
-
* Iterate all children of this path
|
|
2971
|
-
*/
|
|
2972
|
-
*children(path) {
|
|
2973
|
-
throwIfFailed(this.validate(path));
|
|
2974
|
-
if (this.#root === void 0) return;
|
|
2975
|
-
yield* children(path, this.#root, this.#pathOpts);
|
|
2976
|
-
}
|
|
2977
|
-
/**
|
|
2978
|
-
* Iterate all siblings of this path
|
|
2979
|
-
*/
|
|
2980
|
-
*siblings(path) {
|
|
2981
|
-
throwIfFailed(this.validate(path));
|
|
2982
|
-
if (this.#root === void 0) return;
|
|
2983
|
-
yield* siblings$1(path, this.#root, this.#pathOpts);
|
|
2984
|
-
}
|
|
2985
|
-
/**
|
|
2986
|
-
* Iterate all siblings of this path
|
|
2987
|
-
*/
|
|
2988
|
-
*siblingsValues(path) {
|
|
2989
|
-
throwIfFailed(this.validate(path));
|
|
2990
|
-
if (this.#root === void 0) return;
|
|
2991
|
-
yield* siblingsValues(path, this.#root, this.#pathOpts);
|
|
2992
|
-
}
|
|
2993
|
-
/**
|
|
2994
|
-
* Returns the parent node of `path`, or _undefined_ if not found or at root.
|
|
2995
|
-
*/
|
|
2996
|
-
parent(path) {
|
|
2997
|
-
throwIfFailed(this.validate(path));
|
|
2998
|
-
if (this.#root === void 0) return;
|
|
2999
|
-
return parent(path, this.#root, this.#pathOpts);
|
|
3000
|
-
}
|
|
3001
|
-
get separator() {
|
|
3002
|
-
return this.#pathOpts.separator;
|
|
3003
|
-
}
|
|
3004
|
-
/**
|
|
3005
|
-
* Returns the root tree node.
|
|
3006
|
-
* @returns The root tree node, or _undefined_ if tree is empty
|
|
3007
|
-
*/
|
|
3008
|
-
get root() {
|
|
3009
|
-
return this.#root;
|
|
3010
|
-
}
|
|
3011
|
-
};
|
|
3012
|
-
/**
|
|
3013
|
-
* Adds a value by a string path, with '.' as a the default delimiter
|
|
3014
|
-
* Automatically generates intermediate nodes.
|
|
3015
|
-
*
|
|
3016
|
-
* ```js
|
|
3017
|
-
* const root = addValueByPath({}, 'c');
|
|
3018
|
-
* addValueByPath({x:'blah'}, 'c.users.admin', root);
|
|
3019
|
-
* ```
|
|
3020
|
-
*
|
|
3021
|
-
* Creates the structure:
|
|
3022
|
-
* ```
|
|
3023
|
-
* c value: { } label: c
|
|
3024
|
-
* + users value: undefined label: users
|
|
3025
|
-
* + admin value: { x: 'blah' } label: admin
|
|
3026
|
-
* ```
|
|
3027
|
-
*
|
|
3028
|
-
* By default, multiple values under same key are overwritten, with the most recent winning.
|
|
3029
|
-
* @param value Value to add
|
|
3030
|
-
* @param path Path to add at
|
|
3031
|
-
* @param node Node to insert
|
|
3032
|
-
* @param pathOpts Options
|
|
3033
|
-
*/
|
|
3034
|
-
function addValueByPath(value, path, pathOpts, node) {
|
|
3035
|
-
const separator = pathOpts.separator;
|
|
3036
|
-
const duplicatePath = pathOpts.duplicates;
|
|
3037
|
-
const split = path.split(separator);
|
|
3038
|
-
let count = 0;
|
|
3039
|
-
for (const p of split) {
|
|
3040
|
-
const lastEntry = count === split.length - 1;
|
|
3041
|
-
const found = findChildByLabel(p, node);
|
|
3042
|
-
if (found === void 0) node = createNode$1({
|
|
3043
|
-
value: lastEntry ? value : void 0,
|
|
3044
|
-
label: p
|
|
3045
|
-
}, node);
|
|
3046
|
-
else {
|
|
3047
|
-
node = found;
|
|
3048
|
-
if (lastEntry) switch (duplicatePath) {
|
|
3049
|
-
case `ignore`: break;
|
|
3050
|
-
case `allow`: {
|
|
3051
|
-
const existing = getValuesFromNode(node);
|
|
3052
|
-
node.value = {
|
|
3053
|
-
values: [...existing, value],
|
|
3054
|
-
label: p
|
|
3055
|
-
};
|
|
3056
|
-
break;
|
|
3057
|
-
}
|
|
3058
|
-
case `overwrite`:
|
|
3059
|
-
node.value = {
|
|
3060
|
-
value,
|
|
3061
|
-
label: p
|
|
3062
|
-
};
|
|
3063
|
-
break;
|
|
3064
|
-
}
|
|
3065
|
-
else node = found;
|
|
3066
|
-
}
|
|
3067
|
-
count++;
|
|
3068
|
-
}
|
|
3069
|
-
if (node === void 0) throw new Error(`Could not create tree`);
|
|
3070
|
-
return node;
|
|
3071
|
-
}
|
|
3072
|
-
/**
|
|
3073
|
-
* Removes the value at the given path, returning _true_ if there was something to remove.
|
|
3074
|
-
* @param node
|
|
3075
|
-
* @returns _true_ if something removed
|
|
3076
|
-
*/
|
|
3077
|
-
function isLabelledNodeEmpty(node) {
|
|
3078
|
-
if (node.value === void 0) return true;
|
|
3079
|
-
if (`values` in node.value) return node.value.values.length === 0;
|
|
3080
|
-
if (`value` in node.value) return node.value.value === void 0;
|
|
3081
|
-
return true;
|
|
3082
|
-
}
|
|
3083
|
-
function pruneLabelledBranch(node) {
|
|
3084
|
-
if (node.childrenStore.length > 0) return;
|
|
3085
|
-
if (!isLabelledNodeEmpty(node)) return;
|
|
3086
|
-
const parent = node.parent;
|
|
3087
|
-
if (!parent) return;
|
|
3088
|
-
remove$1(node);
|
|
3089
|
-
pruneLabelledBranch(parent);
|
|
3090
|
-
}
|
|
3091
|
-
function removeValueByPath(path, root, pathOpts) {
|
|
3092
|
-
if (root === void 0) return false;
|
|
3093
|
-
const c = findChildByPath(path, root, pathOpts);
|
|
3094
|
-
if (c === void 0) return false;
|
|
3095
|
-
c.value = void 0;
|
|
3096
|
-
pruneLabelledBranch(c);
|
|
3097
|
-
return true;
|
|
3098
|
-
}
|
|
3099
|
-
function clearValuesByPath(path, root, pathOpts) {
|
|
3100
|
-
if (root === void 0) return false;
|
|
3101
|
-
const c = findChildByPath(path, root, pathOpts);
|
|
3102
|
-
if (c === void 0) return false;
|
|
3103
|
-
c.value = {
|
|
3104
|
-
label: c.value?.label ?? ``,
|
|
3105
|
-
value: void 0
|
|
3106
|
-
};
|
|
3107
|
-
return true;
|
|
3108
|
-
}
|
|
3109
|
-
/**
|
|
3110
|
-
* Return the length of children of `path`, or NaN if path not found.
|
|
3111
|
-
*/
|
|
3112
|
-
function childrenLengthByPath(path, searchStart, pathOpts) {
|
|
3113
|
-
if (searchStart === void 0) return NaN;
|
|
3114
|
-
const c = findChildByPath(path, searchStart, pathOpts);
|
|
3115
|
-
if (c === void 0) return NaN;
|
|
3116
|
-
return c.childrenStore.length;
|
|
3117
|
-
}
|
|
3118
|
-
/**
|
|
3119
|
-
* Iterate over all the children of `path`
|
|
3120
|
-
*/
|
|
3121
|
-
function* children(path, searchStart, pathOpts) {
|
|
3122
|
-
if (searchStart === void 0) return;
|
|
3123
|
-
const c = findChildByPath(path, searchStart, pathOpts);
|
|
3124
|
-
if (c === void 0) return;
|
|
3125
|
-
for (const ch of c.childrenStore) yield ch;
|
|
3126
|
-
}
|
|
3127
|
-
/**
|
|
3128
|
-
* Iterate over all the siblings of `path`, excluding the node at `path` itself.
|
|
3129
|
-
* Yields LabelledNode instances, which allow you to traverse tree. If all you care about is the values, use {@link siblingsValues} instead.
|
|
3130
|
-
*/
|
|
3131
|
-
function* siblings$1(path, searchStart, pathOpts) {
|
|
3132
|
-
if (searchStart === void 0) return;
|
|
3133
|
-
const c = findChildByPath(path, searchStart, pathOpts);
|
|
3134
|
-
if (c === void 0) return;
|
|
3135
|
-
const parent = c.parent;
|
|
3136
|
-
if (parent === void 0) return;
|
|
3137
|
-
for (const ch of parent.childrenStore) {
|
|
3138
|
-
if (ch === c) continue;
|
|
3139
|
-
if (typeof ch === `undefined`) throw new TypeError(`Unexpected undefined child node`);
|
|
3140
|
-
yield ch;
|
|
3141
|
-
}
|
|
3142
|
-
}
|
|
3143
|
-
/**
|
|
3144
|
-
* Iterate over the values of all the siblings of `path`, excluding the node at `path` itself. If you need to traverse tree, use {@link siblings} instead.
|
|
3145
|
-
* @param path
|
|
3146
|
-
* @param searchStart
|
|
3147
|
-
* @param pathOpts
|
|
3148
|
-
*/
|
|
3149
|
-
function* siblingsValues(path, searchStart, pathOpts) {
|
|
3150
|
-
for (const s of siblings$1(path, searchStart, pathOpts)) {
|
|
3151
|
-
if (s.value === void 0) continue;
|
|
3152
|
-
yield s.value;
|
|
3153
|
-
}
|
|
3154
|
-
}
|
|
3155
|
-
/**
|
|
3156
|
-
* Return the parent node of `path`, or undefined if not found or at root.
|
|
3157
|
-
*/
|
|
3158
|
-
function parent(path, searchStart, pathOpts) {
|
|
3159
|
-
if (searchStart === void 0) return;
|
|
3160
|
-
const c = findChildByPath(path, searchStart, pathOpts);
|
|
3161
|
-
if (c === void 0) return;
|
|
3162
|
-
return c.parent;
|
|
3163
|
-
}
|
|
3164
|
-
function* parentValues(start) {
|
|
3165
|
-
for (const p of parents$1(start)) {
|
|
3166
|
-
if (p.value === void 0) continue;
|
|
3167
|
-
yield p.value;
|
|
3168
|
-
}
|
|
3169
|
-
}
|
|
3170
|
-
/**
|
|
3171
|
-
* Searches direct children, returning the node that has the given `label`
|
|
3172
|
-
* @param label
|
|
3173
|
-
* @param node
|
|
3174
|
-
* @returns Child node, or _undefined_
|
|
3175
|
-
*/
|
|
3176
|
-
function findChildByLabel(label, node) {
|
|
3177
|
-
if (node === void 0) return void 0;
|
|
3178
|
-
if (label === void 0) throw new Error(`Parameter 'label' cannot be undefined`);
|
|
3179
|
-
if (node.value?.label === label) return node;
|
|
3180
|
-
for (const c of node.childrenStore) if (c.value?.label === label) return c;
|
|
3181
|
-
}
|
|
3182
|
-
/**
|
|
3183
|
-
* Searches children, returning the node that has the given `value`.
|
|
3184
|
-
* @param value Value
|
|
3185
|
-
* @param node Node to start search from
|
|
3186
|
-
* @param maxDepth Maximum depth, defaults to full recursion
|
|
3187
|
-
* @param eq Equality function
|
|
3188
|
-
* @returns Child, or _undefined_ if not found
|
|
3189
|
-
*/
|
|
3190
|
-
function findAnyChildByValue$1(value, node, maxDepth = Number.MAX_SAFE_INTEGER, eq = isEqualValueDefault) {
|
|
3191
|
-
if (typeof node === `undefined`) throw new TypeError(`Param 'node' is undefined`);
|
|
3192
|
-
if (maxDepth <= 0) return;
|
|
3193
|
-
if (typeof value === `undefined`) throw new Error(`Param 'value' cannot be undefined`);
|
|
3194
|
-
for (const c of node.childrenStore) if (hasValue(value, c, eq)) return c;
|
|
3195
|
-
for (const c of node.childrenStore) {
|
|
3196
|
-
const result = findAnyChildByValue$1(value, c, maxDepth - 1, eq);
|
|
3197
|
-
if (typeof result !== `undefined`) return result;
|
|
3198
|
-
}
|
|
3199
|
-
}
|
|
3200
|
-
function hasValue(value, node, eq = isEqualDefault) {
|
|
3201
|
-
if (typeof node.value === `undefined`) return false;
|
|
3202
|
-
if (isSingleValue(node.value)) {
|
|
3203
|
-
if (eq(node.value.value, value)) return true;
|
|
3204
|
-
} else if (isMultiValue(node.value)) {
|
|
3205
|
-
for (const v of node.value.values) if (eq(v, value)) return true;
|
|
3206
|
-
}
|
|
3207
|
-
return false;
|
|
3208
|
-
}
|
|
3209
|
-
function valueByPath(path, node, pathOpts = {}) {
|
|
3210
|
-
const values = valuesByPath(path, node, pathOpts);
|
|
3211
|
-
if (typeof values === `undefined`) return;
|
|
3212
|
-
if (values.length === 0) return void 0;
|
|
3213
|
-
if (values.length > 1) throw new Error(`Multiple values at path. Use getValues instead`);
|
|
3214
|
-
return values[0];
|
|
3215
|
-
}
|
|
3216
|
-
function getValuesFromNode(node) {
|
|
3217
|
-
if (node.value === void 0) return [];
|
|
3218
|
-
if (`values` in node.value) return node.value.values;
|
|
3219
|
-
if (`value` in node.value) {
|
|
3220
|
-
if (node.value.value === void 0) return [];
|
|
3221
|
-
return [node.value.value];
|
|
3222
|
-
}
|
|
3223
|
-
return [];
|
|
3224
|
-
}
|
|
3225
|
-
function findChildByPath(path, searchStart, pathOpts) {
|
|
3226
|
-
if (path.endsWith(pathOpts.separator) && pathOpts.startsWithSeparator) path = path.slice(0, -pathOpts.separator.length);
|
|
3227
|
-
const split = path.split(pathOpts.separator);
|
|
3228
|
-
let c = searchStart;
|
|
3229
|
-
for (const p of split) {
|
|
3230
|
-
c = findChildByLabel(p, c);
|
|
3231
|
-
if (c === void 0) return;
|
|
3232
|
-
}
|
|
3233
|
-
return c;
|
|
3234
|
-
}
|
|
3235
|
-
function valuesByPath(path, searchStart, pathOpts = {}) {
|
|
3236
|
-
const separator = pathOpts.separator ?? `.`;
|
|
3237
|
-
const split = path.split(separator);
|
|
3238
|
-
let c = searchStart;
|
|
3239
|
-
for (const p of split) {
|
|
3240
|
-
c = findChildByLabel(p, c);
|
|
3241
|
-
if (c === void 0) return;
|
|
3242
|
-
}
|
|
3243
|
-
return getValuesFromNode(c);
|
|
3244
|
-
}
|
|
3245
|
-
function formatInspectValue(v) {
|
|
3246
|
-
if (v === void 0) return `undefined`;
|
|
3247
|
-
if (v === null) return `null`;
|
|
3248
|
-
if (typeof v === `string`) return `"${v}"`;
|
|
3249
|
-
if (typeof v === `number` || typeof v === `boolean`) return String(v);
|
|
3250
|
-
if (Array.isArray(v)) {
|
|
3251
|
-
if (v.length === 0) return `[]`;
|
|
3252
|
-
return `[ ${v.map(formatInspectValue).join(`, `)} ]`;
|
|
3253
|
-
}
|
|
3254
|
-
if (typeof v === `object`) return `{ ${Object.entries(v).map(([k, val]) => `${k}: ${formatInspectValue(val)}`).join(`, `)} }`;
|
|
3255
|
-
return String(v);
|
|
3256
|
-
}
|
|
3257
|
-
/**
|
|
3258
|
-
* Returns a string representation of a LabelledNode tree.
|
|
3259
|
-
* Format: `{ label: "x", value: ..., children: [...] }`
|
|
3260
|
-
*/
|
|
3261
|
-
function toStringDeep$2(node) {
|
|
3262
|
-
const label = node.value?.label ?? `?`;
|
|
3263
|
-
const innerValue = node.value === void 0 ? void 0 : `values` in node.value ? node.value.values : `value` in node.value ? node.value.value : void 0;
|
|
3264
|
-
const children = node.childrenStore.map((c) => toStringDeep$2(c));
|
|
3265
|
-
const childrenStr = children.length === 0 ? `[]` : `[ ${children.join(`, `)} ]`;
|
|
3266
|
-
return `{ label: "${label}", value: ${formatInspectValue(innerValue)}, children: ${childrenStr} }`;
|
|
3267
|
-
}
|
|
3268
|
-
var traversable_tree_exports = /* @__PURE__ */ __exportAll({
|
|
3269
|
-
breadthFirst: () => breadthFirst$1,
|
|
3270
|
-
childrenLength: () => childrenLength,
|
|
3271
|
-
couldAddChild: () => couldAddChild,
|
|
3272
|
-
depthFirst: () => depthFirst$1,
|
|
3273
|
-
find: () => find$2,
|
|
3274
|
-
findAnyChildByValue: () => findAnyChildByValue,
|
|
3275
|
-
findAnyParentByValue: () => findAnyParentByValue,
|
|
3276
|
-
findByValue: () => findByValue,
|
|
3277
|
-
findChildByValue: () => findChildByValue,
|
|
3278
|
-
findParentByValue: () => findParentByValue,
|
|
3279
|
-
followValue: () => followValue,
|
|
3280
|
-
hasAnyChild: () => hasAnyChild,
|
|
3281
|
-
hasAnyChildValue: () => hasAnyChildValue,
|
|
3282
|
-
hasAnyParent: () => hasAnyParent,
|
|
3283
|
-
hasAnyParentValue: () => hasAnyParentValue,
|
|
3284
|
-
hasChild: () => hasChild,
|
|
3285
|
-
hasChildValue: () => hasChildValue,
|
|
3286
|
-
hasParent: () => hasParent,
|
|
3287
|
-
hasParentValue: () => hasParentValue,
|
|
3288
|
-
parents: () => parents,
|
|
3289
|
-
siblings: () => siblings,
|
|
3290
|
-
toString: () => toString,
|
|
3291
|
-
toStringDeep: () => toStringDeep$1
|
|
3292
|
-
});
|
|
3293
|
-
/**
|
|
3294
|
-
* Returns the number of children of `tree`.
|
|
3295
|
-
* Under the hood is just `[ ...tree.children() ].length`
|
|
3296
|
-
* @param tree
|
|
3297
|
-
* @returns
|
|
3298
|
-
*/
|
|
3299
|
-
const childrenLength = (tree) => {
|
|
3300
|
-
return [...tree.children()].length;
|
|
3301
|
-
};
|
|
3302
|
-
/**
|
|
3303
|
-
* Returns _true_ if `child` is parented at any level (grand-parented etc) by `possibleParent`
|
|
3304
|
-
* @param child Child being sought
|
|
3305
|
-
* @param possibleParent Possible parent of child
|
|
3306
|
-
* @param eq Equality comparison function {@link isEqualDefault} used by default
|
|
3307
|
-
* @returns
|
|
3308
|
-
*/
|
|
3309
|
-
const hasAnyParent = (child, possibleParent, eq) => {
|
|
3310
|
-
return hasParent(child, possibleParent, eq, Number.MAX_SAFE_INTEGER);
|
|
3311
|
-
};
|
|
3312
|
-
/**
|
|
3313
|
-
* Returns _true_ if `child` is parented at any level (grand-parented etc) by a parent with value `possibleParentValue`
|
|
3314
|
-
* @param child Child being sought
|
|
3315
|
-
* @param possibleParentValue Value of possible parent of child
|
|
3316
|
-
* @param eq Equality comparison function {@link isEqualDefault} used by default
|
|
3317
|
-
* @throws TypeError if `child` is undefined
|
|
3318
|
-
* @returns
|
|
3319
|
-
*/
|
|
3320
|
-
const hasAnyParentValue = (child, possibleParentValue, eq) => {
|
|
3321
|
-
if (typeof child === `undefined`) throw new TypeError(`Param 'child' is undefined`);
|
|
3322
|
-
return hasParentValue(child, possibleParentValue, eq, Number.MAX_SAFE_INTEGER);
|
|
3323
|
-
};
|
|
3324
|
-
/**
|
|
3325
|
-
* Returns any parent of `child` that has value `possibleParentValue`. Returns _undefined_ if not found.
|
|
3326
|
-
* @param child Child being sought
|
|
3327
|
-
* @param possibleParentValue Value of possible parent of child
|
|
3328
|
-
* @param eq Equality comparison function {@link isEqualDefault} used by default
|
|
3329
|
-
* @returns
|
|
3330
|
-
*/
|
|
3331
|
-
const findAnyParentByValue = (child, possibleParentValue, eq) => {
|
|
3332
|
-
return findParentByValue(child, possibleParentValue, eq, Number.MAX_SAFE_INTEGER);
|
|
3333
|
-
};
|
|
3334
|
-
/**
|
|
3335
|
-
* Returns _true_ if `child` exists within `possibleParent`. By default it only looks at the immediate
|
|
3336
|
-
* parent (maxDepth: 0). Use Number.MAX_SAFE_INTEGER for searching recursively upwards (or {@link hasAnyParent})
|
|
3337
|
-
* @param child Child being sought
|
|
3338
|
-
* @param possibleParent Possible parent of child
|
|
3339
|
-
* @param maxDepth Max depth of traversal. Default of 0 only looks for immediate parent.
|
|
3340
|
-
* @param eq Equality comparison function. {@link isEqualDefault} used by default.
|
|
3341
|
-
* @returns
|
|
3342
|
-
*/
|
|
3343
|
-
const hasParent = (child, possibleParent, eq = isEqualDefault, maxDepth = 0) => {
|
|
3344
|
-
if (maxDepth < 0) return false;
|
|
3345
|
-
const isChildTrav = isTraversable(child);
|
|
3346
|
-
const isParentTrav = isTraversable(possibleParent);
|
|
3347
|
-
const p = isChildTrav ? child.getParent() : child.parent;
|
|
3348
|
-
if (typeof p === `undefined`) return false;
|
|
3349
|
-
if (eq(p, possibleParent)) return true;
|
|
3350
|
-
if (eq(isChildTrav ? p.getIdentity() : p.value, isParentTrav ? possibleParent.getIdentity() : possibleParent.value)) return true;
|
|
3351
|
-
return hasParent(p, possibleParent, eq, maxDepth - 1);
|
|
3352
|
-
};
|
|
3353
|
-
/**
|
|
3354
|
-
* Checks if a child node has a parent with a certain value
|
|
3355
|
-
* Note: by default only checks immediate parent. Set maxDepth to a large value to recurse
|
|
3356
|
-
*
|
|
3357
|
-
* Uses `getValue()` on the parent if that function exists.
|
|
3358
|
-
* @param child Node to start looking from
|
|
3359
|
-
* @param possibleParentValue Value to seek
|
|
3360
|
-
* @param eq Equality checker
|
|
3361
|
-
* @param maxDepth Defaults to 0, so it only checks immediate parent
|
|
3362
|
-
* @returns
|
|
3363
|
-
*/
|
|
3364
|
-
const hasParentValue = (child, possibleParentValue, eq = isEqualDefault, maxDepth = 0) => {
|
|
3365
|
-
if (child === void 0) throw new Error(`Param 'child' is undefined`);
|
|
3366
|
-
if (maxDepth < 0) return false;
|
|
3367
|
-
const p = `getParent` in child ? child.getParent() : child.parent;
|
|
3368
|
-
if (p === void 0) return false;
|
|
3369
|
-
if (eq(`getValue` in p ? p.getValue() : p.value, possibleParentValue)) return true;
|
|
3370
|
-
return hasParentValue(p, possibleParentValue, eq, maxDepth - 1);
|
|
3371
|
-
};
|
|
3372
|
-
/**
|
|
3373
|
-
* Returns any parent of `child` that has value `possibleParentValue`. Returns _undefined_ if not found.
|
|
3374
|
-
* @param child Child being sought
|
|
3375
|
-
* @param possibleParentValue Value of possible parent of child
|
|
3376
|
-
* @param eq Equality comparison function {@link isEqualDefault} used by default
|
|
3377
|
-
* @param maxDepth Maximum depth of traversal. Default of 0 only looks for immediate parent.
|
|
3378
|
-
* @returns
|
|
3379
|
-
*/
|
|
3380
|
-
const findParentByValue = (child, possibleParentValue, eq = isEqualDefault, maxDepth = 0) => {
|
|
3381
|
-
if (maxDepth < 0) return;
|
|
3382
|
-
const p = `getParent` in child ? child.getParent() : child.parent;
|
|
3383
|
-
if (p === void 0) return;
|
|
3384
|
-
if (eq(`getValue` in p ? p.getValue() : p.value, possibleParentValue)) return p;
|
|
3385
|
-
return findParentByValue(p, possibleParentValue, eq, maxDepth - 1);
|
|
3386
|
-
};
|
|
3387
|
-
/**
|
|
3388
|
-
* Returns _true_ if `prospectiveChild` can be legally added to `parent`.
|
|
3389
|
-
* _False_ is returned if:
|
|
3390
|
-
* * `parent` and `prospectiveChild` are equal
|
|
3391
|
-
* * `parent` already contains `prospectiveChild`
|
|
3392
|
-
* * `prospectiveChild` has `parent` as its own child
|
|
3393
|
-
*
|
|
3394
|
-
* Throws an error if `parent` or `prospectiveChild` is null/undefined.
|
|
3395
|
-
* @param parent Parent to add to
|
|
3396
|
-
* @param prospectiveChild Prospective child
|
|
3397
|
-
* @param eq Equality function
|
|
3398
|
-
*/
|
|
3399
|
-
const couldAddChild = (parent, prospectiveChild, eq = isEqualDefault) => {
|
|
3400
|
-
if (eq(parent, prospectiveChild)) throw new Error(`Child equals parent`);
|
|
3401
|
-
if (hasAnyChild(parent, prospectiveChild, eq)) throw new Error(`Circular. Parent already has child`);
|
|
3402
|
-
if (hasAnyChild(prospectiveChild, parent, eq)) throw new Error(`Prospective child has parent as child relation`);
|
|
3403
|
-
};
|
|
3404
|
-
/**
|
|
3405
|
-
* Returns _true_ if _possibleChild_ is contained within _parent_ tree.
|
|
3406
|
-
* That is, it is any sub-child.
|
|
3407
|
-
* @param parent Parent tree
|
|
3408
|
-
* @param possibleChild Sought child
|
|
3409
|
-
* @param eq Equality function, or {@link isEqualDefault} if undefined.
|
|
3410
|
-
* @returns
|
|
3411
|
-
*/
|
|
3412
|
-
const hasAnyChild = (parent, possibleChild, eq = isEqualDefault) => {
|
|
3413
|
-
return hasChild(parent, possibleChild, eq, Number.MAX_SAFE_INTEGER);
|
|
3414
|
-
};
|
|
3415
|
-
/**
|
|
3416
|
-
* Returns _true_ if `parent` has any child with value `possibleChildValue`. It explores
|
|
3417
|
-
* at children at any depth from `parent`.
|
|
3418
|
-
* @param parent
|
|
3419
|
-
* @param possibleChildValue
|
|
3420
|
-
* @param eq
|
|
3421
|
-
* @returns
|
|
3422
|
-
*/
|
|
3423
|
-
const hasAnyChildValue = (parent, possibleChildValue, eq = isEqualDefault) => {
|
|
3424
|
-
return hasChildValue(parent, possibleChildValue, eq, Number.MAX_SAFE_INTEGER);
|
|
3425
|
-
};
|
|
3426
|
-
/**
|
|
3427
|
-
* Returns _true_ if _possibleChild_ is contained within _maxDepth_ children
|
|
3428
|
-
* of _parent_ node. By default only looks at immediate children (maxDepth = 0).
|
|
3429
|
-
*
|
|
3430
|
-
* ```js
|
|
3431
|
-
* // Just check parentNode for childNode
|
|
3432
|
-
* Trees.hasChild(parentNode, childNode);
|
|
3433
|
-
* // See if parentNode or parentNode's parents have childNode
|
|
3434
|
-
* Trees.hasChild(parentNode, childNode, 1);
|
|
3435
|
-
* // Use custom equality function, in this case comparing on name field
|
|
3436
|
-
* Trees.hasChild(parentNode, childNode, 0, (a, b) => a.name === b.name);
|
|
3437
|
-
* ```
|
|
3438
|
-
* @param parent Parent tree
|
|
3439
|
-
* @param possibleChild Sought child
|
|
3440
|
-
* @param maxDepth Maximum depth. 0 for immediate children, Number.MAX_SAFE_INTEGER for boundless
|
|
3441
|
-
* @param eq Equality function, or {@link isEqualDefault} if undefined.
|
|
3442
|
-
* @returns
|
|
3443
|
-
*/
|
|
3444
|
-
const hasChild = (parent, possibleChild, eq = isEqualDefault, maxDepth = 0) => {
|
|
3445
|
-
if (maxDepth < 0) return false;
|
|
3446
|
-
if (eq(parent, possibleChild)) return true;
|
|
3447
|
-
const pId = `getIdentity` in parent ? parent.getIdentity() : parent.value;
|
|
3448
|
-
const pcId = `getIdentity` in possibleChild ? possibleChild.getIdentity() : possibleChild.value;
|
|
3449
|
-
if (eq(pId, pcId)) return true;
|
|
3450
|
-
for (const c of breadthFirst$1(parent, maxDepth)) {
|
|
3451
|
-
const cId = `getIdentity` in c ? c.getIdentity() : c.value;
|
|
3452
|
-
if (eq(c, possibleChild)) return true;
|
|
3453
|
-
if (eq(cId, pcId)) return true;
|
|
3454
|
-
}
|
|
3455
|
-
return false;
|
|
3456
|
-
};
|
|
3457
|
-
/**
|
|
3458
|
-
* Returns _true_ if `parent` has any child with value `possibleChildValue`. It explores
|
|
3459
|
-
* at children up to `maxDepth` from `parent`. By default only looks at immediate children (maxDepth = 0).
|
|
3460
|
-
* @param parent
|
|
3461
|
-
* @param possibleValue
|
|
3462
|
-
* @param eq
|
|
3463
|
-
* @param maxDepth
|
|
3464
|
-
* @returns
|
|
3465
|
-
*/
|
|
3466
|
-
const hasChildValue = (parent, possibleValue, eq = isEqualDefault, maxDepth = 0) => {
|
|
3467
|
-
if (maxDepth < 0) return false;
|
|
3468
|
-
if (eq(parent.getValue(), possibleValue)) return true;
|
|
3469
|
-
for (const c of breadthFirst$1(parent, maxDepth)) if (eq(c.getValue(), possibleValue)) return true;
|
|
3470
|
-
return false;
|
|
3471
|
-
};
|
|
3472
|
-
/**
|
|
3473
|
-
* Iterates over siblings of `node`.
|
|
3474
|
-
*
|
|
3475
|
-
* Other iteration options:
|
|
3476
|
-
* * {@link breadthFirst}: Children, breadth-first
|
|
3477
|
-
* * {@link depthFirst}: Children, depth-first
|
|
3478
|
-
* * {@link parents}: Chain of parents, starting with immediate parent
|
|
3479
|
-
* * {@link siblings}: Nodes with same parent
|
|
3480
|
-
* @param node Node to begin from
|
|
3481
|
-
* @returns
|
|
3482
|
-
*/
|
|
3483
|
-
function* siblings(node) {
|
|
3484
|
-
const p = node.getParent();
|
|
3485
|
-
if (p === void 0) return;
|
|
3486
|
-
for (const s of p.children()) {
|
|
3487
|
-
if (s === node) continue;
|
|
3488
|
-
yield s;
|
|
3489
|
-
}
|
|
3490
|
-
}
|
|
3491
|
-
/**
|
|
3492
|
-
* Iterates over parents of `node`, starting with immediate parent
|
|
3493
|
-
*
|
|
3494
|
-
* Other iteration options:
|
|
3495
|
-
* * {@link breadthFirst}: Children, breadth-first
|
|
3496
|
-
* * {@link depthFirst}: Children, depth-first
|
|
3497
|
-
* * {@link parents}: Chain of parents, starting with immediate parent
|
|
3498
|
-
* * {@link siblings}: Nodes with same parent
|
|
3499
|
-
* @param node Node to begin from
|
|
3500
|
-
* @returns
|
|
3501
|
-
*/
|
|
3502
|
-
function* parents(node) {
|
|
3503
|
-
if (isTraversable(node)) {
|
|
3504
|
-
let p = node.getParent();
|
|
3505
|
-
while (p !== void 0) {
|
|
3506
|
-
yield p;
|
|
3507
|
-
p = p.getParent();
|
|
3508
|
-
}
|
|
3509
|
-
} else {
|
|
3510
|
-
let p = node.parent;
|
|
3511
|
-
while (p !== void 0) {
|
|
3512
|
-
yield p;
|
|
3513
|
-
p = p.parent;
|
|
3514
|
-
}
|
|
3515
|
-
}
|
|
3516
|
-
}
|
|
3517
|
-
/**
|
|
3518
|
-
* Descends `parent`, breadth-first, looking for a particular value.
|
|
3519
|
-
* Returns _undefined_ if not found.
|
|
3520
|
-
* @param parent
|
|
3521
|
-
* @param possibleValue
|
|
3522
|
-
* @param eq
|
|
3523
|
-
* @returns
|
|
3524
|
-
*/
|
|
3525
|
-
function findAnyChildByValue(parent, possibleValue, eq = isEqualDefault) {
|
|
3526
|
-
return findChildByValue(parent, possibleValue, eq, Number.MAX_SAFE_INTEGER);
|
|
3527
|
-
}
|
|
3528
|
-
/**
|
|
3529
|
-
* Searches breadth-first for `possibleValue` under and including `parent`.
|
|
3530
|
-
* `maxDepth` sets he maximum level to which the tree is searched.
|
|
3531
|
-
* @param parent
|
|
3532
|
-
* @param possibleValue
|
|
3533
|
-
* @param eq
|
|
3534
|
-
* @param maxDepth
|
|
3535
|
-
* @returns
|
|
3536
|
-
*/
|
|
3537
|
-
function findChildByValue(parent, possibleValue, eq = isEqualDefault, maxDepth = 0) {
|
|
3538
|
-
if (maxDepth < 0) return;
|
|
3539
|
-
const isTraver = isTraversable(parent);
|
|
3540
|
-
if (isTraver) {
|
|
3541
|
-
if (eq(parent.getValue(), possibleValue)) return parent;
|
|
3542
|
-
} else if (eq(parent.value, possibleValue)) return parent;
|
|
3543
|
-
for (const d of breadthFirst$1(parent, maxDepth)) if (isTraver) {
|
|
3544
|
-
if (eq(d.getValue(), possibleValue)) return d;
|
|
3545
|
-
} else if (eq(d.value, possibleValue)) return d;
|
|
3546
|
-
}
|
|
3547
|
-
/**
|
|
3548
|
-
* Iterates over children of `root`, depth-first.
|
|
3549
|
-
*
|
|
3550
|
-
* Other iteration options:
|
|
3551
|
-
* * {@link breadthFirst}: Children, breadth-first
|
|
3552
|
-
* * {@link depthFirst}: Children, depth-first
|
|
3553
|
-
* * {@link parents}: Chain of parents, starting with immediate parent
|
|
3554
|
-
* * {@link siblings}: Nodes with same parent
|
|
3555
|
-
* @param root Root node
|
|
3556
|
-
* @returns
|
|
3557
|
-
*/
|
|
3558
|
-
function* depthFirst$1(root) {
|
|
3559
|
-
if (!root) return;
|
|
3560
|
-
const stack = new StackMutable();
|
|
3561
|
-
let entry = root;
|
|
3562
|
-
while (entry) {
|
|
3563
|
-
const entries = isTraversable(entry) ? [...entry.children()] : [...entry.childrenStore];
|
|
3564
|
-
stack.push(...entries);
|
|
3565
|
-
if (stack.isEmpty) break;
|
|
3566
|
-
entry = stack.pop();
|
|
3567
|
-
if (entry) yield entry;
|
|
3568
|
-
}
|
|
3569
|
-
}
|
|
3570
|
-
/**
|
|
3571
|
-
* Iterates over the children of `root`, breadth-first
|
|
3572
|
-
*
|
|
3573
|
-
* Other iteration options:
|
|
3574
|
-
* * {@link breadthFirst}: Children, breadth-first
|
|
3575
|
-
* * {@link depthFirst}: Children, depth-first
|
|
3576
|
-
* * {@link parents}: Chain of parents, starting with immediate parent
|
|
3577
|
-
* * {@link siblings}: Nodes with same parent
|
|
3578
|
-
*
|
|
3579
|
-
* @example Traversing over a simple object
|
|
3580
|
-
* ```js
|
|
3581
|
-
* const myObj = { name: `Pedro`, size: 45, colour: `orange` };
|
|
3582
|
-
* const root = Trees.FromObject.asDynamicTraversable(myObj);
|
|
3583
|
-
* for (const v of Trees.Traverse.breadthFirst(root)) {
|
|
3584
|
-
* // v.getValue() yields:
|
|
3585
|
-
* // { name: 'name', sourceValue: 'Pedro' ...},
|
|
3586
|
-
* // { name: 'size', sourceValue: 45 ... }
|
|
3587
|
-
* // ...
|
|
3588
|
-
* }
|
|
3589
|
-
* ```
|
|
3590
|
-
* @param root Root node
|
|
3591
|
-
* @param depth How many levels to traverse
|
|
3592
|
-
* @returns
|
|
3593
|
-
*/
|
|
3594
|
-
function* breadthFirst$1(root, depth = Number.MAX_SAFE_INTEGER) {
|
|
3595
|
-
if (!root) return;
|
|
3596
|
-
const queue = isTraversable(root) ? new QueueMutable() : new QueueMutable();
|
|
3597
|
-
let entry = root;
|
|
3598
|
-
while (entry) {
|
|
3599
|
-
if (depth < 0) return;
|
|
3600
|
-
if (entry !== void 0) {
|
|
3601
|
-
const kids = `childrenStore` in entry ? entry.childrenStore : entry.children();
|
|
3602
|
-
for (const c of kids) {
|
|
3603
|
-
yield c;
|
|
3604
|
-
queue.enqueue(c);
|
|
3605
|
-
}
|
|
3606
|
-
}
|
|
3607
|
-
entry = queue.dequeue();
|
|
3608
|
-
depth--;
|
|
3609
|
-
}
|
|
3610
|
-
}
|
|
3611
|
-
/**
|
|
3612
|
-
* Applies `predicate` to `root` and all its child nodes, returning the node where
|
|
3613
|
-
* `predicate` yields _true_.
|
|
3614
|
-
* Use {@link findByValue} to find a node by its value
|
|
3615
|
-
* @param root
|
|
3616
|
-
* @param predicate
|
|
3617
|
-
* @param order Iterate children by breadth or depth. Default 'breadth'
|
|
3618
|
-
* @returns
|
|
3619
|
-
*/
|
|
3620
|
-
function find$2(root, predicate, order = `breadth`) {
|
|
3621
|
-
if (predicate(root)) return root;
|
|
3622
|
-
const iter = order === `breadth` ? breadthFirst$1 : depthFirst$1;
|
|
3623
|
-
for (const c of iter(root)) if (predicate(c)) return c;
|
|
3624
|
-
}
|
|
3625
|
-
/**
|
|
3626
|
-
* Applies `predicate` to `root` and all its child nodes, returning the node value for
|
|
3627
|
-
* `predicate` yields _true_.
|
|
3628
|
-
* Use {@link find} to filter by nodes rather than values
|
|
3629
|
-
*
|
|
3630
|
-
* ```js
|
|
3631
|
-
* const n = findByValue(root, (v) => v.name === 'Bob');
|
|
3632
|
-
* ```
|
|
3633
|
-
* @param root
|
|
3634
|
-
* @param predicate
|
|
3635
|
-
* @param order Iterate children by breadth or depth. Default 'breadth'
|
|
3636
|
-
* @returns
|
|
3637
|
-
*/
|
|
3638
|
-
function findByValue(root, predicate, order = `breadth`) {
|
|
3639
|
-
if (predicate(root.getValue())) return root;
|
|
3640
|
-
const iter = order === `breadth` ? breadthFirst$1 : depthFirst$1;
|
|
3641
|
-
for (const c of iter(root)) if (predicate(c.getValue())) return c;
|
|
3642
|
-
}
|
|
3643
|
-
/**
|
|
3644
|
-
* Search through children in a path-like manner.
|
|
3645
|
-
*
|
|
3646
|
-
* It finds the first child of `root` that matches `continuePredicate`.
|
|
3647
|
-
* The function gets passed a depth of 1 to begin with. It recurses, looking for the next sub-child, etc.
|
|
3648
|
-
*
|
|
3649
|
-
* If it can't find a child, it stops.
|
|
3650
|
-
*
|
|
3651
|
-
* This is different to 'find' functions, which exhaustively search all possible child nodes, regardless of position in tree.
|
|
3652
|
-
*
|
|
3653
|
-
* ```js
|
|
3654
|
-
* const path = 'a.aa.aaa'.split('.');
|
|
3655
|
-
* const pred = (nodeValue, depth) => {
|
|
3656
|
-
* if (nodeValue === path[0]) {
|
|
3657
|
-
* path.shift(); // Remove first element
|
|
3658
|
-
* return true;
|
|
3659
|
-
* }
|
|
3660
|
-
* return false;
|
|
3661
|
-
* }
|
|
3662
|
-
*
|
|
3663
|
-
* // Assuming we have a tree of string values:
|
|
3664
|
-
* // a
|
|
3665
|
-
* // - aa
|
|
3666
|
-
* // - aaa
|
|
3667
|
-
* // - ab
|
|
3668
|
-
* // b
|
|
3669
|
-
* // - ba
|
|
3670
|
-
* for (const c of follow(tree, pred)) {
|
|
3671
|
-
* // Returns nodes: a, aa and then aaa
|
|
3672
|
-
* }
|
|
3673
|
-
* ```
|
|
3674
|
-
* @param root
|
|
3675
|
-
* @param continuePredicate
|
|
3676
|
-
* @param depth
|
|
3677
|
-
*/
|
|
3678
|
-
function* followValue(root, continuePredicate, depth = 1) {
|
|
3679
|
-
for (const c of root.children()) if (continuePredicate(c.getValue(), depth)) {
|
|
3680
|
-
yield c.getValue();
|
|
3681
|
-
yield* followValue(c, continuePredicate, depth + 1);
|
|
3682
|
-
}
|
|
3683
|
-
}
|
|
3684
|
-
function toStringDeep$1(node, depth = 0) {
|
|
3685
|
-
if (node === void 0) return `(undefined)`;
|
|
3686
|
-
if (node === null) return `(null)`;
|
|
3687
|
-
const v = node.getValue();
|
|
3688
|
-
let type = typeof v;
|
|
3689
|
-
if (Array.isArray(v)) type = `array`;
|
|
3690
|
-
let t = ` `.repeat(depth) + `value: ${JSON.stringify(v)} (${type})\n`;
|
|
3691
|
-
for (const n of node.children()) t += toStringDeep$1(n, depth + 1);
|
|
3692
|
-
return t;
|
|
3693
|
-
}
|
|
3694
|
-
function toString(...nodes) {
|
|
3695
|
-
let t = ``;
|
|
3696
|
-
for (const node of nodes) {
|
|
3697
|
-
const v = node.getValue();
|
|
3698
|
-
const vString = toStringAbbreviate(v);
|
|
3699
|
-
const children = [...node.children()];
|
|
3700
|
-
const parent = node.getParent();
|
|
3701
|
-
let type = typeof v;
|
|
3702
|
-
if (Array.isArray(v)) type = `array`;
|
|
3703
|
-
t += `value: ${vString} (${type}) kids: ${children.length} parented: ${parent ? `y` : `n`}\n`;
|
|
3704
|
-
}
|
|
3705
|
-
return t;
|
|
3706
|
-
}
|
|
3707
|
-
var binary_tree_exports = /* @__PURE__ */ __exportAll({
|
|
3708
|
-
addLeft: () => addLeft,
|
|
3709
|
-
addRight: () => addRight,
|
|
3710
|
-
balanceFactor: () => balanceFactor,
|
|
3711
|
-
breadthFirst: () => breadthFirst,
|
|
3712
|
-
createNode: () => createNode,
|
|
3713
|
-
depthFirst: () => depthFirst,
|
|
3714
|
-
find: () => find$1,
|
|
3715
|
-
fromArray: () => fromArray$1,
|
|
3716
|
-
getLeft: () => getLeft,
|
|
3717
|
-
getRight: () => getRight,
|
|
3718
|
-
grandparent: () => grandparent,
|
|
3719
|
-
hasLeft: () => hasLeft,
|
|
3720
|
-
hasRight: () => hasRight,
|
|
3721
|
-
height: () => height,
|
|
3722
|
-
inOrder: () => inOrder$1,
|
|
3723
|
-
isLeaf: () => isLeaf,
|
|
3724
|
-
isParentLeftChild: () => isParentLeftChild,
|
|
3725
|
-
isParentRightChild: () => isParentRightChild,
|
|
3726
|
-
leftSubtreeHeightFn: () => leftSubtreeHeightFn,
|
|
3727
|
-
parentChildSide: () => parentChildSide,
|
|
3728
|
-
postOrder: () => postOrder$1,
|
|
3729
|
-
preOrder: () => preOrder$1,
|
|
3730
|
-
removeNode: () => removeNode,
|
|
3731
|
-
rightSubtreeHeightFn: () => rightSubtreeHeightFn,
|
|
3732
|
-
root: () => root$1,
|
|
3733
|
-
rootWrapped: () => rootWrapped,
|
|
3734
|
-
setLeft: () => setLeft,
|
|
3735
|
-
setRight: () => setRight,
|
|
3736
|
-
sibling: () => sibling,
|
|
3737
|
-
toArray: () => toArray,
|
|
3738
|
-
toStringDeep: () => toStringDeep,
|
|
3739
|
-
uncle: () => uncle,
|
|
3740
|
-
wrap: () => wrap
|
|
3741
|
-
});
|
|
3742
|
-
const getLeftChild = (node) => {
|
|
3743
|
-
return node.childrenStore[0];
|
|
3744
|
-
};
|
|
3745
|
-
const getRightChild = (node) => {
|
|
3746
|
-
return node.childrenStore[1];
|
|
3747
|
-
};
|
|
3748
|
-
const getLeft = (node) => {
|
|
3749
|
-
return getLeftChild(node);
|
|
3750
|
-
};
|
|
3751
|
-
const getRight = (node) => {
|
|
3752
|
-
return getRightChild(node);
|
|
3753
|
-
};
|
|
3754
|
-
const hasLeft = (node) => {
|
|
3755
|
-
return getLeftChild(node) !== void 0;
|
|
3756
|
-
};
|
|
3757
|
-
const hasRight = (node) => {
|
|
3758
|
-
return getRightChild(node) !== void 0;
|
|
3759
|
-
};
|
|
3760
|
-
const isLeaf = (node) => {
|
|
3761
|
-
return !hasLeft(node) && !hasRight(node);
|
|
3762
|
-
};
|
|
3763
|
-
const setLeft = (parent, child) => {
|
|
3764
|
-
const existingLeft = getLeftChild(parent);
|
|
3765
|
-
if (existingLeft) existingLeft.parent = void 0;
|
|
3766
|
-
const children = [...parent.childrenStore];
|
|
3767
|
-
if (child === void 0 && children.length <= 1) {
|
|
3768
|
-
parent.childrenStore = [];
|
|
3769
|
-
return;
|
|
3770
|
-
} else if (child === void 0) {
|
|
3771
|
-
children[0] = void 0;
|
|
3772
|
-
parent.childrenStore = children;
|
|
3773
|
-
return;
|
|
3774
|
-
}
|
|
3775
|
-
if (children.length === 0) children.push(child);
|
|
3776
|
-
else children[0] = child;
|
|
3777
|
-
parent.childrenStore = children;
|
|
3778
|
-
child.parent = parent;
|
|
3779
|
-
};
|
|
3780
|
-
const setRight = (parent, child) => {
|
|
3781
|
-
const existingRight = getRightChild(parent);
|
|
3782
|
-
if (existingRight) existingRight.parent = void 0;
|
|
3783
|
-
const children = [...parent.childrenStore];
|
|
3784
|
-
if (child === void 0) {
|
|
3785
|
-
if (children.length >= 2) {
|
|
3786
|
-
children[1] = void 0;
|
|
3787
|
-
if (children[0] === void 0) parent.childrenStore = [];
|
|
3788
|
-
else parent.childrenStore = children;
|
|
3789
|
-
}
|
|
3790
|
-
return;
|
|
3791
|
-
}
|
|
3792
|
-
if (children.length === 0) children.push(void 0, child);
|
|
3793
|
-
else if (children.length === 1) children.push(child);
|
|
3794
|
-
else children[1] = child;
|
|
3795
|
-
parent.childrenStore = children;
|
|
3796
|
-
child.parent = parent;
|
|
3797
|
-
};
|
|
3798
|
-
const removeNode = (node) => {
|
|
3799
|
-
const p = node.parent;
|
|
3800
|
-
if (!p) return;
|
|
3801
|
-
if (p.childrenStore[0] === node) setLeft(p, void 0);
|
|
3802
|
-
else if (p.childrenStore[1] === node) setRight(p, void 0);
|
|
3803
|
-
};
|
|
3804
|
-
const sibling = (node) => {
|
|
3805
|
-
const parent = node.parent;
|
|
3806
|
-
if (!parent) return void 0;
|
|
3807
|
-
const left = getLeftChild(parent);
|
|
3808
|
-
const right = getRightChild(parent);
|
|
3809
|
-
if (left === node) return right;
|
|
3810
|
-
if (right === node) return left;
|
|
3811
|
-
};
|
|
3812
|
-
const uncle = (node) => {
|
|
3813
|
-
const parent = node.parent;
|
|
3814
|
-
if (!parent) return void 0;
|
|
3815
|
-
return sibling(parent);
|
|
3816
|
-
};
|
|
3817
|
-
const grandparent = (node) => {
|
|
3818
|
-
const parent = node.parent;
|
|
3819
|
-
if (!parent) return void 0;
|
|
3820
|
-
return parent.parent;
|
|
3821
|
-
};
|
|
3822
|
-
const isParentLeftChild = (node) => {
|
|
3823
|
-
const parent = node.parent;
|
|
3824
|
-
if (!parent) return false;
|
|
3825
|
-
return getLeftChild(parent) === node;
|
|
3826
|
-
};
|
|
3827
|
-
const isParentRightChild = (node) => {
|
|
3828
|
-
const parent = node.parent;
|
|
3829
|
-
if (!parent) return false;
|
|
3830
|
-
return getRightChild(parent) === node;
|
|
3831
|
-
};
|
|
3832
|
-
const parentChildSide = (node) => {
|
|
3833
|
-
if (!node.parent) return `neutral`;
|
|
3834
|
-
return isParentLeftChild(node) ? `left` : `right`;
|
|
3835
|
-
};
|
|
3836
|
-
const leftSubtreeHeight = (node) => {
|
|
3837
|
-
const left = getLeftChild(node);
|
|
3838
|
-
return left ? subtreeHeight(left) + 1 : 0;
|
|
3839
|
-
};
|
|
3840
|
-
const rightSubtreeHeight = (node) => {
|
|
3841
|
-
const right = getRightChild(node);
|
|
3842
|
-
return right ? subtreeHeight(right) + 1 : 0;
|
|
3843
|
-
};
|
|
3844
|
-
const subtreeHeight = (node) => {
|
|
3845
|
-
return Math.max(leftSubtreeHeight(node), rightSubtreeHeight(node));
|
|
3846
|
-
};
|
|
3847
|
-
const height = (node) => {
|
|
3848
|
-
return subtreeHeight(node);
|
|
3849
|
-
};
|
|
3850
|
-
const balanceFactor = (node) => {
|
|
3851
|
-
return leftSubtreeHeight(node) - rightSubtreeHeight(node);
|
|
3852
|
-
};
|
|
3853
|
-
const leftSubtreeHeightFn = leftSubtreeHeight;
|
|
3854
|
-
const rightSubtreeHeightFn = rightSubtreeHeight;
|
|
3855
|
-
const addLeft = (value, parent) => {
|
|
3856
|
-
const existingLeft = getLeftChild(parent);
|
|
3857
|
-
if (existingLeft) existingLeft.parent = void 0;
|
|
3858
|
-
const child = {
|
|
3859
|
-
value,
|
|
3860
|
-
parent,
|
|
3861
|
-
childrenStore: []
|
|
3862
|
-
};
|
|
3863
|
-
const children = [...parent.childrenStore];
|
|
3864
|
-
if (children.length === 0) children.push(child);
|
|
3865
|
-
else if (children.length === 1) children[0] = child;
|
|
3866
|
-
else children[0] = child;
|
|
3867
|
-
parent.childrenStore = children;
|
|
3868
|
-
return child;
|
|
3869
|
-
};
|
|
3870
|
-
const addRight = (value, parent) => {
|
|
3871
|
-
const existingRight = getRightChild(parent);
|
|
3872
|
-
if (existingRight) existingRight.parent = void 0;
|
|
3873
|
-
const child = {
|
|
3874
|
-
value,
|
|
3875
|
-
parent,
|
|
3876
|
-
childrenStore: []
|
|
3877
|
-
};
|
|
3878
|
-
const children = [...parent.childrenStore];
|
|
3879
|
-
if (children.length === 0) {
|
|
3880
|
-
children.push(void 0);
|
|
3881
|
-
children.push(child);
|
|
3882
|
-
} else if (children.length === 1) children.push(child);
|
|
3883
|
-
else children[1] = child;
|
|
3884
|
-
parent.childrenStore = children;
|
|
3885
|
-
return child;
|
|
3886
|
-
};
|
|
3887
|
-
const root$1 = (value) => {
|
|
3888
|
-
return root$2(value);
|
|
3889
|
-
};
|
|
3890
|
-
const createNode = (value, parent) => {
|
|
3891
|
-
return createNode$1(value, parent);
|
|
3892
|
-
};
|
|
3893
|
-
const unwrapNode = (node) => {
|
|
3894
|
-
return `node` in node ? node.node : node;
|
|
3895
|
-
};
|
|
3896
|
-
const wrapNode = (node) => {
|
|
3897
|
-
return wrap(node);
|
|
3898
|
-
};
|
|
3899
|
-
const wrap = (node) => {
|
|
3900
|
-
return {
|
|
3901
|
-
node,
|
|
3902
|
-
get left() {
|
|
3903
|
-
const left = getLeftChild(node);
|
|
3904
|
-
return left ? wrapNode(left) : void 0;
|
|
3905
|
-
},
|
|
3906
|
-
get right() {
|
|
3907
|
-
const right = getRightChild(node);
|
|
3908
|
-
return right ? wrapNode(right) : void 0;
|
|
3909
|
-
},
|
|
3910
|
-
set left(value) {
|
|
3911
|
-
setLeft(node, value ? unwrapNode(value) : void 0);
|
|
3912
|
-
},
|
|
3913
|
-
set right(value) {
|
|
3914
|
-
setRight(node, value ? unwrapNode(value) : void 0);
|
|
3915
|
-
},
|
|
3916
|
-
get parentChildSide() {
|
|
3917
|
-
return parentChildSide(node);
|
|
3918
|
-
},
|
|
3919
|
-
get isParentLeftChild() {
|
|
3920
|
-
return isParentLeftChild(node);
|
|
3921
|
-
},
|
|
3922
|
-
get isParentRightChild() {
|
|
3923
|
-
return isParentRightChild(node);
|
|
3924
|
-
},
|
|
3925
|
-
get isLeaf() {
|
|
3926
|
-
return isLeaf(node);
|
|
3927
|
-
},
|
|
3928
|
-
get sibling() {
|
|
3929
|
-
const sib = sibling(node);
|
|
3930
|
-
return sib ? wrapNode(sib) : void 0;
|
|
3931
|
-
},
|
|
3932
|
-
get uncle() {
|
|
3933
|
-
const unc = uncle(node);
|
|
3934
|
-
return unc ? wrapNode(unc) : void 0;
|
|
3935
|
-
},
|
|
3936
|
-
get grandparent() {
|
|
3937
|
-
const gp = grandparent(node);
|
|
3938
|
-
return gp ? wrapNode(gp) : void 0;
|
|
3939
|
-
},
|
|
3940
|
-
get leftSubtreeHeight() {
|
|
3941
|
-
return leftSubtreeHeight(node);
|
|
3942
|
-
},
|
|
3943
|
-
get rightSubtreeHeight() {
|
|
3944
|
-
return rightSubtreeHeight(node);
|
|
3945
|
-
},
|
|
3946
|
-
get height() {
|
|
3947
|
-
return height(node);
|
|
3948
|
-
},
|
|
3949
|
-
get balanceFactor() {
|
|
3950
|
-
return balanceFactor(node);
|
|
3951
|
-
},
|
|
3952
|
-
has(value) {
|
|
3953
|
-
return find$1(node, value) !== void 0;
|
|
3954
|
-
},
|
|
3955
|
-
addLeft(value) {
|
|
3956
|
-
return wrapNode(addLeft(value, node));
|
|
3957
|
-
},
|
|
3958
|
-
addRight(value) {
|
|
3959
|
-
return wrapNode(addRight(value, node));
|
|
3960
|
-
},
|
|
3961
|
-
setLeft(nodeOrWrapped) {
|
|
3962
|
-
setLeft(node, unwrapNode(nodeOrWrapped));
|
|
3963
|
-
},
|
|
3964
|
-
setRight(nodeOrWrapped) {
|
|
3965
|
-
setRight(node, unwrapNode(nodeOrWrapped));
|
|
3966
|
-
},
|
|
3967
|
-
remove() {
|
|
3968
|
-
removeNode(node);
|
|
3969
|
-
}
|
|
3970
|
-
};
|
|
3971
|
-
};
|
|
3972
|
-
const rootWrapped = (value) => {
|
|
3973
|
-
return wrap(root$2(value));
|
|
3974
|
-
};
|
|
3975
|
-
const find$1 = (root, value) => {
|
|
3976
|
-
for (const n of breadthFirst(root)) if (n.value === value) return n;
|
|
3977
|
-
};
|
|
3978
|
-
function* inOrder$1(node) {
|
|
3979
|
-
const left = getLeftChild(node);
|
|
3980
|
-
if (left) yield* inOrder$1(left);
|
|
3981
|
-
yield node;
|
|
3982
|
-
const right = getRightChild(node);
|
|
3983
|
-
if (right) yield* inOrder$1(right);
|
|
3984
|
-
}
|
|
3985
|
-
function* preOrder$1(node) {
|
|
3986
|
-
yield node;
|
|
3987
|
-
const left = getLeftChild(node);
|
|
3988
|
-
if (left) yield* preOrder$1(left);
|
|
3989
|
-
const right = getRightChild(node);
|
|
3990
|
-
if (right) yield* preOrder$1(right);
|
|
3991
|
-
}
|
|
3992
|
-
function* postOrder$1(node) {
|
|
3993
|
-
const left = getLeftChild(node);
|
|
3994
|
-
if (left) yield* postOrder$1(left);
|
|
3995
|
-
const right = getRightChild(node);
|
|
3996
|
-
if (right) yield* postOrder$1(right);
|
|
3997
|
-
yield node;
|
|
3998
|
-
}
|
|
3999
|
-
function* depthFirst(node) {
|
|
4000
|
-
const left = getLeftChild(node);
|
|
4001
|
-
const right = getRightChild(node);
|
|
4002
|
-
if (left) yield* depthFirst(left);
|
|
4003
|
-
if (right) yield* depthFirst(right);
|
|
4004
|
-
yield node;
|
|
4005
|
-
}
|
|
4006
|
-
function* breadthFirst(node) {
|
|
4007
|
-
yield node;
|
|
4008
|
-
const queue = [];
|
|
4009
|
-
queue.push(...node.childrenStore.filter((c) => c !== void 0 && c.value !== void 0));
|
|
4010
|
-
while (queue.length > 0) {
|
|
4011
|
-
const current = queue.shift();
|
|
4012
|
-
yield current;
|
|
4013
|
-
queue.push(...current.childrenStore.filter((c) => c !== void 0 && c.value !== void 0));
|
|
4014
|
-
}
|
|
4015
|
-
}
|
|
4016
|
-
const fromArray$1 = (array) => {
|
|
4017
|
-
if (array.length === 0) return void 0;
|
|
4018
|
-
const rootNode = root$2(array[0]);
|
|
4019
|
-
const insert = (index, parent) => {
|
|
4020
|
-
const leftIdx = 2 * index + 1;
|
|
4021
|
-
const rightIdx = 2 * index + 2;
|
|
4022
|
-
if (leftIdx < array.length) {
|
|
4023
|
-
addLeft(array[leftIdx], parent);
|
|
4024
|
-
insert(leftIdx, getLeftChild(parent));
|
|
4025
|
-
}
|
|
4026
|
-
if (rightIdx < array.length) {
|
|
4027
|
-
addRight(array[rightIdx], parent);
|
|
4028
|
-
insert(rightIdx, getRightChild(parent));
|
|
4029
|
-
}
|
|
4030
|
-
};
|
|
4031
|
-
insert(0, rootNode);
|
|
4032
|
-
return rootNode;
|
|
4033
|
-
};
|
|
4034
|
-
const toArray = (root) => {
|
|
4035
|
-
const result = [];
|
|
4036
|
-
for (const node of breadthFirst(root)) if (node.value !== void 0) result.push(node.value);
|
|
4037
|
-
return result;
|
|
4038
|
-
};
|
|
4039
|
-
const toStringDeep = (node, indent = 0) => {
|
|
4040
|
-
const v = node.value !== void 0 ? JSON.stringify(node.value) : `-`;
|
|
4041
|
-
const prefix = ` `.repeat(indent);
|
|
4042
|
-
const left = getLeftChild(node);
|
|
4043
|
-
const right = getRightChild(node);
|
|
4044
|
-
let result = `${prefix}${v}`;
|
|
4045
|
-
if (left || right) {
|
|
4046
|
-
result += `\n`;
|
|
4047
|
-
if (left) {
|
|
4048
|
-
result += `${prefix} L: ${toStringDeep(left, indent + 1)}`;
|
|
4049
|
-
if (right) result += `\n`;
|
|
4050
|
-
}
|
|
4051
|
-
if (right) result += `${prefix} R: ${toStringDeep(right, indent + 1)}`;
|
|
4052
|
-
}
|
|
4053
|
-
return result;
|
|
4054
|
-
};
|
|
4055
|
-
var binary_search_tree_exports = /* @__PURE__ */ __exportAll({
|
|
4056
|
-
Bst: () => Bst,
|
|
4057
|
-
create: () => create,
|
|
4058
|
-
find: () => find,
|
|
4059
|
-
fromArray: () => fromArray,
|
|
4060
|
-
has: () => has,
|
|
4061
|
-
inOrder: () => inOrder,
|
|
4062
|
-
insert: () => insert,
|
|
4063
|
-
max: () => max,
|
|
4064
|
-
min: () => min,
|
|
4065
|
-
postOrder: () => postOrder,
|
|
4066
|
-
preOrder: () => preOrder,
|
|
4067
|
-
remove: () => remove,
|
|
4068
|
-
root: () => root,
|
|
4069
|
-
valuesInOrder: () => valuesInOrder
|
|
4070
|
-
});
|
|
4071
|
-
var Bst = class {
|
|
4072
|
-
root;
|
|
4073
|
-
comparer;
|
|
4074
|
-
constructor(comparer = defaultComparer) {
|
|
4075
|
-
this.comparer = comparer;
|
|
4076
|
-
this.root = root$1();
|
|
4077
|
-
}
|
|
4078
|
-
insert(value) {
|
|
4079
|
-
this.root = insert(this.root, value, this.comparer);
|
|
4080
|
-
return this.root;
|
|
4081
|
-
}
|
|
4082
|
-
has(value) {
|
|
4083
|
-
return has(this.root, value, this.comparer);
|
|
4084
|
-
}
|
|
4085
|
-
find(value) {
|
|
4086
|
-
return find(this.root, value, this.comparer);
|
|
4087
|
-
}
|
|
4088
|
-
remove(value) {
|
|
4089
|
-
const result = remove(this.root, value, this.comparer);
|
|
4090
|
-
if (result) this.root = result;
|
|
4091
|
-
return result !== void 0;
|
|
4092
|
-
}
|
|
4093
|
-
min() {
|
|
4094
|
-
return min(this.root);
|
|
4095
|
-
}
|
|
4096
|
-
max() {
|
|
4097
|
-
return max(this.root);
|
|
4098
|
-
}
|
|
4099
|
-
inOrder() {
|
|
4100
|
-
return inOrder(this.root);
|
|
4101
|
-
}
|
|
4102
|
-
preOrder() {
|
|
4103
|
-
return preOrder(this.root);
|
|
4104
|
-
}
|
|
4105
|
-
postOrder() {
|
|
4106
|
-
return postOrder(this.root);
|
|
4107
|
-
}
|
|
4108
|
-
valuesInOrder() {
|
|
4109
|
-
return valuesInOrder(this.root);
|
|
4110
|
-
}
|
|
4111
|
-
toArrayInOrder() {
|
|
4112
|
-
return Array.from(this.valuesInOrder());
|
|
4113
|
-
}
|
|
4114
|
-
};
|
|
4115
|
-
const insert = (root, value, compare = defaultComparer) => {
|
|
4116
|
-
if (root.value === void 0) {
|
|
4117
|
-
root.value = value;
|
|
4118
|
-
return root;
|
|
4119
|
-
}
|
|
4120
|
-
let current = root;
|
|
4121
|
-
while (true) {
|
|
4122
|
-
const cmp = compare(value, current.value);
|
|
4123
|
-
if (cmp < 0) {
|
|
4124
|
-
const left = getLeft(current);
|
|
4125
|
-
if (left) current = left;
|
|
4126
|
-
else {
|
|
4127
|
-
addLeft(value, current);
|
|
4128
|
-
break;
|
|
4129
|
-
}
|
|
4130
|
-
} else if (cmp > 0) {
|
|
4131
|
-
const right = getRight(current);
|
|
4132
|
-
if (right) current = right;
|
|
4133
|
-
else {
|
|
4134
|
-
addRight(value, current);
|
|
4135
|
-
break;
|
|
4136
|
-
}
|
|
4137
|
-
} else break;
|
|
4138
|
-
}
|
|
4139
|
-
return root;
|
|
4140
|
-
};
|
|
4141
|
-
const has = (root, value, compare = defaultComparer) => {
|
|
4142
|
-
return find(root, value, compare) !== void 0;
|
|
4143
|
-
};
|
|
4144
|
-
const find = (root, value, compare = defaultComparer) => {
|
|
4145
|
-
if (!root || root.value === void 0) return void 0;
|
|
4146
|
-
const cmp = compare(value, root.value);
|
|
4147
|
-
if (cmp === 0) return root;
|
|
4148
|
-
else if (cmp < 0) {
|
|
4149
|
-
const left = getLeft(root);
|
|
4150
|
-
return left ? find(left, value, compare) : void 0;
|
|
4151
|
-
} else {
|
|
4152
|
-
const right = getRight(root);
|
|
4153
|
-
return right ? find(right, value, compare) : void 0;
|
|
1415
|
+
${primaryIcon}${primaryLabel}
|
|
1416
|
+
</button>
|
|
1417
|
+
<ixfx-menu-trigger .registry=${this.registry} .keyboardManager=${this.keyboardManager}>
|
|
1418
|
+
${this._renderCaret(`chevron-right`, `Choose action`)}
|
|
1419
|
+
<ixfx-menu-container slot="menu">
|
|
1420
|
+
${popupItems}
|
|
1421
|
+
</ixfx-menu-container>
|
|
1422
|
+
</ixfx-menu-trigger>
|
|
1423
|
+
</div>
|
|
1424
|
+
`;
|
|
4154
1425
|
}
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
}
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
}
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
* @param node
|
|
4276
|
-
* @returns
|
|
4277
|
-
*/
|
|
4278
|
-
const isTreeNode = (node) => {
|
|
4279
|
-
if (`parent` in node && `childrenStore` in node && `value` in node) {
|
|
4280
|
-
if (Array.isArray(node.childrenStore)) return true;
|
|
1426
|
+
static {
|
|
1427
|
+
this.styles = [
|
|
1428
|
+
themeFallbacks,
|
|
1429
|
+
prominenceStyles,
|
|
1430
|
+
buttonStyles,
|
|
1431
|
+
css`
|
|
1432
|
+
:host {
|
|
1433
|
+
display: inline-flex;
|
|
1434
|
+
max-width: 100%;
|
|
1435
|
+
vertical-align: middle;
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
slot.switcher-data {
|
|
1439
|
+
display: none;
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
.split {
|
|
1443
|
+
display: inline-flex;
|
|
1444
|
+
width: 100%;
|
|
1445
|
+
background: var(--surface-3, #ccc);
|
|
1446
|
+
color: var(--surface-3-text, #000);
|
|
1447
|
+
border: var(--border, 1px solid #999);
|
|
1448
|
+
border-radius: var(--radius-xl, 8px);
|
|
1449
|
+
corner-shape: superellipse(1);
|
|
1450
|
+
box-shadow:
|
|
1451
|
+
inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-4) 30%, transparent),
|
|
1452
|
+
inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 20%, transparent),
|
|
1453
|
+
2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 30%, transparent);
|
|
1454
|
+
overflow: hidden;
|
|
1455
|
+
transition: background var(--transition, 0.2s), border-color var(--transition, 0.2s);
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
/* Switcher: accent the caret separator to signal "this changes the default" */
|
|
1459
|
+
.split.switcher button.caret {
|
|
1460
|
+
border-inline-start-color: var(--accent, #666);
|
|
1461
|
+
opacity: 0.7;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
.split.switcher button.caret:hover:not(:disabled) {
|
|
1465
|
+
opacity: 1;
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
/* Caret is dimmed when there is no popup content */
|
|
1469
|
+
button.caret[data-empty] {
|
|
1470
|
+
opacity: 0.3;
|
|
1471
|
+
pointer-events: none;
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
.split:has(button:hover:not(:disabled)) {
|
|
1475
|
+
border-color: var(--accent, #666);
|
|
1476
|
+
box-shadow:
|
|
1477
|
+
inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-5) 70%, transparent),
|
|
1478
|
+
inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 60%, transparent),
|
|
1479
|
+
2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 90%, transparent);
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
.split:has(button:active:not(:disabled)) {
|
|
1483
|
+
transform: translateY(1px);
|
|
1484
|
+
box-shadow: inset 1px 1px 0px 0.5px color-mix(in oklch, var(--surface-1), transparent);
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
button.primary,
|
|
1488
|
+
button.caret {
|
|
1489
|
+
border: none;
|
|
1490
|
+
border-radius: 0;
|
|
1491
|
+
background: none;
|
|
1492
|
+
box-shadow: none;
|
|
1493
|
+
color: inherit;
|
|
1494
|
+
margin: 0;
|
|
1495
|
+
cursor: pointer;
|
|
1496
|
+
display: inline-flex;
|
|
1497
|
+
align-items: center;
|
|
1498
|
+
justify-content: center;
|
|
1499
|
+
transition: background var(--transition, 0.2s), opacity var(--transition, 0.2s);
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
button.primary {
|
|
1503
|
+
flex: 1;
|
|
1504
|
+
padding: var(--space-m, 8px) var(--space-l, 12px);
|
|
1505
|
+
gap: 0.5em;
|
|
1506
|
+
overflow: hidden;
|
|
1507
|
+
white-space: nowrap;
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
button.caret {
|
|
1511
|
+
padding: var(--space-m, 8px) var(--space-s, 6px);
|
|
1512
|
+
border-inline-start: var(--border, 1px solid #999);
|
|
1513
|
+
flex-shrink: 0;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
button.primary:hover:not(:disabled),
|
|
1517
|
+
button.caret:hover:not(:disabled) {
|
|
1518
|
+
background: color-mix(in oklch, var(--surface-4) 80%, transparent);
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
button.primary:active:not(:disabled),
|
|
1522
|
+
button.caret:active:not(:disabled) {
|
|
1523
|
+
background: var(--surface-2, #aaa);
|
|
1524
|
+
transform: none;
|
|
1525
|
+
box-shadow: none;
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
button.primary:disabled,
|
|
1529
|
+
button.caret:disabled {
|
|
1530
|
+
opacity: 0.5;
|
|
1531
|
+
cursor: not-allowed;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
button.primary:focus-visible,
|
|
1535
|
+
button.caret:focus-visible {
|
|
1536
|
+
outline: 2px solid var(--accent, #666);
|
|
1537
|
+
outline-offset: -2px;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
ixfx-menu-trigger {
|
|
1541
|
+
display: inline-flex;
|
|
1542
|
+
align-items: stretch;
|
|
1543
|
+
}
|
|
1544
|
+
`
|
|
1545
|
+
];
|
|
4281
1546
|
}
|
|
4282
|
-
return false;
|
|
4283
|
-
};
|
|
4284
|
-
/**
|
|
4285
|
-
* Checks if `node` is of type {@link TraversableTree}.
|
|
4286
|
-
*
|
|
4287
|
-
* Checks by looking for: children, getParent, getValue and getIdentity defined on `node`.
|
|
4288
|
-
* @param node
|
|
4289
|
-
* @returns
|
|
4290
|
-
*/
|
|
4291
|
-
const isTraversable = (node) => {
|
|
4292
|
-
return `children` in node && `getParent` in node && `getValue` in node && `getIdentity` in node;
|
|
4293
1547
|
};
|
|
1548
|
+
__decorate([property({ attribute: false })], SplitButton.prototype, "registry", void 0);
|
|
1549
|
+
__decorate([property({ attribute: false })], SplitButton.prototype, "keyboardManager", void 0);
|
|
1550
|
+
__decorate([property({ type: String })], SplitButton.prototype, "mode", void 0);
|
|
1551
|
+
__decorate([property({
|
|
1552
|
+
type: String,
|
|
1553
|
+
attribute: `default-value`
|
|
1554
|
+
})], SplitButton.prototype, "defaultValue", void 0);
|
|
1555
|
+
__decorate([property({ attribute: false })], SplitButton.prototype, "itemsProvider", void 0);
|
|
1556
|
+
__decorate([property({ attribute: false })], SplitButton.prototype, "items", void 0);
|
|
1557
|
+
__decorate([query(`ixfx-menu-trigger`)], SplitButton.prototype, "_menuTrigger", void 0);
|
|
1558
|
+
__decorate([state()], SplitButton.prototype, "_compact", void 0);
|
|
1559
|
+
__decorate([state()], SplitButton.prototype, "_selectedCommand", void 0);
|
|
1560
|
+
__decorate([state()], SplitButton.prototype, "_selectedLabel", void 0);
|
|
1561
|
+
__decorate([state()], SplitButton.prototype, "_selectedIcon", void 0);
|
|
1562
|
+
__decorate([state()], SplitButton.prototype, "_switcherItems", void 0);
|
|
1563
|
+
__decorate([state()], SplitButton.prototype, "_dynamicItems", void 0);
|
|
1564
|
+
__decorate([state()], SplitButton.prototype, "_loadingItems", void 0);
|
|
1565
|
+
__decorate([state()], SplitButton.prototype, "_menuHasItems", void 0);
|
|
1566
|
+
SplitButton = __decorate([safeCustomElement(`ixfx-split-button`)], SplitButton);
|
|
4294
1567
|
//#endregion
|
|
4295
1568
|
//#region src/crumbs/crumb-path-controller.ts
|
|
4296
1569
|
var CrumbPathController = class {
|
|
@@ -4301,7 +1574,7 @@ var CrumbPathController = class {
|
|
|
4301
1574
|
constructor(options = {}) {
|
|
4302
1575
|
this.#separator = options.separator ?? `/`;
|
|
4303
1576
|
this.#onQuery = options.onQuery;
|
|
4304
|
-
this.#pathed = new
|
|
1577
|
+
this.#pathed = new Trees.Pathed.Pathed({ separator: this.#separator });
|
|
4305
1578
|
if (options.paths) this.addPaths(options.paths);
|
|
4306
1579
|
}
|
|
4307
1580
|
get separator() {
|
|
@@ -4410,7 +1683,6 @@ let CrumbPathElement = class CrumbPathElement extends LitElement {
|
|
|
4410
1683
|
case `Escape`:
|
|
4411
1684
|
e.preventDefault();
|
|
4412
1685
|
this.#closeDropdown();
|
|
4413
|
-
break;
|
|
4414
1686
|
}
|
|
4415
1687
|
};
|
|
4416
1688
|
this.#onHostKeyDown = (e) => {
|
|
@@ -4749,9 +2021,11 @@ let CrumbPathElement = class CrumbPathElement extends LitElement {
|
|
|
4749
2021
|
#onHostKeyDown;
|
|
4750
2022
|
render() {
|
|
4751
2023
|
const segments = this.#getSegments();
|
|
4752
|
-
if (this._editing)
|
|
2024
|
+
if (this._editing) {
|
|
2025
|
+
const editValue = this.path;
|
|
2026
|
+
return html`
|
|
4753
2027
|
<ixfx-ac-text
|
|
4754
|
-
.value=${
|
|
2028
|
+
.value=${editValue}
|
|
4755
2029
|
.tabSuffix=${this.separator}
|
|
4756
2030
|
.completionProvider=${this.#makeCompletionProvider()}
|
|
4757
2031
|
@change=${this.#onAcChange}
|
|
@@ -4759,6 +2033,7 @@ let CrumbPathElement = class CrumbPathElement extends LitElement {
|
|
|
4759
2033
|
@keydown=${this.#onAcKeyDown}
|
|
4760
2034
|
></ixfx-ac-text>
|
|
4761
2035
|
`;
|
|
2036
|
+
}
|
|
4762
2037
|
const rootSegments = this.#getRootSegments();
|
|
4763
2038
|
const leadingCaret = this.siblingLookup && rootSegments.length === 0 ? html`
|
|
4764
2039
|
<div class="caret ${this._openIdx === -1 ? `open` : ``} ${this._confirmedLeafIndices.has(``) ? `disabled` : ``}"
|
|
@@ -4986,7 +2261,7 @@ CrumbPathElement = __decorate([safeCustomElement(`ixfx-crumb-path`)], CrumbPathE
|
|
|
4986
2261
|
//#endregion
|
|
4987
2262
|
//#region src/editable-label/editable-number.ts
|
|
4988
2263
|
const DRAG_THRESHOLD_PX = 3;
|
|
4989
|
-
let EditableNumber = class EditableNumber extends EditableLabel {
|
|
2264
|
+
let EditableNumber = class EditableNumber extends WheelNudgeMixin(EditableLabel) {
|
|
4990
2265
|
#dragStartY;
|
|
4991
2266
|
#dragStartValue;
|
|
4992
2267
|
#dragging;
|
|
@@ -5239,14 +2514,15 @@ let EditableNumber = class EditableNumber extends EditableLabel {
|
|
|
5239
2514
|
this.style.setProperty(`--value`, String(normalized));
|
|
5240
2515
|
let valueStart = 0;
|
|
5241
2516
|
let valueEnd = normalized;
|
|
5242
|
-
if (this.linearStyle === `bipolar`)
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
2517
|
+
if (this.linearStyle === `bipolar`) {
|
|
2518
|
+
if (normalized <= .5) {
|
|
2519
|
+
valueStart = normalized;
|
|
2520
|
+
valueEnd = .5;
|
|
2521
|
+
} else {
|
|
2522
|
+
valueStart = .5;
|
|
2523
|
+
valueEnd = normalized;
|
|
2524
|
+
}
|
|
2525
|
+
} else if (this.linearStyle === `unipolar`) {
|
|
5250
2526
|
valueStart = .5 - normalized * .5;
|
|
5251
2527
|
valueEnd = .5 + normalized * .5;
|
|
5252
2528
|
}
|
|
@@ -5288,8 +2564,7 @@ let EditableNumber = class EditableNumber extends EditableLabel {
|
|
|
5288
2564
|
_handleArrowKey(e) {
|
|
5289
2565
|
const range = (this.max ?? 100) - (this.min ?? 0);
|
|
5290
2566
|
if (range === 0) return false;
|
|
5291
|
-
const
|
|
5292
|
-
const effectiveStep = resolveStep(range, void 0, this.step) / shiftDivisor;
|
|
2567
|
+
const effectiveStep = resolveAxisStep(range, this.stops, this.step, e.shiftKey);
|
|
5293
2568
|
let delta = 0;
|
|
5294
2569
|
let handled = false;
|
|
5295
2570
|
switch (e.key) {
|
|
@@ -5310,33 +2585,49 @@ let EditableNumber = class EditableNumber extends EditableLabel {
|
|
|
5310
2585
|
case `End`:
|
|
5311
2586
|
delta = (this.max ?? 0) - this._parseValue();
|
|
5312
2587
|
handled = true;
|
|
5313
|
-
break;
|
|
5314
2588
|
}
|
|
5315
2589
|
if (handled) {
|
|
5316
2590
|
e.preventDefault();
|
|
5317
|
-
|
|
5318
|
-
const current = this._parseValue();
|
|
5319
|
-
const newValue = this._clamp(this._snap(current + delta));
|
|
5320
|
-
const newValueStr = this.step !== void 0 ? this._formatNumber(newValue) : newValue.toFixed(this.precision);
|
|
5321
|
-
this.value = newValueStr;
|
|
5322
|
-
this._requestDisplayUpdate();
|
|
5323
|
-
this._updateValueCss(this._normalizedValue(newValue));
|
|
5324
|
-
if (newValueStr !== prev) this.dispatchEvent(new CustomEvent(`input`, {
|
|
5325
|
-
detail: { value: newValueStr },
|
|
5326
|
-
bubbles: true,
|
|
5327
|
-
composed: true
|
|
5328
|
-
}));
|
|
5329
|
-
requestAnimationFrame(() => {
|
|
5330
|
-
if (this.value !== prev) this.dispatchEvent(new CustomEvent(`change`, {
|
|
5331
|
-
detail: { value: this.value },
|
|
5332
|
-
bubbles: true,
|
|
5333
|
-
composed: true
|
|
5334
|
-
}));
|
|
5335
|
-
});
|
|
2591
|
+
this._applyDelta(delta);
|
|
5336
2592
|
return true;
|
|
5337
2593
|
}
|
|
5338
2594
|
return false;
|
|
5339
2595
|
}
|
|
2596
|
+
/**
|
|
2597
|
+
* Apply a signed delta to the current value, clamp/snap/format, and fire
|
|
2598
|
+
* `input`/`change`. Shared between arrow-key handler and the wheel handler.
|
|
2599
|
+
*/
|
|
2600
|
+
_applyDelta(delta) {
|
|
2601
|
+
const prev = this.value;
|
|
2602
|
+
const current = this._parseValue();
|
|
2603
|
+
const newValue = this._clamp(this._snap(current + delta));
|
|
2604
|
+
const newValueStr = this.step !== void 0 ? this._formatNumber(newValue) : newValue.toFixed(this.precision);
|
|
2605
|
+
this.value = newValueStr;
|
|
2606
|
+
this._requestDisplayUpdate();
|
|
2607
|
+
this._updateValueCss(this._normalizedValue(newValue));
|
|
2608
|
+
if (newValueStr !== prev) this.dispatchEvent(new CustomEvent(`input`, {
|
|
2609
|
+
detail: { value: newValueStr },
|
|
2610
|
+
bubbles: true,
|
|
2611
|
+
composed: true
|
|
2612
|
+
}));
|
|
2613
|
+
requestAnimationFrame(() => {
|
|
2614
|
+
if (this.value !== prev) this.dispatchEvent(new CustomEvent(`change`, {
|
|
2615
|
+
detail: { value: this.value },
|
|
2616
|
+
bubbles: true,
|
|
2617
|
+
composed: true
|
|
2618
|
+
}));
|
|
2619
|
+
});
|
|
2620
|
+
}
|
|
2621
|
+
_shouldHandleWheel() {
|
|
2622
|
+
if (this._editing) return false;
|
|
2623
|
+
return super._shouldHandleWheel();
|
|
2624
|
+
}
|
|
2625
|
+
_applyWheelDelta(direction, event) {
|
|
2626
|
+
const range = (this.max ?? 100) - (this.min ?? 0);
|
|
2627
|
+
if (range === 0) return;
|
|
2628
|
+
const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);
|
|
2629
|
+
this._applyDelta(direction * effectiveStep);
|
|
2630
|
+
}
|
|
5340
2631
|
_parseValue() {
|
|
5341
2632
|
return Number.parseFloat(this.value) || 0;
|
|
5342
2633
|
}
|
|
@@ -5359,6 +2650,11 @@ let EditableNumber = class EditableNumber extends EditableLabel {
|
|
|
5359
2650
|
return n;
|
|
5360
2651
|
}
|
|
5361
2652
|
_snap(n) {
|
|
2653
|
+
if (this.stops && this.stops > 1) {
|
|
2654
|
+
const min = this.min ?? 0;
|
|
2655
|
+
const stopStep = ((this.max ?? 100) - min) / this.stops;
|
|
2656
|
+
return Math.round((n - min) / stopStep) * stopStep + min;
|
|
2657
|
+
}
|
|
5362
2658
|
if (!this.step) return n;
|
|
5363
2659
|
return Math.round(n / this.step) * this.step;
|
|
5364
2660
|
}
|
|
@@ -5549,6 +2845,7 @@ let EditableNumber = class EditableNumber extends EditableLabel {
|
|
|
5549
2845
|
__decorate([property({ type: Number })], EditableNumber.prototype, "min", void 0);
|
|
5550
2846
|
__decorate([property({ type: Number })], EditableNumber.prototype, "max", void 0);
|
|
5551
2847
|
__decorate([property({ type: Number })], EditableNumber.prototype, "step", void 0);
|
|
2848
|
+
__decorate([property({ type: Number })], EditableNumber.prototype, "stops", void 0);
|
|
5552
2849
|
__decorate([property({
|
|
5553
2850
|
type: Number,
|
|
5554
2851
|
attribute: `drag-sensitivity`
|
|
@@ -5971,9 +3268,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
5971
3268
|
}
|
|
5972
3269
|
break;
|
|
5973
3270
|
}
|
|
5974
|
-
case `Escape`:
|
|
5975
|
-
this._clearSelection();
|
|
5976
|
-
break;
|
|
3271
|
+
case `Escape`: this._clearSelection();
|
|
5977
3272
|
}
|
|
5978
3273
|
};
|
|
5979
3274
|
this._onClick = (e) => {
|
|
@@ -6142,7 +3437,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
6142
3437
|
_replaceSelection(item) {
|
|
6143
3438
|
if (this.selectionMode === `none`) return;
|
|
6144
3439
|
const previous = this._selectedItems;
|
|
6145
|
-
const next = new Set([item]);
|
|
3440
|
+
const next = /* @__PURE__ */ new Set([item]);
|
|
6146
3441
|
this._selectedItems = next;
|
|
6147
3442
|
this.#selectionAnchor = item;
|
|
6148
3443
|
this._syncItemStates();
|
|
@@ -6229,7 +3524,7 @@ let VerticalListElement = class VerticalListElement extends LitElement {
|
|
|
6229
3524
|
} else if (e.shiftKey && (this.selectionMode === `multiple` || mode === `vscode`)) this._rangeSelectTo(item);
|
|
6230
3525
|
else this._replaceSelection(item);
|
|
6231
3526
|
break;
|
|
6232
|
-
case `checked`:
|
|
3527
|
+
case `checked`:
|
|
6233
3528
|
}
|
|
6234
3529
|
}
|
|
6235
3530
|
_handleSpaceKey(item) {
|
|
@@ -6867,11 +4162,13 @@ let RangeMultiElement = class RangeMultiElement extends LitElement {
|
|
|
6867
4162
|
}
|
|
6868
4163
|
a = newA;
|
|
6869
4164
|
b = newB;
|
|
6870
|
-
} else if (which === `a`)
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
else b
|
|
6874
|
-
|
|
4165
|
+
} else if (which === `a`) {
|
|
4166
|
+
if (v > this.b && this.crossover === `stop`) t.valueAsNumber = this.#scaleTo100(this.a);
|
|
4167
|
+
else a = v;
|
|
4168
|
+
} else if (which === `b`) {
|
|
4169
|
+
if (v < a && this.crossover === `stop`) t.valueAsNumber = this.#scaleTo100(this.b);
|
|
4170
|
+
else b = v;
|
|
4171
|
+
} else throw new Error(`Expected 'a' or 'b', got: '${t.id}'`);
|
|
6875
4172
|
this.setPoles(a, b);
|
|
6876
4173
|
}
|
|
6877
4174
|
setPoles(a, b) {
|
|
@@ -6930,63 +4227,65 @@ let RangeMultiElement = class RangeMultiElement extends LitElement {
|
|
|
6930
4227
|
const currentPos = isVertical ? current.offset.y : current.offset.x;
|
|
6931
4228
|
const amt = (isVertical ? startPos - currentPos : currentPos - startPos) / valuePerPix;
|
|
6932
4229
|
polesChanged = true;
|
|
6933
|
-
if (draggingWhich === `a`)
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
4230
|
+
if (draggingWhich === `a`) {
|
|
4231
|
+
if (resizeMode === `bipolar`) {
|
|
4232
|
+
const calcA = startA + amt;
|
|
4233
|
+
const calcB = startB - amt;
|
|
4234
|
+
if (calcA < min || calcB > max || calcA > max || calcB < min) return;
|
|
4235
|
+
setPoles(calcA, calcB);
|
|
4236
|
+
} else if (resizeMode === `bipolar-flex`) {
|
|
4237
|
+
let calcA = startA + amt;
|
|
4238
|
+
let calcB = startB;
|
|
4239
|
+
if (startB <= min) calcB = min;
|
|
4240
|
+
else if (startB >= max) calcB = max;
|
|
4241
|
+
else {
|
|
4242
|
+
calcA = startA + amt;
|
|
4243
|
+
calcB = startB - amt;
|
|
4244
|
+
}
|
|
4245
|
+
if (calcA < min) calcA = min;
|
|
4246
|
+
if (calcA > max) calcA = max;
|
|
4247
|
+
if (calcB < min) calcB = min;
|
|
4248
|
+
if (calcB > max) calcB = max;
|
|
4249
|
+
if (calcA > calcB) return;
|
|
4250
|
+
setPoles(calcA, calcB);
|
|
4251
|
+
} else {
|
|
4252
|
+
let constrainedAmt = amt;
|
|
4253
|
+
if (startA + amt < min) constrainedAmt = min - startA;
|
|
4254
|
+
if (startB + constrainedAmt > max) constrainedAmt = max - startB;
|
|
4255
|
+
const finalA = startA + constrainedAmt;
|
|
4256
|
+
const finalB = startB + constrainedAmt;
|
|
4257
|
+
if (finalA >= min && finalB <= max) setPoles(finalA, finalB);
|
|
6946
4258
|
}
|
|
6947
|
-
|
|
6948
|
-
if (
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
4259
|
+
} else if (draggingWhich === `b`) {
|
|
4260
|
+
if (resizeMode === `bipolar`) {
|
|
4261
|
+
const calcA = startA - amt;
|
|
4262
|
+
const calcB = startB + amt;
|
|
4263
|
+
if (calcA < min || calcB > max || calcA > max || calcB < min) return;
|
|
4264
|
+
setPoles(calcA, calcB);
|
|
4265
|
+
} else if (resizeMode === `bipolar-flex`) {
|
|
4266
|
+
let calcA = startA;
|
|
4267
|
+
let calcB = startB + amt;
|
|
4268
|
+
if (startA <= min) calcA = min;
|
|
4269
|
+
else if (startA >= max) calcA = max;
|
|
4270
|
+
else {
|
|
4271
|
+
calcA = startA - amt;
|
|
4272
|
+
calcB = startB + amt;
|
|
4273
|
+
}
|
|
4274
|
+
if (calcA < min) calcA = min;
|
|
4275
|
+
if (calcA > max) calcA = max;
|
|
4276
|
+
if (calcB < min) calcB = min;
|
|
4277
|
+
if (calcB > max) calcB = max;
|
|
4278
|
+
if (calcA > calcB) return;
|
|
4279
|
+
setPoles(calcA, calcB);
|
|
4280
|
+
} else {
|
|
4281
|
+
let constrainedAmt = amt;
|
|
4282
|
+
if (startA + amt < min) constrainedAmt = min - startA;
|
|
4283
|
+
if (startB + constrainedAmt > max) constrainedAmt = max - startB;
|
|
4284
|
+
const finalA = startA + constrainedAmt;
|
|
4285
|
+
const finalB = startB + constrainedAmt;
|
|
4286
|
+
if (finalA >= min && finalB <= max) setPoles(finalA, finalB);
|
|
6974
4287
|
}
|
|
6975
|
-
|
|
6976
|
-
if (calcA > max) calcA = max;
|
|
6977
|
-
if (calcB < min) calcB = min;
|
|
6978
|
-
if (calcB > max) calcB = max;
|
|
6979
|
-
if (calcA > calcB) return;
|
|
6980
|
-
setPoles(calcA, calcB);
|
|
6981
|
-
} else {
|
|
6982
|
-
let constrainedAmt = amt;
|
|
6983
|
-
if (startA + amt < min) constrainedAmt = min - startA;
|
|
6984
|
-
if (startB + constrainedAmt > max) constrainedAmt = max - startB;
|
|
6985
|
-
const finalA = startA + constrainedAmt;
|
|
6986
|
-
const finalB = startB + constrainedAmt;
|
|
6987
|
-
if (finalA >= min && finalB <= max) setPoles(finalA, finalB);
|
|
6988
|
-
}
|
|
6989
|
-
else if (resizeMode === `bipolar`) {
|
|
4288
|
+
} else if (resizeMode === `bipolar`) {
|
|
6990
4289
|
const calcA = startA + amt;
|
|
6991
4290
|
const calcB = startB + amt;
|
|
6992
4291
|
if (calcA < min || calcB > max) return;
|
|
@@ -7366,13 +4665,18 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
7366
4665
|
}
|
|
7367
4666
|
|
|
7368
4667
|
.toolbar {
|
|
7369
|
-
display:
|
|
4668
|
+
/* Always laid out (display: flex) so the tab's width doesn't shift when
|
|
4669
|
+
the toolbar appears on selection. visibility: hidden keeps the
|
|
4670
|
+
toolbar from receiving pointer events or painting, while preserving
|
|
4671
|
+
the space its contents take up. */
|
|
4672
|
+
display: flex;
|
|
7370
4673
|
align-items: center;
|
|
7371
4674
|
gap: var(--space-xs);
|
|
4675
|
+
visibility: hidden;
|
|
7372
4676
|
}
|
|
7373
4677
|
|
|
7374
4678
|
:host([selected]) .toolbar {
|
|
7375
|
-
|
|
4679
|
+
visibility: visible;
|
|
7376
4680
|
}
|
|
7377
4681
|
|
|
7378
4682
|
slot[name="toolbar"] {
|
|
@@ -7795,86 +5099,11 @@ function monitorIndeterminate(targetElOrQuery, watchedElsOrQueries) {
|
|
|
7795
5099
|
};
|
|
7796
5100
|
}
|
|
7797
5101
|
//#endregion
|
|
7798
|
-
//#region src/util/is-numeric.ts
|
|
7799
|
-
function isNumeric(str) {
|
|
7800
|
-
if (typeof str === `number`) return true;
|
|
7801
|
-
if (typeof str !== `string`) return false;
|
|
7802
|
-
const trimmed = str.trim();
|
|
7803
|
-
return trimmed !== `` && !Number.isNaN(Number(trimmed));
|
|
7804
|
-
}
|
|
7805
|
-
//#endregion
|
|
7806
|
-
//#region src/util/tooltip.ts
|
|
7807
|
-
var _TooltipElement;
|
|
7808
|
-
let TooltipElement = class TooltipElement extends LitElement {
|
|
7809
|
-
static {
|
|
7810
|
-
_TooltipElement = this;
|
|
7811
|
-
}
|
|
7812
|
-
constructor(..._args) {
|
|
7813
|
-
super(..._args);
|
|
7814
|
-
this.valueFormatTooltip = _TooltipElement.defaultFormatter;
|
|
7815
|
-
this.orientation = `top`;
|
|
7816
|
-
this.anchor = `--tooltip`;
|
|
7817
|
-
}
|
|
7818
|
-
static {
|
|
7819
|
-
this.numberFormatter = (v) => Math.floor(v).toString();
|
|
7820
|
-
}
|
|
7821
|
-
static {
|
|
7822
|
-
this.defaultFormatter = (v) => {
|
|
7823
|
-
if (typeof v === `number`) {
|
|
7824
|
-
if (Number.isInteger(v)) return v.toString();
|
|
7825
|
-
return v.toFixed(2);
|
|
7826
|
-
} else if (typeof v === `string`) return v;
|
|
7827
|
-
else return JSON.stringify(v);
|
|
7828
|
-
};
|
|
7829
|
-
}
|
|
7830
|
-
#renderIcon() {
|
|
7831
|
-
if (!this.icon) return nothing;
|
|
7832
|
-
if (this.icon.startsWith(`<svg`)) return html`<span class="tooltip-icon" style="display:inline-flex;align-items:center;margin-right:0.25em">${unsafeHTML(this.icon)}</span>`;
|
|
7833
|
-
if (!getIcon(this.icon)) return nothing;
|
|
7834
|
-
return html`<ixfx-icon class="tooltip-icon" style="margin-right:0.25em" name="${this.icon}"></ixfx-icon>`;
|
|
7835
|
-
}
|
|
7836
|
-
render() {
|
|
7837
|
-
const classes = {
|
|
7838
|
-
"tooltip": true,
|
|
7839
|
-
"tooltip-orientation-top": this.orientation === `top`,
|
|
7840
|
-
"tooltip-orientation-bottom": this.orientation === `bottom`,
|
|
7841
|
-
"tooltip-orientation-right": this.orientation === `right`,
|
|
7842
|
-
"tooltip-orientation-left": this.orientation === `left`,
|
|
7843
|
-
"tooltip-type-text": true,
|
|
7844
|
-
"tooltip-type-number": false,
|
|
7845
|
-
"tooltip-style-bubble": true
|
|
7846
|
-
};
|
|
7847
|
-
let value = ``;
|
|
7848
|
-
switch (typeof this.value) {
|
|
7849
|
-
case `number`:
|
|
7850
|
-
classes[`tooltip-type-number`] = true;
|
|
7851
|
-
value = this.valueFormatTooltip(this.value);
|
|
7852
|
-
break;
|
|
7853
|
-
case `string`:
|
|
7854
|
-
if (isNumeric(this.value)) {
|
|
7855
|
-
classes[`tooltip-type-number`] = true;
|
|
7856
|
-
value = this.valueFormatTooltip(Number.parseFloat(this.value));
|
|
7857
|
-
} else value = this.value;
|
|
7858
|
-
break;
|
|
7859
|
-
default: value = JSON.stringify(this.value);
|
|
7860
|
-
}
|
|
7861
|
-
return html`<output style="--anchor-id: ${this.anchor}" class=${classMap(classes)}>${this.#renderIcon()}${value}</output>`;
|
|
7862
|
-
}
|
|
7863
|
-
createRenderRoot() {
|
|
7864
|
-
return this;
|
|
7865
|
-
}
|
|
7866
|
-
};
|
|
7867
|
-
__decorate([property({ type: String })], TooltipElement.prototype, "orientation", void 0);
|
|
7868
|
-
__decorate([property({ type: String })], TooltipElement.prototype, "anchor", void 0);
|
|
7869
|
-
__decorate([property()], TooltipElement.prototype, "value", void 0);
|
|
7870
|
-
__decorate([property({ type: String })], TooltipElement.prototype, "icon", void 0);
|
|
7871
|
-
TooltipElement = _TooltipElement = __decorate([safeCustomElement(`ixfx-tooltip`)], TooltipElement);
|
|
7872
|
-
//#endregion
|
|
7873
5102
|
//#region src/index.ts
|
|
7874
5103
|
function init() {
|
|
7875
5104
|
console.log(`Init`);
|
|
7876
5105
|
}
|
|
7877
5106
|
//#endregion
|
|
7878
|
-
export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, EditableLabel, EditableNumber, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, SelectHorizontalElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, collectDataResult, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, createTreeListAdapter, createVerticalListAdapter, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
|
|
5107
|
+
export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, EditableLabel, EditableNumber, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, SelectHorizontalElement, SliderInputElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, collectDataResult, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, createTreeListAdapter, createVerticalListAdapter, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
|
|
7879
5108
|
|
|
7880
5109
|
//# sourceMappingURL=index.js.map
|