@dynamix-layout/core 0.0.2-beta.0 → 0.0.6
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/CHANGELOG.md +31 -0
- package/README.md +159 -61
- package/{LICENSE → dist/LICENSE} +1 -1
- package/dist/core.cjs.js +57 -0
- package/dist/core.es.js +1025 -0
- package/dist/core.iife.js +57 -1
- package/dist/core.umd.js +57 -1
- package/dist/types/app/comparator.d.ts +3 -0
- package/dist/types/app/dynamix.d.ts +97 -0
- package/dist/types/app/index.d.ts +4 -64
- package/dist/types/app/queue.d.ts +217 -0
- package/dist/types/app/reactive-state.d.ts +3 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/type/index.d.ts +54 -0
- package/package.json +60 -30
- package/dist/core.js +0 -1
- package/dist/core.mjs +0 -244
- package/dist/types/lib/Constant.d.ts +0 -14
- package/dist/types/lib/Element.d.ts +0 -22
- package/dist/types/lib/Helper.d.ts +0 -21
- package/dist/types/lib/Method.d.ts +0 -1
- package/dist/types/lib/index.d.ts +0 -4
- package/dist/types/types/Element.d.ts +0 -103
- package/dist/types/types/Method.d.ts +0 -5
- package/dist/types/types/index.d.ts +0 -2
- package/src/app/index.ts +0 -291
- package/src/index.ts +0 -3
- package/src/lib/Constant.ts +0 -17
- package/src/lib/Element.ts +0 -66
- package/src/lib/Helper.ts +0 -259
- package/src/lib/Method.ts +0 -12
- package/src/lib/index.ts +0 -4
- package/src/types/Element.ts +0 -116
- package/src/types/Method.ts +0 -4
- package/src/types/index.ts +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @dynamix-layout/core
|
|
2
2
|
|
|
3
|
+
## 0.0.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#25](https://github.com/akash-aman/dynamix-layout/pull/25) [`8b7ab1a`](https://github.com/akash-aman/dynamix-layout/commit/8b7ab1a0317dae85400ed381c85a4e50c35db41e) Thanks [@akash-aman](https://github.com/akash-aman)! - feat(core): enhance demo with GIFs/MP4s and update README for better structure
|
|
8
|
+
- Updated `.hintrc` to enforce consistent casing for TypeScript.
|
|
9
|
+
- Added demo assets (GIFs, MP4) to showcase layout functionality.
|
|
10
|
+
- Cleaned up `.npmignore` to exclude `.map` files.
|
|
11
|
+
- Removed unused `vite-plugin-compression2` dependency.
|
|
12
|
+
- Improved README structure and visual assets for `core` package.
|
|
13
|
+
- Added TypeScript configuration files for clearer project setup.
|
|
14
|
+
|
|
15
|
+
feat(react): initial release of DynamixLayout React component
|
|
16
|
+
- Introduced `@dynamix-layout/react` package to provide a React wrapper around `@dynamix-layout/core`.
|
|
17
|
+
- Added `DynamixLayout` component with support for dynamic, draggable, and resizable layouts.
|
|
18
|
+
- Included usage examples and updated README for better developer onboarding.
|
|
19
|
+
- Integrated demo assets (GIFs, MP4s) to showcase layout behavior.
|
|
20
|
+
- Refactored tests to validate component behavior and ensure coverage.
|
|
21
|
+
|
|
22
|
+
## 0.0.5
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Refactored layout core and added unit tests for reactive state and layout logic
|
|
27
|
+
- Replaced legacy `Layout` class with modular utilities: `Queue` and `createReactiveState`.
|
|
28
|
+
- Improved layout shifting algorithm (`shiftTree`) and bond-based slider behavior.
|
|
29
|
+
- Added comprehensive unit tests for layout validation, tree integrity, and reactive state handling.
|
|
30
|
+
- Simplified exports and cleaned up `index.ts`, `.gitignore`, and `package.json` structure.
|
|
31
|
+
- Refactored `vite.config.ts`, `tsconfig.json`, and `vitest.config.ts` for clarity and consistency.
|
|
32
|
+
- Added license metadata to Vite config and updated author name in LICENSE.
|
|
33
|
+
|
|
3
34
|
## 0.0.2-beta.0
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,109 +1,207 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
](https://www.patreon.com/akashaman)
|
|
4
|
+
[](https://www.buymeacoffee.com/akashaman)
|
|
5
|
+
[](mailto:sir.akashaman@gmail.com)
|
|
6
|
+
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
# 🚀 @dynamix-layout/core
|
|
4
10
|
|
|
5
11
|
## Overview
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
**@dynamix-layout/core** is the **engine** that powers the **creation**, **management**, and **dynamic modification** of your layout structures. It handles the **internal logic** of the layout tree, including **node creation**, **dimension calculation**, and **state updates**. This package works with a **hierarchical tree structure** composed of `Node` objects and exposes a **reactive state** for seamless integration with modern UI frameworks.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
### Made with ❤️ by [Akash Aman](https://linktr.ee/akash_aman)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Core Classes
|
|
8
26
|
|
|
9
|
-
|
|
27
|
+
The package is built around three primary classes: `DynamixLayoutCore`, `Node`, and `Bond`.
|
|
10
28
|
|
|
11
|
-
|
|
29
|
+
1. **`DynamixLayoutCore`**: The main controller class that you instantiate to create and manage the entire layout. It serves as the primary public API.
|
|
30
|
+
2. **`Node`**: The fundamental building block of the layout tree. Each `Node` can be a `row`, a `tabset`, or a `tab`.
|
|
31
|
+
3. **`Bond`**: A special object that represents the draggable separator between two nodes, allowing for resizing.
|
|
12
32
|
|
|
13
|
-
|
|
33
|
+
---
|
|
14
34
|
|
|
15
|
-
|
|
35
|
+
## `DynamixLayoutCore` Class
|
|
16
36
|
|
|
17
|
-
|
|
37
|
+
The `DynamixLayoutCore` class is the central point of control for your entire layout configuration.
|
|
18
38
|
|
|
19
|
-
|
|
39
|
+
### Constructor
|
|
20
40
|
|
|
21
|
-
|
|
41
|
+
When initializing the `DynamixLayoutCore` class, you provide a single **options object**.
|
|
22
42
|
|
|
23
|
-
|
|
43
|
+
`new DynamixLayoutCore(options)`
|
|
24
44
|
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
45
|
+
- **`options`** (`object`): An object containing configuration properties.
|
|
46
|
+
- **`tabs`** (`string[]`): An array of tab names to generate an initial binary tree layout. Defaults to `[]`.
|
|
47
|
+
- **`tree`** (`LayoutTree | null`): A serialized JSON representation of a previously saved layout (`LayoutTree` object). If provided, it will recreate that specific layout. Defaults to `null`.
|
|
48
|
+
- **`tabsIds`** (`Map<string, string>`): A map where keys are tab names and values are their unique IDs. This is useful for persisting tab identities across sessions.
|
|
49
|
+
- **`minW`** (`number`): The minimum width for a `tabset`. Defaults to `40`.
|
|
50
|
+
- **`minH`** (`number`): The minimum height for a `tabset`. Defaults to `40`.
|
|
51
|
+
- **`bond`** (`number`): The width or height (in pixels) of the draggable separator (`Bond`) between nodes. Defaults to `10`.
|
|
30
52
|
|
|
31
|
-
|
|
53
|
+
### Reactive Properties
|
|
32
54
|
|
|
33
|
-
|
|
55
|
+
The layout's state is exposed through static reactive properties on the `Node` class. You can subscribe to these to drive your UI.
|
|
34
56
|
|
|
35
|
-
|
|
57
|
+
- **`Node.cache.nodOpts`**: A reactive map of all `tabset` nodes and their options.
|
|
58
|
+
- **`Node.cache.bndOpts`**: A reactive map of all `bond` objects.
|
|
59
|
+
- **`Node.cache.tabOpts`**: A reactive map of all `tab` nodes within their respective tabsets.
|
|
60
|
+
|
|
61
|
+
### Methods
|
|
62
|
+
|
|
63
|
+
#### 🌳 `updateTree(src, des, layout)`
|
|
64
|
+
|
|
65
|
+
This is the core method for rearranging the layout. It moves a source node (`src`) to a new position relative to a destination node (`des`).
|
|
66
|
+
|
|
67
|
+
- **`src`** (`string`): The unique ID of the node to move (can be a `tab` or a `tabset`).
|
|
68
|
+
- **`des`** (`string`): The unique ID of the destination node.
|
|
69
|
+
- **`layout`** (`'top' | 'bottom' | 'left' | 'right' | 'contain'`): Specifies how the source should be placed relative to the destination.
|
|
70
|
+
- `top`, `bottom`, `left`, `right`: Places the source node by splitting the destination area.
|
|
71
|
+
- `contain`: Places a source `tab` into the destination `tabset`.
|
|
72
|
+
|
|
73
|
+
**Returns**: `boolean` - `true` if the update was successful, `false` otherwise.
|
|
36
74
|
|
|
37
|
-
Example:
|
|
38
75
|
```javascript
|
|
39
|
-
|
|
76
|
+
// Moves the node with 'sidebar-id' to be to the left of 'main-content-id'
|
|
77
|
+
layout.updateTree('sidebar-id', 'main-content-id', 'left')
|
|
40
78
|
```
|
|
41
79
|
|
|
42
|
-
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
#### 📏 `updateDimension(dim, disableTimeout, timeout)`
|
|
83
|
+
|
|
84
|
+
Recalculates all node dimensions within the layout, typically after the main container has been resized.
|
|
43
85
|
|
|
44
|
-
|
|
86
|
+
- **`dim`** (`{ w, h, x, y }`): An object representing the new dimensions of the root container.
|
|
87
|
+
- **`disableTimeout`** (`boolean`): If `true`, the update runs instantly. Otherwise, it's debounced. Defaults to `false`.
|
|
88
|
+
- **`timeout`** (`number`): The debounce delay in milliseconds. Defaults to `2`.
|
|
89
|
+
|
|
90
|
+
<!-- end list -->
|
|
45
91
|
|
|
46
|
-
Example:
|
|
47
92
|
```javascript
|
|
48
|
-
|
|
93
|
+
// On window resize, update the layout dimensions
|
|
94
|
+
layout.updateDimension({
|
|
95
|
+
w: window.innerWidth,
|
|
96
|
+
h: window.innerHeight,
|
|
97
|
+
x: 0,
|
|
98
|
+
y: 0,
|
|
99
|
+
})
|
|
49
100
|
```
|
|
50
101
|
|
|
51
|
-
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
#### ↔️ `updateSlider(id, dim, disableTimeout, timeout)`
|
|
105
|
+
|
|
106
|
+
Updates the layout in response to a user dragging a `Bond` (slider).
|
|
107
|
+
|
|
108
|
+
- **`id`** (`string`): The unique ID of the `Bond` being moved.
|
|
109
|
+
- **`dim`** (`{ x, y }`): An object with the new coordinates of the slider.
|
|
110
|
+
- **`disableTimeout`** (`boolean`): If `true`, the update runs instantly. Defaults to `false`.
|
|
111
|
+
- **`timeout`** (`number`): The debounce delay in milliseconds. Defaults to `2`.
|
|
52
112
|
|
|
53
|
-
|
|
113
|
+
<!-- end list -->
|
|
54
114
|
|
|
55
|
-
Example:
|
|
56
115
|
```javascript
|
|
57
|
-
|
|
116
|
+
// When a user drags a separator
|
|
117
|
+
layout.updateSlider('bond-123', { x: 450, y: 300 })
|
|
58
118
|
```
|
|
59
119
|
|
|
60
|
-
|
|
120
|
+
---
|
|
61
121
|
|
|
62
|
-
|
|
122
|
+
#### 🗑️ `clearAllCache()`
|
|
123
|
+
|
|
124
|
+
Clears all internal caches for nodes, bonds, dimensions, and other layout data. Use this when completely destroying or resetting the layout.
|
|
63
125
|
|
|
64
|
-
Example:
|
|
65
126
|
```javascript
|
|
66
|
-
|
|
127
|
+
layout.clearAllCache()
|
|
67
128
|
```
|
|
68
129
|
|
|
69
|
-
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## `Node` Class
|
|
133
|
+
|
|
134
|
+
The `Node` represents a single element in the layout tree. You will typically interact with Node data through the reactive properties rather than manipulating `Node` objects directly.
|
|
135
|
+
|
|
136
|
+
### Constructor
|
|
70
137
|
|
|
71
|
-
|
|
138
|
+
`new Node(options)`
|
|
72
139
|
|
|
73
|
-
|
|
140
|
+
- **`options`** (`object`): An object containing node properties like `type`, `host`, `name`, `part`, `dims`, `unId`, and `open`.
|
|
74
141
|
|
|
75
|
-
|
|
142
|
+
### Static Cache (`Node.cache`)
|
|
76
143
|
|
|
77
|
-
|
|
144
|
+
The `Node` class contains a static `cache` object. This centralized cache holds the state for the entire layout, including maps of all nodes, dimensions, and the **reactive options** that your UI will consume. **Direct manipulation of the cache is not recommended.**
|
|
145
|
+
|
|
146
|
+
### Methods
|
|
147
|
+
|
|
148
|
+
#### 💾 `toJSON()`
|
|
149
|
+
|
|
150
|
+
Serializes the node and its entire subtree into a JSON object (`LayoutTree`). This is used to save the current state of the layout.
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
const rootNode = DynamixLayoutCore._root // Access the static root node
|
|
154
|
+
const layoutJSON = rootNode.toJSON()
|
|
155
|
+
// localStorage.setItem('savedLayout', JSON.stringify(layoutJSON));
|
|
156
|
+
```
|
|
78
157
|
|
|
79
158
|
## Example Usage
|
|
80
159
|
|
|
81
160
|
```javascript
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
//
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
//
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
//
|
|
101
|
-
|
|
161
|
+
import { DynamixLayoutCore, Node } from '@dynamix-layout/core'
|
|
162
|
+
|
|
163
|
+
// 1. Initialize the Layout class
|
|
164
|
+
// Provide an options object to the constructor
|
|
165
|
+
const layout = new DynamixLayoutCore({
|
|
166
|
+
tabs: ['editor', 'terminal', 'preview'],
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
// ...or restore a layout from a saved JSON object
|
|
170
|
+
// const savedLayout = JSON.parse(localStorage.getItem('savedLayout'));
|
|
171
|
+
// const layout = new DynamixLayoutCore({ tree: savedLayout });
|
|
172
|
+
|
|
173
|
+
// 2. Set the initial dimensions of your container
|
|
174
|
+
layout.updateDimension({ w: 1200, h: 800, x: 0, y: 0 }, true)
|
|
175
|
+
|
|
176
|
+
// 3. Subscribe to reactive state to render your UI.
|
|
177
|
+
const unsubscribe = Node.cache.nodOpts.onChange((nodeOptionsMap) => {
|
|
178
|
+
console.log('Layout updated!', nodeOptionsMap)
|
|
179
|
+
// Your UI rendering logic here...
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
// 4. Move a tab to a new location
|
|
183
|
+
// (In a real app, you'd get these IDs from the reactive state)
|
|
184
|
+
setTimeout(() => {
|
|
185
|
+
const terminalTabId = 'some-unique-id-for-terminal-tab'
|
|
186
|
+
const editorTabsetId = 'some-unique-id-for-editor-tabset'
|
|
187
|
+
|
|
188
|
+
// Move the terminal tab into the editor's tabset
|
|
189
|
+
layout.updateTree(terminalTabId, editorTabsetId, 'contain')
|
|
190
|
+
}, 2000)
|
|
191
|
+
|
|
192
|
+
// 5. Clean up when the component unmounts
|
|
193
|
+
// unsubscribe();
|
|
194
|
+
// layout.clearAllCache();
|
|
102
195
|
```
|
|
103
196
|
|
|
104
|
-
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
<div align="center">
|
|
105
200
|
|
|
106
|
-
|
|
201
|
+
[](https://www.patreon.com/akashaman)
|
|
202
|
+
[](https://www.buymeacoffee.com/akashaman)
|
|
203
|
+
[](mailto:sir.akashaman@gmail.com)
|
|
107
204
|
|
|
108
|
-
|
|
205
|
+
### Made with ❤️ by [Akash Aman](https://linktr.ee/akash_aman)
|
|
109
206
|
|
|
207
|
+
</div>
|
package/{LICENSE → dist/LICENSE}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2025 Akash Aman <sir.akashaman@gmail.com> (https://akash.cx)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/dist/core.cjs.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class N{buffer;head=0;tail=0;count=0;capacity;constructor(t=16,e=[]){this.capacity=Math.max(t,e.length),this.buffer=new Array(this.capacity),e.forEach(i=>{this.enqueue(i)})}enqueue(t){this.count===this.capacity&&this.resize(),this.buffer[this.tail]=t,this.tail=(this.tail+1)%this.capacity,this.count++}enqueueFront(t){this.count===this.capacity&&this.resize(),this.head=(this.head-1+this.capacity)%this.capacity,this.buffer[this.head]=t,this.count++}insert(t,e){if(t<0||t>this.count)return!1;if(t===0)return this.enqueueFront(e),!0;if(t===this.count)return this.enqueue(e),!0;this.count===this.capacity&&this.resize();const i=t,n=this.count-t;return i<=n?this.shiftLeft(t,e):this.shiftRight(t,e),this.count++,!0}insertArray(t,e){if(t<0||t>this.count)return!1;if(e.length===0)return!0;if(t===0){for(let d=e.length-1;d>=0;d--)this.enqueueFront(e[d]);return!0}if(t===this.count)return e.forEach(d=>this.enqueue(d)),!0;for(;this.count+e.length>this.capacity;)this.resize();const i=t,n=this.count-t,s=e.length;return i<=n?this.shiftLeftArray(t,e):this.shiftRightArray(t,e),this.count+=s,!0}insertQueue(t,e){if(t<0||t>this.count)return!1;if(e.isEmpty())return!0;const i=e.size();if(t===0){const o=e.toArray();for(let h=o.length-1;h>=0;h--)this.enqueueFront(o[h]);return!0}if(t===this.count){for(const o of e)this.enqueue(o);return!0}for(;this.count+i>this.capacity;)this.resize();const n=e.toArray(),s=t,d=this.count-t;return s<=d?this.shiftLeftArray(t,n):this.shiftRightArray(t,n),this.count+=i,!0}push(t){this.enqueue(t)}unshift(t){this.enqueueFront(t)}dequeue(){if(this.count===0)return;const t=this.buffer[this.head];return this.head=(this.head+1)%this.capacity,this.count--,t}dequeueBack(){if(this.count===0)return;this.tail=(this.tail-1+this.capacity)%this.capacity;const t=this.buffer[this.tail];return this.count--,t}indexOf(t){for(let e=0;e<this.count;e++){const i=(this.head+e)%this.capacity;if(this.buffer[i]===t)return e}return-1}remove(t){const e=this.indexOf(t);return e===-1?!1:(this.removeAt(e),!0)}removeAt(t){if(t<0||t>=this.count)return;if(t===0)return this.dequeue();if(t===this.count-1)return this.dequeueBack();const e=(this.head+t)%this.capacity,i=this.buffer[e],n=t,s=this.count-t-1;return n<=s?this.shiftRightForRemoval(t):this.shiftLeftForRemoval(t),this.count--,i}shift(){return this.dequeue()}pop(){return this.dequeueBack()}fifoAdd(t){this.enqueue(t)}fifoRemove(){return this.dequeue()}filoAdd(t){this.enqueue(t)}filoRemove(){return this.dequeueBack()}lifoAdd(t){this.enqueueFront(t)}lifoRemove(){return this.dequeue()}liloAdd(t){this.enqueueFront(t)}liloRemove(){return this.dequeueBack()}get(t){if(t<0||t>=this.count)return;const e=(this.head+t)%this.capacity;return this.buffer[e]}set(t,e){if(t<0||t>=this.count)return!1;const i=(this.head+t)%this.capacity;return this.buffer[i]=e,!0}peek(){return this.count>0?this.buffer[this.head]:void 0}peekBack(){if(this.count===0)return;const t=(this.tail-1+this.capacity)%this.capacity;return this.buffer[t]}front(){return this.peek()}back(){return this.peekBack()}size(){return this.count}getCapacity(){return this.capacity}isEmpty(){return this.count===0}isFull(){return this.count===this.capacity}clear(){this.head=0,this.tail=0,this.count=0}toArray(){const t=[];for(let e=0;e<this.count;e++){const i=(this.head+e)%this.capacity;t.push(this.buffer[i])}return t}*[Symbol.iterator](){for(let t=0;t<this.count;t++){const e=(this.head+t)%this.capacity;yield this.buffer[e]}}*forward(){for(let t=0;t<this.count;t++){const e=(this.head+t)%this.capacity;yield this.buffer[e]}}*reverse(){for(let t=this.count-1;t>=0;t--){const e=(this.head+t)%this.capacity;yield this.buffer[e]}}*entries(){for(let t=0;t<this.count;t++){const e=(this.head+t)%this.capacity;yield[t,this.buffer[e]]}}*keys(){for(let t=0;t<this.count;t++)yield t}*values(){for(let t=0;t<this.count;t++){const e=(this.head+t)%this.capacity;yield this.buffer[e]}}toString(){return`Queue(${this.toArray().join(", ")})`}resize(){const t=this.capacity*2,e=new Array(t);for(let i=0;i<this.count;i++){const n=(this.head+i)%this.capacity;e[i]=this.buffer[n]}this.buffer=e,this.capacity=t,this.head=0,this.tail=this.count}shiftLeft(t,e){this.head=(this.head-1+this.capacity)%this.capacity;for(let n=0;n<t;n++){const s=(this.head+1+n)%this.capacity,d=(this.head+n)%this.capacity;this.buffer[d]=this.buffer[s]}const i=(this.head+t)%this.capacity;this.buffer[i]=e}shiftRight(t,e){for(let n=this.count-1;n>=t;n--){const s=(this.head+n)%this.capacity,d=(this.head+n+1)%this.capacity;this.buffer[d]=this.buffer[s]}const i=(this.head+t)%this.capacity;this.buffer[i]=e,this.tail=(this.tail+1)%this.capacity}shiftRightForRemoval(t){for(let e=t;e>0;e--){const i=(this.head+e-1)%this.capacity,n=(this.head+e)%this.capacity;this.buffer[n]=this.buffer[i]}this.head=(this.head+1)%this.capacity}shiftLeftForRemoval(t){for(let e=t;e<this.count-1;e++){const i=(this.head+e+1)%this.capacity,n=(this.head+e)%this.capacity;this.buffer[n]=this.buffer[i]}this.tail=(this.tail-1+this.capacity)%this.capacity}shiftLeftArray(t,e){const i=e.length;this.head=(this.head-i+this.capacity)%this.capacity;for(let n=0;n<t;n++){const s=(this.head+i+n)%this.capacity,d=(this.head+n)%this.capacity;this.buffer[d]=this.buffer[s]}for(let n=0;n<i;n++){const s=(this.head+t+n)%this.capacity;this.buffer[s]=e[n]}}shiftRightArray(t,e){const i=e.length;for(let n=this.count-1;n>=t;n--){const s=(this.head+n)%this.capacity,d=(this.head+n+i)%this.capacity;this.buffer[d]=this.buffer[s]}for(let n=0;n<i;n++){const s=(this.head+t+n)%this.capacity;this.buffer[s]=e[n]}this.tail=(this.tail+i)%this.capacity}}function g(I,t=(e,i)=>e===i){let e=I;const i=new Set;let n=[];const s=()=>e,d=(l,f=!1)=>{if(f){e=l;return}t(e,l)||(e=l,i.forEach(m=>m(e)),n.forEach(m=>m(e)),n=[])},o=()=>{i.forEach(l=>l(e)),n.forEach(l=>l(e)),n=[]},h=l=>(i.add(l),()=>i.delete(l)),r=()=>new Promise(l=>{n.push(l)});return{get:s,set:d,onChange:h,nextChange:r,triggerChange:o,onChangePromise:l=>{let f=!0;return(async()=>{for(;f;){const p=await r();if(!f)break;l(p)}})(),()=>{f=!1}}}}function E(I,t){if(I.size!==t.size)return!1;for(const[e,i]of I.entries()){const n=t.get(e);if(!n||!O(i,n))return!1}return!0}function O(I,t){if(I.typNode!==t.typNode||I.nodName!==t.nodName||I.uidNode!==t.uidNode||I.nodPart!==t.nodPart)return!1;const e=I.nodDims,i=t.nodDims;return e.x===i.x&&e.y===i.y&&e.w===i.w&&e.h===i.h}class a{static cache={dimMins:new Map,mapDirs:new Map,tabCnts:new Map,mapElem:new Map,tabOpts:g(new Map,E),nodOpts:g(new Map,E),bndOpts:g(new Map,E)};kids=new N;dims={w:0,h:0,x:0,y:0};unId;next=null;prev=null;type="row";name="";part=0;host=null;open="";constructor(t={}){const e={type:"row",host:null,name:"",part:100,dims:{w:0,h:0,x:0,y:0},unId:crypto.randomUUID(),open:""};this.type=t.type??e.type,this.host=t.host??e.host,this.name=t.name??e.name,this.part=t.part??e.part,this.dims=t.dims??e.dims,this.open=t.open??e.open,this.unId=t.unId||e.unId}addBond(t,e=null){if(!e)return;const i=new x(t,this,e);a.cache.mapElem.set(i.unId,i)}getReqDimension(){const t=a.cache.dimMins.get(this.unId),e=a.cache.tabCnts.get(this.unId),i=Math.max(t.minWidth,e.horizontal*c._minW+Math.max(0,e.horizontal-1)*c._bond),n=Math.max(t.minHeight,e.vertical*c._minH+Math.max(0,e.vertical-1)*c._bond);return{width:i,height:n}}calcDimensions(){const t=a.cache.mapDirs.get(this.unId);if(!this.kids)return;let e=0;const i=a.cache.dimMins.get(this.unId)||{minWidth:0,minHeight:0};let n=0;for(const o of this.kids)e+=o.part;if(e===0)return;let s;t?s=this.dims.w-i.minWidth:s=this.dims.h-i.minHeight;let d=s;for(const o of this.kids){const h=a.cache.dimMins.get(o.unId)||{minWidth:0,minHeight:0};if(this.dims.w<i.minWidth)t?(o.dims.w=h.minWidth,o.dims.h=this.dims.h,o.dims.x=this.dims.x+n,o.dims.y=this.dims.y,n+=o.dims.w+c._bond):(o.dims.h=h.minHeight,o.dims.w=this.dims.w,o.dims.y=this.dims.y+n,o.dims.x=this.dims.x,n+=o.dims.h+c._bond);else{const r=o.part/e,u=Math.floor(s*r);if(o===this.kids.peekBack()){t?(o.dims.w=h.minWidth+d,o.dims.h=this.dims.h,o.dims.x=this.dims.x+n,o.dims.y=this.dims.y,n+=o.dims.w+c._bond):(o.dims.h=h.minHeight+d,o.dims.w=this.dims.w,o.dims.y=this.dims.y+n,o.dims.x=this.dims.x,n+=o.dims.h+c._bond);break}t?(o.dims.w=h.minWidth+u,o.dims.h=this.dims.h,o.dims.x=this.dims.x+n,o.dims.y=this.dims.y,n+=o.dims.w+c._bond):(o.dims.h=h.minHeight+u,o.dims.w=this.dims.w,o.dims.y=this.dims.y+n,o.dims.x=this.dims.x,n+=o.dims.h+c._bond),d-=u}o.next&&(t?o.next.dims={w:c._bond,h:o.dims.h,x:o.dims.x+o.dims.w,y:o.dims.y}:o.next.dims={w:o.dims.w,h:c._bond,x:o.dims.x,y:o.dims.y+o.dims.h})}}toJSON(){const t=[];for(const i of this.kids)t.push(i.toJSON());const e={typNode:this.type,nodPart:this.part,nodName:this.name,uidNode:this.unId};return this.open&&(e.nodOpen=this.open),t.length>0&&(e.nodKids=t),e}}class c{static _root;static _tree;static _minW=40;static _minH=40;static _bond=10;static _inst=null;nodeOps;cntdown=null;tabsIds=new Map;constructor(t={}){const e={tabs:[],tree:null,minW:40,minH:40,bond:10,uqid:"dynamix-layout-root",tabsIds:new Map,...t};this.tabsIds=e.tabsIds,e.tree&&(c._tree=e.tree),c._root=new a({unId:e.uqid,name:e.uqid,type:"row"}),this.nodeOps=g(new Map,E),c._minW=e.minW,c._minH=e.minH,c._bond=e.bond;const i=new N(e.tabs.length,e.tabs);c._tree?this.createNodeLayout():this.createBinaryNodeTreeFromQueue(i),c._inst=this}*JSONLayoutIterator(t){const e=new N;for(e.enqueue(t);!e.isEmpty();){const i=e.dequeue();if(i&&(yield i,i.nodKids&&i.nodKids.length>0))for(const n of i.nodKids)e.enqueue(n)}}*NodeLayoutIterator(t){const e=new N;for(e.enqueue(t);!e.isEmpty();){const i=e.dequeue();if(i&&(a.cache.mapElem.set(i.unId,i),yield i,i.kids.size()>0))for(const n of i.kids)e.enqueue(n)}}*NodeLayoutRecursiveIterator(t){for(const e of t.kids)yield*this.NodeLayoutRecursiveIterator(e);yield t}updateChildDirections(t){const e=a.cache.mapDirs.get(t.unId);if(e===void 0){console.warn(`Cannot update child directions for node ${t.unId}; its own direction is not set.`);return}for(const i of t.kids)a.cache.mapDirs.set(i.unId,!e),i.kids.size()>0&&(i.host=t,this.updateChildDirections(i),i.next&&a.cache.mapDirs.set(i.next.unId,!e))}createNodeLayout(t=c._tree){const e=this.JSONLayoutIterator(t),i=this.NodeLayoutIterator(c._root);for(a.cache.mapDirs.set(c._root.unId,!0);;){const n=e.next(),s=i.next();if(n.done||s.done)break;const d=n.value,o=s.value;!d||!o||this.createNodeTreeFromJSONTree(d,o)}this.calcTabsetCountAndMinDim()}createNodeTreeFromJSONTree(t,e){const i=a.cache.mapDirs.get(e.unId);for(const n of t.nodKids||[]){const s=this.createNodeFromJSON(n),d=e.kids.peekBack();s.host=e,s.addBond(s.host,d),e.kids.enqueue(s),a.cache.mapDirs.set(s.unId,!i)}e.type==="tabset"&&a.cache.mapElem.set(e.unId,e),e.type==="tab"&&a.cache.mapElem.set(e.unId,e)}createBinaryNodeTreeFromQueue(t,e=c._root){const i=new N;for(i.enqueue(e),a.cache.mapDirs.set(c._root.unId,!0);!t.isEmpty();){const n=i.dequeue();if(!n)break;const s=a.cache.mapDirs.get(n.unId);if(t.size()==2){const u=t.dequeue(),l=t.dequeue(),f=new a({type:"tabset",host:n}),m=new a({type:"tabset",host:n}),p=new a({type:"tab",host:f,name:u,unId:this.tabsIds.get(u??"")??crypto.randomUUID()}),w=new a({type:"tab",host:m,name:l,unId:this.tabsIds.get(l??"")??crypto.randomUUID()});f.open=p.name,m.open=w.name,f.kids.enqueue(p),m.kids.enqueue(w),n.kids.enqueue(f),n.kids.enqueue(m),m.addBond(n,f),a.cache.mapDirs.set(f.unId,!s),a.cache.mapDirs.set(m.unId,!s),a.cache.mapElem.set(f.unId,f),a.cache.mapElem.set(m.unId,m),a.cache.mapDirs.set(p.unId,s),a.cache.mapDirs.set(w.unId,s),a.cache.mapElem.set(p.unId,p),a.cache.mapElem.set(w.unId,w),console.log(this.tabsIds);break}const d=t.dequeue(),o=new a({type:"tabset",host:n}),h=new a({type:"row",host:n}),r=new a({type:"tab",host:o,name:d,unId:this.tabsIds.get(d??"")??crypto.randomUUID()});o.open=r.name,o.kids.enqueue(r),n.kids.enqueue(o),n.kids.enqueue(h),h.addBond(n,o),a.cache.mapDirs.set(o.unId,!s),a.cache.mapDirs.set(h.unId,!s),a.cache.mapElem.set(o.unId,o),a.cache.mapDirs.set(r.unId,s),a.cache.mapElem.set(r.unId,r),i.enqueue(h)}this.calcTabsetCountAndMinDim()}createNodeFromJSON(t){const e=new a({type:t.typNode,name:t.nodName,unId:t.uidNode,part:t.nodPart,dims:{w:0,h:0,x:0,y:0},open:typeof t.nodOpen=="string"?t.nodOpen:""});return t.typNode==="tab"&&(e.unId=this.tabsIds.get(t.nodName)||t.uidNode),e}calcTabsetCountAndMinDim(t=c._root,e=!0){t===c._root&&e&&(a.cache.tabCnts.clear(),a.cache.dimMins.clear(),a.cache.mapElem.clear(),a.cache.mapElem.clear(),a.cache.mapElem.clear(),a.cache.mapElem.clear(),a.cache.nodOpts.get().clear(),a.cache.bndOpts.get().clear());for(const i of this.NodeLayoutRecursiveIterator(t)){const n=a.cache.tabCnts,s=a.cache.dimMins;a.cache.mapElem.set(i.unId,i);const d=n.set(i.unId,{horizontal:0,vertical:0}).get(i.unId),o=s.set(i.unId,{minWidth:0,minHeight:0}).get(i.unId),h=a.cache.mapDirs.get(i.unId);if(i.type==="tab"&&(a.cache.mapElem.set(i.unId,i),s.set(i.unId,{minWidth:0,minHeight:0})),i.next&&a.cache.mapElem.set(i.next.unId,i.next),i.type==="tabset"&&(a.cache.mapElem.set(i.unId,i),s.set(i.unId,{minWidth:c._minW,minHeight:c._minH}),h?n.set(i.unId,{horizontal:0,vertical:1}):n.set(i.unId,{horizontal:1,vertical:0})),i.type==="row"){for(const r of i.kids){const u=n.get(r.unId),l=s.get(r.unId);u&&(d.horizontal+=u.horizontal,d.vertical+=u.vertical,h?(o.minHeight=Math.max(o.minHeight,l.minHeight),o.minWidth+=l.minWidth):(o.minHeight+=l.minHeight,o.minWidth=Math.max(o.minWidth,l.minWidth)))}h?o.minWidth+=(i.kids.size()-1)*c._bond:o.minHeight+=(i.kids.size()-1)*c._bond}}}calculateRootAdjustment(){const t=c._root.getReqDimension();let e=!1,i=c._root.dims.w,n=c._root.dims.h;return c._root.dims.w<t.width&&(i=t.width,e=!0),c._root.dims.h<t.height&&(n=t.height,e=!0),e&&(c._root.dims.w=i,c._root.dims.h=n),{adjustedW:i,adjustedH:n,wasAdjusted:e}}calcDimensions(t=c._root,e=!1){const i=new Map,n=new Map,s=new Map;t===c._root&&this.calculateRootAdjustment();for(const d of this.NodeLayoutIterator(t)){d.calcDimensions();const o=a.cache.mapDirs.get(d.unId);if(d.type==="tabset"){const h={typNode:d.type,nodName:d.name,uidNode:d.unId,nodPart:d.part,nodOpen:d.open,nodeDir:o,nodKids:Array.from(d.kids).map(r=>{const u={typNode:r.type,nodName:r.name,uidNode:r.unId,nodPart:r.part,nodOpen:d.open===r.name,nodeDir:!o,nodDims:{...d.dims}};return s.set(r.unId,u),u}),nodDims:{...d.dims}};i.set(d.unId,h)}if(d.next&&d.type!=="tab"){const h={typNode:"bond",nodName:d.name,uidNode:d.next.unId,nodeDir:o,nodPart:0,nodDims:{...d.next.dims}};n.set(d.next.unId,h)}}a.cache.nodOpts.set(i,e),a.cache.bndOpts.set(n,e),a.cache.tabOpts.set(s,e)}updateDimension(t,e=!1,i=2){if(c._root.dims=t,e){this.calcDimensions(c._root);return}this.cntdown&&(clearTimeout(this.cntdown),this.cntdown=null),this.cntdown=setTimeout(()=>{this.cntdown=null,this.calcDimensions()},i)}updateSlider(t,e,i=!1,n=2){if(i){this.updateSliderDimension(t,e);return}this.cntdown&&(clearTimeout(this.cntdown),this.cntdown=null),this.cntdown=setTimeout(()=>{this.cntdown=null,this.updateSliderDimension(t,e)},n)}updateSliderDimension(t,e){const i=a.cache.mapElem.get(t);if(!i||!(i instanceof x)){console.warn(`Bond with id ${t} not found or is not a Bond instance`);return}const n=a.cache.mapDirs.get(i.host.unId),s=i.prev,d=i.next,o=i.host;if(!s||!d||!o){console.warn("Missing prev, next, or host node",s,d,o);return}const h=a.cache.dimMins.get(s.unId)||{minWidth:0,minHeight:0},r=a.cache.dimMins.get(d.unId)||{minWidth:0,minHeight:0},u=c._bond/2;if(n){const l=d.dims.x+d.dims.w,f=s.dims.x+h.minWidth+u,m=l-r.minWidth-u,p=Math.max(f,Math.min(m,e.x));i.dims.x=p-u,s.dims.w=i.dims.x-s.dims.x,d.dims.x=p+u,d.dims.w=l-d.dims.x;const w=Math.max(0,s.dims.w-h.minWidth),k=Math.max(0,d.dims.w-r.minWidth),b=w+k,y=s.part+d.part;b>0?(s.part=w/b*y,d.part=k/b*y):(s.part=y/2,d.part=y/2)}else{const l=d.dims.y+d.dims.h,f=s.dims.y+h.minHeight+u,m=l-r.minHeight-u,p=Math.max(f,Math.min(m,e.y));i.dims.y=p-u,s.dims.h=i.dims.y-s.dims.y,d.dims.y=p+u,d.dims.h=l-d.dims.y;const w=Math.max(0,s.dims.h-h.minHeight),k=Math.max(0,d.dims.h-r.minHeight),b=w+k,y=s.part+d.part;b>0?(s.part=w/b*y,d.part=k/b*y):(s.part=y/2,d.part=y/2)}this.calcDimensions(o)}updateTree(t,e,i){const n=a.cache.mapElem.get(t);let s=a.cache.mapElem.get(e);return!n||!(n instanceof a)||!s||!(s instanceof a)?(console.warn(`Source node ${t} not found or is not a Node instance`),!1):n?.type=="tab"&&n.host===s&&s.kids.size()<2?(console.warn("Cannot move to self as it has only one tab"),!1):n?.type=="tabset"&&s?.host===n?(console.warn("Cannot move tabset to self as it is already a child"),!1):!n||!s?(console.warn(`Source or destination node not found: ${t}, ${e}`),!1):n===s?(console.warn("Source and destination nodes are the same, no action taken."),!1):!n.host||!s.host&&s.type!=="row"?(console.warn(`Source node or destination node's host is null: ${n.unId}, ${s.unId}`),!1):s.type==="row"&&i==="contain"?(console.warn(`Cannot move to a row with 'contain' layout: ${s.unId}`),!1):n.type==="row"?!1:(s.type==="tabset"&&i==="contain"&&(s=s.kids.peekBack()||s),s.type==="tab"&&(i==="contain"||i==="left"||i==="right")?this.moveNodeAsTab(n,s,i):s.type==="row"&&i!=="contain"?this.moveRelativeToRoot(n,s,i):s.type==="tabset"&&i!=="contain"&&this.moveRelativeToTabset(n,s,i),this.calcTabsetCountAndMinDim(),this.calcDimensions(c._root,!0),!0)}moveNodeAsTab(t,e,i){if(!e||!e.host){console.warn(`Destination node ${e.unId} has no host, cannot move.`);return}this.removeNode(t);const n=e.host,s=n.kids.indexOf(e);if(s===void 0||s===-1)return;const d=i==="contain"||i==="left",o=d?s:s+1,h=n.kids.get(o+1),r=n.kids.get(o-1),u=e.next,l=e.prev;if(!d&&u?(a.cache.mapElem.delete(u.unId),a.cache.nodOpts.get().delete(u.unId)):d&&l&&(a.cache.mapElem.delete(l.unId),a.cache.nodOpts.get().delete(l.unId)),t.type=="tab")d?(r&&t.addBond(n,r),e.addBond(n,t)):(t.addBond(n,e),h&&h.addBond(n,t)),n.kids.insert(o,t),t.host=n,n.open=t.name;else if(t.type=="tabset"){const f=t.kids.peek(),m=t.kids.peekBack();d?(f&&r&&f.addBond(n,r),m&&e&&e.addBond(n,m)):(f&&e&&f.addBond(n,e),m&&h&&h.addBond(n,m)),n.kids.insertQueue(o,t.kids);for(const p of t.kids)p.host=n,p.next&&(p.next.host=n);n.open=m?m.name:""}this.updateChildDirections(n)}moveRelativeToRoot(t,e,i){this.removeNode(t);const n=a.cache.mapDirs.get(e.unId),s=i==="top"||i==="left";if(t.type==="tab"){const d=new a({type:"tabset",host:e.host});d.kids.enqueue(t),t.host=d,d.open=t.name,n==!1?i==="left"||i==="right"?this.insertNodeWithNewParent(d,e,s):this.insertNode(e,d,s):i==="top"||i==="bottom"?this.insertNodeWithNewParent(d,e,s):this.insertNode(e,d,s)}else t.type==="tabset"&&(n==!1?i==="left"||i==="right"?this.insertNodeWithNewParent(t,e,s):this.insertNode(e,t,s):i==="top"||i==="bottom"?this.insertNodeWithNewParent(t,e,s):this.insertNode(e,t,s))}moveRelativeToTabset(t,e,i){this.removeNode(t);const n=a.cache.mapDirs.get(e.unId),s=i==="top"||i==="left";if(t.type==="tab"){const d=new a({type:"tabset",host:e.host});d.kids.enqueue(t),t.host=d,d.open=t.name,n==!1?i==="top"||i==="bottom"?this.insertNodeWithNewParent(d,e,s):this.insertNode(e,d,s):i==="left"||i==="right"?this.insertNodeWithNewParent(d,e,s):this.insertNode(e,d,s)}else t.type==="tabset"&&(n==!1?i==="top"||i==="bottom"?this.insertNodeWithNewParent(t,e,s):this.insertNode(e,t,s):i==="left"||i==="right"?this.insertNodeWithNewParent(t,e,s):this.insertNode(e,t,s))}insertNode(t,e,i){const n=t.host;if(t==c._root){const l=c._root.kids.peek(),f=c._root.kids.peekBack();i?(c._root.kids.enqueueFront(e),l&&l.addBond(c._root,e)):(c._root.kids.enqueue(e),f&&e.addBond(c._root,f)),e.host=c._root,this.updateChildDirections(c._root);return}if(!n){console.warn(`Destination node ${t.unId} has no host, cannot insert.`);return}const s=n.kids.indexOf(t);if(s===-1){console.warn(`Destination node ${t.unId} not found in its host's kids.`);return}const d=a.cache.mapDirs.get(n.unId);d&&a.cache.mapDirs.set(e.unId,!d);const o=n.kids.get(s+1),h=n.kids.get(s-1),r=t.next,u=t.prev;e.host=n,i?(n.kids.insert(s,e),t.addBond(n,e),h&&e.addBond(n,h),u&&(a.cache.mapElem.delete(u.unId),a.cache.nodOpts.get().delete(u.unId))):(n.kids.insert(s+1,e),e.addBond(n,t),o&&o.addBond(n,e),r&&(a.cache.mapElem.delete(r.unId),a.cache.nodOpts.get().delete(r.unId))),this.updateChildDirections(n)}insertNodeWithNewParent(t,e,i){const n=new N,s=new a({type:"tabset",host:e.host});if(!e||!t){console.warn(`Destination node ${e.unId} has no host, cannot insert.`);return}if(e===c._root){const o=new a({type:"row",host:e});if(e.kids.size()==1&&e.kids.peek()?.type==="tabset"){const h=e.kids.dequeue();if(!h){console.warn(`No kid found in destination node ${e.unId}, cannot insert.`);return}i?(o.kids.enqueue(t),o.kids.enqueue(h),e.kids.enqueue(o),h.addBond(o,t)):(o.kids.enqueue(h),o.kids.enqueue(t),t.addBond(o,h),e.kids.enqueue(o)),t.host=o,h.host=o}else if(e.kids.size()==1&&e.kids.peek()?.type==="row"){const h=e.kids.peek(),r=h?.kids.peek(),u=h?.kids.peekBack();i&&h?(h.kids.enqueueFront(t),r&&r.addBond(h,t)):h&&(h.kids.enqueue(t),u&&t.addBond(h,u)),t.host=h}else if(e.kids.size()>1){const h=new a({type:"row",host:e}),r=new a({type:"row",host:h});for(const u of e.kids)r.kids.enqueue(u),u.host=r,u.next&&(u.next.host=r);t.host=h,e.kids.clear(),i?(h.kids.enqueueFront(t),h.kids.enqueue(r),r.addBond(h,t)):(h.kids.enqueue(r),h.kids.enqueue(t),t.addBond(h,r)),e.kids.enqueue(h)}this.updateChildDirections(e);return}t.host=e,s.host=e,s.kids=e.kids,s.open=e.open;const d=a.cache.mapDirs.get(e.unId);for(const o of s.kids)o.host=s,o.next&&(o.next.host=s),a.cache.mapDirs.set(o.unId,d);for(const o of t.kids)o.host=t,o.next&&(o.next.host=t),a.cache.mapDirs.set(o.unId,d);a.cache.mapDirs.set(s.unId,!d),a.cache.mapDirs.set(t.unId,!d),i?(n.enqueue(t),n.enqueue(s),e.kids=n,e.type="row",s.addBond(e,t)):(n.enqueue(s),n.enqueue(t),e.kids=n,e.type="row",t.addBond(e,s))}moveAdjacentNodeToGrandParent(t){if(!t.host||!t.host.host){console.warn(`Source node ${t.unId} has no host, cannot move.`);return}const e=t.host,i=t.host.host,n=i.kids.indexOf(e),s=i.kids.get(n-1),d=i.kids.get(n+1),o=t.kids.peek(),h=t.kids.peekBack();this.removeKid(e);let r=n;if(t.type=="row"&&e){s&&o&&o.addBond(i,s),d&&h&&d.addBond(i,h);for(const u of t.kids)u.host=i,u.next&&(u.next.host=i),i.kids.insert(r,u),a.cache.mapDirs.set(u.unId,!a.cache.mapDirs.get(i.unId)),a.cache.dimMins.delete(u.unId),r++}else if(t.type=="tabset"){s&&t.addBond(i,s),d&&d.addBond(i,t),i.kids.insert(r,t),t.host=i,a.cache.mapDirs.set(t.unId,!a.cache.mapDirs.get(i.unId));for(const u of t.kids)a.cache.mapDirs.set(u.unId,a.cache.mapDirs.get(i.unId)),a.cache.dimMins.delete(u.unId)}}removeRelation(t,e=!0){const i=t.host,n=t.prev,s=t.next;if(t.host=null,t.next=null,t.prev=null,n&&(n.next=null),s&&(s.prev=null),!e)return t;n&&s&&n.prev&&s.next?n.prev.addBond(i,s.next):n&&n.prev?n.prev.next=null:s&&s.next&&(s.next.prev=null)}removeNode(t){if(!t.host){console.warn("Kid node has no host, cannot remove.");return}const e=t?.host,i=e?.host;if(this.removeKid(t),t.type==="tabset"&&e.kids.size()===1){const n=e.kids.peek();n&&this.moveAdjacentNodeToGrandParent(n)}else if(t.type==="tab"&&e.kids.size()===0&&i.kids.size()===2){this.removeKid(e);const n=i?.kids.peek();n&&this.moveAdjacentNodeToGrandParent(n)}else if(t.type==="tab"&&e.kids.size()===0&&i.kids.size()>2)this.removeKid(e);else if(t.type==="tab"&&e.open===t.name&&e.kids.size()>0){const n=e.kids.peek();n&&(e.open=n.name)}}removeKid(t){if(!t.host){console.warn("Kid node has no host, cannot remove.");return}const e=t.host,i=e.kids.indexOf(t),n=e.kids.get(i+1),s=e.kids.get(i-1),d=t.next,o=t.prev;if(i===-1){console.warn("Kid node not found in its host's kids.");return}d&&(a.cache.mapElem.delete(d.unId),a.cache.nodOpts.get().delete(d.unId)),o&&(a.cache.mapElem.delete(o.unId),a.cache.nodOpts.get().delete(o.unId)),n&&s?n.addBond(e,s):n?n.prev=null:s&&(s.next=null),e.kids.removeAt(i),a.cache.mapElem.delete(t.unId),a.cache.dimMins.delete(t.unId),a.cache.mapDirs.delete(t.unId),a.cache.tabCnts.delete(t.unId),t.type==="tabset"&&a.cache.mapElem.delete(t.unId),t.type==="tab"&&a.cache.mapElem.delete(t.unId),t.host=null,t.next=null,t.prev=null}clearAllCache(){a.cache.dimMins.clear(),a.cache.mapDirs.clear(),a.cache.tabCnts.clear(),a.cache.mapElem.clear(),a.cache.nodOpts.get().clear(),a.cache.bndOpts.get().clear()}}class x{dims={w:0,h:0,x:0,y:0};unId=crypto.randomUUID();next=null;prev=null;host=null;constructor(t=null,e=null,i=null){this.host=t,this.next=e,this.prev=i,this.next&&(this.next.prev=this),this.prev&&(this.prev.next=this)}toJSON(){return{nodName:this.host?.name||"",typNode:"bond",uidNode:this.unId,nodPart:0,nodOpen:"",nodKids:[]}}}(()=>{if(typeof window>"u")return;const I="color: #03A9F4; font-weight: bold; line-height: 1.2;",t="color: #E0E0E0; font-size: 12px;",e="color: #42a5f5; font-size: 12px;",i="color: #9E9E9E; font-size: 10px;",n=`
|
|
2
|
+
██████╗ ██╗ ██╗ ███╗ ██╗ █████╗ ███╗ ███╗ ██████╗ ██╗ ██╗
|
|
3
|
+
██╔══██╗╚██╗ ██╔╝ ████╗ ██║ ██╔══██╗ ████╗ ████║ ╚═██╔═╝ ╚██╗██╔╝
|
|
4
|
+
██║ ██║ ╚████╔╝ ██╔██╗ ██║ ███████║ ██╔████╔██║ ██║ ╚███╔╝
|
|
5
|
+
██║ ██║ ╚██╔╝ ██║╚██╗██║ ██╔══██║ ██║╚██╔╝██║ ██║ ██╔██╗
|
|
6
|
+
██████╔╝ ██║ ██║ ╚████║ ██║ ██║ ██║ ╚═╝ ██║ ██████╗ ██╔╝ ██╗
|
|
7
|
+
╚═════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
|
|
8
|
+
██╗ █████╗ ██╗ ██╗ ██████╗ ██╗ ██╗████████╗
|
|
9
|
+
██║ ██╔══██╗ ╚██╗ ██╔╝ ██╔═══██╗ ██║ ██║╚══██╔══╝
|
|
10
|
+
██║ ███████║ ╚████╔╝ ██║ ██║ ██║ ██║ ██║
|
|
11
|
+
██║ ██╔══██║ ╚██╔╝ ██║ ██║ ██║ ██║ ██║
|
|
12
|
+
███████╗ ██║ ██║ ██║ ╚██████╔╝ ╚█████╔╝ ██║
|
|
13
|
+
╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚════╝ ╚═╝
|
|
14
|
+
`;console.groupCollapsed("%cDYNAMIX LAYOUT (click to expand)","color: #03A9F4; font-weight: bold; font-size: 14px;"),console.log(`%c${n}`,I),console.log("%c A powerful, dynamic layout system 🚀",t),console.log(`%c ⚡ For docs and more info,
|
|
15
|
+
⚡ visit: https://github.com/akash-aman/dynamix-layout`,e),console.log(`%cMIT License
|
|
16
|
+
|
|
17
|
+
Copyright (c) 2025 Akash Aman <sir.akashaman@gmail.com> (https://akash.cx)
|
|
18
|
+
|
|
19
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
20
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
21
|
+
in the Software without restriction, including without limitation the rights
|
|
22
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
23
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
24
|
+
furnished to do so, subject to the following conditions:
|
|
25
|
+
|
|
26
|
+
The above copyright notice and this permission notice shall be included in all
|
|
27
|
+
copies or substantial portions of the Software.
|
|
28
|
+
|
|
29
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
30
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
31
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
32
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
33
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
34
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
35
|
+
SOFTWARE.
|
|
36
|
+
`,i),console.groupEnd(),typeof window<"u"&&(window.__DYNAMIX_LAYOUT__={__LICENSE__:`MIT License
|
|
37
|
+
|
|
38
|
+
Copyright (c) 2025 Akash Aman <sir.akashaman@gmail.com> (https://akash.cx)
|
|
39
|
+
|
|
40
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
41
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
42
|
+
in the Software without restriction, including without limitation the rights
|
|
43
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
44
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
45
|
+
furnished to do so, subject to the following conditions:
|
|
46
|
+
|
|
47
|
+
The above copyright notice and this permission notice shall be included in all
|
|
48
|
+
copies or substantial portions of the Software.
|
|
49
|
+
|
|
50
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
51
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
52
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
53
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
54
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
55
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
56
|
+
SOFTWARE.
|
|
57
|
+
`,__LAYOUT__:c})})();exports.Bond=x;exports.DynamixLayoutCore=c;exports.Node=a;exports.Queue=N;exports.areNodeOptionsEqual=O;exports.areNodeOptionsMapEqual=E;exports.createReactiveState=g;
|