@dashfoo/core 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -12
- package/dist/index.d.ts +123 -123
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -10
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/state/node-attrs.ts","../src/state/actions.ts","../src/model/schema.ts","../src/model/builders.ts","../src/geometry/geometry.ts","../src/geometry/snap.ts","../src/state/history.ts","../src/model/ids.ts","../src/model/invariants.ts","../src/machines/dashfoo-machine.ts","../src/machines/drag-dock-machine.ts","../src/state/reducer.ts","../src/model/serialize.ts","../src/model/stack.ts","../src/model/tree.ts"],"mappings":";;;;;;cA8CM,wBAAsB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAEU,EAAA,KAAA;;;cC1ChC,oBAAkB,EAAA;;;;;;;cAUlB,cAAY,EAAA,uBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EhB,EAAA,KAAA;KAEG,eAAe,EAAE,aAAa;KAC9B,mBAAmB,EAAE,aAAa;KAClC,SAAS,EAAE,aAAa;KAExB;EAAe;EAAgB,UAAU;EAAc;;;;;cChGtD;KAED,+CAA+C,MAAM;GAAgB,cAAc;;cAElF,iBAAiB,EAAE,QAAQ;cAW3B,YAAU,EAAA;;;;;;cACV,YAAU,EAAA;;;;;;;;cACV,mBAAiB,EAAA;;;;cAEjB,iBAAe,EAAA;;;;;;;;;;GAGnB,EAAA,KAAA;cAEI,YAAU,EAAA;;;;GAId,EAAA,KAAA;cAEI,eAAa,EAAA;;;;;;;;;GASjB,EAAA,KAAA;;;;;cAMI,wBAAsB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAW1B,EAAA,KAAA;cAEI,kBAAgB,EAAA,QAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAMhB,eAAa,EAAA;EACD,UAAA,EAAE,SAAS,EAAE,iBAAiB,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUpE,EAAA,KAAA;KAEG,UAAU,EAAE,aAAa;KACzB,eAAe,EAAE,aAAa;cAE7B,gBAAc,EAAA;;;;;GAKlB,EAAA,KAAA;cAEI,iBAAe,EAAA;;;;;;;;;IAtBH,UAAA,EAAE,SAAS,EAAE,iBAAiB,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BpE,EAAA,KAAA;cAEI,wBAAsB,EAAA;;;;;;;;;;;;;;;;;;;GAY1B,EAAA,KAAA;cAEI,eAAa,EAAA;;;;;;;;;;;MA9CD,UAAA,EAAE,SAAS,EAAE,iBAAiB,sBAAsB
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/state/node-attrs.ts","../src/state/actions.ts","../src/model/schema.ts","../src/model/builders.ts","../src/geometry/geometry.ts","../src/geometry/snap.ts","../src/state/history.ts","../src/model/ids.ts","../src/model/invariants.ts","../src/machines/dashfoo-machine.ts","../src/machines/drag-dock-machine.ts","../src/state/reducer.ts","../src/model/serialize.ts","../src/model/stack.ts","../src/model/tree.ts"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -390,29 +390,31 @@ const tab = (component, name, options = {}) => ({
|
|
|
390
390
|
});
|
|
391
391
|
const tabset = (children, options = {}) => {
|
|
392
392
|
const { max, min, ...rest } = options;
|
|
393
|
-
|
|
393
|
+
const built = {
|
|
394
394
|
children,
|
|
395
395
|
type: "tabset",
|
|
396
396
|
...rest,
|
|
397
|
-
...max === void 0 ? {} : { max: toDimension(max) },
|
|
398
|
-
...min === void 0 ? {} : { min: toDimension(min) },
|
|
399
397
|
id: options.id ?? createNodeId("tabset"),
|
|
400
398
|
selected: clampSelected(children.length, options.selected ?? 0),
|
|
401
399
|
weight: options.weight ?? 1
|
|
402
400
|
};
|
|
401
|
+
if (max !== void 0) built.max = toDimension(max);
|
|
402
|
+
if (min !== void 0) built.min = toDimension(min);
|
|
403
|
+
return built;
|
|
403
404
|
};
|
|
404
405
|
const row = (children, options = {}) => {
|
|
405
406
|
const { max, min, ...rest } = options;
|
|
406
|
-
|
|
407
|
+
const built = {
|
|
407
408
|
children,
|
|
408
409
|
type: "row",
|
|
409
410
|
...rest,
|
|
410
|
-
...max === void 0 ? {} : { max: toDimension(max) },
|
|
411
|
-
...min === void 0 ? {} : { min: toDimension(min) },
|
|
412
411
|
id: options.id ?? createNodeId("row"),
|
|
413
412
|
orientation: options.orientation ?? "row",
|
|
414
413
|
weight: options.weight ?? 1
|
|
415
414
|
};
|
|
415
|
+
if (max !== void 0) built.max = toDimension(max);
|
|
416
|
+
if (min !== void 0) built.min = toDimension(min);
|
|
417
|
+
return built;
|
|
416
418
|
};
|
|
417
419
|
const floatNode = (layout, geometry, options = {}) => ({
|
|
418
420
|
geometry,
|
|
@@ -684,10 +686,10 @@ const settleSnap = (sizes, boundaryIndex, grid) => {
|
|
|
684
686
|
const inheritSlot = (row, survivor) => {
|
|
685
687
|
const sized = {
|
|
686
688
|
...survivor,
|
|
687
|
-
weight: row.weight
|
|
688
|
-
...row.min === void 0 ? {} : { min: row.min },
|
|
689
|
-
...row.max === void 0 ? {} : { max: row.max }
|
|
689
|
+
weight: row.weight
|
|
690
690
|
};
|
|
691
|
+
if (row.min !== void 0) sized.min = row.min;
|
|
692
|
+
if (row.max !== void 0) sized.max = row.max;
|
|
691
693
|
if (sized.type === "row" && row.snap !== void 0) return {
|
|
692
694
|
...sized,
|
|
693
695
|
snap: row.snap
|
|
@@ -1251,7 +1253,7 @@ const parseModel = (value) => {
|
|
|
1251
1253
|
return model;
|
|
1252
1254
|
};
|
|
1253
1255
|
const toJSON = (model) => JSON.stringify(model);
|
|
1254
|
-
const fromJSON = (json) => parseModel(JSON.parse(json));
|
|
1256
|
+
const fromJSON = (json) => parseModel(jsonValueSchema.parse(JSON.parse(json)));
|
|
1255
1257
|
|
|
1256
1258
|
//#endregion
|
|
1257
1259
|
//#region src/model/stack.ts
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/lib/clamp-selected.ts","../src/model/schema.ts","../src/state/node-attrs.ts","../src/state/actions.ts","../src/model/ids.ts","../src/model/tree.ts","../src/model/builders.ts","../src/lib/assert-never.ts","../src/geometry/geometry.ts","../src/geometry/snap.ts","../src/model/invariants.ts","../src/state/surgery.ts","../src/state/floats.ts","../src/state/reducer.ts","../src/state/history.ts","../src/machines/dashfoo-machine.ts","../src/machines/drag-dock-machine.ts","../src/model/serialize.ts","../src/model/stack.ts"],"sourcesContent":["/** In `lib/` because both the parse boundary and `normalize` need it, and\n * importing it from either would close a module cycle. */\nconst clampSelected = (length: number, selected: number): number => {\n if (length === 0) {\n return 0;\n }\n\n const base = Number.isFinite(selected) ? Math.trunc(selected) : 0;\n if (base < 0) {\n return 0;\n }\n if (base > length - 1) {\n return length - 1;\n }\n return base;\n};\n\nexport { clampSelected };\n","import { z } from \"zod\";\n\nimport { clampSelected } from \"../lib/clamp-selected\";\n\n/** Weights are relative shares of a row, not percentages. */\nconst DEFAULT_WEIGHT = 1;\n\ntype JsonValue = string | number | boolean | null | Array<JsonValue> | { [key: string]: JsonValue };\n\nconst jsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(jsonValueSchema),\n z.record(z.string(), jsonValueSchema),\n ]),\n);\n\nconst edgeSchema = z.enum([\"top\", \"bottom\", \"left\", \"right\"]);\nconst unitSchema = z.enum([\"px\", \"%\", \"em\", \"rem\", \"vh\", \"vw\"]);\nconst orientationSchema = z.enum([\"row\", \"column\"]);\n\nconst dimensionSchema = z.object({\n unit: unitSchema,\n value: z.number(),\n});\n\nconst snapSchema = z.object({\n divisions: z.union([z.number().positive(), z.literal(\"panels\")]).optional(),\n step: z.number().min(0).optional(),\n threshold: z.number().positive().optional(),\n});\n\nconst tabNodeSchema = z.object({\n component: z.string(),\n config: jsonValueSchema.optional(),\n enableClose: z.boolean().optional(),\n enableDrag: z.boolean().optional(),\n enableRename: z.boolean().optional(),\n id: z.string(),\n name: z.string(),\n type: z.literal(\"tab\"),\n});\n\n/**\n * Kept pre-transform so `node-attrs` can `.pick()` from it: a pipe has no\n * `.pick`, and `.partial()` over a defaulted field still fills the default in.\n */\nconst tabsetNodeObjectSchema = z.object({\n children: z.array(tabNodeSchema),\n enableClose: z.boolean().optional(),\n enableMaximize: z.boolean().optional(),\n id: z.string(),\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n name: z.string().optional(),\n selected: z.number().int(),\n type: z.literal(\"tabset\"),\n weight: z.number().default(DEFAULT_WEIGHT),\n});\n\nconst tabsetNodeSchema = tabsetNodeObjectSchema.transform((tabset) => ({\n ...tabset,\n selected: clampSelected(tabset.children.length, tabset.selected),\n}));\n\n/** The getter's explicit return type is required: without it, TS7023. */\nconst rowNodeSchema = z.object({\n get children(): z.ZodArray<z.ZodUnion<[typeof rowNodeSchema, typeof tabsetNodeSchema]>> {\n return z.array(z.union([rowNodeSchema, tabsetNodeSchema]));\n },\n id: z.string(),\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n orientation: orientationSchema,\n snap: snapSchema.optional(),\n type: z.literal(\"row\"),\n weight: z.number().default(DEFAULT_WEIGHT),\n});\n\ntype RowNode = z.infer<typeof rowNodeSchema>;\ntype RowNodeInput = z.input<typeof rowNodeSchema>;\n\nconst geometrySchema = z.object({\n height: z.number(),\n left: z.number(),\n top: z.number(),\n width: z.number(),\n});\n\nconst floatNodeSchema = z.object({\n geometry: geometrySchema,\n id: z.string(),\n layout: rowNodeSchema,\n\n minimized: z.boolean().optional(),\n name: z.string().optional(),\n type: z.literal(\"float\"),\n});\n\nconst globalAttributesSchema = z.object({\n enableSplitDock: z.boolean().optional(),\n enableSplitResize: z.boolean().optional(),\n snap: snapSchema.optional(),\n splitterSize: z.number().optional(),\n tabEnableClose: z.boolean().optional(),\n tabEnableDrag: z.boolean().optional(),\n tabEnableRename: z.boolean().optional(),\n tabLocation: z.enum([\"top\", \"bottom\"]).optional(),\n tabSetEnableMaximize: z.boolean().optional(),\n tabSetEnableTabStrip: z.boolean().optional(),\n tabSetMinSize: z.number().optional(),\n});\n\nconst dashfooSchema = z.object({\n activeTabsetId: z.string().optional(),\n floats: z.array(floatNodeSchema).default(() => []),\n global: globalAttributesSchema,\n layout: rowNodeSchema,\n maximizedTabsetId: z.string().optional(),\n version: z.literal(1),\n});\n\ntype Json = JsonValue;\ntype Edge = z.infer<typeof edgeSchema>;\ntype Unit = z.infer<typeof unitSchema>;\ntype Orientation = z.infer<typeof orientationSchema>;\ntype Dimension = z.infer<typeof dimensionSchema>;\ntype SnapConfig = z.infer<typeof snapSchema>;\ntype TabNode = z.infer<typeof tabNodeSchema>;\ntype TabsetNode = z.infer<typeof tabsetNodeSchema>;\ntype Geometry = z.infer<typeof geometrySchema>;\ntype FloatNode = z.infer<typeof floatNodeSchema>;\ntype GlobalAttributes = z.infer<typeof globalAttributesSchema>;\ntype Dashfoo = z.infer<typeof dashfooSchema>;\n/** The loose shape `dashfooSchema` accepts: `weight` and `floats` may be omitted. */\ntype DashfooInput = z.input<typeof dashfooSchema>;\ntype Node = RowNode | TabsetNode | TabNode;\n\nexport {\n dashfooSchema,\n DEFAULT_WEIGHT,\n dimensionSchema,\n edgeSchema,\n floatNodeSchema,\n geometrySchema,\n globalAttributesSchema,\n jsonValueSchema,\n orientationSchema,\n rowNodeSchema,\n snapSchema,\n tabNodeSchema,\n tabsetNodeObjectSchema,\n tabsetNodeSchema,\n unitSchema,\n};\n\nexport type {\n Dashfoo,\n DashfooInput,\n Dimension,\n Edge,\n FloatNode,\n Geometry,\n GlobalAttributes,\n Json,\n Node,\n Orientation,\n RowNode,\n RowNodeInput,\n SnapConfig,\n TabNode,\n TabsetNode,\n Unit,\n};\n","import { z } from \"zod\";\n\nimport {\n dimensionSchema,\n orientationSchema,\n snapSchema,\n tabNodeSchema,\n tabsetNodeObjectSchema,\n} from \"../model/schema\";\n\nconst mutableTabAttrsSchema = tabNodeSchema\n .pick({\n config: true,\n enableClose: true,\n enableDrag: true,\n enableRename: true,\n name: true,\n })\n .partial();\n\n/** `weight` is re-declared, not picked: `.partial()` over a defaulted field still injects the default. */\nconst mutableTabsetAttrsSchema = tabsetNodeObjectSchema\n .pick({\n enableClose: true,\n enableMaximize: true,\n max: true,\n min: true,\n selected: true,\n })\n .extend({ weight: z.number() })\n .partial();\n\nconst mutableRowAttrsSchema = z\n .object({\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n orientation: orientationSchema,\n snap: snapSchema.optional(),\n weight: z.number(),\n })\n .partial();\n\n/**\n * Merged, not a union: a union of all-optional members matches its first member\n * and strips the rest. The reducer enforces which keys a given node accepts.\n */\nconst mutableNodeAttrsSchema = mutableTabAttrsSchema\n .extend(mutableTabsetAttrsSchema.shape)\n .extend(mutableRowAttrsSchema.shape);\n\nexport {\n mutableNodeAttrsSchema,\n mutableRowAttrsSchema,\n mutableTabAttrsSchema,\n mutableTabsetAttrsSchema,\n};\n","import { z } from \"zod\";\n\nimport { geometrySchema, globalAttributesSchema, tabNodeSchema } from \"../model/schema\";\n\nimport { mutableNodeAttrsSchema } from \"./node-attrs\";\n\nconst dockLocationSchema = z.enum([\n \"center\",\n \"split-bottom\",\n \"split-left\",\n \"split-right\",\n \"split-top\",\n]);\n\nconst splitWeightsSchema = z.array(z.number());\n\nconst actionSchema = z.discriminatedUnion(\"type\", [\n z.object({\n index: z.number().int().optional(),\n location: dockLocationSchema,\n tab: tabNodeSchema,\n targetId: z.string(),\n type: z.literal(\"addNode\"),\n }),\n z.object({\n index: z.number().int().optional(),\n location: dockLocationSchema,\n sourceId: z.string(),\n targetId: z.string(),\n type: z.literal(\"moveNode\"),\n }),\n // No `index`: a tabset docks beside or merges into its target, so there is no\n // slot in a tab strip to land at.\n z.object({\n location: dockLocationSchema,\n sourceId: z.string(),\n targetId: z.string(),\n type: z.literal(\"moveTabset\"),\n }),\n z.object({ index: z.number().int(), tabsetId: z.string(), type: z.literal(\"selectTab\") }),\n z.object({ tabsetId: z.string(), type: z.literal(\"setActiveTabset\") }),\n z.object({ tabsetId: z.string().nullable(), type: z.literal(\"setMaximizedTabset\") }),\n z.object({ name: z.string(), tabId: z.string(), type: z.literal(\"renameTab\") }),\n z.object({ tabId: z.string(), type: z.literal(\"deleteTab\") }),\n z.object({ tabsetId: z.string(), type: z.literal(\"deleteTabset\") }),\n z.object({\n rowId: z.string(),\n type: z.literal(\"adjustSplit\"),\n weights: splitWeightsSchema,\n }),\n z.object({\n attrs: mutableNodeAttrsSchema,\n nodeId: z.string(),\n type: z.literal(\"updateNodeAttributes\"),\n }),\n z.object({ attrs: globalAttributesSchema.partial(), type: z.literal(\"updateGlobalAttributes\") }),\n\n z.object({\n floatId: z.string().optional(),\n geometry: geometrySchema.optional(),\n tabId: z.string(),\n type: z.literal(\"floatTab\"),\n }),\n\n z.object({\n floatId: z.string().optional(),\n geometry: geometrySchema.optional(),\n tabsetId: z.string(),\n type: z.literal(\"floatTabset\"),\n }),\n\n z.object({\n floatId: z.string(),\n location: dockLocationSchema.optional(),\n targetId: z.string().optional(),\n type: z.literal(\"dockFloat\"),\n }),\n\n z.object({\n floatId: z.string(),\n geometry: geometrySchema,\n type: z.literal(\"moveFloat\"),\n }),\n\n z.object({\n floatId: z.string(),\n minimized: z.boolean(),\n type: z.literal(\"setFloatMinimized\"),\n }),\n\n z.object({\n floatId: z.string(),\n name: z.string(),\n type: z.literal(\"renameFloat\"),\n }),\n]);\n\ntype DockLocation = z.infer<typeof dockLocationSchema>;\ntype MutableNodeAttrs = z.infer<typeof mutableNodeAttrsSchema>;\ntype Action = z.infer<typeof actionSchema>;\n\ntype DropIntent = { index?: number; location: DockLocation; targetId: string };\n\nexport { actionSchema, dockLocationSchema };\nexport type { Action, DockLocation, DropIntent, MutableNodeAttrs };\n","const createNodeId = (prefix = \"node\"): string => `${prefix}-${crypto.randomUUID()}`;\n\nconst createTabId = (): string => createNodeId(\"tab\");\n\nexport { createNodeId, createTabId };\n","import type { Dashfoo, FloatNode, RowNode, TabNode, TabsetNode } from \"./schema\";\n\ntype TabContainer = TabsetNode;\ntype TabLocation = { container: TabContainer; index: number; tab: TabNode };\n\nconst collectRoots = (model: Dashfoo): Array<RowNode> => [\n model.layout,\n ...model.floats.map((float) => float.layout),\n];\n\nconst findFloat = (model: Dashfoo, floatId: string): FloatNode | undefined =>\n model.floats.find((float) => float.id === floatId);\n\ntype AttributedNode = RowNode | TabNode | TabsetNode;\n\ntype Visit = {\n index: number;\n node: AttributedNode;\n parent: RowNode | TabsetNode | undefined;\n};\n\n/**\n * Depth-first pre-order; a defined `visit` result stops the walk. With unique\n * ids the order is immaterial, but a duplicate-id model (which the builder and\n * the parser both warn about) resolves to whichever copy this reaches first.\n */\nconst walk = <T>(\n row: RowNode,\n visit: (found: Visit) => T | undefined,\n parent?: RowNode,\n index = -1,\n): T | undefined => {\n const atRoot = visit({ index, node: row, parent });\n if (atRoot !== undefined) {\n return atRoot;\n }\n for (const [childIndex, child] of row.children.entries()) {\n if (child.type === \"row\") {\n const inRow = walk(child, visit, row, childIndex);\n if (inRow !== undefined) {\n return inRow;\n }\n continue;\n }\n const atTabset = visit({ index: childIndex, node: child, parent: row });\n if (atTabset !== undefined) {\n return atTabset;\n }\n for (const [tabIndex, tab] of child.children.entries()) {\n const atTab = visit({ index: tabIndex, node: tab, parent: child });\n if (atTab !== undefined) {\n return atTab;\n }\n }\n }\n return undefined;\n};\n\ntype Located<N extends AttributedNode> = {\n index: number;\n node: N;\n parent: RowNode | TabsetNode | undefined;\n};\n\nconst isRow = (node: AttributedNode): node is RowNode => node.type === \"row\";\nconst isTab = (node: AttributedNode): node is TabNode => node.type === \"tab\";\nconst isTabset = (node: AttributedNode): node is TabsetNode => node.type === \"tabset\";\n\n/** Predicate-first, so an id shared across node kinds resolves the same way here as anywhere else. */\nconst locate = <N extends AttributedNode>(\n model: Dashfoo,\n id: string,\n is: (node: AttributedNode) => node is N,\n): Located<N> | undefined => {\n for (const root of collectRoots(model)) {\n const found = walk(root, ({ index, node, parent }) =>\n node.id === id && is(node) ? { index, node, parent } : undefined,\n );\n if (found) {\n return found;\n }\n }\n return undefined;\n};\n\nconst collectTabsetsInRow = (row: RowNode, acc: Array<TabsetNode>): void => {\n walk(row, ({ node }) => {\n if (node.type === \"tabset\") {\n acc.push(node);\n }\n return undefined;\n });\n};\n\nconst collectTabsets = (model: Dashfoo): Array<TabsetNode> => {\n const acc: Array<TabsetNode> = [];\n for (const root of collectRoots(model)) {\n collectTabsetsInRow(root, acc);\n }\n return acc;\n};\n\nconst getFirstTabset = (model: Dashfoo): TabsetNode | undefined => collectTabsets(model)[0];\n\nconst findTabset = (model: Dashfoo, tabsetId: string): TabsetNode | undefined =>\n locate(model, tabsetId, isTabset)?.node;\n\nconst findTab = (model: Dashfoo, tabId: string): TabLocation | undefined => {\n const found = locate(model, tabId, isTab);\n return found?.parent?.type === \"tabset\"\n ? { container: found.parent, index: found.index, tab: found.node }\n : undefined;\n};\n\nconst findRow = (model: Dashfoo, id: string): RowNode | undefined => locate(model, id, isRow)?.node;\n\nconst findAttributedNode = (model: Dashfoo, id: string): AttributedNode | undefined => {\n for (const root of collectRoots(model)) {\n const found = walk(root, ({ node }) => (node.id === id ? node : undefined));\n if (found) {\n return found;\n }\n }\n return undefined;\n};\n\nconst findRootContaining = (model: Dashfoo, nodeId: string): RowNode | undefined => {\n for (const root of collectRoots(model)) {\n const hit = walk(root, ({ node }) => (node.id === nodeId ? true : undefined));\n if (hit) {\n return root;\n }\n }\n return undefined;\n};\n\nconst findTabsetParent = (\n model: Dashfoo,\n tabsetId: string,\n): { index: number; parent: RowNode } | undefined => {\n const found = locate(model, tabsetId, isTabset);\n return found?.parent?.type === \"row\" ? { index: found.index, parent: found.parent } : undefined;\n};\n\nconst collectIdsInRow = (row: RowNode, acc: Array<string>): void => {\n walk(row, ({ node }) => {\n acc.push(node.id);\n return undefined;\n });\n};\n\nconst findDuplicateIds = (model: Dashfoo): Array<string> => {\n const ids: Array<string> = [];\n for (const float of model.floats) {\n ids.push(float.id);\n }\n for (const root of collectRoots(model)) {\n collectIdsInRow(root, ids);\n }\n const seen = new Set<string>();\n const duplicates = new Set<string>();\n for (const id of ids) {\n if (seen.has(id)) {\n duplicates.add(id);\n }\n seen.add(id);\n }\n return [...duplicates];\n};\n\nexport {\n collectRoots,\n collectTabsets,\n collectTabsetsInRow,\n findAttributedNode,\n findDuplicateIds,\n findFloat,\n findRootContaining,\n findRow,\n findTab,\n findTabset,\n findTabsetParent,\n getFirstTabset,\n};\nexport type { AttributedNode, TabContainer, TabLocation };\n","import { clampSelected } from \"../lib/clamp-selected\";\n\nimport { createNodeId } from \"./ids\";\nimport { DEFAULT_WEIGHT } from \"./schema\";\nimport type {\n Dashfoo,\n Dimension,\n FloatNode,\n Geometry,\n GlobalAttributes,\n Json,\n RowNode,\n SnapConfig,\n TabNode,\n TabsetNode,\n} from \"./schema\";\nimport { findDuplicateIds } from \"./tree\";\n\nconst toDimension = (value: number | Dimension): Dimension =>\n typeof value === \"number\" ? { unit: \"px\", value } : value;\n\ntype TabOptions = {\n config?: Json;\n enableClose?: boolean;\n enableDrag?: boolean;\n enableRename?: boolean;\n id?: string;\n};\n\nconst tab = (component: string, name: string, options: TabOptions = {}): TabNode => ({\n component,\n name,\n type: \"tab\",\n ...options,\n id: options.id ?? component,\n});\n\ntype TabsetOptions = {\n enableClose?: boolean;\n enableMaximize?: boolean;\n id?: string;\n max?: number | Dimension;\n min?: number | Dimension;\n name?: string;\n selected?: number;\n weight?: number;\n};\n\nconst tabset = (children: Array<TabNode>, options: TabsetOptions = {}): TabsetNode => {\n const { max, min, ...rest } = options;\n return {\n children,\n type: \"tabset\",\n ...rest,\n ...(max === undefined ? {} : { max: toDimension(max) }),\n ...(min === undefined ? {} : { min: toDimension(min) }),\n id: options.id ?? createNodeId(\"tabset\"),\n selected: clampSelected(children.length, options.selected ?? 0),\n weight: options.weight ?? DEFAULT_WEIGHT,\n };\n};\n\ntype RowOptions = {\n id?: string;\n max?: number | Dimension;\n min?: number | Dimension;\n orientation?: RowNode[\"orientation\"];\n snap?: SnapConfig;\n weight?: number;\n};\n\nconst row = (children: RowNode[\"children\"], options: RowOptions = {}): RowNode => {\n const { max, min, ...rest } = options;\n return {\n children,\n type: \"row\",\n ...rest,\n ...(max === undefined ? {} : { max: toDimension(max) }),\n ...(min === undefined ? {} : { min: toDimension(min) }),\n id: options.id ?? createNodeId(\"row\"),\n orientation: options.orientation ?? \"row\",\n weight: options.weight ?? DEFAULT_WEIGHT,\n };\n};\n\ntype FloatOptions = {\n id?: string;\n name?: string;\n};\n\nconst floatNode = (layout: RowNode, geometry: Geometry, options: FloatOptions = {}): FloatNode => ({\n geometry,\n layout,\n type: \"float\",\n ...options,\n id: options.id ?? createNodeId(\"float\"),\n});\n\ntype ModelOptions = {\n activeTabsetId?: string;\n floats?: Array<FloatNode>;\n global?: GlobalAttributes;\n maximizedTabsetId?: string;\n};\n\nconst model = (layout: RowNode, options: ModelOptions = {}): Dashfoo => {\n const built: Dashfoo = {\n layout,\n version: 1,\n ...options,\n floats: options.floats ?? [],\n global: options.global ?? {},\n };\n const duplicates = findDuplicateIds(built);\n if (duplicates.length > 0) {\n // oxlint-disable-next-line no-console\n console.warn(\n `[dashfoo] builder produced duplicate node ids: ${duplicates.join(\", \")}. Pass explicit ids when reusing a component`,\n );\n }\n return built;\n};\n\nexport { floatNode, model, row, tab, tabset };\nexport type { FloatOptions, ModelOptions, RowOptions, TabOptions, TabsetOptions };\n","const assertNever = (value: never): never => {\n throw new Error(`Unhandled variant: ${JSON.stringify(value)}`);\n};\n\nexport { assertNever };\n","import { assertNever } from \"../lib/assert-never\";\nimport type { Edge } from \"../model/schema\";\nimport type { DockLocation } from \"../state/actions\";\n\ntype Point = { x: number; y: number };\ntype Rect = { height: number; width: number; x: number; y: number };\ntype BandOptions = { bandFraction?: number };\ntype DockZone = { location: DockLocation; points: Array<Point> };\n\nconst DEFAULT_BAND_FRACTION = 0.22;\n\nconst edgeDistances = (\n pointer: Point,\n rect: Rect,\n): { bottom: number; left: number; right: number; top: number } => {\n const fx = (pointer.x - rect.x) / rect.width;\n const fy = (pointer.y - rect.y) / rect.height;\n return { bottom: 1 - fy, left: fx, right: 1 - fx, top: fy };\n};\n\nconst closestEdge = (d: { bottom: number; left: number; right: number; top: number }): Edge => {\n const min = Math.min(d.left, d.right, d.top, d.bottom);\n if (min === d.left) {\n return \"left\";\n }\n if (min === d.right) {\n return \"right\";\n }\n if (min === d.top) {\n return \"top\";\n }\n return \"bottom\";\n};\n\nconst splitEdge = (location: DockLocation): Edge | undefined => {\n switch (location) {\n case \"center\": {\n return undefined;\n }\n case \"split-bottom\": {\n return \"bottom\";\n }\n case \"split-left\": {\n return \"left\";\n }\n case \"split-right\": {\n return \"right\";\n }\n case \"split-top\": {\n return \"top\";\n }\n default: {\n return assertNever(location);\n }\n }\n};\n\nconst resolveDockTarget = (pointer: Point, rect: Rect, opts?: BandOptions): DockLocation => {\n const band = opts?.bandFraction ?? DEFAULT_BAND_FRACTION;\n\n if (rect.width <= 0 || rect.height <= 0) {\n return \"center\";\n }\n const distances = edgeDistances(pointer, rect);\n const min = Math.min(distances.left, distances.right, distances.top, distances.bottom);\n\n if (min > band) {\n return \"center\";\n }\n return `split-${closestEdge(distances)}`;\n};\n\nconst dockZonePolygons = (rect: Rect, opts?: BandOptions): Array<DockZone> => {\n const { height: h, width: w, x, y } = rect;\n const nw: Point = { x, y };\n const ne: Point = { x: x + w, y };\n const se: Point = { x: x + w, y: y + h };\n const sw: Point = { x, y: y + h };\n if (w <= 0 || h <= 0) {\n return [{ location: \"center\", points: [nw, ne, se, sw] }];\n }\n const band = opts?.bandFraction ?? DEFAULT_BAND_FRACTION;\n const bx = band * w;\n const by = band * h;\n const innerNw: Point = { x: x + bx, y: y + by };\n const innerNe: Point = { x: x + w - bx, y: y + by };\n const innerSe: Point = { x: x + w - bx, y: y + h - by };\n const innerSw: Point = { x: x + bx, y: y + h - by };\n return [\n { location: \"center\", points: [innerNw, innerNe, innerSe, innerSw] },\n { location: \"split-left\", points: [nw, innerNw, innerSw, sw] },\n { location: \"split-right\", points: [ne, se, innerSe, innerNe] },\n { location: \"split-top\", points: [nw, ne, innerNe, innerNw] },\n { location: \"split-bottom\", points: [sw, innerSw, innerSe, se] },\n ];\n};\n\nconst zoneRect = (rect: Rect, location: DockLocation): Rect => {\n const halfW = rect.width / 2;\n const halfH = rect.height / 2;\n switch (location) {\n case \"split-bottom\": {\n return { height: halfH, width: rect.width, x: rect.x, y: rect.y + halfH };\n }\n case \"split-left\": {\n return { height: rect.height, width: halfW, x: rect.x, y: rect.y };\n }\n case \"split-right\": {\n return { height: rect.height, width: halfW, x: rect.x + halfW, y: rect.y };\n }\n case \"split-top\": {\n return { height: halfH, width: rect.width, x: rect.x, y: rect.y };\n }\n case \"center\": {\n return rect;\n }\n default: {\n return assertNever(location);\n }\n }\n};\n\nexport { dockZonePolygons, resolveDockTarget, splitEdge, zoneRect };\nexport type { BandOptions, DockZone, Point, Rect };\n","import type { SnapConfig } from \"../model/schema\";\n\nconst DEFAULT_SNAP_THRESHOLD = 4;\n\nconst TARGET_PRECISION = 1e6;\n\nconst addMultiples = (targets: Set<number>, increment: number): void => {\n if (increment <= 0) {\n return;\n }\n for (let position = increment; position < 100; position += increment) {\n const rounded = Math.round(position * TARGET_PRECISION) / TARGET_PRECISION;\n if (rounded < 100) {\n targets.add(rounded);\n }\n }\n};\n\nconst resolveSnapTargets = (config: SnapConfig, panelCount: number): Array<number> => {\n const targets = new Set<number>();\n if (config.step !== undefined && config.step > 0) {\n addMultiples(targets, config.step);\n }\n if (config.divisions !== undefined) {\n const divisions = config.divisions === \"panels\" ? panelCount : config.divisions;\n if (divisions >= 2) {\n addMultiples(targets, 100 / divisions);\n }\n }\n return [...targets].toSorted((a, b) => a - b);\n};\n\ntype SnapGrid = { targets: Array<number>; threshold: number };\n\nconst resolveSnapGrid = (config: SnapConfig | null, panelCount: number): SnapGrid => ({\n targets: config === null ? [] : resolveSnapTargets(config, panelCount),\n threshold: config?.threshold ?? DEFAULT_SNAP_THRESHOLD,\n});\n\nconst snapEnabled = (grid: SnapGrid): boolean => grid.targets.length > 0;\n\nconst nearestTarget = (position: number, targets: Array<number>): number | undefined =>\n targets.reduce<number | undefined>((best, target) => {\n if (best === undefined || Math.abs(target - position) < Math.abs(best - position)) {\n return target;\n }\n return best;\n }, undefined);\n\ntype SnapResult = { sizes: Array<number>; snapped: boolean };\n\nconst snapSizes = (sizes: Array<number>, boundaryIndex: number, grid: SnapGrid): SnapResult => {\n const { targets, threshold } = grid;\n const left = sizes[boundaryIndex];\n const right = sizes[boundaryIndex + 1];\n if (boundaryIndex < 0 || left === undefined || right === undefined || targets.length === 0) {\n return { sizes, snapped: false };\n }\n\n let position = 0;\n for (let index = 0; index <= boundaryIndex; index++) {\n position += sizes[index] ?? 0;\n }\n\n const target = nearestTarget(position, targets);\n if (target === undefined || Math.abs(target - position) > threshold) {\n return { sizes, snapped: false };\n }\n\n const delta = target - position;\n if (left + delta < 0 || right - delta < 0) {\n return { sizes, snapped: false };\n }\n\n const next = [...sizes];\n next[boundaryIndex] = left + delta;\n next[boundaryIndex + 1] = right - delta;\n return { sizes: next, snapped: true };\n};\n\ntype SnapDecision =\n | { kind: \"inactive\" }\n | { kind: \"clear\" }\n | { kind: \"engage\"; sizes: Array<number> };\n\nconst decideSnap = (\n sizes: Array<number>,\n boundaryIndex: number | null,\n grid: SnapGrid,\n): SnapDecision => {\n if (boundaryIndex === null || !snapEnabled(grid)) {\n return { kind: \"inactive\" };\n }\n const { sizes: snappedSizes, snapped } = snapSizes(sizes, boundaryIndex, grid);\n return snapped ? { kind: \"engage\", sizes: snappedSizes } : { kind: \"clear\" };\n};\n\nconst settleSnap = (\n sizes: Array<number>,\n boundaryIndex: number | null,\n grid: SnapGrid,\n): Array<number> => {\n const decision = decideSnap(sizes, boundaryIndex, grid);\n return decision.kind === \"engage\" ? decision.sizes : sizes;\n};\n\nexport {\n DEFAULT_SNAP_THRESHOLD,\n decideSnap,\n resolveSnapGrid,\n resolveSnapTargets,\n settleSnap,\n snapEnabled,\n snapSizes,\n};\nexport type { SnapDecision, SnapGrid, SnapResult };\n","import type { Dashfoo, FloatNode, RowNode } from \"./schema\";\n\ntype RowChild = RowNode[\"children\"][number];\n\n/**\n * The survivor takes over the collapsed row's slot, so it has to take the slot's\n * sizing too: dropping it widens a pinned sidebar, permanently, since this runs\n * on every persist. `snap` is row-only, so it travels only to a row survivor.\n */\nconst inheritSlot = (row: RowNode, survivor: RowChild): RowChild => {\n const sized: RowChild = {\n ...survivor,\n weight: row.weight,\n ...(row.min === undefined ? {} : { min: row.min }),\n ...(row.max === undefined ? {} : { max: row.max }),\n };\n\n if (sized.type === \"row\" && row.snap !== undefined) {\n return { ...sized, snap: row.snap };\n }\n return sized;\n};\n\n/** Records the id of every tabset it keeps, in document order. */\nconst normalizeRowChildren = (\n children: RowNode[\"children\"],\n keptTabsetIds: Array<string>,\n): RowNode[\"children\"] => {\n const out: RowNode[\"children\"] = [];\n\n for (const child of children) {\n if (child.type === \"tabset\") {\n if (child.children.length > 0) {\n out.push(child);\n keptTabsetIds.push(child.id);\n }\n continue;\n }\n\n // A recorded id implies a survivor, which keeps its ancestor rows alive, so\n // a dropped row never leaves ids behind.\n const grandchildren = normalizeRowChildren(child.children, keptTabsetIds);\n if (grandchildren.length === 0) {\n continue;\n }\n if (grandchildren.length === 1) {\n const only = grandchildren[0];\n if (only !== undefined) {\n out.push(inheritSlot(child, only));\n }\n continue;\n }\n out.push({ ...child, children: grandchildren });\n }\n\n return out;\n};\n\nconst normalizeLayout = (root: RowNode, keptTabsetIds: Array<string>): RowNode => {\n let children = normalizeRowChildren(root.children, keptTabsetIds);\n let orientation = root.orientation;\n\n let inner = children[0];\n while (children.length === 1 && inner?.type === \"row\") {\n children = inner.children;\n orientation = inner.orientation;\n inner = children[0];\n }\n\n return { ...root, children, orientation };\n};\n\nconst normalize = (model: Dashfoo): Dashfoo => {\n const mainTabsetIds: Array<string> = [];\n const layout = normalizeLayout(model.layout, mainTabsetIds);\n\n const floats: Array<FloatNode> = [];\n const floatTabsetIds: Array<string> = [];\n for (const float of model.floats) {\n const ownTabsetIds: Array<string> = [];\n const floatLayout = normalizeLayout(float.layout, ownTabsetIds);\n if (floatLayout.children.length > 0) {\n floats.push({ ...float, layout: floatLayout });\n floatTabsetIds.push(...ownTabsetIds);\n }\n }\n\n const mainIds = new Set(mainTabsetIds);\n const liveIds = new Set([...mainTabsetIds, ...floatTabsetIds]);\n const firstTabsetId = mainTabsetIds[0] ?? floatTabsetIds[0];\n\n const activeTabsetId =\n model.activeTabsetId !== undefined && liveIds.has(model.activeTabsetId)\n ? model.activeTabsetId\n : firstTabsetId;\n\n // Main layout only: floats opt out of maximize, so an id that moved into one\n // would render twice, in the main area and inside the float.\n const maximizedTabsetId =\n model.maximizedTabsetId !== undefined && mainIds.has(model.maximizedTabsetId)\n ? model.maximizedTabsetId\n : undefined;\n\n return { ...model, activeTabsetId, floats, layout, maximizedTabsetId };\n};\n\nexport { normalize };\n","import { clampSelected } from \"../lib/clamp-selected\";\nimport { createNodeId } from \"../model/ids\";\nimport type { Dashfoo, Orientation, RowNode, TabNode, TabsetNode } from \"../model/schema\";\nimport { DEFAULT_WEIGHT } from \"../model/schema\";\nimport type { TabContainer } from \"../model/tree\";\nimport { findTabset, findTabsetParent } from \"../model/tree\";\n\nimport type { DockLocation } from \"./actions\";\n\n/** The four locations that produce a split. `center` merges instead, so it is not one of them. */\ntype SplitLocation = Exclude<DockLocation, \"center\">;\n\nconst removeTabsetReturning = (model: Dashfoo, tabsetId: string): TabsetNode | undefined => {\n const found = findTabsetParent(model, tabsetId);\n if (!found) {\n return undefined;\n }\n const [removed] = found.parent.children.splice(found.index, 1);\n return removed?.type === \"tabset\" ? removed : undefined;\n};\n\n/** Total, so a sixth `DockLocation` is a compile error here rather than a wrong default. */\nconst SPLIT_PLACEMENT = {\n \"split-bottom\": { before: false, orientation: \"column\" },\n \"split-left\": { before: true, orientation: \"row\" },\n \"split-right\": { before: false, orientation: \"row\" },\n \"split-top\": { before: true, orientation: \"column\" },\n} as const satisfies Record<SplitLocation, { before: boolean; orientation: Orientation }>;\n\nconst placeBesideTarget = (\n draft: Dashfoo,\n placed: TabsetNode,\n targetId: string,\n location: SplitLocation,\n): boolean => {\n const targetTabset = findTabset(draft, targetId);\n const found = findTabsetParent(draft, targetId);\n if (!targetTabset || !found) {\n return false;\n }\n\n const { before, orientation } = SPLIT_PLACEMENT[location];\n\n if (found.parent.orientation === orientation) {\n const half = targetTabset.weight / 2;\n targetTabset.weight = half;\n placed.weight = half;\n found.parent.children.splice(before ? found.index : found.index + 1, 0, placed);\n } else {\n const newRow: RowNode = {\n children: before ? [placed, targetTabset] : [targetTabset, placed],\n id: createNodeId(\"row\"),\n orientation,\n type: \"row\",\n weight: targetTabset.weight,\n };\n targetTabset.weight = 50;\n placed.weight = 50;\n found.parent.children.splice(found.index, 1, newRow);\n }\n\n draft.activeTabsetId = placed.id;\n return true;\n};\n\ntype DropTarget = { id: string; index?: number; location: DockLocation };\n\nconst insertTab = (draft: Dashfoo, tab: TabNode, target: DropTarget): boolean => {\n const { id: targetId, index, location } = target;\n const targetTabset = findTabset(draft, targetId);\n if (!targetTabset) {\n return false;\n }\n\n if (location === \"center\") {\n const at = Math.min(\n Math.max(index ?? targetTabset.children.length, 0),\n targetTabset.children.length,\n );\n targetTabset.children.splice(at, 0, tab);\n targetTabset.selected = at;\n return true;\n }\n\n const newTabset: TabsetNode = {\n children: [tab],\n id: createNodeId(\"tabset\"),\n selected: 0,\n type: \"tabset\",\n weight: DEFAULT_WEIGHT,\n };\n return placeBesideTarget(draft, newTabset, targetId, location);\n};\n\n/** Re-clamps here rather than leaving the whole tree to be re-walked afterwards. */\nconst detachTab = (container: TabContainer, index: number): TabNode | undefined => {\n const removed = container.children.splice(index, 1).at(0);\n container.selected = clampSelected(container.children.length, container.selected);\n return removed;\n};\n\nconst mergeTabsInto = (target: TabsetNode, tabs: Array<TabNode>, selectedOffset: number): void => {\n const mergeStart = target.children.length;\n target.children.push(...tabs);\n target.selected = mergeStart + selectedOffset;\n};\n\nconst wrapTabInLayout = (tab: TabNode): RowNode => ({\n children: [\n {\n children: [tab],\n id: createNodeId(\"tabset\"),\n selected: 0,\n type: \"tabset\",\n weight: DEFAULT_WEIGHT,\n },\n ],\n id: createNodeId(\"row\"),\n orientation: \"row\",\n type: \"row\",\n weight: DEFAULT_WEIGHT,\n});\n\nconst wrapTabsetInLayout = (tabset: TabsetNode): RowNode => ({\n children: [tabset],\n id: createNodeId(\"row\"),\n orientation: \"row\",\n type: \"row\",\n weight: DEFAULT_WEIGHT,\n});\n\nexport {\n detachTab,\n insertTab,\n mergeTabsInto,\n placeBesideTarget,\n removeTabsetReturning,\n wrapTabInLayout,\n wrapTabsetInLayout,\n};\nexport type { DropTarget, SplitLocation };\n","import { clampSelected } from \"../lib/clamp-selected\";\nimport { createNodeId } from \"../model/ids\";\nimport type { Dashfoo, FloatNode, Geometry, RowNode, TabsetNode } from \"../model/schema\";\nimport { DEFAULT_WEIGHT } from \"../model/schema\";\nimport { collectTabsetsInRow } from \"../model/tree\";\n\nimport type { DockLocation } from \"./actions\";\nimport {\n mergeTabsInto,\n placeBesideTarget,\n removeTabsetReturning,\n wrapTabsetInLayout,\n} from \"./surgery\";\n\nconst DEFAULT_FLOAT_GEOMETRY: Geometry = { height: 360, left: 80, top: 80, width: 480 };\n\nconst uniqueFloatName = (base: string, floats: Array<FloatNode>): string => {\n const used = new Set(floats.map((float) => float.name));\n if (!used.has(base)) {\n return base;\n }\n let index = 1;\n while (used.has(`${base} ${index}`)) {\n index += 1;\n }\n return `${base} ${index}`;\n};\n\nconst pushFloat = (\n draft: Dashfoo,\n layout: RowNode,\n geometry: Geometry | undefined,\n floatId: string | undefined,\n): void => {\n const float: FloatNode = {\n geometry: geometry ?? DEFAULT_FLOAT_GEOMETRY,\n id: floatId ?? createNodeId(\"float\"),\n layout,\n name: uniqueFloatName(\"Panel\", draft.floats),\n type: \"float\",\n };\n draft.floats = [...draft.floats, float];\n\n const tabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(layout, tabsets);\n const first = tabsets.at(0);\n if (first) {\n draft.activeTabsetId = first.id;\n }\n};\n\nconst floatTabsetById = (\n draft: Dashfoo,\n tabsetId: string,\n geometry: Geometry | undefined,\n floatId: string | undefined,\n): boolean => {\n const detached = removeTabsetReturning(draft, tabsetId);\n if (!detached) {\n return false;\n }\n pushFloat(draft, wrapTabsetInLayout(detached), geometry, floatId);\n return true;\n};\n\nconst resolveMainTarget = (\n draft: Dashfoo,\n targetId: string | undefined,\n): TabsetNode | undefined => {\n const mainTabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(draft.layout, mainTabsets);\n if (targetId !== undefined) {\n const explicit = mainTabsets.find((tabset) => tabset.id === targetId);\n if (explicit) {\n return explicit;\n }\n }\n if (draft.activeTabsetId !== undefined) {\n const active = mainTabsets.find((tabset) => tabset.id === draft.activeTabsetId);\n if (active) {\n return active;\n }\n }\n return mainTabsets[0];\n};\n\nconst dockFloat = (\n draft: Dashfoo,\n floatId: string,\n targetId: string | undefined,\n location: DockLocation | undefined,\n): boolean => {\n const index = draft.floats.findIndex((float) => float.id === floatId);\n const float = draft.floats.at(index);\n if (index === -1 || !float) {\n return false;\n }\n\n const tabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(float.layout, tabsets);\n const tabs = tabsets.flatMap((tabset) => tabset.children);\n if (tabs.length === 0) {\n return false;\n }\n\n const leadTabset = tabsets.at(0);\n const selectedOffset = leadTabset\n ? clampSelected(leadTabset.children.length, leadTabset.selected)\n : 0;\n\n // Resolved before the float leaves `draft.floats`: nothing is removed until\n // there is somewhere for its tabs to land.\n const target = resolveMainTarget(draft, targetId);\n draft.floats.splice(index, 1);\n\n if (!target) {\n draft.layout = float.layout;\n draft.activeTabsetId = leadTabset?.id;\n return true;\n }\n\n if (location === \"center\") {\n mergeTabsInto(target, tabs, selectedOffset);\n draft.activeTabsetId = target.id;\n return true;\n }\n\n const placed: TabsetNode =\n tabsets.length === 1 && leadTabset\n ? leadTabset\n : {\n children: tabs,\n id: createNodeId(\"tabset\"),\n selected: selectedOffset,\n type: \"tabset\",\n weight: DEFAULT_WEIGHT,\n };\n return placeBesideTarget(draft, placed, target.id, location ?? \"split-right\");\n};\n\nexport { dockFloat, floatTabsetById, pushFloat, uniqueFloatName };\n","import { assertNever } from \"../lib/assert-never\";\nimport { clampSelected } from \"../lib/clamp-selected\";\nimport { normalize } from \"../model/invariants\";\nimport type { Dashfoo, Geometry, GlobalAttributes } from \"../model/schema\";\nimport type { AttributedNode } from \"../model/tree\";\nimport { findAttributedNode, findFloat, findRow, findTab, findTabset } from \"../model/tree\";\n\nimport type { Action, MutableNodeAttrs } from \"./actions\";\nimport { dockFloat, floatTabsetById, pushFloat, uniqueFloatName } from \"./floats\";\nimport {\n mutableRowAttrsSchema,\n mutableTabAttrsSchema,\n mutableTabsetAttrsSchema,\n} from \"./node-attrs\";\nimport {\n detachTab,\n insertTab,\n mergeTabsInto,\n placeBesideTarget,\n removeTabsetReturning,\n wrapTabInLayout,\n} from \"./surgery\";\n\nconst parseNodeAttrs = (node: AttributedNode, attrs: MutableNodeAttrs): MutableNodeAttrs => {\n switch (node.type) {\n case \"row\": {\n return mutableRowAttrsSchema.parse(attrs);\n }\n case \"tab\": {\n return mutableTabAttrsSchema.parse(attrs);\n }\n case \"tabset\": {\n const parsed = mutableTabsetAttrsSchema.parse(attrs);\n return parsed.selected === undefined\n ? parsed\n : { ...parsed, selected: clampSelected(node.children.length, parsed.selected) };\n }\n default: {\n return assertNever(node);\n }\n }\n};\n\nconst sameGeometry = (a: Geometry, b: Geometry): boolean =>\n a.height === b.height && a.left === b.left && a.top === b.top && a.width === b.width;\n\nconst alreadyApplied = (\n target: AttributedNode | GlobalAttributes,\n attrs: MutableNodeAttrs | Partial<GlobalAttributes>,\n): boolean => {\n const current = new Map<string, unknown>(Object.entries(target));\n return Object.entries(attrs).every(([key, value]) => Object.is(current.get(key), value));\n};\n\n/** Reports whether it changed anything, so `history.dispatch` can skip a no-op. */\nconst applyAction = (draft: Dashfoo, action: Action): boolean => {\n switch (action.type) {\n case \"addNode\": {\n return insertTab(draft, action.tab, {\n id: action.targetId,\n index: action.index,\n location: action.location,\n });\n }\n case \"adjustSplit\": {\n const row = findRow(draft, action.rowId);\n if (!row) {\n return false;\n }\n let changed = false;\n for (let index = 0; index < action.weights.length; index++) {\n const child = row.children.at(index);\n const weight = action.weights[index];\n if (!child || weight === undefined || child.weight === weight) {\n continue;\n }\n child.weight = weight;\n changed = true;\n }\n return changed;\n }\n case \"deleteTab\": {\n const location = findTab(draft, action.tabId);\n if (!location) {\n return false;\n }\n detachTab(location.container, location.index);\n return true;\n }\n case \"deleteTabset\": {\n return removeTabsetReturning(draft, action.tabsetId) !== undefined;\n }\n case \"dockFloat\": {\n return dockFloat(draft, action.floatId, action.targetId, action.location);\n }\n case \"floatTab\": {\n const location = findTab(draft, action.tabId);\n if (!location) {\n return false;\n }\n const removed = detachTab(location.container, location.index);\n if (!removed) {\n return false;\n }\n pushFloat(draft, wrapTabInLayout(removed), action.geometry, action.floatId);\n return true;\n }\n case \"floatTabset\": {\n return floatTabsetById(draft, action.tabsetId, action.geometry, action.floatId);\n }\n case \"moveFloat\": {\n const float = findFloat(draft, action.floatId);\n if (!float || sameGeometry(float.geometry, action.geometry)) {\n return false;\n }\n float.geometry = action.geometry;\n return true;\n }\n case \"moveNode\": {\n const source = findTab(draft, action.sourceId);\n // Resolved before the tab leaves its container: nothing else holds it.\n if (!source || !findTabset(draft, action.targetId)) {\n return false;\n }\n\n const removed = detachTab(source.container, source.index);\n if (!removed) {\n return false;\n }\n return insertTab(draft, removed, {\n id: action.targetId,\n index: action.index,\n location: action.location,\n });\n }\n case \"moveTabset\": {\n if (action.sourceId === action.targetId) {\n return false;\n }\n const source = findTabset(draft, action.sourceId);\n const target = findTabset(draft, action.targetId);\n if (!source || !target) {\n return false;\n }\n if (action.location === \"center\") {\n mergeTabsInto(\n target,\n source.children,\n clampSelected(source.children.length, source.selected),\n );\n removeTabsetReturning(draft, action.sourceId);\n return true;\n }\n\n const detached = removeTabsetReturning(draft, action.sourceId);\n return detached\n ? placeBesideTarget(draft, detached, action.targetId, action.location)\n : false;\n }\n case \"renameFloat\": {\n const float = findFloat(draft, action.floatId);\n if (!float) {\n return false;\n }\n const others = draft.floats.filter((other) => other.id !== action.floatId);\n const name = uniqueFloatName(action.name, others);\n if (float.name === name) {\n return false;\n }\n float.name = name;\n return true;\n }\n case \"renameTab\": {\n const location = findTab(draft, action.tabId);\n if (!location || location.tab.name === action.name) {\n return false;\n }\n location.tab.name = action.name;\n return true;\n }\n case \"selectTab\": {\n const tabset = findTabset(draft, action.tabsetId);\n if (!tabset) {\n return false;\n }\n const selected = clampSelected(tabset.children.length, action.index);\n if (tabset.selected === selected) {\n return false;\n }\n tabset.selected = selected;\n return true;\n }\n case \"setActiveTabset\": {\n if (draft.activeTabsetId === action.tabsetId || !findTabset(draft, action.tabsetId)) {\n return false;\n }\n draft.activeTabsetId = action.tabsetId;\n return true;\n }\n case \"setFloatMinimized\": {\n const float = findFloat(draft, action.floatId);\n if (!float || (float.minimized ?? false) === action.minimized) {\n return false;\n }\n float.minimized = action.minimized;\n return true;\n }\n case \"setMaximizedTabset\": {\n const next = action.tabsetId ?? undefined;\n if (draft.maximizedTabsetId === next) {\n return false;\n }\n draft.maximizedTabsetId = next;\n return true;\n }\n case \"updateGlobalAttributes\": {\n if (alreadyApplied(draft.global, action.attrs)) {\n return false;\n }\n Object.assign(draft.global, action.attrs);\n return true;\n }\n case \"updateNodeAttributes\": {\n const node = findAttributedNode(draft, action.nodeId);\n if (!node) {\n return false;\n }\n const parsed = parseNodeAttrs(node, action.attrs);\n if (alreadyApplied(node, parsed)) {\n return false;\n }\n Object.assign(node, parsed);\n return true;\n }\n default: {\n return assertNever(action);\n }\n }\n};\n\n/** Identity-equal output means \"no edit\". A rejected action skips `normalize`, so\n * pass a model that has already been through it. */\nconst reducer = (model: Dashfoo, action: Action): Dashfoo => {\n const draft = structuredClone(model);\n if (!applyAction(draft, action)) {\n return model;\n }\n return normalize(draft);\n};\n\nexport { reducer };\n","import type { Dashfoo } from \"../model/schema\";\n\nimport type { Action } from \"./actions\";\nimport { reducer } from \"./reducer\";\n\ntype History = {\n future: Array<Dashfoo>;\n past: Array<Dashfoo>;\n present: Dashfoo;\n};\n\nconst HISTORY_LIMIT = 100;\n\nconst createHistory = (present: Dashfoo): History => ({\n future: [],\n past: [],\n present,\n});\n\nconst canUndo = (history: History): boolean => history.past.length > 0;\nconst canRedo = (history: History): boolean => history.future.length > 0;\n\n/**\n * An action that changed nothing is not an edit: recording it would spend an\n * undo slot and clear a redo stack the user just built. Not coalescing (ADR\n * 0002): two distinct edits are still two entries.\n */\nconst dispatch = (history: History, action: Action): History => {\n const present = reducer(history.present, action);\n if (Object.is(present, history.present)) {\n return history;\n }\n return { future: [], past: [...history.past, history.present].slice(-HISTORY_LIMIT), present };\n};\n\nconst undo = (history: History): History => {\n const previous = history.past.at(-1);\n if (previous === undefined) {\n return history;\n }\n return {\n future: [history.present, ...history.future],\n past: history.past.slice(0, -1),\n present: previous,\n };\n};\n\nconst redo = (history: History): History => {\n const [next, ...rest] = history.future;\n if (next === undefined) {\n return history;\n }\n return {\n future: rest,\n past: [...history.past, history.present].slice(-HISTORY_LIMIT),\n present: next,\n };\n};\n\nexport { canRedo, canUndo, createHistory, dispatch, HISTORY_LIMIT, redo, undo };\nexport type { History };\n","import { assign, setup } from \"xstate\";\n\nimport type { Dashfoo } from \"../model/schema\";\nimport type { Action } from \"../state/actions\";\nimport type { History } from \"../state/history\";\nimport { createHistory, dispatch, redo, undo } from \"../state/history\";\n\ntype DashfooContext = { history: History };\n\ntype DashfooEvent =\n | { action: Action; type: \"DISPATCH\" }\n | { model: Dashfoo; type: \"SET_MODEL\" }\n | { type: \"REDO\" }\n | { type: \"UNDO\" };\n\ntype DashfooMachineInput = { model: Dashfoo };\n\nconst dashfooMachine = setup({\n types: {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n context: {} as DashfooContext,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n events: {} as DashfooEvent,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n input: {} as DashfooMachineInput,\n },\n}).createMachine({\n context: ({ input }) => ({ history: createHistory(input.model) }),\n id: \"dashfoo\",\n initial: \"ready\",\n states: {\n ready: {\n on: {\n DISPATCH: {\n actions: assign({\n history: ({ context, event }) => dispatch(context.history, event.action),\n }),\n },\n REDO: {\n actions: assign({ history: ({ context }) => redo(context.history) }),\n },\n SET_MODEL: {\n actions: assign({ history: ({ event }) => createHistory(event.model) }),\n },\n UNDO: {\n actions: assign({ history: ({ context }) => undo(context.history) }),\n },\n },\n },\n },\n});\n\nexport { dashfooMachine };\n","import { assign, emit, setup } from \"xstate\";\n\nimport type { TabNode } from \"../model/schema\";\nimport type { Action, DropIntent } from \"../state/actions\";\n\ntype DragSubject =\n | { id: string; kind: \"tab\" | \"tabset\" }\n | { id: string; kind: \"external\"; tab: TabNode };\n\n/** `scope` names whoever resolved the intent, echoed back on `COMMIT` so the host can route the action. */\ntype DropResolution = { intent: DropIntent; scope: string };\n\n/** One value, so a drop target without a subject is unrepresentable. See ADR 0002. */\ntype DragState =\n | { drop: DropResolution | null; kind: \"dragging\"; subject: DragSubject }\n | { kind: \"idle\" };\n\ntype DragContext = { drag: DragState };\n\ntype DragEvent =\n | { drop: DropResolution | null; type: \"OVER\" }\n | { subject: DragSubject; type: \"START\" }\n | { type: \"CANCEL\" }\n | { type: \"DROP\" };\n\ntype DragEmitted = { action: Action; scope: string; type: \"COMMIT\" };\n\n/** One definition of both \"is this drop valid\" and \"what does it do\", so the guard and the emit agree. */\nconst dropAction = (drag: DragState): { action: Action; scope: string } | null => {\n if (drag.kind !== \"dragging\" || drag.drop === null) {\n return null;\n }\n const { intent, scope } = drag.drop;\n const { subject } = drag;\n\n if (subject.kind === \"external\") {\n return {\n action: {\n index: intent.index,\n location: intent.location,\n tab: subject.tab,\n targetId: intent.targetId,\n type: \"addNode\",\n },\n scope,\n };\n }\n if (subject.kind === \"tabset\") {\n return {\n action: {\n location: intent.location,\n sourceId: subject.id,\n targetId: intent.targetId,\n type: \"moveTabset\",\n },\n scope,\n };\n }\n return {\n action: {\n index: intent.index,\n location: intent.location,\n sourceId: subject.id,\n targetId: intent.targetId,\n type: \"moveNode\",\n },\n scope,\n };\n};\n\nconst dragDockMachine = setup({\n guards: {\n hasValidDrop: ({ context }) => dropAction(context.drag) !== null,\n },\n types: {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n context: {} as DragContext,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n emitted: {} as DragEmitted,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n events: {} as DragEvent,\n },\n}).createMachine({\n context: { drag: { kind: \"idle\" } },\n id: \"dragDock\",\n initial: \"idle\",\n states: {\n dragging: {\n on: {\n CANCEL: { target: \"idle\" },\n DROP: [\n {\n actions: emit(({ context }) => {\n const resolved = dropAction(context.drag);\n if (resolved === null) {\n throw new Error(\"drop requires a subject and a resolved drop target\");\n }\n return { action: resolved.action, scope: resolved.scope, type: \"COMMIT\" };\n }),\n guard: \"hasValidDrop\",\n target: \"idle\",\n },\n { target: \"idle\" },\n ],\n OVER: {\n actions: assign({\n drag: ({ context, event }) =>\n context.drag.kind === \"dragging\"\n ? { ...context.drag, drop: event.drop }\n : context.drag,\n }),\n },\n },\n },\n idle: {\n entry: assign({ drag: { kind: \"idle\" } }),\n on: {\n START: {\n actions: assign({\n drag: ({ event }) => ({ drop: null, kind: \"dragging\", subject: event.subject }),\n }),\n target: \"dragging\",\n },\n },\n },\n },\n});\n\nexport { dragDockMachine, dropAction };\nexport type { DragState, DragSubject, DropResolution };\n","import { normalize } from \"./invariants\";\nimport type { Dashfoo } from \"./schema\";\nimport { dashfooSchema } from \"./schema\";\nimport { findDuplicateIds } from \"./tree\";\n\nconst parseModel = (value: unknown): Dashfoo => {\n const model = normalize(dashfooSchema.parse(value));\n const duplicates = findDuplicateIds(model);\n if (duplicates.length > 0) {\n // oxlint-disable-next-line no-console\n console.warn(`[dashfoo] duplicate node ids in the loaded layout: ${duplicates.join(\", \")}`);\n }\n return model;\n};\n\nconst toJSON = (model: Dashfoo): string => JSON.stringify(model);\n\nconst fromJSON = (json: string): Dashfoo => parseModel(JSON.parse(json));\n\nexport { fromJSON, parseModel, toJSON };\n","import { normalize } from \"./invariants\";\nimport type { Dashfoo, Orientation, TabsetNode } from \"./schema\";\nimport { collectTabsetsInRow } from \"./tree\";\n\nconst stackModel = (model: Dashfoo, orientation: Orientation = \"column\"): Dashfoo => {\n const mainTabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(model.layout, mainTabsets);\n const children: Array<TabsetNode> = [];\n for (const tabset of mainTabsets) {\n children.push({ ...tabset, weight: 1 });\n }\n\n return normalize({\n ...model,\n layout: {\n children,\n id: model.layout.id,\n orientation,\n type: \"row\",\n weight: model.layout.weight,\n },\n maximizedTabsetId: undefined,\n });\n};\n\nexport { stackModel };\n"],"mappings":";;;;;;AAEA,MAAM,iBAAiB,QAAgB,aAA6B;CAClE,IAAI,WAAW,GACb,OAAO;CAGT,MAAM,OAAO,OAAO,SAAS,QAAQ,IAAI,KAAK,MAAM,QAAQ,IAAI;CAChE,IAAI,OAAO,GACT,OAAO;CAET,IAAI,OAAO,SAAS,GAClB,OAAO,SAAS;CAElB,OAAO;AACT;;;;;ACVA,MAAM,iBAAiB;AAIvB,MAAM,kBAAwC,EAAE,WAC9C,EAAE,MAAM;CACN,EAAE,OAAO;CACT,EAAE,OAAO;CACT,EAAE,QAAQ;CACV,EAAE,KAAK;CACP,EAAE,MAAM,eAAe;CACvB,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;AACtC,CAAC,CACH;AAEA,MAAM,aAAa,EAAE,KAAK;CAAC;CAAO;CAAU;CAAQ;AAAO,CAAC;AAC5D,MAAM,aAAa,EAAE,KAAK;CAAC;CAAM;CAAK;CAAM;CAAO;CAAM;AAAI,CAAC;AAC9D,MAAM,oBAAoB,EAAE,KAAK,CAAC,OAAO,QAAQ,CAAC;AAElD,MAAM,kBAAkB,EAAE,OAAO;CAC/B,MAAM;CACN,OAAO,EAAE,OAAO;AAClB,CAAC;AAED,MAAM,aAAa,EAAE,OAAO;CAC1B,WAAW,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,SAAS,GAAG,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;CAC1E,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CACjC,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;AAC5C,CAAC;AAED,MAAM,gBAAgB,EAAE,OAAO;CAC7B,WAAW,EAAE,OAAO;CACpB,QAAQ,gBAAgB,SAAS;CACjC,aAAa,EAAE,QAAQ,CAAC,CAAC,SAAS;CAClC,YAAY,EAAE,QAAQ,CAAC,CAAC,SAAS;CACjC,cAAc,EAAE,QAAQ,CAAC,CAAC,SAAS;CACnC,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,MAAM,EAAE,QAAQ,KAAK;AACvB,CAAC;;;;;AAMD,MAAM,yBAAyB,EAAE,OAAO;CACtC,UAAU,EAAE,MAAM,aAAa;CAC/B,aAAa,EAAE,QAAQ,CAAC,CAAC,SAAS;CAClC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,SAAS;CACrC,IAAI,EAAE,OAAO;CACb,KAAK,gBAAgB,SAAS;CAC9B,KAAK,gBAAgB,SAAS;CAC9B,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI;CACzB,MAAM,EAAE,QAAQ,QAAQ;CACxB,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAsB;AAC3C,CAAC;AAED,MAAM,mBAAmB,uBAAuB,WAAW,YAAY;CACrE,GAAG;CACH,UAAU,cAAc,OAAO,SAAS,QAAQ,OAAO,QAAQ;AACjE,EAAE;;AAGF,MAAM,gBAAgB,EAAE,OAAO;CAC7B,IAAI,WAAoF;EACtF,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,eAAe,gBAAgB,CAAC,CAAC;CAC3D;CACA,IAAI,EAAE,OAAO;CACb,KAAK,gBAAgB,SAAS;CAC9B,KAAK,gBAAgB,SAAS;CAC9B,aAAa;CACb,MAAM,WAAW,SAAS;CAC1B,MAAM,EAAE,QAAQ,KAAK;CACrB,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAsB;AAC3C,CAAC;AAKD,MAAM,iBAAiB,EAAE,OAAO;CAC9B,QAAQ,EAAE,OAAO;CACjB,MAAM,EAAE,OAAO;CACf,KAAK,EAAE,OAAO;CACd,OAAO,EAAE,OAAO;AAClB,CAAC;AAED,MAAM,kBAAkB,EAAE,OAAO;CAC/B,UAAU;CACV,IAAI,EAAE,OAAO;CACb,QAAQ;CAER,WAAW,EAAE,QAAQ,CAAC,CAAC,SAAS;CAChC,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,MAAM,EAAE,QAAQ,OAAO;AACzB,CAAC;AAED,MAAM,yBAAyB,EAAE,OAAO;CACtC,iBAAiB,EAAE,QAAQ,CAAC,CAAC,SAAS;CACtC,mBAAmB,EAAE,QAAQ,CAAC,CAAC,SAAS;CACxC,MAAM,WAAW,SAAS;CAC1B,cAAc,EAAE,OAAO,CAAC,CAAC,SAAS;CAClC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,SAAS;CACrC,eAAe,EAAE,QAAQ,CAAC,CAAC,SAAS;CACpC,iBAAiB,EAAE,QAAQ,CAAC,CAAC,SAAS;CACtC,aAAa,EAAE,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS;CAChD,sBAAsB,EAAE,QAAQ,CAAC,CAAC,SAAS;CAC3C,sBAAsB,EAAE,QAAQ,CAAC,CAAC,SAAS;CAC3C,eAAe,EAAE,OAAO,CAAC,CAAC,SAAS;AACrC,CAAC;AAED,MAAM,gBAAgB,EAAE,OAAO;CAC7B,gBAAgB,EAAE,OAAO,CAAC,CAAC,SAAS;CACpC,QAAQ,EAAE,MAAM,eAAe,CAAC,CAAC,cAAc,CAAC,CAAC;CACjD,QAAQ;CACR,QAAQ;CACR,mBAAmB,EAAE,OAAO,CAAC,CAAC,SAAS;CACvC,SAAS,EAAE,QAAQ,CAAC;AACtB,CAAC;;;;ACjHD,MAAM,wBAAwB,cAC3B,KAAK;CACJ,QAAQ;CACR,aAAa;CACb,YAAY;CACZ,cAAc;CACd,MAAM;AACR,CAAC,CAAC,CACD,QAAQ;;AAGX,MAAM,2BAA2B,uBAC9B,KAAK;CACJ,aAAa;CACb,gBAAgB;CAChB,KAAK;CACL,KAAK;CACL,UAAU;AACZ,CAAC,CAAC,CACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAC9B,QAAQ;AAEX,MAAM,wBAAwB,EAC3B,OAAO;CACN,KAAK,gBAAgB,SAAS;CAC9B,KAAK,gBAAgB,SAAS;CAC9B,aAAa;CACb,MAAM,WAAW,SAAS;CAC1B,QAAQ,EAAE,OAAO;AACnB,CAAC,CAAC,CACD,QAAQ;;;;;AAMX,MAAM,yBAAyB,sBAC5B,OAAO,yBAAyB,KAAK,CAAC,CACtC,OAAO,sBAAsB,KAAK;;;;AC1CrC,MAAM,qBAAqB,EAAE,KAAK;CAChC;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,qBAAqB,EAAE,MAAM,EAAE,OAAO,CAAC;AAE7C,MAAM,eAAe,EAAE,mBAAmB,QAAQ;CAChD,EAAE,OAAO;EACP,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;EACjC,UAAU;EACV,KAAK;EACL,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,QAAQ,SAAS;CAC3B,CAAC;CACD,EAAE,OAAO;EACP,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;EACjC,UAAU;EACV,UAAU,EAAE,OAAO;EACnB,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,QAAQ,UAAU;CAC5B,CAAC;CAGD,EAAE,OAAO;EACP,UAAU;EACV,UAAU,EAAE,OAAO;EACnB,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,QAAQ,YAAY;CAC9B,CAAC;CACD,EAAE,OAAO;EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI;EAAG,UAAU,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,WAAW;CAAE,CAAC;CACxF,EAAE,OAAO;EAAE,UAAU,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,iBAAiB;CAAE,CAAC;CACrE,EAAE,OAAO;EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;EAAG,MAAM,EAAE,QAAQ,oBAAoB;CAAE,CAAC;CACnF,EAAE,OAAO;EAAE,MAAM,EAAE,OAAO;EAAG,OAAO,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,WAAW;CAAE,CAAC;CAC9E,EAAE,OAAO;EAAE,OAAO,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,WAAW;CAAE,CAAC;CAC5D,EAAE,OAAO;EAAE,UAAU,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,cAAc;CAAE,CAAC;CAClE,EAAE,OAAO;EACP,OAAO,EAAE,OAAO;EAChB,MAAM,EAAE,QAAQ,aAAa;EAC7B,SAAS;CACX,CAAC;CACD,EAAE,OAAO;EACP,OAAO;EACP,QAAQ,EAAE,OAAO;EACjB,MAAM,EAAE,QAAQ,sBAAsB;CACxC,CAAC;CACD,EAAE,OAAO;EAAE,OAAO,uBAAuB,QAAQ;EAAG,MAAM,EAAE,QAAQ,wBAAwB;CAAE,CAAC;CAE/F,EAAE,OAAO;EACP,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;EAC7B,UAAU,eAAe,SAAS;EAClC,OAAO,EAAE,OAAO;EAChB,MAAM,EAAE,QAAQ,UAAU;CAC5B,CAAC;CAED,EAAE,OAAO;EACP,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;EAC7B,UAAU,eAAe,SAAS;EAClC,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,QAAQ,aAAa;CAC/B,CAAC;CAED,EAAE,OAAO;EACP,SAAS,EAAE,OAAO;EAClB,UAAU,mBAAmB,SAAS;EACtC,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;EAC9B,MAAM,EAAE,QAAQ,WAAW;CAC7B,CAAC;CAED,EAAE,OAAO;EACP,SAAS,EAAE,OAAO;EAClB,UAAU;EACV,MAAM,EAAE,QAAQ,WAAW;CAC7B,CAAC;CAED,EAAE,OAAO;EACP,SAAS,EAAE,OAAO;EAClB,WAAW,EAAE,QAAQ;EACrB,MAAM,EAAE,QAAQ,mBAAmB;CACrC,CAAC;CAED,EAAE,OAAO;EACP,SAAS,EAAE,OAAO;EAClB,MAAM,EAAE,OAAO;EACf,MAAM,EAAE,QAAQ,aAAa;CAC/B,CAAC;AACH,CAAC;;;;AC/FD,MAAM,gBAAgB,SAAS,WAAmB,GAAG,OAAO,GAAG,OAAO,WAAW;AAEjF,MAAM,oBAA4B,aAAa,KAAK;;;;ACGpD,MAAM,gBAAgB,UAAmC,CACvD,MAAM,QACN,GAAG,MAAM,OAAO,KAAK,UAAU,MAAM,MAAM,CAC7C;AAEA,MAAM,aAAa,OAAgB,YACjC,MAAM,OAAO,MAAM,UAAU,MAAM,OAAO,OAAO;;;;;;AAenD,MAAM,QACJ,KACA,OACA,QACA,QAAQ,OACU;CAClB,MAAM,SAAS,MAAM;EAAE;EAAO,MAAM;EAAK;CAAO,CAAC;CACjD,IAAI,WAAW,QACb,OAAO;CAET,KAAK,MAAM,CAAC,YAAY,UAAU,IAAI,SAAS,QAAQ,GAAG;EACxD,IAAI,MAAM,SAAS,OAAO;GACxB,MAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU;GAChD,IAAI,UAAU,QACZ,OAAO;GAET;EACF;EACA,MAAM,WAAW,MAAM;GAAE,OAAO;GAAY,MAAM;GAAO,QAAQ;EAAI,CAAC;EACtE,IAAI,aAAa,QACf,OAAO;EAET,KAAK,MAAM,CAAC,UAAU,QAAQ,MAAM,SAAS,QAAQ,GAAG;GACtD,MAAM,QAAQ,MAAM;IAAE,OAAO;IAAU,MAAM;IAAK,QAAQ;GAAM,CAAC;GACjE,IAAI,UAAU,QACZ,OAAO;EAEX;CACF;AAEF;AAQA,MAAM,SAAS,SAA0C,KAAK,SAAS;AACvE,MAAM,SAAS,SAA0C,KAAK,SAAS;AACvE,MAAM,YAAY,SAA6C,KAAK,SAAS;;AAG7E,MAAM,UACJ,OACA,IACA,OAC2B;CAC3B,KAAK,MAAM,QAAQ,aAAa,KAAK,GAAG;EACtC,MAAM,QAAQ,KAAK,OAAO,EAAE,OAAO,MAAM,aACvC,KAAK,OAAO,MAAM,GAAG,IAAI,IAAI;GAAE;GAAO;GAAM;EAAO,IAAI,MACzD;EACA,IAAI,OACF,OAAO;CAEX;AAEF;AAEA,MAAM,uBAAuB,KAAc,QAAiC;CAC1E,KAAK,MAAM,EAAE,WAAW;EACtB,IAAI,KAAK,SAAS,UAChB,IAAI,KAAK,IAAI;CAGjB,CAAC;AACH;AAEA,MAAM,kBAAkB,UAAsC;CAC5D,MAAM,MAAyB,CAAC;CAChC,KAAK,MAAM,QAAQ,aAAa,KAAK,GACnC,oBAAoB,MAAM,GAAG;CAE/B,OAAO;AACT;AAEA,MAAM,kBAAkB,UAA2C,eAAe,KAAK,CAAC,CAAC;AAEzF,MAAM,cAAc,OAAgB,aAClC,OAAO,OAAO,UAAU,QAAQ,CAAC,EAAE;AAErC,MAAM,WAAW,OAAgB,UAA2C;CAC1E,MAAM,QAAQ,OAAO,OAAO,OAAO,KAAK;CACxC,OAAO,OAAO,QAAQ,SAAS,WAC3B;EAAE,WAAW,MAAM;EAAQ,OAAO,MAAM;EAAO,KAAK,MAAM;CAAK,IAC/D;AACN;AAEA,MAAM,WAAW,OAAgB,OAAoC,OAAO,OAAO,IAAI,KAAK,CAAC,EAAE;AAE/F,MAAM,sBAAsB,OAAgB,OAA2C;CACrF,KAAK,MAAM,QAAQ,aAAa,KAAK,GAAG;EACtC,MAAM,QAAQ,KAAK,OAAO,EAAE,WAAY,KAAK,OAAO,KAAK,OAAO,MAAU;EAC1E,IAAI,OACF,OAAO;CAEX;AAEF;AAEA,MAAM,sBAAsB,OAAgB,WAAwC;CAClF,KAAK,MAAM,QAAQ,aAAa,KAAK,GAEnC,IADY,KAAK,OAAO,EAAE,WAAY,KAAK,OAAO,SAAS,OAAO,MAC5D,GACJ,OAAO;AAIb;AAEA,MAAM,oBACJ,OACA,aACmD;CACnD,MAAM,QAAQ,OAAO,OAAO,UAAU,QAAQ;CAC9C,OAAO,OAAO,QAAQ,SAAS,QAAQ;EAAE,OAAO,MAAM;EAAO,QAAQ,MAAM;CAAO,IAAI;AACxF;AAEA,MAAM,mBAAmB,KAAc,QAA6B;CAClE,KAAK,MAAM,EAAE,WAAW;EACtB,IAAI,KAAK,KAAK,EAAE;CAElB,CAAC;AACH;AAEA,MAAM,oBAAoB,UAAkC;CAC1D,MAAM,MAAqB,CAAC;CAC5B,KAAK,MAAM,SAAS,MAAM,QACxB,IAAI,KAAK,MAAM,EAAE;CAEnB,KAAK,MAAM,QAAQ,aAAa,KAAK,GACnC,gBAAgB,MAAM,GAAG;CAE3B,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,6BAAa,IAAI,IAAY;CACnC,KAAK,MAAM,MAAM,KAAK;EACpB,IAAI,KAAK,IAAI,EAAE,GACb,WAAW,IAAI,EAAE;EAEnB,KAAK,IAAI,EAAE;CACb;CACA,OAAO,CAAC,GAAG,UAAU;AACvB;;;;ACtJA,MAAM,eAAe,UACnB,OAAO,UAAU,WAAW;CAAE,MAAM;CAAM;AAAM,IAAI;AAUtD,MAAM,OAAO,WAAmB,MAAc,UAAsB,CAAC,OAAgB;CACnF;CACA;CACA,MAAM;CACN,GAAG;CACH,IAAI,QAAQ,MAAM;AACpB;AAaA,MAAM,UAAU,UAA0B,UAAyB,CAAC,MAAkB;CACpF,MAAM,EAAE,KAAK,KAAK,GAAG,SAAS;CAC9B,OAAO;EACL;EACA,MAAM;EACN,GAAG;EACH,GAAI,QAAQ,SAAY,CAAC,IAAI,EAAE,KAAK,YAAY,GAAG,EAAE;EACrD,GAAI,QAAQ,SAAY,CAAC,IAAI,EAAE,KAAK,YAAY,GAAG,EAAE;EACrD,IAAI,QAAQ,MAAM,aAAa,QAAQ;EACvC,UAAU,cAAc,SAAS,QAAQ,QAAQ,YAAY,CAAC;EAC9D,QAAQ,QAAQ;CAClB;AACF;AAWA,MAAM,OAAO,UAA+B,UAAsB,CAAC,MAAe;CAChF,MAAM,EAAE,KAAK,KAAK,GAAG,SAAS;CAC9B,OAAO;EACL;EACA,MAAM;EACN,GAAG;EACH,GAAI,QAAQ,SAAY,CAAC,IAAI,EAAE,KAAK,YAAY,GAAG,EAAE;EACrD,GAAI,QAAQ,SAAY,CAAC,IAAI,EAAE,KAAK,YAAY,GAAG,EAAE;EACrD,IAAI,QAAQ,MAAM,aAAa,KAAK;EACpC,aAAa,QAAQ,eAAe;EACpC,QAAQ,QAAQ;CAClB;AACF;AAOA,MAAM,aAAa,QAAiB,UAAoB,UAAwB,CAAC,OAAkB;CACjG;CACA;CACA,MAAM;CACN,GAAG;CACH,IAAI,QAAQ,MAAM,aAAa,OAAO;AACxC;AASA,MAAM,SAAS,QAAiB,UAAwB,CAAC,MAAe;CACtE,MAAM,QAAiB;EACrB;EACA,SAAS;EACT,GAAG;EACH,QAAQ,QAAQ,UAAU,CAAC;EAC3B,QAAQ,QAAQ,UAAU,CAAC;CAC7B;CACA,MAAM,aAAa,iBAAiB,KAAK;CACzC,IAAI,WAAW,SAAS,GAEtB,QAAQ,KACN,kDAAkD,WAAW,KAAK,IAAI,EAAE,6CAC1E;CAEF,OAAO;AACT;;;;ACzHA,MAAM,eAAe,UAAwB;CAC3C,MAAM,IAAI,MAAM,sBAAsB,KAAK,UAAU,KAAK,GAAG;AAC/D;;;;ACOA,MAAM,wBAAwB;AAE9B,MAAM,iBACJ,SACA,SACiE;CACjE,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK,KAAK;CACvC,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK,KAAK;CACvC,OAAO;EAAE,QAAQ,IAAI;EAAI,MAAM;EAAI,OAAO,IAAI;EAAI,KAAK;CAAG;AAC5D;AAEA,MAAM,eAAe,MAA0E;CAC7F,MAAM,MAAM,KAAK,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;CACrD,IAAI,QAAQ,EAAE,MACZ,OAAO;CAET,IAAI,QAAQ,EAAE,OACZ,OAAO;CAET,IAAI,QAAQ,EAAE,KACZ,OAAO;CAET,OAAO;AACT;AAEA,MAAM,aAAa,aAA6C;CAC9D,QAAQ,UAAR;EACE,KAAK,UACH;EAEF,KAAK,gBACH,OAAO;EAET,KAAK,cACH,OAAO;EAET,KAAK,eACH,OAAO;EAET,KAAK,aACH,OAAO;EAET,SACE,OAAO,YAAY,QAAQ;CAE/B;AACF;AAEA,MAAM,qBAAqB,SAAgB,MAAY,SAAqC;CAC1F,MAAM,OAAO,MAAM,gBAAgB;CAEnC,IAAI,KAAK,SAAS,KAAK,KAAK,UAAU,GACpC,OAAO;CAET,MAAM,YAAY,cAAc,SAAS,IAAI;CAG7C,IAFY,KAAK,IAAI,UAAU,MAAM,UAAU,OAAO,UAAU,KAAK,UAAU,MAEzE,IAAI,MACR,OAAO;CAET,OAAO,SAAS,YAAY,SAAS;AACvC;AAEA,MAAM,oBAAoB,MAAY,SAAwC;CAC5E,MAAM,EAAE,QAAQ,GAAG,OAAO,GAAG,GAAG,MAAM;CACtC,MAAM,KAAY;EAAE;EAAG;CAAE;CACzB,MAAM,KAAY;EAAE,GAAG,IAAI;EAAG;CAAE;CAChC,MAAM,KAAY;EAAE,GAAG,IAAI;EAAG,GAAG,IAAI;CAAE;CACvC,MAAM,KAAY;EAAE;EAAG,GAAG,IAAI;CAAE;CAChC,IAAI,KAAK,KAAK,KAAK,GACjB,OAAO,CAAC;EAAE,UAAU;EAAU,QAAQ;GAAC;GAAI;GAAI;GAAI;EAAE;CAAE,CAAC;CAE1D,MAAM,OAAO,MAAM,gBAAgB;CACnC,MAAM,KAAK,OAAO;CAClB,MAAM,KAAK,OAAO;CAClB,MAAM,UAAiB;EAAE,GAAG,IAAI;EAAI,GAAG,IAAI;CAAG;CAC9C,MAAM,UAAiB;EAAE,GAAG,IAAI,IAAI;EAAI,GAAG,IAAI;CAAG;CAClD,MAAM,UAAiB;EAAE,GAAG,IAAI,IAAI;EAAI,GAAG,IAAI,IAAI;CAAG;CACtD,MAAM,UAAiB;EAAE,GAAG,IAAI;EAAI,GAAG,IAAI,IAAI;CAAG;CAClD,OAAO;EACL;GAAE,UAAU;GAAU,QAAQ;IAAC;IAAS;IAAS;IAAS;GAAO;EAAE;EACnE;GAAE,UAAU;GAAc,QAAQ;IAAC;IAAI;IAAS;IAAS;GAAE;EAAE;EAC7D;GAAE,UAAU;GAAe,QAAQ;IAAC;IAAI;IAAI;IAAS;GAAO;EAAE;EAC9D;GAAE,UAAU;GAAa,QAAQ;IAAC;IAAI;IAAI;IAAS;GAAO;EAAE;EAC5D;GAAE,UAAU;GAAgB,QAAQ;IAAC;IAAI;IAAS;IAAS;GAAE;EAAE;CACjE;AACF;AAEA,MAAM,YAAY,MAAY,aAAiC;CAC7D,MAAM,QAAQ,KAAK,QAAQ;CAC3B,MAAM,QAAQ,KAAK,SAAS;CAC5B,QAAQ,UAAR;EACE,KAAK,gBACH,OAAO;GAAE,QAAQ;GAAO,OAAO,KAAK;GAAO,GAAG,KAAK;GAAG,GAAG,KAAK,IAAI;EAAM;EAE1E,KAAK,cACH,OAAO;GAAE,QAAQ,KAAK;GAAQ,OAAO;GAAO,GAAG,KAAK;GAAG,GAAG,KAAK;EAAE;EAEnE,KAAK,eACH,OAAO;GAAE,QAAQ,KAAK;GAAQ,OAAO;GAAO,GAAG,KAAK,IAAI;GAAO,GAAG,KAAK;EAAE;EAE3E,KAAK,aACH,OAAO;GAAE,QAAQ;GAAO,OAAO,KAAK;GAAO,GAAG,KAAK;GAAG,GAAG,KAAK;EAAE;EAElE,KAAK,UACH,OAAO;EAET,SACE,OAAO,YAAY,QAAQ;CAE/B;AACF;;;;ACtHA,MAAM,yBAAyB;AAE/B,MAAM,mBAAmB;AAEzB,MAAM,gBAAgB,SAAsB,cAA4B;CACtE,IAAI,aAAa,GACf;CAEF,KAAK,IAAI,WAAW,WAAW,WAAW,KAAK,YAAY,WAAW;EACpE,MAAM,UAAU,KAAK,MAAM,WAAW,gBAAgB,IAAI;EAC1D,IAAI,UAAU,KACZ,QAAQ,IAAI,OAAO;CAEvB;AACF;AAEA,MAAM,sBAAsB,QAAoB,eAAsC;CACpF,MAAM,0BAAU,IAAI,IAAY;CAChC,IAAI,OAAO,SAAS,UAAa,OAAO,OAAO,GAC7C,aAAa,SAAS,OAAO,IAAI;CAEnC,IAAI,OAAO,cAAc,QAAW;EAClC,MAAM,YAAY,OAAO,cAAc,WAAW,aAAa,OAAO;EACtE,IAAI,aAAa,GACf,aAAa,SAAS,MAAM,SAAS;CAEzC;CACA,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,UAAU,GAAG,MAAM,IAAI,CAAC;AAC9C;AAIA,MAAM,mBAAmB,QAA2B,gBAAkC;CACpF,SAAS,WAAW,OAAO,CAAC,IAAI,mBAAmB,QAAQ,UAAU;CACrE,WAAW,QAAQ;AACrB;AAEA,MAAM,eAAe,SAA4B,KAAK,QAAQ,SAAS;AAEvE,MAAM,iBAAiB,UAAkB,YACvC,QAAQ,QAA4B,MAAM,WAAW;CACnD,IAAI,SAAS,UAAa,KAAK,IAAI,SAAS,QAAQ,IAAI,KAAK,IAAI,OAAO,QAAQ,GAC9E,OAAO;CAET,OAAO;AACT,GAAG,MAAS;AAId,MAAM,aAAa,OAAsB,eAAuB,SAA+B;CAC7F,MAAM,EAAE,SAAS,cAAc;CAC/B,MAAM,OAAO,MAAM;CACnB,MAAM,QAAQ,MAAM,gBAAgB;CACpC,IAAI,gBAAgB,KAAK,SAAS,UAAa,UAAU,UAAa,QAAQ,WAAW,GACvF,OAAO;EAAE;EAAO,SAAS;CAAM;CAGjC,IAAI,WAAW;CACf,KAAK,IAAI,QAAQ,GAAG,SAAS,eAAe,SAC1C,YAAY,MAAM,UAAU;CAG9B,MAAM,SAAS,cAAc,UAAU,OAAO;CAC9C,IAAI,WAAW,UAAa,KAAK,IAAI,SAAS,QAAQ,IAAI,WACxD,OAAO;EAAE;EAAO,SAAS;CAAM;CAGjC,MAAM,QAAQ,SAAS;CACvB,IAAI,OAAO,QAAQ,KAAK,QAAQ,QAAQ,GACtC,OAAO;EAAE;EAAO,SAAS;CAAM;CAGjC,MAAM,OAAO,CAAC,GAAG,KAAK;CACtB,KAAK,iBAAiB,OAAO;CAC7B,KAAK,gBAAgB,KAAK,QAAQ;CAClC,OAAO;EAAE,OAAO;EAAM,SAAS;CAAK;AACtC;AAOA,MAAM,cACJ,OACA,eACA,SACiB;CACjB,IAAI,kBAAkB,QAAQ,CAAC,YAAY,IAAI,GAC7C,OAAO,EAAE,MAAM,WAAW;CAE5B,MAAM,EAAE,OAAO,cAAc,YAAY,UAAU,OAAO,eAAe,IAAI;CAC7E,OAAO,UAAU;EAAE,MAAM;EAAU,OAAO;CAAa,IAAI,EAAE,MAAM,QAAQ;AAC7E;AAEA,MAAM,cACJ,OACA,eACA,SACkB;CAClB,MAAM,WAAW,WAAW,OAAO,eAAe,IAAI;CACtD,OAAO,SAAS,SAAS,WAAW,SAAS,QAAQ;AACvD;;;;;;;;;AC/FA,MAAM,eAAe,KAAc,aAAiC;CAClE,MAAM,QAAkB;EACtB,GAAG;EACH,QAAQ,IAAI;EACZ,GAAI,IAAI,QAAQ,SAAY,CAAC,IAAI,EAAE,KAAK,IAAI,IAAI;EAChD,GAAI,IAAI,QAAQ,SAAY,CAAC,IAAI,EAAE,KAAK,IAAI,IAAI;CAClD;CAEA,IAAI,MAAM,SAAS,SAAS,IAAI,SAAS,QACvC,OAAO;EAAE,GAAG;EAAO,MAAM,IAAI;CAAK;CAEpC,OAAO;AACT;;AAGA,MAAM,wBACJ,UACA,kBACwB;CACxB,MAAM,MAA2B,CAAC;CAElC,KAAK,MAAM,SAAS,UAAU;EAC5B,IAAI,MAAM,SAAS,UAAU;GAC3B,IAAI,MAAM,SAAS,SAAS,GAAG;IAC7B,IAAI,KAAK,KAAK;IACd,cAAc,KAAK,MAAM,EAAE;GAC7B;GACA;EACF;EAIA,MAAM,gBAAgB,qBAAqB,MAAM,UAAU,aAAa;EACxE,IAAI,cAAc,WAAW,GAC3B;EAEF,IAAI,cAAc,WAAW,GAAG;GAC9B,MAAM,OAAO,cAAc;GAC3B,IAAI,SAAS,QACX,IAAI,KAAK,YAAY,OAAO,IAAI,CAAC;GAEnC;EACF;EACA,IAAI,KAAK;GAAE,GAAG;GAAO,UAAU;EAAc,CAAC;CAChD;CAEA,OAAO;AACT;AAEA,MAAM,mBAAmB,MAAe,kBAA0C;CAChF,IAAI,WAAW,qBAAqB,KAAK,UAAU,aAAa;CAChE,IAAI,cAAc,KAAK;CAEvB,IAAI,QAAQ,SAAS;CACrB,OAAO,SAAS,WAAW,KAAK,OAAO,SAAS,OAAO;EACrD,WAAW,MAAM;EACjB,cAAc,MAAM;EACpB,QAAQ,SAAS;CACnB;CAEA,OAAO;EAAE,GAAG;EAAM;EAAU;CAAY;AAC1C;AAEA,MAAM,aAAa,UAA4B;CAC7C,MAAM,gBAA+B,CAAC;CACtC,MAAM,SAAS,gBAAgB,MAAM,QAAQ,aAAa;CAE1D,MAAM,SAA2B,CAAC;CAClC,MAAM,iBAAgC,CAAC;CACvC,KAAK,MAAM,SAAS,MAAM,QAAQ;EAChC,MAAM,eAA8B,CAAC;EACrC,MAAM,cAAc,gBAAgB,MAAM,QAAQ,YAAY;EAC9D,IAAI,YAAY,SAAS,SAAS,GAAG;GACnC,OAAO,KAAK;IAAE,GAAG;IAAO,QAAQ;GAAY,CAAC;GAC7C,eAAe,KAAK,GAAG,YAAY;EACrC;CACF;CAEA,MAAM,UAAU,IAAI,IAAI,aAAa;CACrC,MAAM,0BAAU,IAAI,IAAI,CAAC,GAAG,eAAe,GAAG,cAAc,CAAC;CAC7D,MAAM,gBAAgB,cAAc,MAAM,eAAe;CAEzD,MAAM,iBACJ,MAAM,mBAAmB,UAAa,QAAQ,IAAI,MAAM,cAAc,IAClE,MAAM,iBACN;CAIN,MAAM,oBACJ,MAAM,sBAAsB,UAAa,QAAQ,IAAI,MAAM,iBAAiB,IACxE,MAAM,oBACN;CAEN,OAAO;EAAE,GAAG;EAAO;EAAgB;EAAQ;EAAQ;CAAkB;AACvE;;;;AC5FA,MAAM,yBAAyB,OAAgB,aAA6C;CAC1F,MAAM,QAAQ,iBAAiB,OAAO,QAAQ;CAC9C,IAAI,CAAC,OACH;CAEF,MAAM,CAAC,WAAW,MAAM,OAAO,SAAS,OAAO,MAAM,OAAO,CAAC;CAC7D,OAAO,SAAS,SAAS,WAAW,UAAU;AAChD;;AAGA,MAAM,kBAAkB;CACtB,gBAAgB;EAAE,QAAQ;EAAO,aAAa;CAAS;CACvD,cAAc;EAAE,QAAQ;EAAM,aAAa;CAAM;CACjD,eAAe;EAAE,QAAQ;EAAO,aAAa;CAAM;CACnD,aAAa;EAAE,QAAQ;EAAM,aAAa;CAAS;AACrD;AAEA,MAAM,qBACJ,OACA,QACA,UACA,aACY;CACZ,MAAM,eAAe,WAAW,OAAO,QAAQ;CAC/C,MAAM,QAAQ,iBAAiB,OAAO,QAAQ;CAC9C,IAAI,CAAC,gBAAgB,CAAC,OACpB,OAAO;CAGT,MAAM,EAAE,QAAQ,gBAAgB,gBAAgB;CAEhD,IAAI,MAAM,OAAO,gBAAgB,aAAa;EAC5C,MAAM,OAAO,aAAa,SAAS;EACnC,aAAa,SAAS;EACtB,OAAO,SAAS;EAChB,MAAM,OAAO,SAAS,OAAO,SAAS,MAAM,QAAQ,MAAM,QAAQ,GAAG,GAAG,MAAM;CAChF,OAAO;EACL,MAAM,SAAkB;GACtB,UAAU,SAAS,CAAC,QAAQ,YAAY,IAAI,CAAC,cAAc,MAAM;GACjE,IAAI,aAAa,KAAK;GACtB;GACA,MAAM;GACN,QAAQ,aAAa;EACvB;EACA,aAAa,SAAS;EACtB,OAAO,SAAS;EAChB,MAAM,OAAO,SAAS,OAAO,MAAM,OAAO,GAAG,MAAM;CACrD;CAEA,MAAM,iBAAiB,OAAO;CAC9B,OAAO;AACT;AAIA,MAAM,aAAa,OAAgB,KAAc,WAAgC;CAC/E,MAAM,EAAE,IAAI,UAAU,OAAO,aAAa;CAC1C,MAAM,eAAe,WAAW,OAAO,QAAQ;CAC/C,IAAI,CAAC,cACH,OAAO;CAGT,IAAI,aAAa,UAAU;EACzB,MAAM,KAAK,KAAK,IACd,KAAK,IAAI,SAAS,aAAa,SAAS,QAAQ,CAAC,GACjD,aAAa,SAAS,MACxB;EACA,aAAa,SAAS,OAAO,IAAI,GAAG,GAAG;EACvC,aAAa,WAAW;EACxB,OAAO;CACT;CAEA,MAAM,YAAwB;EAC5B,UAAU,CAAC,GAAG;EACd,IAAI,aAAa,QAAQ;EACzB,UAAU;EACV,MAAM;EACN;CACF;CACA,OAAO,kBAAkB,OAAO,WAAW,UAAU,QAAQ;AAC/D;;AAGA,MAAM,aAAa,WAAyB,UAAuC;CACjF,MAAM,UAAU,UAAU,SAAS,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;CACxD,UAAU,WAAW,cAAc,UAAU,SAAS,QAAQ,UAAU,QAAQ;CAChF,OAAO;AACT;AAEA,MAAM,iBAAiB,QAAoB,MAAsB,mBAAiC;CAChG,MAAM,aAAa,OAAO,SAAS;CACnC,OAAO,SAAS,KAAK,GAAG,IAAI;CAC5B,OAAO,WAAW,aAAa;AACjC;AAEA,MAAM,mBAAmB,SAA2B;CAClD,UAAU,CACR;EACE,UAAU,CAAC,GAAG;EACd,IAAI,aAAa,QAAQ;EACzB,UAAU;EACV,MAAM;EACN;CACF,CACF;CACA,IAAI,aAAa,KAAK;CACtB,aAAa;CACb,MAAM;CACN;AACF;AAEA,MAAM,sBAAsB,YAAiC;CAC3D,UAAU,CAAC,MAAM;CACjB,IAAI,aAAa,KAAK;CACtB,aAAa;CACb,MAAM;CACN;AACF;;;;ACnHA,MAAM,yBAAmC;CAAE,QAAQ;CAAK,MAAM;CAAI,KAAK;CAAI,OAAO;AAAI;AAEtF,MAAM,mBAAmB,MAAc,WAAqC;CAC1E,MAAM,OAAO,IAAI,IAAI,OAAO,KAAK,UAAU,MAAM,IAAI,CAAC;CACtD,IAAI,CAAC,KAAK,IAAI,IAAI,GAChB,OAAO;CAET,IAAI,QAAQ;CACZ,OAAO,KAAK,IAAI,GAAG,KAAK,GAAG,OAAO,GAChC,SAAS;CAEX,OAAO,GAAG,KAAK,GAAG;AACpB;AAEA,MAAM,aACJ,OACA,QACA,UACA,YACS;CACT,MAAM,QAAmB;EACvB,UAAU,YAAY;EACtB,IAAI,WAAW,aAAa,OAAO;EACnC;EACA,MAAM,gBAAgB,SAAS,MAAM,MAAM;EAC3C,MAAM;CACR;CACA,MAAM,SAAS,CAAC,GAAG,MAAM,QAAQ,KAAK;CAEtC,MAAM,UAA6B,CAAC;CACpC,oBAAoB,QAAQ,OAAO;CACnC,MAAM,QAAQ,QAAQ,GAAG,CAAC;CAC1B,IAAI,OACF,MAAM,iBAAiB,MAAM;AAEjC;AAEA,MAAM,mBACJ,OACA,UACA,UACA,YACY;CACZ,MAAM,WAAW,sBAAsB,OAAO,QAAQ;CACtD,IAAI,CAAC,UACH,OAAO;CAET,UAAU,OAAO,mBAAmB,QAAQ,GAAG,UAAU,OAAO;CAChE,OAAO;AACT;AAEA,MAAM,qBACJ,OACA,aAC2B;CAC3B,MAAM,cAAiC,CAAC;CACxC,oBAAoB,MAAM,QAAQ,WAAW;CAC7C,IAAI,aAAa,QAAW;EAC1B,MAAM,WAAW,YAAY,MAAM,WAAW,OAAO,OAAO,QAAQ;EACpE,IAAI,UACF,OAAO;CAEX;CACA,IAAI,MAAM,mBAAmB,QAAW;EACtC,MAAM,SAAS,YAAY,MAAM,WAAW,OAAO,OAAO,MAAM,cAAc;EAC9E,IAAI,QACF,OAAO;CAEX;CACA,OAAO,YAAY;AACrB;AAEA,MAAM,aACJ,OACA,SACA,UACA,aACY;CACZ,MAAM,QAAQ,MAAM,OAAO,WAAW,UAAU,MAAM,OAAO,OAAO;CACpE,MAAM,QAAQ,MAAM,OAAO,GAAG,KAAK;CACnC,IAAI,UAAU,MAAM,CAAC,OACnB,OAAO;CAGT,MAAM,UAA6B,CAAC;CACpC,oBAAoB,MAAM,QAAQ,OAAO;CACzC,MAAM,OAAO,QAAQ,SAAS,WAAW,OAAO,QAAQ;CACxD,IAAI,KAAK,WAAW,GAClB,OAAO;CAGT,MAAM,aAAa,QAAQ,GAAG,CAAC;CAC/B,MAAM,iBAAiB,aACnB,cAAc,WAAW,SAAS,QAAQ,WAAW,QAAQ,IAC7D;CAIJ,MAAM,SAAS,kBAAkB,OAAO,QAAQ;CAChD,MAAM,OAAO,OAAO,OAAO,CAAC;CAE5B,IAAI,CAAC,QAAQ;EACX,MAAM,SAAS,MAAM;EACrB,MAAM,iBAAiB,YAAY;EACnC,OAAO;CACT;CAEA,IAAI,aAAa,UAAU;EACzB,cAAc,QAAQ,MAAM,cAAc;EAC1C,MAAM,iBAAiB,OAAO;EAC9B,OAAO;CACT;CAEA,MAAM,SACJ,QAAQ,WAAW,KAAK,aACpB,aACA;EACE,UAAU;EACV,IAAI,aAAa,QAAQ;EACzB,UAAU;EACV,MAAM;EACN;CACF;CACN,OAAO,kBAAkB,OAAO,QAAQ,OAAO,IAAI,YAAY,aAAa;AAC9E;;;;ACnHA,MAAM,kBAAkB,MAAsB,UAA8C;CAC1F,QAAQ,KAAK,MAAb;EACE,KAAK,OACH,OAAO,sBAAsB,MAAM,KAAK;EAE1C,KAAK,OACH,OAAO,sBAAsB,MAAM,KAAK;EAE1C,KAAK,UAAU;GACb,MAAM,SAAS,yBAAyB,MAAM,KAAK;GACnD,OAAO,OAAO,aAAa,SACvB,SACA;IAAE,GAAG;IAAQ,UAAU,cAAc,KAAK,SAAS,QAAQ,OAAO,QAAQ;GAAE;EAClF;EACA,SACE,OAAO,YAAY,IAAI;CAE3B;AACF;AAEA,MAAM,gBAAgB,GAAa,MACjC,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE;AAEjF,MAAM,kBACJ,QACA,UACY;CACZ,MAAM,UAAU,IAAI,IAAqB,OAAO,QAAQ,MAAM,CAAC;CAC/D,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,WAAW,OAAO,GAAG,QAAQ,IAAI,GAAG,GAAG,KAAK,CAAC;AACzF;;AAGA,MAAM,eAAe,OAAgB,WAA4B;CAC/D,QAAQ,OAAO,MAAf;EACE,KAAK,WACH,OAAO,UAAU,OAAO,OAAO,KAAK;GAClC,IAAI,OAAO;GACX,OAAO,OAAO;GACd,UAAU,OAAO;EACnB,CAAC;EAEH,KAAK,eAAe;GAClB,MAAM,MAAM,QAAQ,OAAO,OAAO,KAAK;GACvC,IAAI,CAAC,KACH,OAAO;GAET,IAAI,UAAU;GACd,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,QAAQ,SAAS;IAC1D,MAAM,QAAQ,IAAI,SAAS,GAAG,KAAK;IACnC,MAAM,SAAS,OAAO,QAAQ;IAC9B,IAAI,CAAC,SAAS,WAAW,UAAa,MAAM,WAAW,QACrD;IAEF,MAAM,SAAS;IACf,UAAU;GACZ;GACA,OAAO;EACT;EACA,KAAK,aAAa;GAChB,MAAM,WAAW,QAAQ,OAAO,OAAO,KAAK;GAC5C,IAAI,CAAC,UACH,OAAO;GAET,UAAU,SAAS,WAAW,SAAS,KAAK;GAC5C,OAAO;EACT;EACA,KAAK,gBACH,OAAO,sBAAsB,OAAO,OAAO,QAAQ,MAAM;EAE3D,KAAK,aACH,OAAO,UAAU,OAAO,OAAO,SAAS,OAAO,UAAU,OAAO,QAAQ;EAE1E,KAAK,YAAY;GACf,MAAM,WAAW,QAAQ,OAAO,OAAO,KAAK;GAC5C,IAAI,CAAC,UACH,OAAO;GAET,MAAM,UAAU,UAAU,SAAS,WAAW,SAAS,KAAK;GAC5D,IAAI,CAAC,SACH,OAAO;GAET,UAAU,OAAO,gBAAgB,OAAO,GAAG,OAAO,UAAU,OAAO,OAAO;GAC1E,OAAO;EACT;EACA,KAAK,eACH,OAAO,gBAAgB,OAAO,OAAO,UAAU,OAAO,UAAU,OAAO,OAAO;EAEhF,KAAK,aAAa;GAChB,MAAM,QAAQ,UAAU,OAAO,OAAO,OAAO;GAC7C,IAAI,CAAC,SAAS,aAAa,MAAM,UAAU,OAAO,QAAQ,GACxD,OAAO;GAET,MAAM,WAAW,OAAO;GACxB,OAAO;EACT;EACA,KAAK,YAAY;GACf,MAAM,SAAS,QAAQ,OAAO,OAAO,QAAQ;GAE7C,IAAI,CAAC,UAAU,CAAC,WAAW,OAAO,OAAO,QAAQ,GAC/C,OAAO;GAGT,MAAM,UAAU,UAAU,OAAO,WAAW,OAAO,KAAK;GACxD,IAAI,CAAC,SACH,OAAO;GAET,OAAO,UAAU,OAAO,SAAS;IAC/B,IAAI,OAAO;IACX,OAAO,OAAO;IACd,UAAU,OAAO;GACnB,CAAC;EACH;EACA,KAAK,cAAc;GACjB,IAAI,OAAO,aAAa,OAAO,UAC7B,OAAO;GAET,MAAM,SAAS,WAAW,OAAO,OAAO,QAAQ;GAChD,MAAM,SAAS,WAAW,OAAO,OAAO,QAAQ;GAChD,IAAI,CAAC,UAAU,CAAC,QACd,OAAO;GAET,IAAI,OAAO,aAAa,UAAU;IAChC,cACE,QACA,OAAO,UACP,cAAc,OAAO,SAAS,QAAQ,OAAO,QAAQ,CACvD;IACA,sBAAsB,OAAO,OAAO,QAAQ;IAC5C,OAAO;GACT;GAEA,MAAM,WAAW,sBAAsB,OAAO,OAAO,QAAQ;GAC7D,OAAO,WACH,kBAAkB,OAAO,UAAU,OAAO,UAAU,OAAO,QAAQ,IACnE;EACN;EACA,KAAK,eAAe;GAClB,MAAM,QAAQ,UAAU,OAAO,OAAO,OAAO;GAC7C,IAAI,CAAC,OACH,OAAO;GAET,MAAM,SAAS,MAAM,OAAO,QAAQ,UAAU,MAAM,OAAO,OAAO,OAAO;GACzE,MAAM,OAAO,gBAAgB,OAAO,MAAM,MAAM;GAChD,IAAI,MAAM,SAAS,MACjB,OAAO;GAET,MAAM,OAAO;GACb,OAAO;EACT;EACA,KAAK,aAAa;GAChB,MAAM,WAAW,QAAQ,OAAO,OAAO,KAAK;GAC5C,IAAI,CAAC,YAAY,SAAS,IAAI,SAAS,OAAO,MAC5C,OAAO;GAET,SAAS,IAAI,OAAO,OAAO;GAC3B,OAAO;EACT;EACA,KAAK,aAAa;GAChB,MAAM,SAAS,WAAW,OAAO,OAAO,QAAQ;GAChD,IAAI,CAAC,QACH,OAAO;GAET,MAAM,WAAW,cAAc,OAAO,SAAS,QAAQ,OAAO,KAAK;GACnE,IAAI,OAAO,aAAa,UACtB,OAAO;GAET,OAAO,WAAW;GAClB,OAAO;EACT;EACA,KAAK;GACH,IAAI,MAAM,mBAAmB,OAAO,YAAY,CAAC,WAAW,OAAO,OAAO,QAAQ,GAChF,OAAO;GAET,MAAM,iBAAiB,OAAO;GAC9B,OAAO;EAET,KAAK,qBAAqB;GACxB,MAAM,QAAQ,UAAU,OAAO,OAAO,OAAO;GAC7C,IAAI,CAAC,UAAU,MAAM,aAAa,WAAW,OAAO,WAClD,OAAO;GAET,MAAM,YAAY,OAAO;GACzB,OAAO;EACT;EACA,KAAK,sBAAsB;GACzB,MAAM,OAAO,OAAO,YAAY;GAChC,IAAI,MAAM,sBAAsB,MAC9B,OAAO;GAET,MAAM,oBAAoB;GAC1B,OAAO;EACT;EACA,KAAK;GACH,IAAI,eAAe,MAAM,QAAQ,OAAO,KAAK,GAC3C,OAAO;GAET,OAAO,OAAO,MAAM,QAAQ,OAAO,KAAK;GACxC,OAAO;EAET,KAAK,wBAAwB;GAC3B,MAAM,OAAO,mBAAmB,OAAO,OAAO,MAAM;GACpD,IAAI,CAAC,MACH,OAAO;GAET,MAAM,SAAS,eAAe,MAAM,OAAO,KAAK;GAChD,IAAI,eAAe,MAAM,MAAM,GAC7B,OAAO;GAET,OAAO,OAAO,MAAM,MAAM;GAC1B,OAAO;EACT;EACA,SACE,OAAO,YAAY,MAAM;CAE7B;AACF;;;AAIA,MAAM,WAAW,OAAgB,WAA4B;CAC3D,MAAM,QAAQ,gBAAgB,KAAK;CACnC,IAAI,CAAC,YAAY,OAAO,MAAM,GAC5B,OAAO;CAET,OAAO,UAAU,KAAK;AACxB;;;;AC7OA,MAAM,gBAAgB;AAEtB,MAAM,iBAAiB,aAA+B;CACpD,QAAQ,CAAC;CACT,MAAM,CAAC;CACP;AACF;AAEA,MAAM,WAAW,YAA8B,QAAQ,KAAK,SAAS;AACrE,MAAM,WAAW,YAA8B,QAAQ,OAAO,SAAS;;;;;;AAOvE,MAAM,YAAY,SAAkB,WAA4B;CAC9D,MAAM,UAAU,QAAQ,QAAQ,SAAS,MAAM;CAC/C,IAAI,OAAO,GAAG,SAAS,QAAQ,OAAO,GACpC,OAAO;CAET,OAAO;EAAE,QAAQ,CAAC;EAAG,MAAM,CAAC,GAAG,QAAQ,MAAM,QAAQ,OAAO,CAAC,CAAC,MAAM,IAAc;EAAG;CAAQ;AAC/F;AAEA,MAAM,QAAQ,YAA8B;CAC1C,MAAM,WAAW,QAAQ,KAAK,GAAG,EAAE;CACnC,IAAI,aAAa,QACf,OAAO;CAET,OAAO;EACL,QAAQ,CAAC,QAAQ,SAAS,GAAG,QAAQ,MAAM;EAC3C,MAAM,QAAQ,KAAK,MAAM,GAAG,EAAE;EAC9B,SAAS;CACX;AACF;AAEA,MAAM,QAAQ,YAA8B;CAC1C,MAAM,CAAC,MAAM,GAAG,QAAQ,QAAQ;CAChC,IAAI,SAAS,QACX,OAAO;CAET,OAAO;EACL,QAAQ;EACR,MAAM,CAAC,GAAG,QAAQ,MAAM,QAAQ,OAAO,CAAC,CAAC,MAAM,IAAc;EAC7D,SAAS;CACX;AACF;;;;ACxCA,MAAM,iBAAiB,MAAM,EAC3B,OAAO;CAEL,SAAS,CAAC;CAEV,QAAQ,CAAC;CAET,OAAO,CAAC;AACV,EACF,CAAC,CAAC,CAAC,cAAc;CACf,UAAU,EAAE,aAAa,EAAE,SAAS,cAAc,MAAM,KAAK,EAAE;CAC/D,IAAI;CACJ,SAAS;CACT,QAAQ,EACN,OAAO,EACL,IAAI;EACF,UAAU,EACR,SAAS,OAAO,EACd,UAAU,EAAE,SAAS,YAAY,SAAS,QAAQ,SAAS,MAAM,MAAM,EACzE,CAAC,EACH;EACA,MAAM,EACJ,SAAS,OAAO,EAAE,UAAU,EAAE,cAAc,KAAK,QAAQ,OAAO,EAAE,CAAC,EACrE;EACA,WAAW,EACT,SAAS,OAAO,EAAE,UAAU,EAAE,YAAY,cAAc,MAAM,KAAK,EAAE,CAAC,EACxE;EACA,MAAM,EACJ,SAAS,OAAO,EAAE,UAAU,EAAE,cAAc,KAAK,QAAQ,OAAO,EAAE,CAAC,EACrE;CACF,EACF,EACF;AACF,CAAC;;;;;ACtBD,MAAM,cAAc,SAA8D;CAChF,IAAI,KAAK,SAAS,cAAc,KAAK,SAAS,MAC5C,OAAO;CAET,MAAM,EAAE,QAAQ,UAAU,KAAK;CAC/B,MAAM,EAAE,YAAY;CAEpB,IAAI,QAAQ,SAAS,YACnB,OAAO;EACL,QAAQ;GACN,OAAO,OAAO;GACd,UAAU,OAAO;GACjB,KAAK,QAAQ;GACb,UAAU,OAAO;GACjB,MAAM;EACR;EACA;CACF;CAEF,IAAI,QAAQ,SAAS,UACnB,OAAO;EACL,QAAQ;GACN,UAAU,OAAO;GACjB,UAAU,QAAQ;GAClB,UAAU,OAAO;GACjB,MAAM;EACR;EACA;CACF;CAEF,OAAO;EACL,QAAQ;GACN,OAAO,OAAO;GACd,UAAU,OAAO;GACjB,UAAU,QAAQ;GAClB,UAAU,OAAO;GACjB,MAAM;EACR;EACA;CACF;AACF;AAEA,MAAM,kBAAkB,MAAM;CAC5B,QAAQ,EACN,eAAe,EAAE,cAAc,WAAW,QAAQ,IAAI,MAAM,KAC9D;CACA,OAAO;EAEL,SAAS,CAAC;EAEV,SAAS,CAAC;EAEV,QAAQ,CAAC;CACX;AACF,CAAC,CAAC,CAAC,cAAc;CACf,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE;CAClC,IAAI;CACJ,SAAS;CACT,QAAQ;EACN,UAAU,EACR,IAAI;GACF,QAAQ,EAAE,QAAQ,OAAO;GACzB,MAAM,CACJ;IACE,SAAS,MAAM,EAAE,cAAc;KAC7B,MAAM,WAAW,WAAW,QAAQ,IAAI;KACxC,IAAI,aAAa,MACf,MAAM,IAAI,MAAM,oDAAoD;KAEtE,OAAO;MAAE,QAAQ,SAAS;MAAQ,OAAO,SAAS;MAAO,MAAM;KAAS;IAC1E,CAAC;IACD,OAAO;IACP,QAAQ;GACV,GACA,EAAE,QAAQ,OAAO,CACnB;GACA,MAAM,EACJ,SAAS,OAAO,EACd,OAAO,EAAE,SAAS,YAChB,QAAQ,KAAK,SAAS,aAClB;IAAE,GAAG,QAAQ;IAAM,MAAM,MAAM;GAAK,IACpC,QAAQ,KAChB,CAAC,EACH;EACF,EACF;EACA,MAAM;GACJ,OAAO,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE,CAAC;GACxC,IAAI,EACF,OAAO;IACL,SAAS,OAAO,EACd,OAAO,EAAE,aAAa;KAAE,MAAM;KAAM,MAAM;KAAY,SAAS,MAAM;IAAQ,GAC/E,CAAC;IACD,QAAQ;GACV,EACF;EACF;CACF;AACF,CAAC;;;;ACzHD,MAAM,cAAc,UAA4B;CAC9C,MAAM,QAAQ,UAAU,cAAc,MAAM,KAAK,CAAC;CAClD,MAAM,aAAa,iBAAiB,KAAK;CACzC,IAAI,WAAW,SAAS,GAEtB,QAAQ,KAAK,sDAAsD,WAAW,KAAK,IAAI,GAAG;CAE5F,OAAO;AACT;AAEA,MAAM,UAAU,UAA2B,KAAK,UAAU,KAAK;AAE/D,MAAM,YAAY,SAA0B,WAAW,KAAK,MAAM,IAAI,CAAC;;;;ACbvE,MAAM,cAAc,OAAgB,cAA2B,aAAsB;CACnF,MAAM,cAAiC,CAAC;CACxC,oBAAoB,MAAM,QAAQ,WAAW;CAC7C,MAAM,WAA8B,CAAC;CACrC,KAAK,MAAM,UAAU,aACnB,SAAS,KAAK;EAAE,GAAG;EAAQ,QAAQ;CAAE,CAAC;CAGxC,OAAO,UAAU;EACf,GAAG;EACH,QAAQ;GACN;GACA,IAAI,MAAM,OAAO;GACjB;GACA,MAAM;GACN,QAAQ,MAAM,OAAO;EACvB;EACA,mBAAmB;CACrB,CAAC;AACH"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/lib/clamp-selected.ts","../src/model/schema.ts","../src/state/node-attrs.ts","../src/state/actions.ts","../src/model/ids.ts","../src/model/tree.ts","../src/model/builders.ts","../src/lib/assert-never.ts","../src/geometry/geometry.ts","../src/geometry/snap.ts","../src/model/invariants.ts","../src/state/surgery.ts","../src/state/floats.ts","../src/state/reducer.ts","../src/state/history.ts","../src/machines/dashfoo-machine.ts","../src/machines/drag-dock-machine.ts","../src/model/serialize.ts","../src/model/stack.ts"],"sourcesContent":["/** In `lib/` because both the parse boundary and `normalize` need it, and\n * importing it from either would close a module cycle. */\nconst clampSelected = (length: number, selected: number): number => {\n if (length === 0) {\n return 0;\n }\n\n const base = Number.isFinite(selected) ? Math.trunc(selected) : 0;\n if (base < 0) {\n return 0;\n }\n if (base > length - 1) {\n return length - 1;\n }\n return base;\n};\n\nexport { clampSelected };\n","import { z } from \"zod\";\n\nimport { clampSelected } from \"../lib/clamp-selected\";\n\n/** Weights are relative shares of a row, not percentages. */\nconst DEFAULT_WEIGHT = 1;\n\ntype JsonValue = string | number | boolean | null | Array<JsonValue> | { [key: string]: JsonValue };\n\nconst jsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(jsonValueSchema),\n z.record(z.string(), jsonValueSchema),\n ]),\n);\n\nconst edgeSchema = z.enum([\"top\", \"bottom\", \"left\", \"right\"]);\nconst unitSchema = z.enum([\"px\", \"%\", \"em\", \"rem\", \"vh\", \"vw\"]);\nconst orientationSchema = z.enum([\"row\", \"column\"]);\n\nconst dimensionSchema = z.object({\n unit: unitSchema,\n value: z.number(),\n});\n\nconst snapSchema = z.object({\n divisions: z.union([z.number().positive(), z.literal(\"panels\")]).optional(),\n step: z.number().min(0).optional(),\n threshold: z.number().positive().optional(),\n});\n\nconst tabNodeSchema = z.object({\n component: z.string(),\n config: jsonValueSchema.optional(),\n enableClose: z.boolean().optional(),\n enableDrag: z.boolean().optional(),\n enableRename: z.boolean().optional(),\n id: z.string(),\n name: z.string(),\n type: z.literal(\"tab\"),\n});\n\n/**\n * Kept pre-transform so `node-attrs` can `.pick()` from it: a pipe has no\n * `.pick`, and `.partial()` over a defaulted field still fills the default in.\n */\nconst tabsetNodeObjectSchema = z.object({\n children: z.array(tabNodeSchema),\n enableClose: z.boolean().optional(),\n enableMaximize: z.boolean().optional(),\n id: z.string(),\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n name: z.string().optional(),\n selected: z.number().int(),\n type: z.literal(\"tabset\"),\n weight: z.number().default(DEFAULT_WEIGHT),\n});\n\nconst tabsetNodeSchema = tabsetNodeObjectSchema.transform((tabset) => ({\n ...tabset,\n selected: clampSelected(tabset.children.length, tabset.selected),\n}));\n\n/** The getter's explicit return type is required: without it, TS7023. */\nconst rowNodeSchema = z.object({\n get children(): z.ZodArray<z.ZodUnion<[typeof rowNodeSchema, typeof tabsetNodeSchema]>> {\n return z.array(z.union([rowNodeSchema, tabsetNodeSchema]));\n },\n id: z.string(),\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n orientation: orientationSchema,\n snap: snapSchema.optional(),\n type: z.literal(\"row\"),\n weight: z.number().default(DEFAULT_WEIGHT),\n});\n\ntype RowNode = z.infer<typeof rowNodeSchema>;\ntype RowNodeInput = z.input<typeof rowNodeSchema>;\n\nconst geometrySchema = z.object({\n height: z.number(),\n left: z.number(),\n top: z.number(),\n width: z.number(),\n});\n\nconst floatNodeSchema = z.object({\n geometry: geometrySchema,\n id: z.string(),\n layout: rowNodeSchema,\n\n minimized: z.boolean().optional(),\n name: z.string().optional(),\n type: z.literal(\"float\"),\n});\n\nconst globalAttributesSchema = z.object({\n enableSplitDock: z.boolean().optional(),\n enableSplitResize: z.boolean().optional(),\n snap: snapSchema.optional(),\n splitterSize: z.number().optional(),\n tabEnableClose: z.boolean().optional(),\n tabEnableDrag: z.boolean().optional(),\n tabEnableRename: z.boolean().optional(),\n tabLocation: z.enum([\"top\", \"bottom\"]).optional(),\n tabSetEnableMaximize: z.boolean().optional(),\n tabSetEnableTabStrip: z.boolean().optional(),\n tabSetMinSize: z.number().optional(),\n});\n\nconst dashfooSchema = z.object({\n activeTabsetId: z.string().optional(),\n floats: z.array(floatNodeSchema).default(() => []),\n global: globalAttributesSchema,\n layout: rowNodeSchema,\n maximizedTabsetId: z.string().optional(),\n version: z.literal(1),\n});\n\ntype Json = JsonValue;\ntype Edge = z.infer<typeof edgeSchema>;\ntype Unit = z.infer<typeof unitSchema>;\ntype Orientation = z.infer<typeof orientationSchema>;\ntype Dimension = z.infer<typeof dimensionSchema>;\ntype SnapConfig = z.infer<typeof snapSchema>;\ntype TabNode = z.infer<typeof tabNodeSchema>;\ntype TabsetNode = z.infer<typeof tabsetNodeSchema>;\ntype Geometry = z.infer<typeof geometrySchema>;\ntype FloatNode = z.infer<typeof floatNodeSchema>;\ntype GlobalAttributes = z.infer<typeof globalAttributesSchema>;\ntype Dashfoo = z.infer<typeof dashfooSchema>;\n/** The loose shape `dashfooSchema` accepts: `weight` and `floats` may be omitted. */\ntype DashfooInput = z.input<typeof dashfooSchema>;\ntype Node = RowNode | TabsetNode | TabNode;\n\nexport {\n dashfooSchema,\n DEFAULT_WEIGHT,\n dimensionSchema,\n edgeSchema,\n floatNodeSchema,\n geometrySchema,\n globalAttributesSchema,\n jsonValueSchema,\n orientationSchema,\n rowNodeSchema,\n snapSchema,\n tabNodeSchema,\n tabsetNodeObjectSchema,\n tabsetNodeSchema,\n unitSchema,\n};\n\nexport type {\n Dashfoo,\n DashfooInput,\n Dimension,\n Edge,\n FloatNode,\n Geometry,\n GlobalAttributes,\n Json,\n Node,\n Orientation,\n RowNode,\n RowNodeInput,\n SnapConfig,\n TabNode,\n TabsetNode,\n Unit,\n};\n","import { z } from \"zod\";\n\nimport {\n dimensionSchema,\n orientationSchema,\n snapSchema,\n tabNodeSchema,\n tabsetNodeObjectSchema,\n} from \"../model/schema\";\n\nconst mutableTabAttrsSchema = tabNodeSchema\n .pick({\n config: true,\n enableClose: true,\n enableDrag: true,\n enableRename: true,\n name: true,\n })\n .partial();\n\n/** `weight` is re-declared, not picked: `.partial()` over a defaulted field still injects the default. */\nconst mutableTabsetAttrsSchema = tabsetNodeObjectSchema\n .pick({\n enableClose: true,\n enableMaximize: true,\n max: true,\n min: true,\n selected: true,\n })\n .extend({ weight: z.number() })\n .partial();\n\nconst mutableRowAttrsSchema = z\n .object({\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n orientation: orientationSchema,\n snap: snapSchema.optional(),\n weight: z.number(),\n })\n .partial();\n\n/**\n * Merged, not a union: a union of all-optional members matches its first member\n * and strips the rest. The reducer enforces which keys a given node accepts.\n */\nconst mutableNodeAttrsSchema = mutableTabAttrsSchema\n .extend(mutableTabsetAttrsSchema.shape)\n .extend(mutableRowAttrsSchema.shape);\n\nexport {\n mutableNodeAttrsSchema,\n mutableRowAttrsSchema,\n mutableTabAttrsSchema,\n mutableTabsetAttrsSchema,\n};\n","import { z } from \"zod\";\n\nimport { geometrySchema, globalAttributesSchema, tabNodeSchema } from \"../model/schema\";\n\nimport { mutableNodeAttrsSchema } from \"./node-attrs\";\n\nconst dockLocationSchema = z.enum([\n \"center\",\n \"split-bottom\",\n \"split-left\",\n \"split-right\",\n \"split-top\",\n]);\n\nconst splitWeightsSchema = z.array(z.number());\n\nconst actionSchema = z.discriminatedUnion(\"type\", [\n z.object({\n index: z.number().int().optional(),\n location: dockLocationSchema,\n tab: tabNodeSchema,\n targetId: z.string(),\n type: z.literal(\"addNode\"),\n }),\n z.object({\n index: z.number().int().optional(),\n location: dockLocationSchema,\n sourceId: z.string(),\n targetId: z.string(),\n type: z.literal(\"moveNode\"),\n }),\n // No `index`: a tabset docks beside or merges into its target, so there is no\n // slot in a tab strip to land at.\n z.object({\n location: dockLocationSchema,\n sourceId: z.string(),\n targetId: z.string(),\n type: z.literal(\"moveTabset\"),\n }),\n z.object({ index: z.number().int(), tabsetId: z.string(), type: z.literal(\"selectTab\") }),\n z.object({ tabsetId: z.string(), type: z.literal(\"setActiveTabset\") }),\n z.object({ tabsetId: z.string().nullable(), type: z.literal(\"setMaximizedTabset\") }),\n z.object({ name: z.string(), tabId: z.string(), type: z.literal(\"renameTab\") }),\n z.object({ tabId: z.string(), type: z.literal(\"deleteTab\") }),\n z.object({ tabsetId: z.string(), type: z.literal(\"deleteTabset\") }),\n z.object({\n rowId: z.string(),\n type: z.literal(\"adjustSplit\"),\n weights: splitWeightsSchema,\n }),\n z.object({\n attrs: mutableNodeAttrsSchema,\n nodeId: z.string(),\n type: z.literal(\"updateNodeAttributes\"),\n }),\n z.object({ attrs: globalAttributesSchema.partial(), type: z.literal(\"updateGlobalAttributes\") }),\n\n z.object({\n floatId: z.string().optional(),\n geometry: geometrySchema.optional(),\n tabId: z.string(),\n type: z.literal(\"floatTab\"),\n }),\n\n z.object({\n floatId: z.string().optional(),\n geometry: geometrySchema.optional(),\n tabsetId: z.string(),\n type: z.literal(\"floatTabset\"),\n }),\n\n z.object({\n floatId: z.string(),\n location: dockLocationSchema.optional(),\n targetId: z.string().optional(),\n type: z.literal(\"dockFloat\"),\n }),\n\n z.object({\n floatId: z.string(),\n geometry: geometrySchema,\n type: z.literal(\"moveFloat\"),\n }),\n\n z.object({\n floatId: z.string(),\n minimized: z.boolean(),\n type: z.literal(\"setFloatMinimized\"),\n }),\n\n z.object({\n floatId: z.string(),\n name: z.string(),\n type: z.literal(\"renameFloat\"),\n }),\n]);\n\ntype DockLocation = z.infer<typeof dockLocationSchema>;\ntype MutableNodeAttrs = z.infer<typeof mutableNodeAttrsSchema>;\ntype Action = z.infer<typeof actionSchema>;\n\ntype DropIntent = { index?: number; location: DockLocation; targetId: string };\n\nexport { actionSchema, dockLocationSchema };\nexport type { Action, DockLocation, DropIntent, MutableNodeAttrs };\n","const createNodeId = (prefix = \"node\"): string => `${prefix}-${crypto.randomUUID()}`;\n\nconst createTabId = (): string => createNodeId(\"tab\");\n\nexport { createNodeId, createTabId };\n","import type { Dashfoo, FloatNode, RowNode, TabNode, TabsetNode } from \"./schema\";\n\ntype TabContainer = TabsetNode;\ntype TabLocation = { container: TabContainer; index: number; tab: TabNode };\n\nconst collectRoots = (model: Dashfoo): Array<RowNode> => [\n model.layout,\n ...model.floats.map((float) => float.layout),\n];\n\nconst findFloat = (model: Dashfoo, floatId: string): FloatNode | undefined =>\n model.floats.find((float) => float.id === floatId);\n\ntype AttributedNode = RowNode | TabNode | TabsetNode;\n\ntype Visit = {\n index: number;\n node: AttributedNode;\n parent: RowNode | TabsetNode | undefined;\n};\n\n/**\n * Depth-first pre-order; a defined `visit` result stops the walk. With unique\n * ids the order is immaterial, but a duplicate-id model (which the builder and\n * the parser both warn about) resolves to whichever copy this reaches first.\n */\nconst walk = <T>(\n row: RowNode,\n visit: (found: Visit) => T | undefined,\n parent?: RowNode,\n index = -1,\n): T | undefined => {\n const atRoot = visit({ index, node: row, parent });\n if (atRoot !== undefined) {\n return atRoot;\n }\n for (const [childIndex, child] of row.children.entries()) {\n if (child.type === \"row\") {\n const inRow = walk(child, visit, row, childIndex);\n if (inRow !== undefined) {\n return inRow;\n }\n continue;\n }\n const atTabset = visit({ index: childIndex, node: child, parent: row });\n if (atTabset !== undefined) {\n return atTabset;\n }\n for (const [tabIndex, tab] of child.children.entries()) {\n const atTab = visit({ index: tabIndex, node: tab, parent: child });\n if (atTab !== undefined) {\n return atTab;\n }\n }\n }\n return undefined;\n};\n\ntype Located<N extends AttributedNode> = {\n index: number;\n node: N;\n parent: RowNode | TabsetNode | undefined;\n};\n\nconst isRow = (node: AttributedNode): node is RowNode => node.type === \"row\";\nconst isTab = (node: AttributedNode): node is TabNode => node.type === \"tab\";\nconst isTabset = (node: AttributedNode): node is TabsetNode => node.type === \"tabset\";\n\n/** Predicate-first, so an id shared across node kinds resolves the same way here as anywhere else. */\nconst locate = <N extends AttributedNode>(\n model: Dashfoo,\n id: string,\n is: (node: AttributedNode) => node is N,\n): Located<N> | undefined => {\n for (const root of collectRoots(model)) {\n const found = walk(root, ({ index, node, parent }) =>\n node.id === id && is(node) ? { index, node, parent } : undefined,\n );\n if (found) {\n return found;\n }\n }\n return undefined;\n};\n\nconst collectTabsetsInRow = (row: RowNode, acc: Array<TabsetNode>): void => {\n walk(row, ({ node }) => {\n if (node.type === \"tabset\") {\n acc.push(node);\n }\n return undefined;\n });\n};\n\nconst collectTabsets = (model: Dashfoo): Array<TabsetNode> => {\n const acc: Array<TabsetNode> = [];\n for (const root of collectRoots(model)) {\n collectTabsetsInRow(root, acc);\n }\n return acc;\n};\n\nconst getFirstTabset = (model: Dashfoo): TabsetNode | undefined => collectTabsets(model)[0];\n\nconst findTabset = (model: Dashfoo, tabsetId: string): TabsetNode | undefined =>\n locate(model, tabsetId, isTabset)?.node;\n\nconst findTab = (model: Dashfoo, tabId: string): TabLocation | undefined => {\n const found = locate(model, tabId, isTab);\n return found?.parent?.type === \"tabset\"\n ? { container: found.parent, index: found.index, tab: found.node }\n : undefined;\n};\n\nconst findRow = (model: Dashfoo, id: string): RowNode | undefined => locate(model, id, isRow)?.node;\n\nconst findAttributedNode = (model: Dashfoo, id: string): AttributedNode | undefined => {\n for (const root of collectRoots(model)) {\n const found = walk(root, ({ node }) => (node.id === id ? node : undefined));\n if (found) {\n return found;\n }\n }\n return undefined;\n};\n\nconst findRootContaining = (model: Dashfoo, nodeId: string): RowNode | undefined => {\n for (const root of collectRoots(model)) {\n const hit = walk(root, ({ node }) => (node.id === nodeId ? true : undefined));\n if (hit) {\n return root;\n }\n }\n return undefined;\n};\n\nconst findTabsetParent = (\n model: Dashfoo,\n tabsetId: string,\n): { index: number; parent: RowNode } | undefined => {\n const found = locate(model, tabsetId, isTabset);\n return found?.parent?.type === \"row\" ? { index: found.index, parent: found.parent } : undefined;\n};\n\nconst collectIdsInRow = (row: RowNode, acc: Array<string>): void => {\n walk(row, ({ node }) => {\n acc.push(node.id);\n return undefined;\n });\n};\n\nconst findDuplicateIds = (model: Dashfoo): Array<string> => {\n const ids: Array<string> = [];\n for (const float of model.floats) {\n ids.push(float.id);\n }\n for (const root of collectRoots(model)) {\n collectIdsInRow(root, ids);\n }\n const seen = new Set<string>();\n const duplicates = new Set<string>();\n for (const id of ids) {\n if (seen.has(id)) {\n duplicates.add(id);\n }\n seen.add(id);\n }\n return [...duplicates];\n};\n\nexport {\n collectRoots,\n collectTabsets,\n collectTabsetsInRow,\n findAttributedNode,\n findDuplicateIds,\n findFloat,\n findRootContaining,\n findRow,\n findTab,\n findTabset,\n findTabsetParent,\n getFirstTabset,\n};\nexport type { AttributedNode, TabContainer, TabLocation };\n","import { clampSelected } from \"../lib/clamp-selected\";\n\nimport { createNodeId } from \"./ids\";\nimport { DEFAULT_WEIGHT } from \"./schema\";\nimport type {\n Dashfoo,\n Dimension,\n FloatNode,\n Geometry,\n GlobalAttributes,\n Json,\n RowNode,\n SnapConfig,\n TabNode,\n TabsetNode,\n} from \"./schema\";\nimport { findDuplicateIds } from \"./tree\";\n\nconst toDimension = (value: number | Dimension): Dimension =>\n typeof value === \"number\" ? { unit: \"px\", value } : value;\n\ntype TabOptions = {\n config?: Json;\n enableClose?: boolean;\n enableDrag?: boolean;\n enableRename?: boolean;\n id?: string;\n};\n\nconst tab = (component: string, name: string, options: TabOptions = {}): TabNode => ({\n component,\n name,\n type: \"tab\",\n ...options,\n id: options.id ?? component,\n});\n\ntype TabsetOptions = {\n enableClose?: boolean;\n enableMaximize?: boolean;\n id?: string;\n max?: number | Dimension;\n min?: number | Dimension;\n name?: string;\n selected?: number;\n weight?: number;\n};\n\nconst tabset = (children: Array<TabNode>, options: TabsetOptions = {}): TabsetNode => {\n const { max, min, ...rest } = options;\n const built: TabsetNode = {\n children,\n type: \"tabset\",\n ...rest,\n id: options.id ?? createNodeId(\"tabset\"),\n selected: clampSelected(children.length, options.selected ?? 0),\n weight: options.weight ?? DEFAULT_WEIGHT,\n };\n if (max !== undefined) {\n built.max = toDimension(max);\n }\n if (min !== undefined) {\n built.min = toDimension(min);\n }\n return built;\n};\n\ntype RowOptions = {\n id?: string;\n max?: number | Dimension;\n min?: number | Dimension;\n orientation?: RowNode[\"orientation\"];\n snap?: SnapConfig;\n weight?: number;\n};\n\nconst row = (children: RowNode[\"children\"], options: RowOptions = {}): RowNode => {\n const { max, min, ...rest } = options;\n const built: RowNode = {\n children,\n type: \"row\",\n ...rest,\n id: options.id ?? createNodeId(\"row\"),\n orientation: options.orientation ?? \"row\",\n weight: options.weight ?? DEFAULT_WEIGHT,\n };\n if (max !== undefined) {\n built.max = toDimension(max);\n }\n if (min !== undefined) {\n built.min = toDimension(min);\n }\n return built;\n};\n\ntype FloatOptions = {\n id?: string;\n name?: string;\n};\n\nconst floatNode = (layout: RowNode, geometry: Geometry, options: FloatOptions = {}): FloatNode => ({\n geometry,\n layout,\n type: \"float\",\n ...options,\n id: options.id ?? createNodeId(\"float\"),\n});\n\ntype ModelOptions = {\n activeTabsetId?: string;\n floats?: Array<FloatNode>;\n global?: GlobalAttributes;\n maximizedTabsetId?: string;\n};\n\nconst model = (layout: RowNode, options: ModelOptions = {}): Dashfoo => {\n const built: Dashfoo = {\n layout,\n version: 1,\n ...options,\n floats: options.floats ?? [],\n global: options.global ?? {},\n };\n const duplicates = findDuplicateIds(built);\n if (duplicates.length > 0) {\n // oxlint-disable-next-line no-console\n console.warn(\n `[dashfoo] builder produced duplicate node ids: ${duplicates.join(\", \")}. Pass explicit ids when reusing a component`,\n );\n }\n return built;\n};\n\nexport { floatNode, model, row, tab, tabset };\nexport type { FloatOptions, ModelOptions, RowOptions, TabOptions, TabsetOptions };\n","const assertNever = (value: never): never => {\n throw new Error(`Unhandled variant: ${JSON.stringify(value)}`);\n};\n\nexport { assertNever };\n","import { assertNever } from \"../lib/assert-never\";\nimport type { Edge } from \"../model/schema\";\nimport type { DockLocation } from \"../state/actions\";\n\ntype Point = { x: number; y: number };\ntype Rect = { height: number; width: number; x: number; y: number };\ntype BandOptions = { bandFraction?: number };\ntype DockZone = { location: DockLocation; points: Array<Point> };\ntype EdgeDistances = { bottom: number; left: number; right: number; top: number };\n\nconst DEFAULT_BAND_FRACTION = 0.22;\n\nconst edgeDistances = (pointer: Point, rect: Rect): EdgeDistances => {\n const fx = (pointer.x - rect.x) / rect.width;\n const fy = (pointer.y - rect.y) / rect.height;\n return { bottom: 1 - fy, left: fx, right: 1 - fx, top: fy };\n};\n\nconst closestEdge = (d: EdgeDistances): Edge => {\n const min = Math.min(d.left, d.right, d.top, d.bottom);\n if (min === d.left) {\n return \"left\";\n }\n if (min === d.right) {\n return \"right\";\n }\n if (min === d.top) {\n return \"top\";\n }\n return \"bottom\";\n};\n\nconst splitEdge = (location: DockLocation): Edge | undefined => {\n switch (location) {\n case \"center\": {\n return undefined;\n }\n case \"split-bottom\": {\n return \"bottom\";\n }\n case \"split-left\": {\n return \"left\";\n }\n case \"split-right\": {\n return \"right\";\n }\n case \"split-top\": {\n return \"top\";\n }\n default: {\n return assertNever(location);\n }\n }\n};\n\nconst resolveDockTarget = (pointer: Point, rect: Rect, opts?: BandOptions): DockLocation => {\n const band = opts?.bandFraction ?? DEFAULT_BAND_FRACTION;\n\n if (rect.width <= 0 || rect.height <= 0) {\n return \"center\";\n }\n const distances = edgeDistances(pointer, rect);\n const min = Math.min(distances.left, distances.right, distances.top, distances.bottom);\n\n if (min > band) {\n return \"center\";\n }\n return `split-${closestEdge(distances)}`;\n};\n\nconst dockZonePolygons = (rect: Rect, opts?: BandOptions): Array<DockZone> => {\n const { height: h, width: w, x, y } = rect;\n const nw: Point = { x, y };\n const ne: Point = { x: x + w, y };\n const se: Point = { x: x + w, y: y + h };\n const sw: Point = { x, y: y + h };\n if (w <= 0 || h <= 0) {\n return [{ location: \"center\", points: [nw, ne, se, sw] }];\n }\n const band = opts?.bandFraction ?? DEFAULT_BAND_FRACTION;\n const bx = band * w;\n const by = band * h;\n const innerNw: Point = { x: x + bx, y: y + by };\n const innerNe: Point = { x: x + w - bx, y: y + by };\n const innerSe: Point = { x: x + w - bx, y: y + h - by };\n const innerSw: Point = { x: x + bx, y: y + h - by };\n return [\n { location: \"center\", points: [innerNw, innerNe, innerSe, innerSw] },\n { location: \"split-left\", points: [nw, innerNw, innerSw, sw] },\n { location: \"split-right\", points: [ne, se, innerSe, innerNe] },\n { location: \"split-top\", points: [nw, ne, innerNe, innerNw] },\n { location: \"split-bottom\", points: [sw, innerSw, innerSe, se] },\n ];\n};\n\nconst zoneRect = (rect: Rect, location: DockLocation): Rect => {\n const halfW = rect.width / 2;\n const halfH = rect.height / 2;\n switch (location) {\n case \"split-bottom\": {\n return { height: halfH, width: rect.width, x: rect.x, y: rect.y + halfH };\n }\n case \"split-left\": {\n return { height: rect.height, width: halfW, x: rect.x, y: rect.y };\n }\n case \"split-right\": {\n return { height: rect.height, width: halfW, x: rect.x + halfW, y: rect.y };\n }\n case \"split-top\": {\n return { height: halfH, width: rect.width, x: rect.x, y: rect.y };\n }\n case \"center\": {\n return rect;\n }\n default: {\n return assertNever(location);\n }\n }\n};\n\nexport { dockZonePolygons, resolveDockTarget, splitEdge, zoneRect };\nexport type { BandOptions, DockZone, Point, Rect };\n","import type { SnapConfig } from \"../model/schema\";\n\nconst DEFAULT_SNAP_THRESHOLD = 4;\n\nconst TARGET_PRECISION = 1e6;\n\nconst addMultiples = (targets: Set<number>, increment: number): void => {\n if (increment <= 0) {\n return;\n }\n for (let position = increment; position < 100; position += increment) {\n const rounded = Math.round(position * TARGET_PRECISION) / TARGET_PRECISION;\n if (rounded < 100) {\n targets.add(rounded);\n }\n }\n};\n\nconst resolveSnapTargets = (config: SnapConfig, panelCount: number): Array<number> => {\n const targets = new Set<number>();\n if (config.step !== undefined && config.step > 0) {\n addMultiples(targets, config.step);\n }\n if (config.divisions !== undefined) {\n const divisions = config.divisions === \"panels\" ? panelCount : config.divisions;\n if (divisions >= 2) {\n addMultiples(targets, 100 / divisions);\n }\n }\n return [...targets].toSorted((a, b) => a - b);\n};\n\ntype SnapGrid = { targets: Array<number>; threshold: number };\n\nconst resolveSnapGrid = (config: SnapConfig | null, panelCount: number): SnapGrid => ({\n targets: config === null ? [] : resolveSnapTargets(config, panelCount),\n threshold: config?.threshold ?? DEFAULT_SNAP_THRESHOLD,\n});\n\nconst snapEnabled = (grid: SnapGrid): boolean => grid.targets.length > 0;\n\nconst nearestTarget = (position: number, targets: Array<number>): number | undefined =>\n targets.reduce<number | undefined>((best, target) => {\n if (best === undefined || Math.abs(target - position) < Math.abs(best - position)) {\n return target;\n }\n return best;\n }, undefined);\n\ntype SnapResult = { sizes: Array<number>; snapped: boolean };\n\nconst snapSizes = (sizes: Array<number>, boundaryIndex: number, grid: SnapGrid): SnapResult => {\n const { targets, threshold } = grid;\n const left = sizes[boundaryIndex];\n const right = sizes[boundaryIndex + 1];\n if (boundaryIndex < 0 || left === undefined || right === undefined || targets.length === 0) {\n return { sizes, snapped: false };\n }\n\n let position = 0;\n for (let index = 0; index <= boundaryIndex; index++) {\n position += sizes[index] ?? 0;\n }\n\n const target = nearestTarget(position, targets);\n if (target === undefined || Math.abs(target - position) > threshold) {\n return { sizes, snapped: false };\n }\n\n const delta = target - position;\n if (left + delta < 0 || right - delta < 0) {\n return { sizes, snapped: false };\n }\n\n const next = [...sizes];\n next[boundaryIndex] = left + delta;\n next[boundaryIndex + 1] = right - delta;\n return { sizes: next, snapped: true };\n};\n\ntype SnapDecision =\n | { kind: \"inactive\" }\n | { kind: \"clear\" }\n | { kind: \"engage\"; sizes: Array<number> };\n\nconst decideSnap = (\n sizes: Array<number>,\n boundaryIndex: number | null,\n grid: SnapGrid,\n): SnapDecision => {\n if (boundaryIndex === null || !snapEnabled(grid)) {\n return { kind: \"inactive\" };\n }\n const { sizes: snappedSizes, snapped } = snapSizes(sizes, boundaryIndex, grid);\n return snapped ? { kind: \"engage\", sizes: snappedSizes } : { kind: \"clear\" };\n};\n\nconst settleSnap = (\n sizes: Array<number>,\n boundaryIndex: number | null,\n grid: SnapGrid,\n): Array<number> => {\n const decision = decideSnap(sizes, boundaryIndex, grid);\n return decision.kind === \"engage\" ? decision.sizes : sizes;\n};\n\nexport {\n DEFAULT_SNAP_THRESHOLD,\n decideSnap,\n resolveSnapGrid,\n resolveSnapTargets,\n settleSnap,\n snapEnabled,\n snapSizes,\n};\nexport type { SnapDecision, SnapGrid, SnapResult };\n","import type { Dashfoo, FloatNode, RowNode } from \"./schema\";\n\ntype RowChild = RowNode[\"children\"][number];\n\n/**\n * The survivor takes over the collapsed row's slot, so it has to take the slot's\n * sizing too: dropping it widens a pinned sidebar, permanently, since this runs\n * on every persist. `snap` is row-only, so it travels only to a row survivor.\n */\nconst inheritSlot = (row: RowNode, survivor: RowChild): RowChild => {\n const sized: RowChild = {\n ...survivor,\n weight: row.weight,\n };\n\n if (row.min !== undefined) {\n sized.min = row.min;\n }\n if (row.max !== undefined) {\n sized.max = row.max;\n }\n\n if (sized.type === \"row\" && row.snap !== undefined) {\n return { ...sized, snap: row.snap };\n }\n return sized;\n};\n\n/** Records the id of every tabset it keeps, in document order. */\nconst normalizeRowChildren = (\n children: RowNode[\"children\"],\n keptTabsetIds: Array<string>,\n): RowNode[\"children\"] => {\n const out: RowNode[\"children\"] = [];\n\n for (const child of children) {\n if (child.type === \"tabset\") {\n if (child.children.length > 0) {\n out.push(child);\n keptTabsetIds.push(child.id);\n }\n continue;\n }\n\n // A recorded id implies a survivor, which keeps its ancestor rows alive, so\n // a dropped row never leaves ids behind.\n const grandchildren = normalizeRowChildren(child.children, keptTabsetIds);\n if (grandchildren.length === 0) {\n continue;\n }\n if (grandchildren.length === 1) {\n const only = grandchildren[0];\n if (only !== undefined) {\n out.push(inheritSlot(child, only));\n }\n continue;\n }\n out.push({ ...child, children: grandchildren });\n }\n\n return out;\n};\n\nconst normalizeLayout = (root: RowNode, keptTabsetIds: Array<string>): RowNode => {\n let children = normalizeRowChildren(root.children, keptTabsetIds);\n let orientation = root.orientation;\n\n let inner = children[0];\n while (children.length === 1 && inner?.type === \"row\") {\n children = inner.children;\n orientation = inner.orientation;\n inner = children[0];\n }\n\n return { ...root, children, orientation };\n};\n\nconst normalize = (model: Dashfoo): Dashfoo => {\n const mainTabsetIds: Array<string> = [];\n const layout = normalizeLayout(model.layout, mainTabsetIds);\n\n const floats: Array<FloatNode> = [];\n const floatTabsetIds: Array<string> = [];\n for (const float of model.floats) {\n const ownTabsetIds: Array<string> = [];\n const floatLayout = normalizeLayout(float.layout, ownTabsetIds);\n if (floatLayout.children.length > 0) {\n floats.push({ ...float, layout: floatLayout });\n floatTabsetIds.push(...ownTabsetIds);\n }\n }\n\n const mainIds = new Set(mainTabsetIds);\n const liveIds = new Set([...mainTabsetIds, ...floatTabsetIds]);\n const firstTabsetId = mainTabsetIds[0] ?? floatTabsetIds[0];\n\n const activeTabsetId =\n model.activeTabsetId !== undefined && liveIds.has(model.activeTabsetId)\n ? model.activeTabsetId\n : firstTabsetId;\n\n // Main layout only: floats opt out of maximize, so an id that moved into one\n // would render twice, in the main area and inside the float.\n const maximizedTabsetId =\n model.maximizedTabsetId !== undefined && mainIds.has(model.maximizedTabsetId)\n ? model.maximizedTabsetId\n : undefined;\n\n return { ...model, activeTabsetId, floats, layout, maximizedTabsetId };\n};\n\nexport { normalize };\n","import { clampSelected } from \"../lib/clamp-selected\";\nimport { createNodeId } from \"../model/ids\";\nimport type { Dashfoo, Orientation, RowNode, TabNode, TabsetNode } from \"../model/schema\";\nimport { DEFAULT_WEIGHT } from \"../model/schema\";\nimport type { TabContainer } from \"../model/tree\";\nimport { findTabset, findTabsetParent } from \"../model/tree\";\n\nimport type { DockLocation } from \"./actions\";\n\n/** The four locations that produce a split. `center` merges instead, so it is not one of them. */\ntype SplitLocation = Exclude<DockLocation, \"center\">;\n\nconst removeTabsetReturning = (model: Dashfoo, tabsetId: string): TabsetNode | undefined => {\n const found = findTabsetParent(model, tabsetId);\n if (!found) {\n return undefined;\n }\n const [removed] = found.parent.children.splice(found.index, 1);\n return removed?.type === \"tabset\" ? removed : undefined;\n};\n\n/** Total, so a sixth `DockLocation` is a compile error here rather than a wrong default. */\nconst SPLIT_PLACEMENT = {\n \"split-bottom\": { before: false, orientation: \"column\" },\n \"split-left\": { before: true, orientation: \"row\" },\n \"split-right\": { before: false, orientation: \"row\" },\n \"split-top\": { before: true, orientation: \"column\" },\n} as const satisfies Record<SplitLocation, { before: boolean; orientation: Orientation }>;\n\nconst placeBesideTarget = (\n draft: Dashfoo,\n placed: TabsetNode,\n targetId: string,\n location: SplitLocation,\n): boolean => {\n const targetTabset = findTabset(draft, targetId);\n const found = findTabsetParent(draft, targetId);\n if (!targetTabset || !found) {\n return false;\n }\n\n const { before, orientation } = SPLIT_PLACEMENT[location];\n\n if (found.parent.orientation === orientation) {\n const half = targetTabset.weight / 2;\n targetTabset.weight = half;\n placed.weight = half;\n found.parent.children.splice(before ? found.index : found.index + 1, 0, placed);\n } else {\n const newRow: RowNode = {\n children: before ? [placed, targetTabset] : [targetTabset, placed],\n id: createNodeId(\"row\"),\n orientation,\n type: \"row\",\n weight: targetTabset.weight,\n };\n targetTabset.weight = 50;\n placed.weight = 50;\n found.parent.children.splice(found.index, 1, newRow);\n }\n\n draft.activeTabsetId = placed.id;\n return true;\n};\n\ntype DropTarget = { id: string; index?: number; location: DockLocation };\n\nconst insertTab = (draft: Dashfoo, tab: TabNode, target: DropTarget): boolean => {\n const { id: targetId, index, location } = target;\n const targetTabset = findTabset(draft, targetId);\n if (!targetTabset) {\n return false;\n }\n\n if (location === \"center\") {\n const at = Math.min(\n Math.max(index ?? targetTabset.children.length, 0),\n targetTabset.children.length,\n );\n targetTabset.children.splice(at, 0, tab);\n targetTabset.selected = at;\n return true;\n }\n\n const newTabset: TabsetNode = {\n children: [tab],\n id: createNodeId(\"tabset\"),\n selected: 0,\n type: \"tabset\",\n weight: DEFAULT_WEIGHT,\n };\n return placeBesideTarget(draft, newTabset, targetId, location);\n};\n\n/** Re-clamps here rather than leaving the whole tree to be re-walked afterwards. */\nconst detachTab = (container: TabContainer, index: number): TabNode | undefined => {\n const removed = container.children.splice(index, 1).at(0);\n container.selected = clampSelected(container.children.length, container.selected);\n return removed;\n};\n\nconst mergeTabsInto = (target: TabsetNode, tabs: Array<TabNode>, selectedOffset: number): void => {\n const mergeStart = target.children.length;\n target.children.push(...tabs);\n target.selected = mergeStart + selectedOffset;\n};\n\nconst wrapTabInLayout = (tab: TabNode): RowNode => ({\n children: [\n {\n children: [tab],\n id: createNodeId(\"tabset\"),\n selected: 0,\n type: \"tabset\",\n weight: DEFAULT_WEIGHT,\n },\n ],\n id: createNodeId(\"row\"),\n orientation: \"row\",\n type: \"row\",\n weight: DEFAULT_WEIGHT,\n});\n\nconst wrapTabsetInLayout = (tabset: TabsetNode): RowNode => ({\n children: [tabset],\n id: createNodeId(\"row\"),\n orientation: \"row\",\n type: \"row\",\n weight: DEFAULT_WEIGHT,\n});\n\nexport {\n detachTab,\n insertTab,\n mergeTabsInto,\n placeBesideTarget,\n removeTabsetReturning,\n wrapTabInLayout,\n wrapTabsetInLayout,\n};\nexport type { DropTarget, SplitLocation };\n","import { clampSelected } from \"../lib/clamp-selected\";\nimport { createNodeId } from \"../model/ids\";\nimport type { Dashfoo, FloatNode, Geometry, RowNode, TabsetNode } from \"../model/schema\";\nimport { DEFAULT_WEIGHT } from \"../model/schema\";\nimport { collectTabsetsInRow } from \"../model/tree\";\n\nimport type { DockLocation } from \"./actions\";\nimport {\n mergeTabsInto,\n placeBesideTarget,\n removeTabsetReturning,\n wrapTabsetInLayout,\n} from \"./surgery\";\n\nconst DEFAULT_FLOAT_GEOMETRY: Geometry = { height: 360, left: 80, top: 80, width: 480 };\n\nconst uniqueFloatName = (base: string, floats: Array<FloatNode>): string => {\n const used = new Set(floats.map((float) => float.name));\n if (!used.has(base)) {\n return base;\n }\n let index = 1;\n while (used.has(`${base} ${index}`)) {\n index += 1;\n }\n return `${base} ${index}`;\n};\n\nconst pushFloat = (\n draft: Dashfoo,\n layout: RowNode,\n geometry: Geometry | undefined,\n floatId: string | undefined,\n): void => {\n const float: FloatNode = {\n geometry: geometry ?? DEFAULT_FLOAT_GEOMETRY,\n id: floatId ?? createNodeId(\"float\"),\n layout,\n name: uniqueFloatName(\"Panel\", draft.floats),\n type: \"float\",\n };\n draft.floats = [...draft.floats, float];\n\n const tabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(layout, tabsets);\n const first = tabsets.at(0);\n if (first) {\n draft.activeTabsetId = first.id;\n }\n};\n\nconst floatTabsetById = (\n draft: Dashfoo,\n tabsetId: string,\n geometry: Geometry | undefined,\n floatId: string | undefined,\n): boolean => {\n const detached = removeTabsetReturning(draft, tabsetId);\n if (!detached) {\n return false;\n }\n pushFloat(draft, wrapTabsetInLayout(detached), geometry, floatId);\n return true;\n};\n\nconst resolveMainTarget = (\n draft: Dashfoo,\n targetId: string | undefined,\n): TabsetNode | undefined => {\n const mainTabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(draft.layout, mainTabsets);\n if (targetId !== undefined) {\n const explicit = mainTabsets.find((tabset) => tabset.id === targetId);\n if (explicit) {\n return explicit;\n }\n }\n if (draft.activeTabsetId !== undefined) {\n const active = mainTabsets.find((tabset) => tabset.id === draft.activeTabsetId);\n if (active) {\n return active;\n }\n }\n return mainTabsets[0];\n};\n\nconst dockFloat = (\n draft: Dashfoo,\n floatId: string,\n targetId: string | undefined,\n location: DockLocation | undefined,\n): boolean => {\n const index = draft.floats.findIndex((float) => float.id === floatId);\n const float = draft.floats.at(index);\n if (index === -1 || !float) {\n return false;\n }\n\n const tabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(float.layout, tabsets);\n const tabs = tabsets.flatMap((tabset) => tabset.children);\n if (tabs.length === 0) {\n return false;\n }\n\n const leadTabset = tabsets.at(0);\n const selectedOffset = leadTabset\n ? clampSelected(leadTabset.children.length, leadTabset.selected)\n : 0;\n\n // Resolved before the float leaves `draft.floats`: nothing is removed until\n // there is somewhere for its tabs to land.\n const target = resolveMainTarget(draft, targetId);\n draft.floats.splice(index, 1);\n\n if (!target) {\n draft.layout = float.layout;\n draft.activeTabsetId = leadTabset?.id;\n return true;\n }\n\n if (location === \"center\") {\n mergeTabsInto(target, tabs, selectedOffset);\n draft.activeTabsetId = target.id;\n return true;\n }\n\n const placed: TabsetNode =\n tabsets.length === 1 && leadTabset\n ? leadTabset\n : {\n children: tabs,\n id: createNodeId(\"tabset\"),\n selected: selectedOffset,\n type: \"tabset\",\n weight: DEFAULT_WEIGHT,\n };\n return placeBesideTarget(draft, placed, target.id, location ?? \"split-right\");\n};\n\nexport { dockFloat, floatTabsetById, pushFloat, uniqueFloatName };\n","import { assertNever } from \"../lib/assert-never\";\nimport { clampSelected } from \"../lib/clamp-selected\";\nimport { normalize } from \"../model/invariants\";\nimport type { Dashfoo, Geometry, GlobalAttributes } from \"../model/schema\";\nimport type { AttributedNode } from \"../model/tree\";\nimport { findAttributedNode, findFloat, findRow, findTab, findTabset } from \"../model/tree\";\n\nimport type { Action, MutableNodeAttrs } from \"./actions\";\nimport { dockFloat, floatTabsetById, pushFloat, uniqueFloatName } from \"./floats\";\nimport {\n mutableRowAttrsSchema,\n mutableTabAttrsSchema,\n mutableTabsetAttrsSchema,\n} from \"./node-attrs\";\nimport {\n detachTab,\n insertTab,\n mergeTabsInto,\n placeBesideTarget,\n removeTabsetReturning,\n wrapTabInLayout,\n} from \"./surgery\";\n\nconst parseNodeAttrs = (node: AttributedNode, attrs: MutableNodeAttrs): MutableNodeAttrs => {\n switch (node.type) {\n case \"row\": {\n return mutableRowAttrsSchema.parse(attrs);\n }\n case \"tab\": {\n return mutableTabAttrsSchema.parse(attrs);\n }\n case \"tabset\": {\n const parsed = mutableTabsetAttrsSchema.parse(attrs);\n return parsed.selected === undefined\n ? parsed\n : { ...parsed, selected: clampSelected(node.children.length, parsed.selected) };\n }\n default: {\n return assertNever(node);\n }\n }\n};\n\nconst sameGeometry = (a: Geometry, b: Geometry): boolean =>\n a.height === b.height && a.left === b.left && a.top === b.top && a.width === b.width;\n\nconst alreadyApplied = (\n target: AttributedNode | GlobalAttributes,\n attrs: MutableNodeAttrs | Partial<GlobalAttributes>,\n): boolean => {\n const current = new Map<string, unknown>(Object.entries(target));\n return Object.entries(attrs).every(([key, value]) => Object.is(current.get(key), value));\n};\n\n/** Reports whether it changed anything, so `history.dispatch` can skip a no-op. */\nconst applyAction = (draft: Dashfoo, action: Action): boolean => {\n switch (action.type) {\n case \"addNode\": {\n return insertTab(draft, action.tab, {\n id: action.targetId,\n index: action.index,\n location: action.location,\n });\n }\n case \"adjustSplit\": {\n const row = findRow(draft, action.rowId);\n if (!row) {\n return false;\n }\n let changed = false;\n for (let index = 0; index < action.weights.length; index++) {\n const child = row.children.at(index);\n const weight = action.weights[index];\n if (!child || weight === undefined || child.weight === weight) {\n continue;\n }\n child.weight = weight;\n changed = true;\n }\n return changed;\n }\n case \"deleteTab\": {\n const location = findTab(draft, action.tabId);\n if (!location) {\n return false;\n }\n detachTab(location.container, location.index);\n return true;\n }\n case \"deleteTabset\": {\n return removeTabsetReturning(draft, action.tabsetId) !== undefined;\n }\n case \"dockFloat\": {\n return dockFloat(draft, action.floatId, action.targetId, action.location);\n }\n case \"floatTab\": {\n const location = findTab(draft, action.tabId);\n if (!location) {\n return false;\n }\n const removed = detachTab(location.container, location.index);\n if (!removed) {\n return false;\n }\n pushFloat(draft, wrapTabInLayout(removed), action.geometry, action.floatId);\n return true;\n }\n case \"floatTabset\": {\n return floatTabsetById(draft, action.tabsetId, action.geometry, action.floatId);\n }\n case \"moveFloat\": {\n const float = findFloat(draft, action.floatId);\n if (!float || sameGeometry(float.geometry, action.geometry)) {\n return false;\n }\n float.geometry = action.geometry;\n return true;\n }\n case \"moveNode\": {\n const source = findTab(draft, action.sourceId);\n // Resolved before the tab leaves its container: nothing else holds it.\n if (!source || !findTabset(draft, action.targetId)) {\n return false;\n }\n\n const removed = detachTab(source.container, source.index);\n if (!removed) {\n return false;\n }\n return insertTab(draft, removed, {\n id: action.targetId,\n index: action.index,\n location: action.location,\n });\n }\n case \"moveTabset\": {\n if (action.sourceId === action.targetId) {\n return false;\n }\n const source = findTabset(draft, action.sourceId);\n const target = findTabset(draft, action.targetId);\n if (!source || !target) {\n return false;\n }\n if (action.location === \"center\") {\n mergeTabsInto(\n target,\n source.children,\n clampSelected(source.children.length, source.selected),\n );\n removeTabsetReturning(draft, action.sourceId);\n return true;\n }\n\n const detached = removeTabsetReturning(draft, action.sourceId);\n return detached\n ? placeBesideTarget(draft, detached, action.targetId, action.location)\n : false;\n }\n case \"renameFloat\": {\n const float = findFloat(draft, action.floatId);\n if (!float) {\n return false;\n }\n const others = draft.floats.filter((other) => other.id !== action.floatId);\n const name = uniqueFloatName(action.name, others);\n if (float.name === name) {\n return false;\n }\n float.name = name;\n return true;\n }\n case \"renameTab\": {\n const location = findTab(draft, action.tabId);\n if (!location || location.tab.name === action.name) {\n return false;\n }\n location.tab.name = action.name;\n return true;\n }\n case \"selectTab\": {\n const tabset = findTabset(draft, action.tabsetId);\n if (!tabset) {\n return false;\n }\n const selected = clampSelected(tabset.children.length, action.index);\n if (tabset.selected === selected) {\n return false;\n }\n tabset.selected = selected;\n return true;\n }\n case \"setActiveTabset\": {\n if (draft.activeTabsetId === action.tabsetId || !findTabset(draft, action.tabsetId)) {\n return false;\n }\n draft.activeTabsetId = action.tabsetId;\n return true;\n }\n case \"setFloatMinimized\": {\n const float = findFloat(draft, action.floatId);\n if (!float || (float.minimized ?? false) === action.minimized) {\n return false;\n }\n float.minimized = action.minimized;\n return true;\n }\n case \"setMaximizedTabset\": {\n const next = action.tabsetId ?? undefined;\n if (draft.maximizedTabsetId === next) {\n return false;\n }\n draft.maximizedTabsetId = next;\n return true;\n }\n case \"updateGlobalAttributes\": {\n if (alreadyApplied(draft.global, action.attrs)) {\n return false;\n }\n Object.assign(draft.global, action.attrs);\n return true;\n }\n case \"updateNodeAttributes\": {\n const node = findAttributedNode(draft, action.nodeId);\n if (!node) {\n return false;\n }\n const parsed = parseNodeAttrs(node, action.attrs);\n if (alreadyApplied(node, parsed)) {\n return false;\n }\n Object.assign(node, parsed);\n return true;\n }\n default: {\n return assertNever(action);\n }\n }\n};\n\n/** Identity-equal output means \"no edit\". A rejected action skips `normalize`, so\n * pass a model that has already been through it. */\nconst reducer = (model: Dashfoo, action: Action): Dashfoo => {\n const draft = structuredClone(model);\n if (!applyAction(draft, action)) {\n return model;\n }\n return normalize(draft);\n};\n\nexport { reducer };\n","import type { Dashfoo } from \"../model/schema\";\n\nimport type { Action } from \"./actions\";\nimport { reducer } from \"./reducer\";\n\ntype History = {\n future: Array<Dashfoo>;\n past: Array<Dashfoo>;\n present: Dashfoo;\n};\n\nconst HISTORY_LIMIT = 100;\n\nconst createHistory = (present: Dashfoo): History => ({\n future: [],\n past: [],\n present,\n});\n\nconst canUndo = (history: History): boolean => history.past.length > 0;\nconst canRedo = (history: History): boolean => history.future.length > 0;\n\n/**\n * An action that changed nothing is not an edit: recording it would spend an\n * undo slot and clear a redo stack the user just built. Not coalescing (ADR\n * 0002): two distinct edits are still two entries.\n */\nconst dispatch = (history: History, action: Action): History => {\n const present = reducer(history.present, action);\n if (Object.is(present, history.present)) {\n return history;\n }\n return { future: [], past: [...history.past, history.present].slice(-HISTORY_LIMIT), present };\n};\n\nconst undo = (history: History): History => {\n const previous = history.past.at(-1);\n if (previous === undefined) {\n return history;\n }\n return {\n future: [history.present, ...history.future],\n past: history.past.slice(0, -1),\n present: previous,\n };\n};\n\nconst redo = (history: History): History => {\n const [next, ...rest] = history.future;\n if (next === undefined) {\n return history;\n }\n return {\n future: rest,\n past: [...history.past, history.present].slice(-HISTORY_LIMIT),\n present: next,\n };\n};\n\nexport { canRedo, canUndo, createHistory, dispatch, HISTORY_LIMIT, redo, undo };\nexport type { History };\n","import { assign, setup } from \"xstate\";\n\nimport type { Dashfoo } from \"../model/schema\";\nimport type { Action } from \"../state/actions\";\nimport type { History } from \"../state/history\";\nimport { createHistory, dispatch, redo, undo } from \"../state/history\";\n\ntype DashfooContext = { history: History };\n\ntype DashfooEvent =\n | { action: Action; type: \"DISPATCH\" }\n | { model: Dashfoo; type: \"SET_MODEL\" }\n | { type: \"REDO\" }\n | { type: \"UNDO\" };\n\ntype DashfooMachineInput = { model: Dashfoo };\n\nconst dashfooMachine = setup({\n types: {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- SAFETY: XState reads this only as phantom compile-time metadata.\n context: {} as DashfooContext,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- SAFETY: XState reads this only as phantom compile-time metadata.\n events: {} as DashfooEvent,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- SAFETY: XState reads this only as phantom compile-time metadata.\n input: {} as DashfooMachineInput,\n },\n}).createMachine({\n context: ({ input }) => ({ history: createHistory(input.model) }),\n id: \"dashfoo\",\n initial: \"ready\",\n states: {\n ready: {\n on: {\n DISPATCH: {\n actions: assign({\n history: ({ context, event }) => dispatch(context.history, event.action),\n }),\n },\n REDO: {\n actions: assign({ history: ({ context }) => redo(context.history) }),\n },\n SET_MODEL: {\n actions: assign({ history: ({ event }) => createHistory(event.model) }),\n },\n UNDO: {\n actions: assign({ history: ({ context }) => undo(context.history) }),\n },\n },\n },\n },\n});\n\nexport { dashfooMachine };\n","import { assign, emit, setup } from \"xstate\";\n\nimport type { TabNode } from \"../model/schema\";\nimport type { Action, DropIntent } from \"../state/actions\";\n\ntype DragSubject =\n | { id: string; kind: \"tab\" | \"tabset\" }\n | { id: string; kind: \"external\"; tab: TabNode };\n\n/** `scope` names whoever resolved the intent, echoed back on `COMMIT` so the host can route the action. */\ntype DropResolution = { intent: DropIntent; scope: string };\n\n/** One value, so a drop target without a subject is unrepresentable. See ADR 0002. */\ntype DragState =\n | { drop: DropResolution | null; kind: \"dragging\"; subject: DragSubject }\n | { kind: \"idle\" };\n\ntype DragContext = { drag: DragState };\n\ntype DragEvent =\n | { drop: DropResolution | null; type: \"OVER\" }\n | { subject: DragSubject; type: \"START\" }\n | { type: \"CANCEL\" }\n | { type: \"DROP\" };\n\ntype DragEmitted = { action: Action; scope: string; type: \"COMMIT\" };\n\n/** One definition of both \"is this drop valid\" and \"what does it do\", so the guard and the emit agree. */\nconst dropAction = (drag: DragState): { action: Action; scope: string } | null => {\n if (drag.kind !== \"dragging\" || drag.drop === null) {\n return null;\n }\n const { intent, scope } = drag.drop;\n const { subject } = drag;\n\n if (subject.kind === \"external\") {\n return {\n action: {\n index: intent.index,\n location: intent.location,\n tab: subject.tab,\n targetId: intent.targetId,\n type: \"addNode\",\n },\n scope,\n };\n }\n if (subject.kind === \"tabset\") {\n return {\n action: {\n location: intent.location,\n sourceId: subject.id,\n targetId: intent.targetId,\n type: \"moveTabset\",\n },\n scope,\n };\n }\n return {\n action: {\n index: intent.index,\n location: intent.location,\n sourceId: subject.id,\n targetId: intent.targetId,\n type: \"moveNode\",\n },\n scope,\n };\n};\n\nconst dragDockMachine = setup({\n guards: {\n hasValidDrop: ({ context }) => dropAction(context.drag) !== null,\n },\n types: {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- SAFETY: XState reads this only as phantom compile-time metadata.\n context: {} as DragContext,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- SAFETY: XState reads this only as phantom compile-time metadata.\n emitted: {} as DragEmitted,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- SAFETY: XState reads this only as phantom compile-time metadata.\n events: {} as DragEvent,\n },\n}).createMachine({\n context: { drag: { kind: \"idle\" } },\n id: \"dragDock\",\n initial: \"idle\",\n states: {\n dragging: {\n on: {\n CANCEL: { target: \"idle\" },\n DROP: [\n {\n actions: emit(({ context }) => {\n const resolved = dropAction(context.drag);\n if (resolved === null) {\n throw new Error(\"drop requires a subject and a resolved drop target\");\n }\n return { action: resolved.action, scope: resolved.scope, type: \"COMMIT\" };\n }),\n guard: \"hasValidDrop\",\n target: \"idle\",\n },\n { target: \"idle\" },\n ],\n OVER: {\n actions: assign({\n drag: ({ context, event }) =>\n context.drag.kind === \"dragging\"\n ? { ...context.drag, drop: event.drop }\n : context.drag,\n }),\n },\n },\n },\n idle: {\n entry: assign({ drag: { kind: \"idle\" } }),\n on: {\n START: {\n actions: assign({\n drag: ({ event }) => ({ drop: null, kind: \"dragging\", subject: event.subject }),\n }),\n target: \"dragging\",\n },\n },\n },\n },\n});\n\nexport { dragDockMachine, dropAction };\nexport type { DragState, DragSubject, DropResolution };\n","import { normalize } from \"./invariants\";\nimport type { Dashfoo } from \"./schema\";\nimport { dashfooSchema, jsonValueSchema } from \"./schema\";\nimport { findDuplicateIds } from \"./tree\";\n\nconst parseModel = (value: unknown): Dashfoo => {\n const model = normalize(dashfooSchema.parse(value));\n const duplicates = findDuplicateIds(model);\n if (duplicates.length > 0) {\n // oxlint-disable-next-line no-console\n console.warn(`[dashfoo] duplicate node ids in the loaded layout: ${duplicates.join(\", \")}`);\n }\n return model;\n};\n\nconst toJSON = (model: Dashfoo): string => JSON.stringify(model);\n\nconst fromJSON = (json: string): Dashfoo => parseModel(jsonValueSchema.parse(JSON.parse(json)));\n\nexport { fromJSON, parseModel, toJSON };\n","import { normalize } from \"./invariants\";\nimport type { Dashfoo, Orientation, TabsetNode } from \"./schema\";\nimport { collectTabsetsInRow } from \"./tree\";\n\nconst stackModel = (model: Dashfoo, orientation: Orientation = \"column\"): Dashfoo => {\n const mainTabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(model.layout, mainTabsets);\n const children: Array<TabsetNode> = [];\n for (const tabset of mainTabsets) {\n children.push({ ...tabset, weight: 1 });\n }\n\n return normalize({\n ...model,\n layout: {\n children,\n id: model.layout.id,\n orientation,\n type: \"row\",\n weight: model.layout.weight,\n },\n maximizedTabsetId: undefined,\n });\n};\n\nexport { stackModel };\n"],"mappings":";;;;;;AAEA,MAAM,iBAAiB,QAAgB,aAA6B;CAClE,IAAI,WAAW,GACb,OAAO;CAGT,MAAM,OAAO,OAAO,SAAS,QAAQ,IAAI,KAAK,MAAM,QAAQ,IAAI;CAChE,IAAI,OAAO,GACT,OAAO;CAET,IAAI,OAAO,SAAS,GAClB,OAAO,SAAS;CAElB,OAAO;AACT;;;;;ACVA,MAAM,iBAAiB;AAIvB,MAAM,kBAAwC,EAAE,WAC9C,EAAE,MAAM;CACN,EAAE,OAAO;CACT,EAAE,OAAO;CACT,EAAE,QAAQ;CACV,EAAE,KAAK;CACP,EAAE,MAAM,eAAe;CACvB,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;AACtC,CAAC,CACH;AAEA,MAAM,aAAa,EAAE,KAAK;CAAC;CAAO;CAAU;CAAQ;AAAO,CAAC;AAC5D,MAAM,aAAa,EAAE,KAAK;CAAC;CAAM;CAAK;CAAM;CAAO;CAAM;AAAI,CAAC;AAC9D,MAAM,oBAAoB,EAAE,KAAK,CAAC,OAAO,QAAQ,CAAC;AAElD,MAAM,kBAAkB,EAAE,OAAO;CAC/B,MAAM;CACN,OAAO,EAAE,OAAO;AAClB,CAAC;AAED,MAAM,aAAa,EAAE,OAAO;CAC1B,WAAW,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,SAAS,GAAG,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;CAC1E,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CACjC,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;AAC5C,CAAC;AAED,MAAM,gBAAgB,EAAE,OAAO;CAC7B,WAAW,EAAE,OAAO;CACpB,QAAQ,gBAAgB,SAAS;CACjC,aAAa,EAAE,QAAQ,CAAC,CAAC,SAAS;CAClC,YAAY,EAAE,QAAQ,CAAC,CAAC,SAAS;CACjC,cAAc,EAAE,QAAQ,CAAC,CAAC,SAAS;CACnC,IAAI,EAAE,OAAO;CACb,MAAM,EAAE,OAAO;CACf,MAAM,EAAE,QAAQ,KAAK;AACvB,CAAC;;;;;AAMD,MAAM,yBAAyB,EAAE,OAAO;CACtC,UAAU,EAAE,MAAM,aAAa;CAC/B,aAAa,EAAE,QAAQ,CAAC,CAAC,SAAS;CAClC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,SAAS;CACrC,IAAI,EAAE,OAAO;CACb,KAAK,gBAAgB,SAAS;CAC9B,KAAK,gBAAgB,SAAS;CAC9B,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI;CACzB,MAAM,EAAE,QAAQ,QAAQ;CACxB,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAsB;AAC3C,CAAC;AAED,MAAM,mBAAmB,uBAAuB,WAAW,YAAY;CACrE,GAAG;CACH,UAAU,cAAc,OAAO,SAAS,QAAQ,OAAO,QAAQ;AACjE,EAAE;;AAGF,MAAM,gBAAgB,EAAE,OAAO;CAC7B,IAAI,WAAoF;EACtF,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,eAAe,gBAAgB,CAAC,CAAC;CAC3D;CACA,IAAI,EAAE,OAAO;CACb,KAAK,gBAAgB,SAAS;CAC9B,KAAK,gBAAgB,SAAS;CAC9B,aAAa;CACb,MAAM,WAAW,SAAS;CAC1B,MAAM,EAAE,QAAQ,KAAK;CACrB,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAsB;AAC3C,CAAC;AAKD,MAAM,iBAAiB,EAAE,OAAO;CAC9B,QAAQ,EAAE,OAAO;CACjB,MAAM,EAAE,OAAO;CACf,KAAK,EAAE,OAAO;CACd,OAAO,EAAE,OAAO;AAClB,CAAC;AAED,MAAM,kBAAkB,EAAE,OAAO;CAC/B,UAAU;CACV,IAAI,EAAE,OAAO;CACb,QAAQ;CAER,WAAW,EAAE,QAAQ,CAAC,CAAC,SAAS;CAChC,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,MAAM,EAAE,QAAQ,OAAO;AACzB,CAAC;AAED,MAAM,yBAAyB,EAAE,OAAO;CACtC,iBAAiB,EAAE,QAAQ,CAAC,CAAC,SAAS;CACtC,mBAAmB,EAAE,QAAQ,CAAC,CAAC,SAAS;CACxC,MAAM,WAAW,SAAS;CAC1B,cAAc,EAAE,OAAO,CAAC,CAAC,SAAS;CAClC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,SAAS;CACrC,eAAe,EAAE,QAAQ,CAAC,CAAC,SAAS;CACpC,iBAAiB,EAAE,QAAQ,CAAC,CAAC,SAAS;CACtC,aAAa,EAAE,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS;CAChD,sBAAsB,EAAE,QAAQ,CAAC,CAAC,SAAS;CAC3C,sBAAsB,EAAE,QAAQ,CAAC,CAAC,SAAS;CAC3C,eAAe,EAAE,OAAO,CAAC,CAAC,SAAS;AACrC,CAAC;AAED,MAAM,gBAAgB,EAAE,OAAO;CAC7B,gBAAgB,EAAE,OAAO,CAAC,CAAC,SAAS;CACpC,QAAQ,EAAE,MAAM,eAAe,CAAC,CAAC,cAAc,CAAC,CAAC;CACjD,QAAQ;CACR,QAAQ;CACR,mBAAmB,EAAE,OAAO,CAAC,CAAC,SAAS;CACvC,SAAS,EAAE,QAAQ,CAAC;AACtB,CAAC;;;;ACjHD,MAAM,wBAAwB,cAC3B,KAAK;CACJ,QAAQ;CACR,aAAa;CACb,YAAY;CACZ,cAAc;CACd,MAAM;AACR,CAAC,CAAC,CACD,QAAQ;;AAGX,MAAM,2BAA2B,uBAC9B,KAAK;CACJ,aAAa;CACb,gBAAgB;CAChB,KAAK;CACL,KAAK;CACL,UAAU;AACZ,CAAC,CAAC,CACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAC9B,QAAQ;AAEX,MAAM,wBAAwB,EAC3B,OAAO;CACN,KAAK,gBAAgB,SAAS;CAC9B,KAAK,gBAAgB,SAAS;CAC9B,aAAa;CACb,MAAM,WAAW,SAAS;CAC1B,QAAQ,EAAE,OAAO;AACnB,CAAC,CAAC,CACD,QAAQ;;;;;AAMX,MAAM,yBAAyB,sBAC5B,OAAO,yBAAyB,KAAK,CAAC,CACtC,OAAO,sBAAsB,KAAK;;;;AC1CrC,MAAM,qBAAqB,EAAE,KAAK;CAChC;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,qBAAqB,EAAE,MAAM,EAAE,OAAO,CAAC;AAE7C,MAAM,eAAe,EAAE,mBAAmB,QAAQ;CAChD,EAAE,OAAO;EACP,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;EACjC,UAAU;EACV,KAAK;EACL,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,QAAQ,SAAS;CAC3B,CAAC;CACD,EAAE,OAAO;EACP,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;EACjC,UAAU;EACV,UAAU,EAAE,OAAO;EACnB,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,QAAQ,UAAU;CAC5B,CAAC;CAGD,EAAE,OAAO;EACP,UAAU;EACV,UAAU,EAAE,OAAO;EACnB,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,QAAQ,YAAY;CAC9B,CAAC;CACD,EAAE,OAAO;EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI;EAAG,UAAU,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,WAAW;CAAE,CAAC;CACxF,EAAE,OAAO;EAAE,UAAU,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,iBAAiB;CAAE,CAAC;CACrE,EAAE,OAAO;EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;EAAG,MAAM,EAAE,QAAQ,oBAAoB;CAAE,CAAC;CACnF,EAAE,OAAO;EAAE,MAAM,EAAE,OAAO;EAAG,OAAO,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,WAAW;CAAE,CAAC;CAC9E,EAAE,OAAO;EAAE,OAAO,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,WAAW;CAAE,CAAC;CAC5D,EAAE,OAAO;EAAE,UAAU,EAAE,OAAO;EAAG,MAAM,EAAE,QAAQ,cAAc;CAAE,CAAC;CAClE,EAAE,OAAO;EACP,OAAO,EAAE,OAAO;EAChB,MAAM,EAAE,QAAQ,aAAa;EAC7B,SAAS;CACX,CAAC;CACD,EAAE,OAAO;EACP,OAAO;EACP,QAAQ,EAAE,OAAO;EACjB,MAAM,EAAE,QAAQ,sBAAsB;CACxC,CAAC;CACD,EAAE,OAAO;EAAE,OAAO,uBAAuB,QAAQ;EAAG,MAAM,EAAE,QAAQ,wBAAwB;CAAE,CAAC;CAE/F,EAAE,OAAO;EACP,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;EAC7B,UAAU,eAAe,SAAS;EAClC,OAAO,EAAE,OAAO;EAChB,MAAM,EAAE,QAAQ,UAAU;CAC5B,CAAC;CAED,EAAE,OAAO;EACP,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;EAC7B,UAAU,eAAe,SAAS;EAClC,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,QAAQ,aAAa;CAC/B,CAAC;CAED,EAAE,OAAO;EACP,SAAS,EAAE,OAAO;EAClB,UAAU,mBAAmB,SAAS;EACtC,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;EAC9B,MAAM,EAAE,QAAQ,WAAW;CAC7B,CAAC;CAED,EAAE,OAAO;EACP,SAAS,EAAE,OAAO;EAClB,UAAU;EACV,MAAM,EAAE,QAAQ,WAAW;CAC7B,CAAC;CAED,EAAE,OAAO;EACP,SAAS,EAAE,OAAO;EAClB,WAAW,EAAE,QAAQ;EACrB,MAAM,EAAE,QAAQ,mBAAmB;CACrC,CAAC;CAED,EAAE,OAAO;EACP,SAAS,EAAE,OAAO;EAClB,MAAM,EAAE,OAAO;EACf,MAAM,EAAE,QAAQ,aAAa;CAC/B,CAAC;AACH,CAAC;;;;AC/FD,MAAM,gBAAgB,SAAS,WAAmB,GAAG,OAAO,GAAG,OAAO,WAAW;AAEjF,MAAM,oBAA4B,aAAa,KAAK;;;;ACGpD,MAAM,gBAAgB,UAAmC,CACvD,MAAM,QACN,GAAG,MAAM,OAAO,KAAK,UAAU,MAAM,MAAM,CAC7C;AAEA,MAAM,aAAa,OAAgB,YACjC,MAAM,OAAO,MAAM,UAAU,MAAM,OAAO,OAAO;;;;;;AAenD,MAAM,QACJ,KACA,OACA,QACA,QAAQ,OACU;CAClB,MAAM,SAAS,MAAM;EAAE;EAAO,MAAM;EAAK;CAAO,CAAC;CACjD,IAAI,WAAW,QACb,OAAO;CAET,KAAK,MAAM,CAAC,YAAY,UAAU,IAAI,SAAS,QAAQ,GAAG;EACxD,IAAI,MAAM,SAAS,OAAO;GACxB,MAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU;GAChD,IAAI,UAAU,QACZ,OAAO;GAET;EACF;EACA,MAAM,WAAW,MAAM;GAAE,OAAO;GAAY,MAAM;GAAO,QAAQ;EAAI,CAAC;EACtE,IAAI,aAAa,QACf,OAAO;EAET,KAAK,MAAM,CAAC,UAAU,QAAQ,MAAM,SAAS,QAAQ,GAAG;GACtD,MAAM,QAAQ,MAAM;IAAE,OAAO;IAAU,MAAM;IAAK,QAAQ;GAAM,CAAC;GACjE,IAAI,UAAU,QACZ,OAAO;EAEX;CACF;AAEF;AAQA,MAAM,SAAS,SAA0C,KAAK,SAAS;AACvE,MAAM,SAAS,SAA0C,KAAK,SAAS;AACvE,MAAM,YAAY,SAA6C,KAAK,SAAS;;AAG7E,MAAM,UACJ,OACA,IACA,OAC2B;CAC3B,KAAK,MAAM,QAAQ,aAAa,KAAK,GAAG;EACtC,MAAM,QAAQ,KAAK,OAAO,EAAE,OAAO,MAAM,aACvC,KAAK,OAAO,MAAM,GAAG,IAAI,IAAI;GAAE;GAAO;GAAM;EAAO,IAAI,MACzD;EACA,IAAI,OACF,OAAO;CAEX;AAEF;AAEA,MAAM,uBAAuB,KAAc,QAAiC;CAC1E,KAAK,MAAM,EAAE,WAAW;EACtB,IAAI,KAAK,SAAS,UAChB,IAAI,KAAK,IAAI;CAGjB,CAAC;AACH;AAEA,MAAM,kBAAkB,UAAsC;CAC5D,MAAM,MAAyB,CAAC;CAChC,KAAK,MAAM,QAAQ,aAAa,KAAK,GACnC,oBAAoB,MAAM,GAAG;CAE/B,OAAO;AACT;AAEA,MAAM,kBAAkB,UAA2C,eAAe,KAAK,CAAC,CAAC;AAEzF,MAAM,cAAc,OAAgB,aAClC,OAAO,OAAO,UAAU,QAAQ,CAAC,EAAE;AAErC,MAAM,WAAW,OAAgB,UAA2C;CAC1E,MAAM,QAAQ,OAAO,OAAO,OAAO,KAAK;CACxC,OAAO,OAAO,QAAQ,SAAS,WAC3B;EAAE,WAAW,MAAM;EAAQ,OAAO,MAAM;EAAO,KAAK,MAAM;CAAK,IAC/D;AACN;AAEA,MAAM,WAAW,OAAgB,OAAoC,OAAO,OAAO,IAAI,KAAK,CAAC,EAAE;AAE/F,MAAM,sBAAsB,OAAgB,OAA2C;CACrF,KAAK,MAAM,QAAQ,aAAa,KAAK,GAAG;EACtC,MAAM,QAAQ,KAAK,OAAO,EAAE,WAAY,KAAK,OAAO,KAAK,OAAO,MAAU;EAC1E,IAAI,OACF,OAAO;CAEX;AAEF;AAEA,MAAM,sBAAsB,OAAgB,WAAwC;CAClF,KAAK,MAAM,QAAQ,aAAa,KAAK,GAEnC,IADY,KAAK,OAAO,EAAE,WAAY,KAAK,OAAO,SAAS,OAAO,MAC5D,GACJ,OAAO;AAIb;AAEA,MAAM,oBACJ,OACA,aACmD;CACnD,MAAM,QAAQ,OAAO,OAAO,UAAU,QAAQ;CAC9C,OAAO,OAAO,QAAQ,SAAS,QAAQ;EAAE,OAAO,MAAM;EAAO,QAAQ,MAAM;CAAO,IAAI;AACxF;AAEA,MAAM,mBAAmB,KAAc,QAA6B;CAClE,KAAK,MAAM,EAAE,WAAW;EACtB,IAAI,KAAK,KAAK,EAAE;CAElB,CAAC;AACH;AAEA,MAAM,oBAAoB,UAAkC;CAC1D,MAAM,MAAqB,CAAC;CAC5B,KAAK,MAAM,SAAS,MAAM,QACxB,IAAI,KAAK,MAAM,EAAE;CAEnB,KAAK,MAAM,QAAQ,aAAa,KAAK,GACnC,gBAAgB,MAAM,GAAG;CAE3B,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,6BAAa,IAAI,IAAY;CACnC,KAAK,MAAM,MAAM,KAAK;EACpB,IAAI,KAAK,IAAI,EAAE,GACb,WAAW,IAAI,EAAE;EAEnB,KAAK,IAAI,EAAE;CACb;CACA,OAAO,CAAC,GAAG,UAAU;AACvB;;;;ACtJA,MAAM,eAAe,UACnB,OAAO,UAAU,WAAW;CAAE,MAAM;CAAM;AAAM,IAAI;AAUtD,MAAM,OAAO,WAAmB,MAAc,UAAsB,CAAC,OAAgB;CACnF;CACA;CACA,MAAM;CACN,GAAG;CACH,IAAI,QAAQ,MAAM;AACpB;AAaA,MAAM,UAAU,UAA0B,UAAyB,CAAC,MAAkB;CACpF,MAAM,EAAE,KAAK,KAAK,GAAG,SAAS;CAC9B,MAAM,QAAoB;EACxB;EACA,MAAM;EACN,GAAG;EACH,IAAI,QAAQ,MAAM,aAAa,QAAQ;EACvC,UAAU,cAAc,SAAS,QAAQ,QAAQ,YAAY,CAAC;EAC9D,QAAQ,QAAQ;CAClB;CACA,IAAI,QAAQ,QACV,MAAM,MAAM,YAAY,GAAG;CAE7B,IAAI,QAAQ,QACV,MAAM,MAAM,YAAY,GAAG;CAE7B,OAAO;AACT;AAWA,MAAM,OAAO,UAA+B,UAAsB,CAAC,MAAe;CAChF,MAAM,EAAE,KAAK,KAAK,GAAG,SAAS;CAC9B,MAAM,QAAiB;EACrB;EACA,MAAM;EACN,GAAG;EACH,IAAI,QAAQ,MAAM,aAAa,KAAK;EACpC,aAAa,QAAQ,eAAe;EACpC,QAAQ,QAAQ;CAClB;CACA,IAAI,QAAQ,QACV,MAAM,MAAM,YAAY,GAAG;CAE7B,IAAI,QAAQ,QACV,MAAM,MAAM,YAAY,GAAG;CAE7B,OAAO;AACT;AAOA,MAAM,aAAa,QAAiB,UAAoB,UAAwB,CAAC,OAAkB;CACjG;CACA;CACA,MAAM;CACN,GAAG;CACH,IAAI,QAAQ,MAAM,aAAa,OAAO;AACxC;AASA,MAAM,SAAS,QAAiB,UAAwB,CAAC,MAAe;CACtE,MAAM,QAAiB;EACrB;EACA,SAAS;EACT,GAAG;EACH,QAAQ,QAAQ,UAAU,CAAC;EAC3B,QAAQ,QAAQ,UAAU,CAAC;CAC7B;CACA,MAAM,aAAa,iBAAiB,KAAK;CACzC,IAAI,WAAW,SAAS,GAEtB,QAAQ,KACN,kDAAkD,WAAW,KAAK,IAAI,EAAE,6CAC1E;CAEF,OAAO;AACT;;;;ACnIA,MAAM,eAAe,UAAwB;CAC3C,MAAM,IAAI,MAAM,sBAAsB,KAAK,UAAU,KAAK,GAAG;AAC/D;;;;ACQA,MAAM,wBAAwB;AAE9B,MAAM,iBAAiB,SAAgB,SAA8B;CACnE,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK,KAAK;CACvC,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK,KAAK;CACvC,OAAO;EAAE,QAAQ,IAAI;EAAI,MAAM;EAAI,OAAO,IAAI;EAAI,KAAK;CAAG;AAC5D;AAEA,MAAM,eAAe,MAA2B;CAC9C,MAAM,MAAM,KAAK,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;CACrD,IAAI,QAAQ,EAAE,MACZ,OAAO;CAET,IAAI,QAAQ,EAAE,OACZ,OAAO;CAET,IAAI,QAAQ,EAAE,KACZ,OAAO;CAET,OAAO;AACT;AAEA,MAAM,aAAa,aAA6C;CAC9D,QAAQ,UAAR;EACE,KAAK,UACH;EAEF,KAAK,gBACH,OAAO;EAET,KAAK,cACH,OAAO;EAET,KAAK,eACH,OAAO;EAET,KAAK,aACH,OAAO;EAET,SACE,OAAO,YAAY,QAAQ;CAE/B;AACF;AAEA,MAAM,qBAAqB,SAAgB,MAAY,SAAqC;CAC1F,MAAM,OAAO,MAAM,gBAAgB;CAEnC,IAAI,KAAK,SAAS,KAAK,KAAK,UAAU,GACpC,OAAO;CAET,MAAM,YAAY,cAAc,SAAS,IAAI;CAG7C,IAFY,KAAK,IAAI,UAAU,MAAM,UAAU,OAAO,UAAU,KAAK,UAAU,MAEzE,IAAI,MACR,OAAO;CAET,OAAO,SAAS,YAAY,SAAS;AACvC;AAEA,MAAM,oBAAoB,MAAY,SAAwC;CAC5E,MAAM,EAAE,QAAQ,GAAG,OAAO,GAAG,GAAG,MAAM;CACtC,MAAM,KAAY;EAAE;EAAG;CAAE;CACzB,MAAM,KAAY;EAAE,GAAG,IAAI;EAAG;CAAE;CAChC,MAAM,KAAY;EAAE,GAAG,IAAI;EAAG,GAAG,IAAI;CAAE;CACvC,MAAM,KAAY;EAAE;EAAG,GAAG,IAAI;CAAE;CAChC,IAAI,KAAK,KAAK,KAAK,GACjB,OAAO,CAAC;EAAE,UAAU;EAAU,QAAQ;GAAC;GAAI;GAAI;GAAI;EAAE;CAAE,CAAC;CAE1D,MAAM,OAAO,MAAM,gBAAgB;CACnC,MAAM,KAAK,OAAO;CAClB,MAAM,KAAK,OAAO;CAClB,MAAM,UAAiB;EAAE,GAAG,IAAI;EAAI,GAAG,IAAI;CAAG;CAC9C,MAAM,UAAiB;EAAE,GAAG,IAAI,IAAI;EAAI,GAAG,IAAI;CAAG;CAClD,MAAM,UAAiB;EAAE,GAAG,IAAI,IAAI;EAAI,GAAG,IAAI,IAAI;CAAG;CACtD,MAAM,UAAiB;EAAE,GAAG,IAAI;EAAI,GAAG,IAAI,IAAI;CAAG;CAClD,OAAO;EACL;GAAE,UAAU;GAAU,QAAQ;IAAC;IAAS;IAAS;IAAS;GAAO;EAAE;EACnE;GAAE,UAAU;GAAc,QAAQ;IAAC;IAAI;IAAS;IAAS;GAAE;EAAE;EAC7D;GAAE,UAAU;GAAe,QAAQ;IAAC;IAAI;IAAI;IAAS;GAAO;EAAE;EAC9D;GAAE,UAAU;GAAa,QAAQ;IAAC;IAAI;IAAI;IAAS;GAAO;EAAE;EAC5D;GAAE,UAAU;GAAgB,QAAQ;IAAC;IAAI;IAAS;IAAS;GAAE;EAAE;CACjE;AACF;AAEA,MAAM,YAAY,MAAY,aAAiC;CAC7D,MAAM,QAAQ,KAAK,QAAQ;CAC3B,MAAM,QAAQ,KAAK,SAAS;CAC5B,QAAQ,UAAR;EACE,KAAK,gBACH,OAAO;GAAE,QAAQ;GAAO,OAAO,KAAK;GAAO,GAAG,KAAK;GAAG,GAAG,KAAK,IAAI;EAAM;EAE1E,KAAK,cACH,OAAO;GAAE,QAAQ,KAAK;GAAQ,OAAO;GAAO,GAAG,KAAK;GAAG,GAAG,KAAK;EAAE;EAEnE,KAAK,eACH,OAAO;GAAE,QAAQ,KAAK;GAAQ,OAAO;GAAO,GAAG,KAAK,IAAI;GAAO,GAAG,KAAK;EAAE;EAE3E,KAAK,aACH,OAAO;GAAE,QAAQ;GAAO,OAAO,KAAK;GAAO,GAAG,KAAK;GAAG,GAAG,KAAK;EAAE;EAElE,KAAK,UACH,OAAO;EAET,SACE,OAAO,YAAY,QAAQ;CAE/B;AACF;;;;ACpHA,MAAM,yBAAyB;AAE/B,MAAM,mBAAmB;AAEzB,MAAM,gBAAgB,SAAsB,cAA4B;CACtE,IAAI,aAAa,GACf;CAEF,KAAK,IAAI,WAAW,WAAW,WAAW,KAAK,YAAY,WAAW;EACpE,MAAM,UAAU,KAAK,MAAM,WAAW,gBAAgB,IAAI;EAC1D,IAAI,UAAU,KACZ,QAAQ,IAAI,OAAO;CAEvB;AACF;AAEA,MAAM,sBAAsB,QAAoB,eAAsC;CACpF,MAAM,0BAAU,IAAI,IAAY;CAChC,IAAI,OAAO,SAAS,UAAa,OAAO,OAAO,GAC7C,aAAa,SAAS,OAAO,IAAI;CAEnC,IAAI,OAAO,cAAc,QAAW;EAClC,MAAM,YAAY,OAAO,cAAc,WAAW,aAAa,OAAO;EACtE,IAAI,aAAa,GACf,aAAa,SAAS,MAAM,SAAS;CAEzC;CACA,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,UAAU,GAAG,MAAM,IAAI,CAAC;AAC9C;AAIA,MAAM,mBAAmB,QAA2B,gBAAkC;CACpF,SAAS,WAAW,OAAO,CAAC,IAAI,mBAAmB,QAAQ,UAAU;CACrE,WAAW,QAAQ;AACrB;AAEA,MAAM,eAAe,SAA4B,KAAK,QAAQ,SAAS;AAEvE,MAAM,iBAAiB,UAAkB,YACvC,QAAQ,QAA4B,MAAM,WAAW;CACnD,IAAI,SAAS,UAAa,KAAK,IAAI,SAAS,QAAQ,IAAI,KAAK,IAAI,OAAO,QAAQ,GAC9E,OAAO;CAET,OAAO;AACT,GAAG,MAAS;AAId,MAAM,aAAa,OAAsB,eAAuB,SAA+B;CAC7F,MAAM,EAAE,SAAS,cAAc;CAC/B,MAAM,OAAO,MAAM;CACnB,MAAM,QAAQ,MAAM,gBAAgB;CACpC,IAAI,gBAAgB,KAAK,SAAS,UAAa,UAAU,UAAa,QAAQ,WAAW,GACvF,OAAO;EAAE;EAAO,SAAS;CAAM;CAGjC,IAAI,WAAW;CACf,KAAK,IAAI,QAAQ,GAAG,SAAS,eAAe,SAC1C,YAAY,MAAM,UAAU;CAG9B,MAAM,SAAS,cAAc,UAAU,OAAO;CAC9C,IAAI,WAAW,UAAa,KAAK,IAAI,SAAS,QAAQ,IAAI,WACxD,OAAO;EAAE;EAAO,SAAS;CAAM;CAGjC,MAAM,QAAQ,SAAS;CACvB,IAAI,OAAO,QAAQ,KAAK,QAAQ,QAAQ,GACtC,OAAO;EAAE;EAAO,SAAS;CAAM;CAGjC,MAAM,OAAO,CAAC,GAAG,KAAK;CACtB,KAAK,iBAAiB,OAAO;CAC7B,KAAK,gBAAgB,KAAK,QAAQ;CAClC,OAAO;EAAE,OAAO;EAAM,SAAS;CAAK;AACtC;AAOA,MAAM,cACJ,OACA,eACA,SACiB;CACjB,IAAI,kBAAkB,QAAQ,CAAC,YAAY,IAAI,GAC7C,OAAO,EAAE,MAAM,WAAW;CAE5B,MAAM,EAAE,OAAO,cAAc,YAAY,UAAU,OAAO,eAAe,IAAI;CAC7E,OAAO,UAAU;EAAE,MAAM;EAAU,OAAO;CAAa,IAAI,EAAE,MAAM,QAAQ;AAC7E;AAEA,MAAM,cACJ,OACA,eACA,SACkB;CAClB,MAAM,WAAW,WAAW,OAAO,eAAe,IAAI;CACtD,OAAO,SAAS,SAAS,WAAW,SAAS,QAAQ;AACvD;;;;;;;;;AC/FA,MAAM,eAAe,KAAc,aAAiC;CAClE,MAAM,QAAkB;EACtB,GAAG;EACH,QAAQ,IAAI;CACd;CAEA,IAAI,IAAI,QAAQ,QACd,MAAM,MAAM,IAAI;CAElB,IAAI,IAAI,QAAQ,QACd,MAAM,MAAM,IAAI;CAGlB,IAAI,MAAM,SAAS,SAAS,IAAI,SAAS,QACvC,OAAO;EAAE,GAAG;EAAO,MAAM,IAAI;CAAK;CAEpC,OAAO;AACT;;AAGA,MAAM,wBACJ,UACA,kBACwB;CACxB,MAAM,MAA2B,CAAC;CAElC,KAAK,MAAM,SAAS,UAAU;EAC5B,IAAI,MAAM,SAAS,UAAU;GAC3B,IAAI,MAAM,SAAS,SAAS,GAAG;IAC7B,IAAI,KAAK,KAAK;IACd,cAAc,KAAK,MAAM,EAAE;GAC7B;GACA;EACF;EAIA,MAAM,gBAAgB,qBAAqB,MAAM,UAAU,aAAa;EACxE,IAAI,cAAc,WAAW,GAC3B;EAEF,IAAI,cAAc,WAAW,GAAG;GAC9B,MAAM,OAAO,cAAc;GAC3B,IAAI,SAAS,QACX,IAAI,KAAK,YAAY,OAAO,IAAI,CAAC;GAEnC;EACF;EACA,IAAI,KAAK;GAAE,GAAG;GAAO,UAAU;EAAc,CAAC;CAChD;CAEA,OAAO;AACT;AAEA,MAAM,mBAAmB,MAAe,kBAA0C;CAChF,IAAI,WAAW,qBAAqB,KAAK,UAAU,aAAa;CAChE,IAAI,cAAc,KAAK;CAEvB,IAAI,QAAQ,SAAS;CACrB,OAAO,SAAS,WAAW,KAAK,OAAO,SAAS,OAAO;EACrD,WAAW,MAAM;EACjB,cAAc,MAAM;EACpB,QAAQ,SAAS;CACnB;CAEA,OAAO;EAAE,GAAG;EAAM;EAAU;CAAY;AAC1C;AAEA,MAAM,aAAa,UAA4B;CAC7C,MAAM,gBAA+B,CAAC;CACtC,MAAM,SAAS,gBAAgB,MAAM,QAAQ,aAAa;CAE1D,MAAM,SAA2B,CAAC;CAClC,MAAM,iBAAgC,CAAC;CACvC,KAAK,MAAM,SAAS,MAAM,QAAQ;EAChC,MAAM,eAA8B,CAAC;EACrC,MAAM,cAAc,gBAAgB,MAAM,QAAQ,YAAY;EAC9D,IAAI,YAAY,SAAS,SAAS,GAAG;GACnC,OAAO,KAAK;IAAE,GAAG;IAAO,QAAQ;GAAY,CAAC;GAC7C,eAAe,KAAK,GAAG,YAAY;EACrC;CACF;CAEA,MAAM,UAAU,IAAI,IAAI,aAAa;CACrC,MAAM,0BAAU,IAAI,IAAI,CAAC,GAAG,eAAe,GAAG,cAAc,CAAC;CAC7D,MAAM,gBAAgB,cAAc,MAAM,eAAe;CAEzD,MAAM,iBACJ,MAAM,mBAAmB,UAAa,QAAQ,IAAI,MAAM,cAAc,IAClE,MAAM,iBACN;CAIN,MAAM,oBACJ,MAAM,sBAAsB,UAAa,QAAQ,IAAI,MAAM,iBAAiB,IACxE,MAAM,oBACN;CAEN,OAAO;EAAE,GAAG;EAAO;EAAgB;EAAQ;EAAQ;CAAkB;AACvE;;;;ACjGA,MAAM,yBAAyB,OAAgB,aAA6C;CAC1F,MAAM,QAAQ,iBAAiB,OAAO,QAAQ;CAC9C,IAAI,CAAC,OACH;CAEF,MAAM,CAAC,WAAW,MAAM,OAAO,SAAS,OAAO,MAAM,OAAO,CAAC;CAC7D,OAAO,SAAS,SAAS,WAAW,UAAU;AAChD;;AAGA,MAAM,kBAAkB;CACtB,gBAAgB;EAAE,QAAQ;EAAO,aAAa;CAAS;CACvD,cAAc;EAAE,QAAQ;EAAM,aAAa;CAAM;CACjD,eAAe;EAAE,QAAQ;EAAO,aAAa;CAAM;CACnD,aAAa;EAAE,QAAQ;EAAM,aAAa;CAAS;AACrD;AAEA,MAAM,qBACJ,OACA,QACA,UACA,aACY;CACZ,MAAM,eAAe,WAAW,OAAO,QAAQ;CAC/C,MAAM,QAAQ,iBAAiB,OAAO,QAAQ;CAC9C,IAAI,CAAC,gBAAgB,CAAC,OACpB,OAAO;CAGT,MAAM,EAAE,QAAQ,gBAAgB,gBAAgB;CAEhD,IAAI,MAAM,OAAO,gBAAgB,aAAa;EAC5C,MAAM,OAAO,aAAa,SAAS;EACnC,aAAa,SAAS;EACtB,OAAO,SAAS;EAChB,MAAM,OAAO,SAAS,OAAO,SAAS,MAAM,QAAQ,MAAM,QAAQ,GAAG,GAAG,MAAM;CAChF,OAAO;EACL,MAAM,SAAkB;GACtB,UAAU,SAAS,CAAC,QAAQ,YAAY,IAAI,CAAC,cAAc,MAAM;GACjE,IAAI,aAAa,KAAK;GACtB;GACA,MAAM;GACN,QAAQ,aAAa;EACvB;EACA,aAAa,SAAS;EACtB,OAAO,SAAS;EAChB,MAAM,OAAO,SAAS,OAAO,MAAM,OAAO,GAAG,MAAM;CACrD;CAEA,MAAM,iBAAiB,OAAO;CAC9B,OAAO;AACT;AAIA,MAAM,aAAa,OAAgB,KAAc,WAAgC;CAC/E,MAAM,EAAE,IAAI,UAAU,OAAO,aAAa;CAC1C,MAAM,eAAe,WAAW,OAAO,QAAQ;CAC/C,IAAI,CAAC,cACH,OAAO;CAGT,IAAI,aAAa,UAAU;EACzB,MAAM,KAAK,KAAK,IACd,KAAK,IAAI,SAAS,aAAa,SAAS,QAAQ,CAAC,GACjD,aAAa,SAAS,MACxB;EACA,aAAa,SAAS,OAAO,IAAI,GAAG,GAAG;EACvC,aAAa,WAAW;EACxB,OAAO;CACT;CAEA,MAAM,YAAwB;EAC5B,UAAU,CAAC,GAAG;EACd,IAAI,aAAa,QAAQ;EACzB,UAAU;EACV,MAAM;EACN;CACF;CACA,OAAO,kBAAkB,OAAO,WAAW,UAAU,QAAQ;AAC/D;;AAGA,MAAM,aAAa,WAAyB,UAAuC;CACjF,MAAM,UAAU,UAAU,SAAS,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;CACxD,UAAU,WAAW,cAAc,UAAU,SAAS,QAAQ,UAAU,QAAQ;CAChF,OAAO;AACT;AAEA,MAAM,iBAAiB,QAAoB,MAAsB,mBAAiC;CAChG,MAAM,aAAa,OAAO,SAAS;CACnC,OAAO,SAAS,KAAK,GAAG,IAAI;CAC5B,OAAO,WAAW,aAAa;AACjC;AAEA,MAAM,mBAAmB,SAA2B;CAClD,UAAU,CACR;EACE,UAAU,CAAC,GAAG;EACd,IAAI,aAAa,QAAQ;EACzB,UAAU;EACV,MAAM;EACN;CACF,CACF;CACA,IAAI,aAAa,KAAK;CACtB,aAAa;CACb,MAAM;CACN;AACF;AAEA,MAAM,sBAAsB,YAAiC;CAC3D,UAAU,CAAC,MAAM;CACjB,IAAI,aAAa,KAAK;CACtB,aAAa;CACb,MAAM;CACN;AACF;;;;ACnHA,MAAM,yBAAmC;CAAE,QAAQ;CAAK,MAAM;CAAI,KAAK;CAAI,OAAO;AAAI;AAEtF,MAAM,mBAAmB,MAAc,WAAqC;CAC1E,MAAM,OAAO,IAAI,IAAI,OAAO,KAAK,UAAU,MAAM,IAAI,CAAC;CACtD,IAAI,CAAC,KAAK,IAAI,IAAI,GAChB,OAAO;CAET,IAAI,QAAQ;CACZ,OAAO,KAAK,IAAI,GAAG,KAAK,GAAG,OAAO,GAChC,SAAS;CAEX,OAAO,GAAG,KAAK,GAAG;AACpB;AAEA,MAAM,aACJ,OACA,QACA,UACA,YACS;CACT,MAAM,QAAmB;EACvB,UAAU,YAAY;EACtB,IAAI,WAAW,aAAa,OAAO;EACnC;EACA,MAAM,gBAAgB,SAAS,MAAM,MAAM;EAC3C,MAAM;CACR;CACA,MAAM,SAAS,CAAC,GAAG,MAAM,QAAQ,KAAK;CAEtC,MAAM,UAA6B,CAAC;CACpC,oBAAoB,QAAQ,OAAO;CACnC,MAAM,QAAQ,QAAQ,GAAG,CAAC;CAC1B,IAAI,OACF,MAAM,iBAAiB,MAAM;AAEjC;AAEA,MAAM,mBACJ,OACA,UACA,UACA,YACY;CACZ,MAAM,WAAW,sBAAsB,OAAO,QAAQ;CACtD,IAAI,CAAC,UACH,OAAO;CAET,UAAU,OAAO,mBAAmB,QAAQ,GAAG,UAAU,OAAO;CAChE,OAAO;AACT;AAEA,MAAM,qBACJ,OACA,aAC2B;CAC3B,MAAM,cAAiC,CAAC;CACxC,oBAAoB,MAAM,QAAQ,WAAW;CAC7C,IAAI,aAAa,QAAW;EAC1B,MAAM,WAAW,YAAY,MAAM,WAAW,OAAO,OAAO,QAAQ;EACpE,IAAI,UACF,OAAO;CAEX;CACA,IAAI,MAAM,mBAAmB,QAAW;EACtC,MAAM,SAAS,YAAY,MAAM,WAAW,OAAO,OAAO,MAAM,cAAc;EAC9E,IAAI,QACF,OAAO;CAEX;CACA,OAAO,YAAY;AACrB;AAEA,MAAM,aACJ,OACA,SACA,UACA,aACY;CACZ,MAAM,QAAQ,MAAM,OAAO,WAAW,UAAU,MAAM,OAAO,OAAO;CACpE,MAAM,QAAQ,MAAM,OAAO,GAAG,KAAK;CACnC,IAAI,UAAU,MAAM,CAAC,OACnB,OAAO;CAGT,MAAM,UAA6B,CAAC;CACpC,oBAAoB,MAAM,QAAQ,OAAO;CACzC,MAAM,OAAO,QAAQ,SAAS,WAAW,OAAO,QAAQ;CACxD,IAAI,KAAK,WAAW,GAClB,OAAO;CAGT,MAAM,aAAa,QAAQ,GAAG,CAAC;CAC/B,MAAM,iBAAiB,aACnB,cAAc,WAAW,SAAS,QAAQ,WAAW,QAAQ,IAC7D;CAIJ,MAAM,SAAS,kBAAkB,OAAO,QAAQ;CAChD,MAAM,OAAO,OAAO,OAAO,CAAC;CAE5B,IAAI,CAAC,QAAQ;EACX,MAAM,SAAS,MAAM;EACrB,MAAM,iBAAiB,YAAY;EACnC,OAAO;CACT;CAEA,IAAI,aAAa,UAAU;EACzB,cAAc,QAAQ,MAAM,cAAc;EAC1C,MAAM,iBAAiB,OAAO;EAC9B,OAAO;CACT;CAEA,MAAM,SACJ,QAAQ,WAAW,KAAK,aACpB,aACA;EACE,UAAU;EACV,IAAI,aAAa,QAAQ;EACzB,UAAU;EACV,MAAM;EACN;CACF;CACN,OAAO,kBAAkB,OAAO,QAAQ,OAAO,IAAI,YAAY,aAAa;AAC9E;;;;ACnHA,MAAM,kBAAkB,MAAsB,UAA8C;CAC1F,QAAQ,KAAK,MAAb;EACE,KAAK,OACH,OAAO,sBAAsB,MAAM,KAAK;EAE1C,KAAK,OACH,OAAO,sBAAsB,MAAM,KAAK;EAE1C,KAAK,UAAU;GACb,MAAM,SAAS,yBAAyB,MAAM,KAAK;GACnD,OAAO,OAAO,aAAa,SACvB,SACA;IAAE,GAAG;IAAQ,UAAU,cAAc,KAAK,SAAS,QAAQ,OAAO,QAAQ;GAAE;EAClF;EACA,SACE,OAAO,YAAY,IAAI;CAE3B;AACF;AAEA,MAAM,gBAAgB,GAAa,MACjC,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE;AAEjF,MAAM,kBACJ,QACA,UACY;CACZ,MAAM,UAAU,IAAI,IAAqB,OAAO,QAAQ,MAAM,CAAC;CAC/D,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,WAAW,OAAO,GAAG,QAAQ,IAAI,GAAG,GAAG,KAAK,CAAC;AACzF;;AAGA,MAAM,eAAe,OAAgB,WAA4B;CAC/D,QAAQ,OAAO,MAAf;EACE,KAAK,WACH,OAAO,UAAU,OAAO,OAAO,KAAK;GAClC,IAAI,OAAO;GACX,OAAO,OAAO;GACd,UAAU,OAAO;EACnB,CAAC;EAEH,KAAK,eAAe;GAClB,MAAM,MAAM,QAAQ,OAAO,OAAO,KAAK;GACvC,IAAI,CAAC,KACH,OAAO;GAET,IAAI,UAAU;GACd,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,QAAQ,SAAS;IAC1D,MAAM,QAAQ,IAAI,SAAS,GAAG,KAAK;IACnC,MAAM,SAAS,OAAO,QAAQ;IAC9B,IAAI,CAAC,SAAS,WAAW,UAAa,MAAM,WAAW,QACrD;IAEF,MAAM,SAAS;IACf,UAAU;GACZ;GACA,OAAO;EACT;EACA,KAAK,aAAa;GAChB,MAAM,WAAW,QAAQ,OAAO,OAAO,KAAK;GAC5C,IAAI,CAAC,UACH,OAAO;GAET,UAAU,SAAS,WAAW,SAAS,KAAK;GAC5C,OAAO;EACT;EACA,KAAK,gBACH,OAAO,sBAAsB,OAAO,OAAO,QAAQ,MAAM;EAE3D,KAAK,aACH,OAAO,UAAU,OAAO,OAAO,SAAS,OAAO,UAAU,OAAO,QAAQ;EAE1E,KAAK,YAAY;GACf,MAAM,WAAW,QAAQ,OAAO,OAAO,KAAK;GAC5C,IAAI,CAAC,UACH,OAAO;GAET,MAAM,UAAU,UAAU,SAAS,WAAW,SAAS,KAAK;GAC5D,IAAI,CAAC,SACH,OAAO;GAET,UAAU,OAAO,gBAAgB,OAAO,GAAG,OAAO,UAAU,OAAO,OAAO;GAC1E,OAAO;EACT;EACA,KAAK,eACH,OAAO,gBAAgB,OAAO,OAAO,UAAU,OAAO,UAAU,OAAO,OAAO;EAEhF,KAAK,aAAa;GAChB,MAAM,QAAQ,UAAU,OAAO,OAAO,OAAO;GAC7C,IAAI,CAAC,SAAS,aAAa,MAAM,UAAU,OAAO,QAAQ,GACxD,OAAO;GAET,MAAM,WAAW,OAAO;GACxB,OAAO;EACT;EACA,KAAK,YAAY;GACf,MAAM,SAAS,QAAQ,OAAO,OAAO,QAAQ;GAE7C,IAAI,CAAC,UAAU,CAAC,WAAW,OAAO,OAAO,QAAQ,GAC/C,OAAO;GAGT,MAAM,UAAU,UAAU,OAAO,WAAW,OAAO,KAAK;GACxD,IAAI,CAAC,SACH,OAAO;GAET,OAAO,UAAU,OAAO,SAAS;IAC/B,IAAI,OAAO;IACX,OAAO,OAAO;IACd,UAAU,OAAO;GACnB,CAAC;EACH;EACA,KAAK,cAAc;GACjB,IAAI,OAAO,aAAa,OAAO,UAC7B,OAAO;GAET,MAAM,SAAS,WAAW,OAAO,OAAO,QAAQ;GAChD,MAAM,SAAS,WAAW,OAAO,OAAO,QAAQ;GAChD,IAAI,CAAC,UAAU,CAAC,QACd,OAAO;GAET,IAAI,OAAO,aAAa,UAAU;IAChC,cACE,QACA,OAAO,UACP,cAAc,OAAO,SAAS,QAAQ,OAAO,QAAQ,CACvD;IACA,sBAAsB,OAAO,OAAO,QAAQ;IAC5C,OAAO;GACT;GAEA,MAAM,WAAW,sBAAsB,OAAO,OAAO,QAAQ;GAC7D,OAAO,WACH,kBAAkB,OAAO,UAAU,OAAO,UAAU,OAAO,QAAQ,IACnE;EACN;EACA,KAAK,eAAe;GAClB,MAAM,QAAQ,UAAU,OAAO,OAAO,OAAO;GAC7C,IAAI,CAAC,OACH,OAAO;GAET,MAAM,SAAS,MAAM,OAAO,QAAQ,UAAU,MAAM,OAAO,OAAO,OAAO;GACzE,MAAM,OAAO,gBAAgB,OAAO,MAAM,MAAM;GAChD,IAAI,MAAM,SAAS,MACjB,OAAO;GAET,MAAM,OAAO;GACb,OAAO;EACT;EACA,KAAK,aAAa;GAChB,MAAM,WAAW,QAAQ,OAAO,OAAO,KAAK;GAC5C,IAAI,CAAC,YAAY,SAAS,IAAI,SAAS,OAAO,MAC5C,OAAO;GAET,SAAS,IAAI,OAAO,OAAO;GAC3B,OAAO;EACT;EACA,KAAK,aAAa;GAChB,MAAM,SAAS,WAAW,OAAO,OAAO,QAAQ;GAChD,IAAI,CAAC,QACH,OAAO;GAET,MAAM,WAAW,cAAc,OAAO,SAAS,QAAQ,OAAO,KAAK;GACnE,IAAI,OAAO,aAAa,UACtB,OAAO;GAET,OAAO,WAAW;GAClB,OAAO;EACT;EACA,KAAK;GACH,IAAI,MAAM,mBAAmB,OAAO,YAAY,CAAC,WAAW,OAAO,OAAO,QAAQ,GAChF,OAAO;GAET,MAAM,iBAAiB,OAAO;GAC9B,OAAO;EAET,KAAK,qBAAqB;GACxB,MAAM,QAAQ,UAAU,OAAO,OAAO,OAAO;GAC7C,IAAI,CAAC,UAAU,MAAM,aAAa,WAAW,OAAO,WAClD,OAAO;GAET,MAAM,YAAY,OAAO;GACzB,OAAO;EACT;EACA,KAAK,sBAAsB;GACzB,MAAM,OAAO,OAAO,YAAY;GAChC,IAAI,MAAM,sBAAsB,MAC9B,OAAO;GAET,MAAM,oBAAoB;GAC1B,OAAO;EACT;EACA,KAAK;GACH,IAAI,eAAe,MAAM,QAAQ,OAAO,KAAK,GAC3C,OAAO;GAET,OAAO,OAAO,MAAM,QAAQ,OAAO,KAAK;GACxC,OAAO;EAET,KAAK,wBAAwB;GAC3B,MAAM,OAAO,mBAAmB,OAAO,OAAO,MAAM;GACpD,IAAI,CAAC,MACH,OAAO;GAET,MAAM,SAAS,eAAe,MAAM,OAAO,KAAK;GAChD,IAAI,eAAe,MAAM,MAAM,GAC7B,OAAO;GAET,OAAO,OAAO,MAAM,MAAM;GAC1B,OAAO;EACT;EACA,SACE,OAAO,YAAY,MAAM;CAE7B;AACF;;;AAIA,MAAM,WAAW,OAAgB,WAA4B;CAC3D,MAAM,QAAQ,gBAAgB,KAAK;CACnC,IAAI,CAAC,YAAY,OAAO,MAAM,GAC5B,OAAO;CAET,OAAO,UAAU,KAAK;AACxB;;;;AC7OA,MAAM,gBAAgB;AAEtB,MAAM,iBAAiB,aAA+B;CACpD,QAAQ,CAAC;CACT,MAAM,CAAC;CACP;AACF;AAEA,MAAM,WAAW,YAA8B,QAAQ,KAAK,SAAS;AACrE,MAAM,WAAW,YAA8B,QAAQ,OAAO,SAAS;;;;;;AAOvE,MAAM,YAAY,SAAkB,WAA4B;CAC9D,MAAM,UAAU,QAAQ,QAAQ,SAAS,MAAM;CAC/C,IAAI,OAAO,GAAG,SAAS,QAAQ,OAAO,GACpC,OAAO;CAET,OAAO;EAAE,QAAQ,CAAC;EAAG,MAAM,CAAC,GAAG,QAAQ,MAAM,QAAQ,OAAO,CAAC,CAAC,MAAM,IAAc;EAAG;CAAQ;AAC/F;AAEA,MAAM,QAAQ,YAA8B;CAC1C,MAAM,WAAW,QAAQ,KAAK,GAAG,EAAE;CACnC,IAAI,aAAa,QACf,OAAO;CAET,OAAO;EACL,QAAQ,CAAC,QAAQ,SAAS,GAAG,QAAQ,MAAM;EAC3C,MAAM,QAAQ,KAAK,MAAM,GAAG,EAAE;EAC9B,SAAS;CACX;AACF;AAEA,MAAM,QAAQ,YAA8B;CAC1C,MAAM,CAAC,MAAM,GAAG,QAAQ,QAAQ;CAChC,IAAI,SAAS,QACX,OAAO;CAET,OAAO;EACL,QAAQ;EACR,MAAM,CAAC,GAAG,QAAQ,MAAM,QAAQ,OAAO,CAAC,CAAC,MAAM,IAAc;EAC7D,SAAS;CACX;AACF;;;;ACxCA,MAAM,iBAAiB,MAAM,EAC3B,OAAO;CAEL,SAAS,CAAC;CAEV,QAAQ,CAAC;CAET,OAAO,CAAC;AACV,EACF,CAAC,CAAC,CAAC,cAAc;CACf,UAAU,EAAE,aAAa,EAAE,SAAS,cAAc,MAAM,KAAK,EAAE;CAC/D,IAAI;CACJ,SAAS;CACT,QAAQ,EACN,OAAO,EACL,IAAI;EACF,UAAU,EACR,SAAS,OAAO,EACd,UAAU,EAAE,SAAS,YAAY,SAAS,QAAQ,SAAS,MAAM,MAAM,EACzE,CAAC,EACH;EACA,MAAM,EACJ,SAAS,OAAO,EAAE,UAAU,EAAE,cAAc,KAAK,QAAQ,OAAO,EAAE,CAAC,EACrE;EACA,WAAW,EACT,SAAS,OAAO,EAAE,UAAU,EAAE,YAAY,cAAc,MAAM,KAAK,EAAE,CAAC,EACxE;EACA,MAAM,EACJ,SAAS,OAAO,EAAE,UAAU,EAAE,cAAc,KAAK,QAAQ,OAAO,EAAE,CAAC,EACrE;CACF,EACF,EACF;AACF,CAAC;;;;;ACtBD,MAAM,cAAc,SAA8D;CAChF,IAAI,KAAK,SAAS,cAAc,KAAK,SAAS,MAC5C,OAAO;CAET,MAAM,EAAE,QAAQ,UAAU,KAAK;CAC/B,MAAM,EAAE,YAAY;CAEpB,IAAI,QAAQ,SAAS,YACnB,OAAO;EACL,QAAQ;GACN,OAAO,OAAO;GACd,UAAU,OAAO;GACjB,KAAK,QAAQ;GACb,UAAU,OAAO;GACjB,MAAM;EACR;EACA;CACF;CAEF,IAAI,QAAQ,SAAS,UACnB,OAAO;EACL,QAAQ;GACN,UAAU,OAAO;GACjB,UAAU,QAAQ;GAClB,UAAU,OAAO;GACjB,MAAM;EACR;EACA;CACF;CAEF,OAAO;EACL,QAAQ;GACN,OAAO,OAAO;GACd,UAAU,OAAO;GACjB,UAAU,QAAQ;GAClB,UAAU,OAAO;GACjB,MAAM;EACR;EACA;CACF;AACF;AAEA,MAAM,kBAAkB,MAAM;CAC5B,QAAQ,EACN,eAAe,EAAE,cAAc,WAAW,QAAQ,IAAI,MAAM,KAC9D;CACA,OAAO;EAEL,SAAS,CAAC;EAEV,SAAS,CAAC;EAEV,QAAQ,CAAC;CACX;AACF,CAAC,CAAC,CAAC,cAAc;CACf,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE;CAClC,IAAI;CACJ,SAAS;CACT,QAAQ;EACN,UAAU,EACR,IAAI;GACF,QAAQ,EAAE,QAAQ,OAAO;GACzB,MAAM,CACJ;IACE,SAAS,MAAM,EAAE,cAAc;KAC7B,MAAM,WAAW,WAAW,QAAQ,IAAI;KACxC,IAAI,aAAa,MACf,MAAM,IAAI,MAAM,oDAAoD;KAEtE,OAAO;MAAE,QAAQ,SAAS;MAAQ,OAAO,SAAS;MAAO,MAAM;KAAS;IAC1E,CAAC;IACD,OAAO;IACP,QAAQ;GACV,GACA,EAAE,QAAQ,OAAO,CACnB;GACA,MAAM,EACJ,SAAS,OAAO,EACd,OAAO,EAAE,SAAS,YAChB,QAAQ,KAAK,SAAS,aAClB;IAAE,GAAG,QAAQ;IAAM,MAAM,MAAM;GAAK,IACpC,QAAQ,KAChB,CAAC,EACH;EACF,EACF;EACA,MAAM;GACJ,OAAO,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE,CAAC;GACxC,IAAI,EACF,OAAO;IACL,SAAS,OAAO,EACd,OAAO,EAAE,aAAa;KAAE,MAAM;KAAM,MAAM;KAAY,SAAS,MAAM;IAAQ,GAC/E,CAAC;IACD,QAAQ;GACV,EACF;EACF;CACF;AACF,CAAC;;;;ACzHD,MAAM,cAAc,UAA4B;CAC9C,MAAM,QAAQ,UAAU,cAAc,MAAM,KAAK,CAAC;CAClD,MAAM,aAAa,iBAAiB,KAAK;CACzC,IAAI,WAAW,SAAS,GAEtB,QAAQ,KAAK,sDAAsD,WAAW,KAAK,IAAI,GAAG;CAE5F,OAAO;AACT;AAEA,MAAM,UAAU,UAA2B,KAAK,UAAU,KAAK;AAE/D,MAAM,YAAY,SAA0B,WAAW,gBAAgB,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC;;;;ACb9F,MAAM,cAAc,OAAgB,cAA2B,aAAsB;CACnF,MAAM,cAAiC,CAAC;CACxC,oBAAoB,MAAM,QAAQ,WAAW;CAC7C,MAAM,WAA8B,CAAC;CACrC,KAAK,MAAM,UAAU,aACnB,SAAS,KAAK;EAAE,GAAG;EAAQ,QAAQ;CAAE,CAAC;CAGxC,OAAO,UAAU;EACf,GAAG;EACH,QAAQ;GACN;GACA,IAAI,MAAM,OAAO;GACjB;GACA,MAAM;GACN,QAAQ,MAAM,OAAO;EACvB;EACA,mBAAmB;CACrB,CAAC;AACH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dashfoo/core",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Headless docking-layout engine: model, actions, reducer, serialization, geometry, and the XState actor system. No React.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Pedro Filho <pedro@filho.me>",
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"xstate": "^5.32.
|
|
29
|
-
"zod": "^4.
|
|
28
|
+
"xstate": "^5.32.6",
|
|
29
|
+
"zod": "^4.5.4"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"typescript": "^
|
|
33
|
-
"vitest": "^4.1.
|
|
32
|
+
"typescript": "^7.0.2",
|
|
33
|
+
"vitest": "^4.1.11",
|
|
34
34
|
"@repo/config-vitest": "0.0.0",
|
|
35
35
|
"@repo/typescript-config": "0.0.0"
|
|
36
36
|
},
|