@e280/strata 0.0.0-0 → 0.0.0-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 CHANGED
@@ -1,72 +1,128 @@
1
1
 
2
+ ![](https://i.imgur.com/h7FohWa.jpeg)
3
+
2
4
  # ⛏️ strata
3
5
 
4
6
  **my 10th state management library, probably**
5
7
  - 📦 `npm install @e280/strata`
6
8
  - single-source-of-truth state tree
7
9
  - immutable except for `mutate(fn)` calls
10
+ - no spooky-dookie proxy magic — just god's honest javascript
8
11
  - undo/redo history, cross-tab sync, localStorage persistence
9
12
 
10
- ## good state management
13
+ <br/>
14
+
15
+ ## get in loser, we're managing state
11
16
 
12
- ### establish a strata with some state
17
+ ### `Strata` is your app's state tree root
13
18
  - better stick to json-friendly serializable data
14
19
  ```ts
15
20
  import {Strata} from "@e280/strata"
16
21
 
17
22
  const strata = new Strata({
18
23
  count: 0,
19
- stuff: {
24
+ snacks: {
20
25
  peanuts: 8,
21
- items: ["hello", "world"],
26
+ bag: ["popcorn", "butter"],
22
27
  },
23
28
  })
24
29
 
25
30
  strata.state.count // 0
26
- strata.state.stuff.peanuts // 8
31
+ strata.state.snacks.peanuts // 8
27
32
  ```
28
33
 
29
- ### how mutations work
34
+ ### formal mutations to change state
30
35
  - ⛔ informal mutations are denied
31
36
  ```ts
32
37
  strata.state.count++ // error is thrown
33
38
  ```
34
- - ✅ formal mutation is allowed
39
+ - ✅ formal mutations are allowed
35
40
  ```ts
36
41
  await strata.mutate(s => s.count++)
37
42
  ```
38
43
 
39
- ### substrata and selectors
40
- - a substrata is a view into a subset of the state tree
44
+ ### `Substrata` is a view into a subtree
45
+ - it's a lens, make lots of them, pass 'em around your app
41
46
  ```ts
42
- const stuff = strata.substrata(s => s.stuff)
47
+ const snacks = strata.substrata(s => s.snacks)
43
48
  ```
44
49
  - run substrata mutations
45
50
  ```ts
46
- await stuff.mutate(s => s.peanuts++)
51
+ await snacks.mutate(s => s.peanuts++)
47
52
  ```
48
- - array mutations are cool, actually
53
+ - array mutations are unironically based, actually
49
54
  ```ts
50
- await stuff.mutate(s => s.items.push("lol"))
55
+ await snacks.mutate(s => s.bag.push("salt"))
51
56
  ```
57
+ - you can make a substrata of another substrata
52
58
 
53
59
  ### onMutation events
54
60
  - you can listen to global mutations on the strata
55
61
  ```ts
56
62
  strata.onMutation(s => console.log(s.count))
57
63
  ```
58
-
59
64
  - substrata listeners don't care about outside changes
60
65
  ```ts
61
- stuff.onMutation(s => console.log(s.peanuts))
66
+ snacks.onMutation(s => console.log(s.peanuts))
62
67
  ```
63
-
64
68
  - onMutation returns a fn to stop listening
65
69
  ```ts
66
70
  const stop = strata.onMutation(s => console.log(s.count))
67
71
  stop() // stop listening
68
72
  ```
69
73
 
74
+ <br/>
75
+
76
+ ## only high-class discerning aristocrats permitted beyond this point
77
+
78
+ ### `Chronstrata` for undo/redo history
79
+ - first, put a `Chronicle` into your state tree
80
+ ```ts
81
+ const strata = new Strata({
82
+ count: 0,
83
+ snacks: Strata.chronicle({
84
+ peanuts: 8,
85
+ bag: ["popcorn", "butter"],
86
+ }),
87
+ })
88
+ ```
89
+ - *big-brain moment:* the whole chronicle *itself* is stored in the state.. serializable.. think persistence — user can close their project, reopen, and their undo/redo history is still chillin' — *brat girl summer*
90
+ - second, make a `Chronstrata` which is like a substrata
91
+ ```ts
92
+ const snacks = strata.chronstrata(64, s => s.snacks)
93
+ // \
94
+ // how many past snapshots to store
95
+ ```
96
+ - mutations will advance history (undoable/redoable)
97
+ ```ts
98
+ await snacks.mutate(s => s.peanuts = 101)
99
+
100
+ await snacks.undo()
101
+ // back to 8 peanuts
102
+
103
+ await snacks.redo()
104
+ // forward to 101 peanuts
105
+ ```
106
+ - you can check how many undoable or redoable steps are available
107
+ ```ts
108
+ snacks.undoable // 0
109
+
110
+ await snacks.mutate(s => s.peanuts = 101)
111
+ await snacks.mutate(s => s.peanuts = 102)
112
+ await snacks.mutate(s => s.peanuts = 103)
113
+
114
+ snacks.undoable // 3
115
+
116
+ await snacks.undo()
117
+
118
+ snacks.undoable // 2
119
+ snacks.redoable // 1
120
+ ```
121
+ - chronstrata can have its own substrata — all their mutations advance history
122
+ - plz pinky-swear right now, that you won't create a chronstrata under a substrata under a chronstrata
123
+
124
+ <br/>
125
+
70
126
  ## a buildercore e280 project
71
127
  free and open source by https://e280.org/
72
128
  join us if you're cool and good at dev
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e280/strata",
3
- "version": "0.0.0-0",
3
+ "version": "0.0.0-1",
4
4
  "description": "state management",
5
5
  "license": "MIT",
6
6
  "author": "Chase Moskal <chasemoskal@gmail.com>",
package/s/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
 
2
- export {Strata} from "./parts/strata.js"
3
- export {Substrata} from "./parts/substrata.js"
4
- export {Options, Mutator, Selector} from "./parts/types.js"
2
+ export * from "./parts/chronstrata.js"
3
+ export * from "./parts/strata.js"
4
+ export * from "./parts/substrata.js"
5
+ export * from "./parts/types.js"
5
6
 
@@ -0,0 +1,84 @@
1
+
2
+ import {Substrata} from "./substrata.js"
3
+ import {Chronicle, Mutator, Options, Selector, Stratum, Substate} from "./types.js"
4
+
5
+ export class Chronstrata<ParentState extends Substate, S extends Substate> implements Stratum<S> {
6
+ #substrata: Substrata<ParentState, Chronicle<S>>
7
+
8
+ constructor(
9
+ public limit: number,
10
+ public parent: Stratum<ParentState>,
11
+ public selector: Selector<ParentState, Chronicle<S>>,
12
+ public options: Options,
13
+ ) {
14
+ this.#substrata = parent.substrata(selector)
15
+ }
16
+
17
+ get state() {
18
+ return this.#substrata.state.present
19
+ }
20
+
21
+ get undoable() {
22
+ return this.#substrata.state.past.length
23
+ }
24
+
25
+ get redoable() {
26
+ return this.#substrata.state.future.length
27
+ }
28
+
29
+ onMutation(fn: (state: S) => void) {
30
+ return this.#substrata.onMutation(chronicle => fn(chronicle.present))
31
+ }
32
+
33
+ /** progress forwards in history */
34
+ async mutate(mutator: Mutator<S>) {
35
+ const limit = Math.max(0, this.limit)
36
+ const snapshot = this.options.clone(this.#substrata.state.present)
37
+ await this.#substrata.mutate(chronicle => {
38
+ mutator(chronicle.present)
39
+ chronicle.past.push(snapshot)
40
+ chronicle.past = chronicle.past.slice(-limit)
41
+ chronicle.future = []
42
+ })
43
+ return this.state
44
+ }
45
+
46
+ /** step backwards into the past, by n steps */
47
+ async undo(n = 1) {
48
+ await this.#substrata.mutate(chronicle => {
49
+ const snapshots = chronicle.past.slice(-n)
50
+ if (snapshots.length >= n) {
51
+ const oldPresent = chronicle.present
52
+ chronicle.present = snapshots.shift()!
53
+ chronicle.past = chronicle.past.slice(0, -n)
54
+ chronicle.future.unshift(oldPresent, ...snapshots)
55
+ }
56
+ })
57
+ }
58
+
59
+ /** step forwards into the future, by n steps */
60
+ async redo(n = 1) {
61
+ await this.#substrata.mutate(chronicle => {
62
+ const snapshots = chronicle.future.slice(0, n)
63
+ if (snapshots.length >= n) {
64
+ const oldPresent = chronicle.present
65
+ chronicle.present = snapshots.shift()!
66
+ chronicle.past.push(oldPresent, ...snapshots)
67
+ chronicle.future = chronicle.future.slice(n)
68
+ }
69
+ })
70
+ }
71
+
72
+ /** wipe past and future snapshots */
73
+ async wipe() {
74
+ await this.#substrata.mutate(chronicle => {
75
+ chronicle.past = []
76
+ chronicle.future = []
77
+ })
78
+ }
79
+
80
+ substrata<Sub extends Substate>(selector: Selector<S, Sub>): Substrata<S, Sub> {
81
+ return new Substrata(this, selector, this.options)
82
+ }
83
+ }
84
+
package/s/parts/strata.ts CHANGED
@@ -2,39 +2,51 @@
2
2
  import {debounce, deep, sub} from "@e280/stz"
3
3
 
4
4
  import {Substrata} from "./substrata.js"
5
+ import {Chronstrata} from "./chronstrata.js"
5
6
  import {processOptions} from "./utils/process-options.js"
6
- import {Mutator, Options, Selector, State, Substate} from "./types.js"
7
+ import {Chronicle, Mutator, Options, Selector, State, Stratum, Substate} from "./types.js"
7
8
 
8
- export class Strata<S extends State> {
9
+ export class Strata<S extends State> implements Stratum<S> {
10
+ static chronicle = <S extends Substate>(state: S): Chronicle<S> => ({
11
+ present: state,
12
+ past: [],
13
+ future: [],
14
+ })
15
+
16
+ options: Options
9
17
  onMutation = sub<[state: S]>()
10
18
 
11
- #options: Options
12
19
  #mutable: S
13
20
  #immutable: S
14
- #dispatchMutation = debounce(0, (state: S) => this.onMutation.pub(state))
21
+ #mutationLock = 0
22
+ #dispatchMutation = debounce(0, async(state: S) => {
23
+ this.#mutationLock++
24
+ try { await this.onMutation.pub(state) }
25
+ finally { this.#mutationLock-- }
26
+ })
15
27
 
16
28
  constructor(state: S, options: Partial<Options> = {}) {
17
- this.#options = processOptions(options)
29
+ this.options = processOptions(options)
18
30
  this.#mutable = state
19
- this.#immutable = deep.freeze(this.#options.clone(state))
31
+ this.#immutable = deep.freeze(this.options.clone(state))
20
32
  }
21
33
 
22
34
  #updateState(state: S) {
23
35
  this.#mutable = state
24
- this.#immutable = deep.freeze(this.#options.clone(state))
36
+ this.#immutable = deep.freeze(this.options.clone(state))
25
37
  }
26
38
 
27
39
  get state() {
28
40
  return this.#immutable
29
41
  }
30
42
 
31
- substrata<Sub extends Substate>(selector: Selector<S, Sub>) {
32
- return new Substrata(this, selector, this.#options)
33
- }
34
-
35
43
  async mutate(mutator: Mutator<S>) {
36
- const oldState = this.#options.clone(this.#mutable)
37
- mutator(this.#mutable)
44
+ const oldState = this.options.clone(this.#mutable)
45
+ if (this.#mutationLock > 0)
46
+ throw new Error("nested mutations are forbidden")
47
+ this.#mutationLock++
48
+ try { mutator(this.#mutable) }
49
+ finally { this.#mutationLock-- }
38
50
  const newState = this.#mutable
39
51
  const isChanged = !deep.equal(newState, oldState)
40
52
  if (isChanged) {
@@ -44,5 +56,16 @@ export class Strata<S extends State> {
44
56
  }
45
57
  return this.#immutable
46
58
  }
59
+
60
+ substrata<Sub extends Substate>(selector: Selector<S, Sub>): Substrata<S, Sub> {
61
+ return new Substrata(this, selector, this.options)
62
+ }
63
+
64
+ chronstrata<Sub extends Substate>(
65
+ limit: number,
66
+ selector: Selector<S, Chronicle<Sub>>,
67
+ ) {
68
+ return new Chronstrata(limit, this, selector, this.options)
69
+ }
47
70
  }
48
71
 
@@ -1,29 +1,25 @@
1
1
 
2
2
  import {debounce, deep, sub} from "@e280/stz"
3
+ import {Chronstrata} from "./chronstrata.js"
4
+ import {Chronicle, Mutator, Options, Selector, Stratum, Substate} from "./types.js"
3
5
 
4
- import {Strata} from "./strata.js"
5
- import {processOptions} from "./utils/process-options.js"
6
- import {Mutator, Options, Selector, State, Substate} from "./types.js"
7
-
8
- export class Substrata<ParentState extends State, S extends Substate> {
6
+ export class Substrata<ParentState extends Substate, S extends Substate> implements Stratum<S> {
9
7
  dispose: () => void
10
8
  onMutation = sub<[state: S]>()
11
9
 
12
- #options: Options
13
10
  #immutable: S
14
11
  #dispatchMutation = debounce(0, (state: S) => this.onMutation.pub(state))
15
12
 
16
13
  constructor(
17
- private strata: Strata<ParentState>,
14
+ private parent: Stratum<ParentState>,
18
15
  private selector: Selector<ParentState, S>,
19
- options: Partial<Options> = {},
16
+ private options: Options,
20
17
  ) {
21
18
 
22
- this.#options = processOptions(options)
23
- const state = this.selector(this.strata.state)
24
- this.#immutable = deep.freeze(this.#options.clone(state))
19
+ const state = this.selector(this.parent.state)
20
+ this.#immutable = deep.freeze(this.options.clone(state))
25
21
 
26
- this.dispose = this.strata.onMutation(async parentState => {
22
+ this.dispose = this.parent.onMutation(async parentState => {
27
23
  const oldState = this.#immutable
28
24
  const newState = this.selector(parentState)
29
25
  const isChanged = !deep.equal(newState, oldState)
@@ -36,7 +32,7 @@ export class Substrata<ParentState extends State, S extends Substate> {
36
32
  }
37
33
 
38
34
  #updateState(state: S) {
39
- this.#immutable = deep.freeze(this.#options.clone(state))
35
+ this.#immutable = deep.freeze(this.options.clone(state))
40
36
  }
41
37
 
42
38
  get state(): S {
@@ -44,12 +40,19 @@ export class Substrata<ParentState extends State, S extends Substate> {
44
40
  }
45
41
 
46
42
  async mutate(mutator: Mutator<S>) {
47
- await this.strata.mutate(parentState => mutator(this.selector(parentState)))
43
+ await this.parent.mutate(parentState => mutator(this.selector(parentState)))
48
44
  return this.#immutable
49
45
  }
50
46
 
51
- substrata<Sub extends Substate>(selector: Selector<S, Sub>) {
52
- return this.strata.substrata(parentState => selector(this.selector(parentState)))
47
+ substrata<Sub extends Substate>(selector: Selector<S, Sub>): Substrata<S, Sub> {
48
+ return new Substrata(this, selector, this.options)
49
+ }
50
+
51
+ chronstrata<Sub extends Substate>(
52
+ limit: number,
53
+ selector: Selector<S, Chronicle<Sub>>,
54
+ ) {
55
+ return new Chronstrata(limit, this, selector, this.options)
53
56
  }
54
57
  }
55
58
 
package/s/parts/types.ts CHANGED
@@ -1,4 +1,6 @@
1
1
 
2
+ import {Substrata} from "./substrata.js"
3
+
2
4
  export type Options = {
3
5
  clone: <X>(x: X) => X
4
6
  }
@@ -9,3 +11,21 @@ export type Mutator<S> = (state: S) => void
9
11
  export type State = {}
10
12
  export type Substate = {} | null | undefined
11
13
 
14
+ export type Stratum<S extends Substate> = {
15
+ readonly state: S
16
+ onMutation(fn: (s: S) => void): () => void
17
+ mutate(mutator: Mutator<S>): Promise<S>
18
+ substrata<Sub extends Substate>(selector: Selector<S, Sub>): Substrata<S, Sub>
19
+ }
20
+
21
+ export type Chronicle<S extends Substate> = {
22
+ // [abc] d [efg]
23
+ // \ \ \
24
+ // \ \ future
25
+ // \ present
26
+ // past
27
+ past: S[]
28
+ present: S
29
+ future: S[]
30
+ }
31
+
package/s/tests.test.ts CHANGED
@@ -23,6 +23,17 @@ await Science.run({
23
23
  expect(strata.state.count).is(2)
24
24
  }),
25
25
 
26
+ "forbidden mutation nesting": Science.test(async() => {
27
+ const strata = new Strata({count: 0})
28
+ await expect(async() => {
29
+ let promise!: Promise<any>
30
+ await strata.mutate(() => {
31
+ promise = strata.mutate(() => {})
32
+ })
33
+ await promise
34
+ }).throwsAsync()
35
+ }),
36
+
26
37
  "state after mutation is frozen": Science.test(async () => {
27
38
  const strata = new Strata({x: 1})
28
39
  await strata.mutate(s => { s.x = 2 })
@@ -55,6 +66,21 @@ await Science.run({
55
66
  expect(mutationCount).is(1)
56
67
  expect(strata.state.items.length).is(3)
57
68
  }),
69
+
70
+ "prevent mutation loops": Science.test(async() => {
71
+ const strata = new Strata({count: 0})
72
+ let mutationCount = 0
73
+ strata.onMutation.sub(async() => {
74
+ mutationCount++
75
+ if (mutationCount > 100)
76
+ return
77
+ await strata.mutate(s => s.count++)
78
+ })
79
+ await expect(async() => {
80
+ await strata.mutate(state => state.count++)
81
+ }).throwsAsync()
82
+ expect(mutationCount).is(1)
83
+ }),
58
84
  }),
59
85
 
60
86
  "substrata": Science.suite({
@@ -114,6 +140,168 @@ await Science.run({
114
140
  await a.mutate(a => a.x = 1)
115
141
  expect(counted).is(0)
116
142
  }),
143
+
144
+ "forbid submutation in mutation": Science.test(async() => {
145
+ const strata = new Strata({a: {b: 0}})
146
+ const a = strata.substrata(s => s.a)
147
+ await expect(async() => {
148
+ let promise!: Promise<any>
149
+ await strata.mutate(() => {
150
+ promise = a.mutate(() => {})
151
+ })
152
+ await promise
153
+ }).throwsAsync()
154
+ }),
155
+
156
+ "forbid mutation in submutation": Science.test(async() => {
157
+ const strata = new Strata({a: {b: 0}})
158
+ const a = strata.substrata(s => s.a)
159
+ await expect(async() => {
160
+ let promise!: Promise<any>
161
+ await a.mutate(() => {
162
+ promise = strata.mutate(() => {})
163
+ })
164
+ await promise
165
+ }).throwsAsync()
166
+ }),
117
167
  }),
168
+
169
+ "chronstrata": (() => {
170
+ const setup = () => {
171
+ const strata = new Strata({
172
+ chron: Strata.chronicle({count: 0}),
173
+ })
174
+ const chron = strata.chronstrata(64, s => s.chron)
175
+ return {strata, chron}
176
+ }
177
+
178
+ return Science.suite({
179
+ "get state": Science.test(async() => {
180
+ const {chron} = setup()
181
+ expect(chron.state.count).is(0)
182
+ }),
183
+
184
+ "mutate": Science.test(async() => {
185
+ const {chron} = setup()
186
+ expect(chron.state.count).is(0)
187
+ await chron.mutate(s => s.count++)
188
+ expect(chron.state.count).is(1)
189
+ await chron.mutate(s => s.count++)
190
+ expect(chron.state.count).is(2)
191
+ }),
192
+
193
+ "undoable/redoable": Science.test(async() => {
194
+ const {chron} = setup()
195
+ expect(chron.undoable).is(0)
196
+ expect(chron.redoable).is(0)
197
+ expect(chron.state.count).is(0)
198
+ await chron.mutate(s => s.count++)
199
+ expect(chron.undoable).is(1)
200
+ await chron.mutate(s => s.count++)
201
+ expect(chron.undoable).is(2)
202
+ await chron.undo()
203
+ expect(chron.undoable).is(1)
204
+ expect(chron.redoable).is(1)
205
+ await chron.undo()
206
+ expect(chron.undoable).is(0)
207
+ expect(chron.redoable).is(2)
208
+ await chron.redo()
209
+ expect(chron.undoable).is(1)
210
+ expect(chron.redoable).is(1)
211
+ }),
212
+
213
+ "undo": Science.test(async() => {
214
+ const {chron} = setup()
215
+ await chron.mutate(s => s.count++)
216
+ await chron.undo()
217
+ expect(chron.state.count).is(0)
218
+ }),
219
+
220
+ "redo": Science.test(async() => {
221
+ const {chron} = setup()
222
+ await chron.mutate(s => s.count++)
223
+ await chron.undo()
224
+ expect(chron.state.count).is(0)
225
+ await chron.redo()
226
+ expect(chron.state.count).is(1)
227
+ }),
228
+
229
+ "undo/redo well ordered": Science.test(async() => {
230
+ const {chron} = setup()
231
+ await chron.mutate(s => s.count++)
232
+ await chron.mutate(s => s.count++)
233
+ await chron.mutate(s => s.count++)
234
+ expect(chron.state.count).is(3)
235
+
236
+ await chron.undo()
237
+ expect(chron.state.count).is(2)
238
+
239
+ await chron.undo()
240
+ expect(chron.state.count).is(1)
241
+
242
+ await chron.redo()
243
+ expect(chron.state.count).is(2)
244
+
245
+ await chron.redo()
246
+ expect(chron.state.count).is(3)
247
+
248
+ await chron.undo()
249
+ expect(chron.state.count).is(2)
250
+
251
+ await chron.undo()
252
+ expect(chron.state.count).is(1)
253
+
254
+ await chron.undo()
255
+ expect(chron.state.count).is(0)
256
+ }),
257
+
258
+ "undo nothing does nothing": Science.test(async() => {
259
+ const {chron} = setup()
260
+ await chron.undo()
261
+ expect(chron.state.count).is(0)
262
+ }),
263
+
264
+ "redo nothing does nothing": Science.test(async() => {
265
+ const {chron} = setup()
266
+ await chron.redo()
267
+ expect(chron.state.count).is(0)
268
+ }),
269
+
270
+ "undo 2x": Science.test(async() => {
271
+ const {chron} = setup()
272
+ await chron.mutate(s => s.count++)
273
+ await chron.mutate(s => s.count++)
274
+ expect(chron.state.count).is(2)
275
+ await chron.undo(2)
276
+ expect(chron.state.count).is(0)
277
+ }),
278
+
279
+ "redo 2x": Science.test(async() => {
280
+ const {chron} = setup()
281
+ await chron.mutate(s => s.count++)
282
+ await chron.mutate(s => s.count++)
283
+ expect(chron.state.count).is(2)
284
+ await chron.undo(2)
285
+ expect(chron.state.count).is(0)
286
+ await chron.redo(2)
287
+ expect(chron.state.count).is(2)
288
+ }),
289
+
290
+ "substrata mutations are tracked": Science.test(async() => {
291
+ const strata = new Strata({
292
+ chron: Strata.chronicle({
293
+ group: {count: 0},
294
+ }),
295
+ })
296
+ const chron = strata.chronstrata(64, s => s.chron)
297
+ const group = chron.substrata(s => s.group)
298
+ expect(group.state.count).is(0)
299
+ await group.mutate(g => g.count = 101)
300
+ expect(group.state.count).is(101)
301
+ await chron.undo()
302
+ expect(group.state.count).is(0)
303
+ }),
304
+ })
305
+ })(),
118
306
  })
119
307
 
package/x/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- export { Strata } from "./parts/strata.js";
2
- export { Substrata } from "./parts/substrata.js";
3
- export { Options, Mutator, Selector } from "./parts/types.js";
1
+ export * from "./parts/chronstrata.js";
2
+ export * from "./parts/strata.js";
3
+ export * from "./parts/substrata.js";
4
+ export * from "./parts/types.js";
package/x/index.js CHANGED
@@ -1,3 +1,5 @@
1
- export { Strata } from "./parts/strata.js";
2
- export { Substrata } from "./parts/substrata.js";
1
+ export * from "./parts/chronstrata.js";
2
+ export * from "./parts/strata.js";
3
+ export * from "./parts/substrata.js";
4
+ export * from "./parts/types.js";
3
5
  //# sourceMappingURL=index.js.map
package/x/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../s/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAA;AACxC,OAAO,EAAC,SAAS,EAAC,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../s/index.ts"],"names":[],"mappings":"AACA,cAAc,wBAAwB,CAAA;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1,23 @@
1
+ import { Substrata } from "./substrata.js";
2
+ import { Chronicle, Mutator, Options, Selector, Stratum, Substate } from "./types.js";
3
+ export declare class Chronstrata<ParentState extends Substate, S extends Substate> implements Stratum<S> {
4
+ #private;
5
+ limit: number;
6
+ parent: Stratum<ParentState>;
7
+ selector: Selector<ParentState, Chronicle<S>>;
8
+ options: Options;
9
+ constructor(limit: number, parent: Stratum<ParentState>, selector: Selector<ParentState, Chronicle<S>>, options: Options);
10
+ get state(): S;
11
+ get undoable(): number;
12
+ get redoable(): number;
13
+ onMutation(fn: (state: S) => void): () => void;
14
+ /** progress forwards in history */
15
+ mutate(mutator: Mutator<S>): Promise<S>;
16
+ /** step backwards into the past, by n steps */
17
+ undo(n?: number): Promise<void>;
18
+ /** step forwards into the future, by n steps */
19
+ redo(n?: number): Promise<void>;
20
+ /** wipe past and future snapshots */
21
+ wipe(): Promise<void>;
22
+ substrata<Sub extends Substate>(selector: Selector<S, Sub>): Substrata<S, Sub>;
23
+ }
@@ -0,0 +1,74 @@
1
+ import { Substrata } from "./substrata.js";
2
+ export class Chronstrata {
3
+ limit;
4
+ parent;
5
+ selector;
6
+ options;
7
+ #substrata;
8
+ constructor(limit, parent, selector, options) {
9
+ this.limit = limit;
10
+ this.parent = parent;
11
+ this.selector = selector;
12
+ this.options = options;
13
+ this.#substrata = parent.substrata(selector);
14
+ }
15
+ get state() {
16
+ return this.#substrata.state.present;
17
+ }
18
+ get undoable() {
19
+ return this.#substrata.state.past.length;
20
+ }
21
+ get redoable() {
22
+ return this.#substrata.state.future.length;
23
+ }
24
+ onMutation(fn) {
25
+ return this.#substrata.onMutation(chronicle => fn(chronicle.present));
26
+ }
27
+ /** progress forwards in history */
28
+ async mutate(mutator) {
29
+ const limit = Math.max(0, this.limit);
30
+ const snapshot = this.options.clone(this.#substrata.state.present);
31
+ await this.#substrata.mutate(chronicle => {
32
+ mutator(chronicle.present);
33
+ chronicle.past.push(snapshot);
34
+ chronicle.past = chronicle.past.slice(-limit);
35
+ chronicle.future = [];
36
+ });
37
+ return this.state;
38
+ }
39
+ /** step backwards into the past, by n steps */
40
+ async undo(n = 1) {
41
+ await this.#substrata.mutate(chronicle => {
42
+ const snapshots = chronicle.past.slice(-n);
43
+ if (snapshots.length >= n) {
44
+ const oldPresent = chronicle.present;
45
+ chronicle.present = snapshots.shift();
46
+ chronicle.past = chronicle.past.slice(0, -n);
47
+ chronicle.future.unshift(oldPresent, ...snapshots);
48
+ }
49
+ });
50
+ }
51
+ /** step forwards into the future, by n steps */
52
+ async redo(n = 1) {
53
+ await this.#substrata.mutate(chronicle => {
54
+ const snapshots = chronicle.future.slice(0, n);
55
+ if (snapshots.length >= n) {
56
+ const oldPresent = chronicle.present;
57
+ chronicle.present = snapshots.shift();
58
+ chronicle.past.push(oldPresent, ...snapshots);
59
+ chronicle.future = chronicle.future.slice(n);
60
+ }
61
+ });
62
+ }
63
+ /** wipe past and future snapshots */
64
+ async wipe() {
65
+ await this.#substrata.mutate(chronicle => {
66
+ chronicle.past = [];
67
+ chronicle.future = [];
68
+ });
69
+ }
70
+ substrata(selector) {
71
+ return new Substrata(this, selector, this.options);
72
+ }
73
+ }
74
+ //# sourceMappingURL=chronstrata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chronstrata.js","sourceRoot":"","sources":["../../s/parts/chronstrata.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AAGxC,MAAM,OAAO,WAAW;IAId;IACA;IACA;IACA;IANT,UAAU,CAAsC;IAEhD,YACS,KAAa,EACb,MAA4B,EAC5B,QAA6C,EAC7C,OAAgB;QAHhB,UAAK,GAAL,KAAK,CAAQ;QACb,WAAM,GAAN,MAAM,CAAsB;QAC5B,aAAQ,GAAR,QAAQ,CAAqC;QAC7C,YAAO,GAAP,OAAO,CAAS;QAExB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;IAC7C,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAA;IACrC,CAAC;IAED,IAAI,QAAQ;QACX,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAA;IACzC,CAAC;IAED,IAAI,QAAQ;QACX,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAA;IAC3C,CAAC;IAED,UAAU,CAAC,EAAsB;QAChC,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACtE,CAAC;IAED,mCAAmC;IACnC,KAAK,CAAC,MAAM,CAAC,OAAmB;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAClE,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;YACxC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YAC1B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC7B,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAA;YAC7C,SAAS,CAAC,MAAM,GAAG,EAAE,CAAA;QACtB,CAAC,CAAC,CAAA;QACF,OAAO,IAAI,CAAC,KAAK,CAAA;IAClB,CAAC;IAED,+CAA+C;IAC/C,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;QACf,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;YACxC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1C,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBAC3B,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAA;gBACpC,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,KAAK,EAAG,CAAA;gBACtC,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5C,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,SAAS,CAAC,CAAA;YACnD,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC;IAED,gDAAgD;IAChD,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;QACf,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;YACxC,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YAC9C,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBAC3B,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAA;gBACpC,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,KAAK,EAAG,CAAA;gBACtC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,SAAS,CAAC,CAAA;gBAC7C,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAC7C,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC;IAED,qCAAqC;IACrC,KAAK,CAAC,IAAI;QACT,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;YACxC,SAAS,CAAC,IAAI,GAAG,EAAE,CAAA;YACnB,SAAS,CAAC,MAAM,GAAG,EAAE,CAAA;QACtB,CAAC,CAAC,CAAA;IACH,CAAC;IAED,SAAS,CAAuB,QAA0B;QACzD,OAAO,IAAI,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IACnD,CAAC;CACD"}
@@ -1,10 +1,14 @@
1
1
  import { Substrata } from "./substrata.js";
2
- import { Mutator, Options, Selector, State, Substate } from "./types.js";
3
- export declare class Strata<S extends State> {
2
+ import { Chronstrata } from "./chronstrata.js";
3
+ import { Chronicle, Mutator, Options, Selector, State, Stratum, Substate } from "./types.js";
4
+ export declare class Strata<S extends State> implements Stratum<S> {
4
5
  #private;
6
+ static chronicle: <S_1 extends Substate>(state: S_1) => Chronicle<S_1>;
7
+ options: Options;
5
8
  onMutation: import("@e280/stz").Sub<[state: S]>;
6
9
  constructor(state: S, options?: Partial<Options>);
7
10
  get state(): S;
8
- substrata<Sub extends Substate>(selector: Selector<S, Sub>): Substrata<S, Sub>;
9
11
  mutate(mutator: Mutator<S>): Promise<S>;
12
+ substrata<Sub extends Substate>(selector: Selector<S, Sub>): Substrata<S, Sub>;
13
+ chronstrata<Sub extends Substate>(limit: number, selector: Selector<S, Chronicle<Sub>>): Chronstrata<S, Sub>;
10
14
  }
package/x/parts/strata.js CHANGED
@@ -1,30 +1,50 @@
1
1
  import { debounce, deep, sub } from "@e280/stz";
2
2
  import { Substrata } from "./substrata.js";
3
+ import { Chronstrata } from "./chronstrata.js";
3
4
  import { processOptions } from "./utils/process-options.js";
4
5
  export class Strata {
6
+ static chronicle = (state) => ({
7
+ present: state,
8
+ past: [],
9
+ future: [],
10
+ });
11
+ options;
5
12
  onMutation = sub();
6
- #options;
7
13
  #mutable;
8
14
  #immutable;
9
- #dispatchMutation = debounce(0, (state) => this.onMutation.pub(state));
15
+ #mutationLock = 0;
16
+ #dispatchMutation = debounce(0, async (state) => {
17
+ this.#mutationLock++;
18
+ try {
19
+ await this.onMutation.pub(state);
20
+ }
21
+ finally {
22
+ this.#mutationLock--;
23
+ }
24
+ });
10
25
  constructor(state, options = {}) {
11
- this.#options = processOptions(options);
26
+ this.options = processOptions(options);
12
27
  this.#mutable = state;
13
- this.#immutable = deep.freeze(this.#options.clone(state));
28
+ this.#immutable = deep.freeze(this.options.clone(state));
14
29
  }
15
30
  #updateState(state) {
16
31
  this.#mutable = state;
17
- this.#immutable = deep.freeze(this.#options.clone(state));
32
+ this.#immutable = deep.freeze(this.options.clone(state));
18
33
  }
19
34
  get state() {
20
35
  return this.#immutable;
21
36
  }
22
- substrata(selector) {
23
- return new Substrata(this, selector, this.#options);
24
- }
25
37
  async mutate(mutator) {
26
- const oldState = this.#options.clone(this.#mutable);
27
- mutator(this.#mutable);
38
+ const oldState = this.options.clone(this.#mutable);
39
+ if (this.#mutationLock > 0)
40
+ throw new Error("nested mutations are forbidden");
41
+ this.#mutationLock++;
42
+ try {
43
+ mutator(this.#mutable);
44
+ }
45
+ finally {
46
+ this.#mutationLock--;
47
+ }
28
48
  const newState = this.#mutable;
29
49
  const isChanged = !deep.equal(newState, oldState);
30
50
  if (isChanged) {
@@ -34,5 +54,11 @@ export class Strata {
34
54
  }
35
55
  return this.#immutable;
36
56
  }
57
+ substrata(selector) {
58
+ return new Substrata(this, selector, this.options);
59
+ }
60
+ chronstrata(limit, selector) {
61
+ return new Chronstrata(limit, this, selector, this.options);
62
+ }
37
63
  }
38
64
  //# sourceMappingURL=strata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"strata.js","sourceRoot":"","sources":["../../s/parts/strata.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAC,MAAM,WAAW,CAAA;AAE7C,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AACxC,OAAO,EAAC,cAAc,EAAC,MAAM,4BAA4B,CAAA;AAGzD,MAAM,OAAO,MAAM;IAClB,UAAU,GAAG,GAAG,EAAc,CAAA;IAE9B,QAAQ,CAAS;IACjB,QAAQ,CAAG;IACX,UAAU,CAAG;IACb,iBAAiB,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;IAEzE,YAAY,KAAQ,EAAE,UAA4B,EAAE;QACnD,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QACvC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1D,CAAC;IAED,YAAY,CAAC,KAAQ;QACpB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1D,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,UAAU,CAAA;IACvB,CAAC;IAED,SAAS,CAAuB,QAA0B;QACzD,OAAO,IAAI,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;IACpD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAmB;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACnD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC9B,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACjD,IAAI,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;YAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAA;YAC5B,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAA;QACxC,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAA;IACvB,CAAC;CACD"}
1
+ {"version":3,"file":"strata.js","sourceRoot":"","sources":["../../s/parts/strata.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,15 @@
1
- import { Strata } from "./strata.js";
2
- import { Mutator, Options, Selector, State, Substate } from "./types.js";
3
- export declare class Substrata<ParentState extends State, S extends Substate> {
1
+ import { Chronstrata } from "./chronstrata.js";
2
+ import { Chronicle, Mutator, Options, Selector, Stratum, Substate } from "./types.js";
3
+ export declare class Substrata<ParentState extends Substate, S extends Substate> implements Stratum<S> {
4
4
  #private;
5
- private strata;
5
+ private parent;
6
6
  private selector;
7
+ private options;
7
8
  dispose: () => void;
8
9
  onMutation: import("@e280/stz").Sub<[state: S]>;
9
- constructor(strata: Strata<ParentState>, selector: Selector<ParentState, S>, options?: Partial<Options>);
10
+ constructor(parent: Stratum<ParentState>, selector: Selector<ParentState, S>, options: Options);
10
11
  get state(): S;
11
12
  mutate(mutator: Mutator<S>): Promise<S>;
12
- substrata<Sub extends Substate>(selector: Selector<S, Sub>): Substrata<ParentState, Sub>;
13
+ substrata<Sub extends Substate>(selector: Selector<S, Sub>): Substrata<S, Sub>;
14
+ chronstrata<Sub extends Substate>(limit: number, selector: Selector<S, Chronicle<Sub>>): Chronstrata<S, Sub>;
13
15
  }
@@ -1,20 +1,20 @@
1
1
  import { debounce, deep, sub } from "@e280/stz";
2
- import { processOptions } from "./utils/process-options.js";
2
+ import { Chronstrata } from "./chronstrata.js";
3
3
  export class Substrata {
4
- strata;
4
+ parent;
5
5
  selector;
6
+ options;
6
7
  dispose;
7
8
  onMutation = sub();
8
- #options;
9
9
  #immutable;
10
10
  #dispatchMutation = debounce(0, (state) => this.onMutation.pub(state));
11
- constructor(strata, selector, options = {}) {
12
- this.strata = strata;
11
+ constructor(parent, selector, options) {
12
+ this.parent = parent;
13
13
  this.selector = selector;
14
- this.#options = processOptions(options);
15
- const state = this.selector(this.strata.state);
16
- this.#immutable = deep.freeze(this.#options.clone(state));
17
- this.dispose = this.strata.onMutation(async (parentState) => {
14
+ this.options = options;
15
+ const state = this.selector(this.parent.state);
16
+ this.#immutable = deep.freeze(this.options.clone(state));
17
+ this.dispose = this.parent.onMutation(async (parentState) => {
18
18
  const oldState = this.#immutable;
19
19
  const newState = this.selector(parentState);
20
20
  const isChanged = !deep.equal(newState, oldState);
@@ -26,17 +26,20 @@ export class Substrata {
26
26
  });
27
27
  }
28
28
  #updateState(state) {
29
- this.#immutable = deep.freeze(this.#options.clone(state));
29
+ this.#immutable = deep.freeze(this.options.clone(state));
30
30
  }
31
31
  get state() {
32
32
  return this.#immutable;
33
33
  }
34
34
  async mutate(mutator) {
35
- await this.strata.mutate(parentState => mutator(this.selector(parentState)));
35
+ await this.parent.mutate(parentState => mutator(this.selector(parentState)));
36
36
  return this.#immutable;
37
37
  }
38
38
  substrata(selector) {
39
- return this.strata.substrata(parentState => selector(this.selector(parentState)));
39
+ return new Substrata(this, selector, this.options);
40
+ }
41
+ chronstrata(limit, selector) {
42
+ return new Chronstrata(limit, this, selector, this.options);
40
43
  }
41
44
  }
42
45
  //# sourceMappingURL=substrata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"substrata.js","sourceRoot":"","sources":["../../s/parts/substrata.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAC,MAAM,WAAW,CAAA;AAG7C,OAAO,EAAC,cAAc,EAAC,MAAM,4BAA4B,CAAA;AAGzD,MAAM,OAAO,SAAS;IASX;IACA;IATV,OAAO,CAAY;IACnB,UAAU,GAAG,GAAG,EAAc,CAAA;IAE9B,QAAQ,CAAS;IACjB,UAAU,CAAG;IACb,iBAAiB,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;IAEzE,YACU,MAA2B,EAC3B,QAAkC,EAC1C,UAA4B,EAAE;QAFtB,WAAM,GAAN,MAAM,CAAqB;QAC3B,aAAQ,GAAR,QAAQ,CAA0B;QAI3C,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;QAEzD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAC,WAAW,EAAC,EAAE;YACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAA;YAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;YAC3C,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;YACjD,IAAI,SAAS,EAAE,CAAC;gBACf,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;gBAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAA;gBAC5B,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAA;YACxC,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC;IAED,YAAY,CAAC,KAAQ;QACpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1D,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,UAAU,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAmB;QAC/B,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QAC5E,OAAO,IAAI,CAAC,UAAU,CAAA;IACvB,CAAC;IAED,SAAS,CAAuB,QAA0B;QACzD,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;IAClF,CAAC;CACD"}
1
+ {"version":3,"file":"substrata.js","sourceRoot":"","sources":["../../s/parts/substrata.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAC,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAG5C,MAAM,OAAO,SAAS;IAQX;IACA;IACA;IATV,OAAO,CAAY;IACnB,UAAU,GAAG,GAAG,EAAc,CAAA;IAE9B,UAAU,CAAG;IACb,iBAAiB,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;IAEzE,YACU,MAA4B,EAC5B,QAAkC,EAClC,OAAgB;QAFhB,WAAM,GAAN,MAAM,CAAsB;QAC5B,aAAQ,GAAR,QAAQ,CAA0B;QAClC,YAAO,GAAP,OAAO,CAAS;QAGzB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;QAExD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAC,WAAW,EAAC,EAAE;YACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAA;YAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;YAC3C,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;YACjD,IAAI,SAAS,EAAE,CAAC;gBACf,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;gBAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAA;gBAC5B,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAA;YACxC,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC;IAED,YAAY,CAAC,KAAQ;QACpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IACzD,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,UAAU,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAmB;QAC/B,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QAC5E,OAAO,IAAI,CAAC,UAAU,CAAA;IACvB,CAAC;IAED,SAAS,CAAuB,QAA0B;QACzD,OAAO,IAAI,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IACnD,CAAC;IAED,WAAW,CACT,KAAa,EACb,QAAqC;QAEtC,OAAO,IAAI,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAC5D,CAAC;CACD"}
@@ -1,3 +1,4 @@
1
+ import { Substrata } from "./substrata.js";
1
2
  export type Options = {
2
3
  clone: <X>(x: X) => X;
3
4
  };
@@ -5,3 +6,14 @@ export type Selector<S, Sub> = (state: S) => Sub;
5
6
  export type Mutator<S> = (state: S) => void;
6
7
  export type State = {};
7
8
  export type Substate = {} | null | undefined;
9
+ export type Stratum<S extends Substate> = {
10
+ readonly state: S;
11
+ onMutation(fn: (s: S) => void): () => void;
12
+ mutate(mutator: Mutator<S>): Promise<S>;
13
+ substrata<Sub extends Substate>(selector: Selector<S, Sub>): Substrata<S, Sub>;
14
+ };
15
+ export type Chronicle<S extends Substate> = {
16
+ past: S[];
17
+ present: S;
18
+ future: S[];
19
+ };
package/x/tests.test.js CHANGED
@@ -18,6 +18,16 @@ await Science.run({
18
18
  await strata.mutate(state => state.count++);
19
19
  expect(strata.state.count).is(2);
20
20
  }),
21
+ "forbidden mutation nesting": Science.test(async () => {
22
+ const strata = new Strata({ count: 0 });
23
+ await expect(async () => {
24
+ let promise;
25
+ await strata.mutate(() => {
26
+ promise = strata.mutate(() => { });
27
+ });
28
+ await promise;
29
+ }).throwsAsync();
30
+ }),
21
31
  "state after mutation is frozen": Science.test(async () => {
22
32
  const strata = new Strata({ x: 1 });
23
33
  await strata.mutate(s => { s.x = 2; });
@@ -47,6 +57,20 @@ await Science.run({
47
57
  expect(mutationCount).is(1);
48
58
  expect(strata.state.items.length).is(3);
49
59
  }),
60
+ "prevent mutation loops": Science.test(async () => {
61
+ const strata = new Strata({ count: 0 });
62
+ let mutationCount = 0;
63
+ strata.onMutation.sub(async () => {
64
+ mutationCount++;
65
+ if (mutationCount > 100)
66
+ return;
67
+ await strata.mutate(s => s.count++);
68
+ });
69
+ await expect(async () => {
70
+ await strata.mutate(state => state.count++);
71
+ }).throwsAsync();
72
+ expect(mutationCount).is(1);
73
+ }),
50
74
  }),
51
75
  "substrata": Science.suite({
52
76
  "get state": Science.test(async () => {
@@ -101,6 +125,147 @@ await Science.run({
101
125
  await a.mutate(a => a.x = 1);
102
126
  expect(counted).is(0);
103
127
  }),
128
+ "forbid submutation in mutation": Science.test(async () => {
129
+ const strata = new Strata({ a: { b: 0 } });
130
+ const a = strata.substrata(s => s.a);
131
+ await expect(async () => {
132
+ let promise;
133
+ await strata.mutate(() => {
134
+ promise = a.mutate(() => { });
135
+ });
136
+ await promise;
137
+ }).throwsAsync();
138
+ }),
139
+ "forbid mutation in submutation": Science.test(async () => {
140
+ const strata = new Strata({ a: { b: 0 } });
141
+ const a = strata.substrata(s => s.a);
142
+ await expect(async () => {
143
+ let promise;
144
+ await a.mutate(() => {
145
+ promise = strata.mutate(() => { });
146
+ });
147
+ await promise;
148
+ }).throwsAsync();
149
+ }),
104
150
  }),
151
+ "chronstrata": (() => {
152
+ const setup = () => {
153
+ const strata = new Strata({
154
+ chron: Strata.chronicle({ count: 0 }),
155
+ });
156
+ const chron = strata.chronstrata(64, s => s.chron);
157
+ return { strata, chron };
158
+ };
159
+ return Science.suite({
160
+ "get state": Science.test(async () => {
161
+ const { chron } = setup();
162
+ expect(chron.state.count).is(0);
163
+ }),
164
+ "mutate": Science.test(async () => {
165
+ const { chron } = setup();
166
+ expect(chron.state.count).is(0);
167
+ await chron.mutate(s => s.count++);
168
+ expect(chron.state.count).is(1);
169
+ await chron.mutate(s => s.count++);
170
+ expect(chron.state.count).is(2);
171
+ }),
172
+ "undoable/redoable": Science.test(async () => {
173
+ const { chron } = setup();
174
+ expect(chron.undoable).is(0);
175
+ expect(chron.redoable).is(0);
176
+ expect(chron.state.count).is(0);
177
+ await chron.mutate(s => s.count++);
178
+ expect(chron.undoable).is(1);
179
+ await chron.mutate(s => s.count++);
180
+ expect(chron.undoable).is(2);
181
+ await chron.undo();
182
+ expect(chron.undoable).is(1);
183
+ expect(chron.redoable).is(1);
184
+ await chron.undo();
185
+ expect(chron.undoable).is(0);
186
+ expect(chron.redoable).is(2);
187
+ await chron.redo();
188
+ expect(chron.undoable).is(1);
189
+ expect(chron.redoable).is(1);
190
+ }),
191
+ "undo": Science.test(async () => {
192
+ const { chron } = setup();
193
+ await chron.mutate(s => s.count++);
194
+ await chron.undo();
195
+ expect(chron.state.count).is(0);
196
+ }),
197
+ "redo": Science.test(async () => {
198
+ const { chron } = setup();
199
+ await chron.mutate(s => s.count++);
200
+ await chron.undo();
201
+ expect(chron.state.count).is(0);
202
+ await chron.redo();
203
+ expect(chron.state.count).is(1);
204
+ }),
205
+ "undo/redo well ordered": Science.test(async () => {
206
+ const { chron } = setup();
207
+ await chron.mutate(s => s.count++);
208
+ await chron.mutate(s => s.count++);
209
+ await chron.mutate(s => s.count++);
210
+ expect(chron.state.count).is(3);
211
+ await chron.undo();
212
+ expect(chron.state.count).is(2);
213
+ await chron.undo();
214
+ expect(chron.state.count).is(1);
215
+ await chron.redo();
216
+ expect(chron.state.count).is(2);
217
+ await chron.redo();
218
+ expect(chron.state.count).is(3);
219
+ await chron.undo();
220
+ expect(chron.state.count).is(2);
221
+ await chron.undo();
222
+ expect(chron.state.count).is(1);
223
+ await chron.undo();
224
+ expect(chron.state.count).is(0);
225
+ }),
226
+ "undo nothing does nothing": Science.test(async () => {
227
+ const { chron } = setup();
228
+ await chron.undo();
229
+ expect(chron.state.count).is(0);
230
+ }),
231
+ "redo nothing does nothing": Science.test(async () => {
232
+ const { chron } = setup();
233
+ await chron.redo();
234
+ expect(chron.state.count).is(0);
235
+ }),
236
+ "undo 2x": Science.test(async () => {
237
+ const { chron } = setup();
238
+ await chron.mutate(s => s.count++);
239
+ await chron.mutate(s => s.count++);
240
+ expect(chron.state.count).is(2);
241
+ await chron.undo(2);
242
+ expect(chron.state.count).is(0);
243
+ }),
244
+ "redo 2x": Science.test(async () => {
245
+ const { chron } = setup();
246
+ await chron.mutate(s => s.count++);
247
+ await chron.mutate(s => s.count++);
248
+ expect(chron.state.count).is(2);
249
+ await chron.undo(2);
250
+ expect(chron.state.count).is(0);
251
+ await chron.redo(2);
252
+ expect(chron.state.count).is(2);
253
+ }),
254
+ "substrata mutations are tracked": Science.test(async () => {
255
+ const strata = new Strata({
256
+ chron: Strata.chronicle({
257
+ group: { count: 0 },
258
+ }),
259
+ });
260
+ const chron = strata.chronstrata(64, s => s.chron);
261
+ const group = chron.substrata(s => s.group);
262
+ expect(group.state.count).is(0);
263
+ await group.mutate(g => g.count = 101);
264
+ expect(group.state.count).is(101);
265
+ await chron.undo();
266
+ expect(group.state.count).is(0);
267
+ }),
268
+ });
269
+ })(),
105
270
  });
106
271
  //# sourceMappingURL=tests.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tests.test.js","sourceRoot":"","sources":["../s/tests.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAE,OAAO,EAAC,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAA;AAExC,MAAM,OAAO,CAAC,GAAG,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC;QACvB,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACnC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACjC,CAAC,CAAC;QAEF,oBAAoB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YAC5C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAA;QAC5C,CAAC,CAAC;QAEF,uBAAuB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YAC/C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YAC3C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YAC3C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACjC,CAAC,CAAC;QAEF,gCAAgC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACzD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,CAAC,EAAE,CAAC,EAAC,CAAC,CAAA;YACjC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;YACrC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAA;QAC1C,CAAC,CAAC;QAEF,yBAAyB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACjD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,IAAI,aAAa,GAAG,CAAC,CAAA;YACrB,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAE,aAAa,EAAE,CAAA,CAAA,CAAC,CAAC,CAAA;YAC9C,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YAC3C,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC,CAAC;QAEF,yBAAyB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACjD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,IAAI,aAAa,GAAG,CAAC,CAAA;YACrB,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAE,aAAa,EAAE,CAAA,CAAA,CAAC,CAAC,CAAA;YAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YACrD,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAC3B,MAAM,OAAO,CAAA;YACb,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC,CAAC;QAEF,+CAA+C,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACvE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAC,CAAC,CAAA;YACtD,IAAI,aAAa,GAAG,CAAC,CAAA;YACrB,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAE,aAAa,EAAE,CAAA,CAAA,CAAC,CAAC,CAAA;YAC9C,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;YACrD,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAC3B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACxC,CAAC,CAAC;KACF,CAAC;IAEF,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC;QAC1B,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACnC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAC,KAAK,EAAE,CAAC,EAAC,EAAC,CAAC,CAAA;YACtD,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;YAC9C,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACpC,CAAC,CAAC;QAEF,mBAAmB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAC5C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;gBACzB,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAA0B;aAClC,CAAC,CAAA;YACF,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxB,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAE,CAAC,CAAC,GAAG,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;YACjC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxB,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;YACpC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAA;YACvC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAA;QACjC,CAAC,CAAC;QAEF,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACtC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAC,EAAC,CAAC,CAAA;YAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACxB,CAAC,CAAC;QAEF,gBAAgB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACzC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAC,EAAC,CAAC,CAAA;YAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAA,CAAC,CAAC,CAAC,CAAA;YAClC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAClC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAC3B,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YACzB,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAC,CAAC,EAAE,GAAG,EAAC,CAAA,CAAC,CAAC,CAAC,CAAA;YACvC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAClC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAC3B,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YACzB,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,GAAG,EAAC,EAAC,CAAA,CAAC,CAAC,CAAC,CAAA;YACjD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAClC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAC3B,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;QAC1B,CAAC,CAAC;QAEF,sCAAsC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YAC9D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAE,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAC,CAAC,CAAA;YACjD,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,IAAI,OAAO,GAAG,CAAC,CAAA;YACf,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAE,OAAO,EAAE,CAAA,CAAA,CAAC,CAAC,CAAA;YACnC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5B,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACtB,CAAC,CAAC;KACF,CAAC;CACF,CAAC,CAAA"}
1
+ {"version":3,"file":"tests.test.js","sourceRoot":"","sources":["../s/tests.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAE,OAAO,EAAC,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAA;AAExC,MAAM,OAAO,CAAC,GAAG,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC;QACvB,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACnC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACjC,CAAC,CAAC;QAEF,oBAAoB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YAC5C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAA;QAC5C,CAAC,CAAC;QAEF,uBAAuB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YAC/C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YAC3C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YAC3C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACjC,CAAC,CAAC;QAEF,4BAA4B,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACpD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,MAAM,MAAM,CAAC,KAAK,IAAG,EAAE;gBACtB,IAAI,OAAsB,CAAA;gBAC1B,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;oBACxB,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gBAClC,CAAC,CAAC,CAAA;gBACF,MAAM,OAAO,CAAA;YACd,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QACjB,CAAC,CAAC;QAEF,gCAAgC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACzD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,CAAC,EAAE,CAAC,EAAC,CAAC,CAAA;YACjC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;YACrC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAA;QAC1C,CAAC,CAAC;QAEF,yBAAyB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACjD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,IAAI,aAAa,GAAG,CAAC,CAAA;YACrB,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAE,aAAa,EAAE,CAAA,CAAA,CAAC,CAAC,CAAA;YAC9C,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YAC3C,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC,CAAC;QAEF,yBAAyB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACjD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,IAAI,aAAa,GAAG,CAAC,CAAA;YACrB,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAE,aAAa,EAAE,CAAA,CAAA,CAAC,CAAC,CAAA;YAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YACrD,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAC3B,MAAM,OAAO,CAAA;YACb,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC,CAAC;QAEF,+CAA+C,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACvE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAC,CAAC,CAAA;YACtD,IAAI,aAAa,GAAG,CAAC,CAAA;YACrB,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAE,aAAa,EAAE,CAAA,CAAA,CAAC,CAAC,CAAA;YAC9C,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;YACrD,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAC3B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACxC,CAAC,CAAC;QAEF,wBAAwB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YAChD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC,CAAA;YACrC,IAAI,aAAa,GAAG,CAAC,CAAA;YACrB,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,IAAG,EAAE;gBAC/B,aAAa,EAAE,CAAA;gBACf,IAAI,aAAa,GAAG,GAAG;oBACtB,OAAM;gBACP,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;YACpC,CAAC,CAAC,CAAA;YACF,MAAM,MAAM,CAAC,KAAK,IAAG,EAAE;gBACtB,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YAC5C,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;YAChB,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC,CAAC;KACF,CAAC;IAEF,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC;QAC1B,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACnC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAC,KAAK,EAAE,CAAC,EAAC,EAAC,CAAC,CAAA;YACtD,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;YAC9C,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACpC,CAAC,CAAC;QAEF,mBAAmB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAC5C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;gBACzB,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAA0B;aAClC,CAAC,CAAA;YACF,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxB,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAE,CAAC,CAAC,GAAG,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;YACjC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxB,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;YACpC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAA;YACvC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAA;QACjC,CAAC,CAAC;QAEF,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACtC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAC,EAAC,CAAC,CAAA;YAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACxB,CAAC,CAAC;QAEF,gBAAgB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACzC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAC,EAAC,CAAC,CAAA;YAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAA,CAAC,CAAC,CAAC,CAAA;YAClC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAClC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAC3B,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YACzB,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAC,CAAC,EAAE,GAAG,EAAC,CAAA,CAAC,CAAC,CAAC,CAAA;YACvC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAClC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAC3B,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YACzB,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,GAAG,EAAC,EAAC,CAAA,CAAC,CAAC,CAAC,CAAA;YACjD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAClC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAC3B,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;QAC1B,CAAC,CAAC;QAEF,sCAAsC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YAC9D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAE,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAC,CAAC,CAAA;YACjD,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,IAAI,OAAO,GAAG,CAAC,CAAA;YACf,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAE,OAAO,EAAE,CAAA,CAAA,CAAC,CAAC,CAAA;YACnC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5B,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACtB,CAAC,CAAC;QAEF,gCAAgC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACxD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAC,CAAC,CAAA;YACtC,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,MAAM,CAAC,KAAK,IAAG,EAAE;gBACtB,IAAI,OAAsB,CAAA;gBAC1B,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;oBACxB,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gBAC7B,CAAC,CAAC,CAAA;gBACF,MAAM,OAAO,CAAA;YACd,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QACjB,CAAC,CAAC;QAEF,gCAAgC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;YACxD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAC,CAAC,CAAA;YACtC,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,MAAM,CAAC,KAAK,IAAG,EAAE;gBACtB,IAAI,OAAsB,CAAA;gBAC1B,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE;oBACnB,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gBAClC,CAAC,CAAC,CAAA;gBACF,MAAM,OAAO,CAAA;YACd,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QACjB,CAAC,CAAC;KACF,CAAC;IAEF,aAAa,EAAE,CAAC,GAAG,EAAE;QACpB,MAAM,KAAK,GAAG,GAAG,EAAE;YAClB,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;gBACzB,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,CAAC;aACnC,CAAC,CAAA;YACF,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;YAClD,OAAO,EAAC,MAAM,EAAE,KAAK,EAAC,CAAA;QACvB,CAAC,CAAA;QAED,OAAO,OAAO,CAAC,KAAK,CAAC;YACpB,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBACnC,MAAM,EAAC,KAAK,EAAC,GAAG,KAAK,EAAE,CAAA;gBACvB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,CAAC,CAAC;YAEF,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBAChC,MAAM,EAAC,KAAK,EAAC,GAAG,KAAK,EAAE,CAAA;gBACvB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC/B,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC/B,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,CAAC,CAAC;YAEF,mBAAmB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBAC3C,MAAM,EAAC,KAAK,EAAC,GAAG,KAAK,EAAE,CAAA;gBACvB,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC/B,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5B,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAC7B,CAAC,CAAC;YAEF,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBAC9B,MAAM,EAAC,KAAK,EAAC,GAAG,KAAK,EAAE,CAAA;gBACvB,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,CAAC,CAAC;YAEF,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBAC9B,MAAM,EAAC,KAAK,EAAC,GAAG,KAAK,EAAE,CAAA;gBACvB,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC/B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,CAAC,CAAC;YAEF,wBAAwB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBAChD,MAAM,EAAC,KAAK,EAAC,GAAG,KAAK,EAAE,CAAA;gBACvB,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAE/B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAE/B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAE/B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAE/B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAE/B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAE/B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAE/B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,CAAC,CAAC;YAEF,2BAA2B,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBACnD,MAAM,EAAC,KAAK,EAAC,GAAG,KAAK,EAAE,CAAA;gBACvB,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,CAAC,CAAC;YAEF,2BAA2B,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBACnD,MAAM,EAAC,KAAK,EAAC,GAAG,KAAK,EAAE,CAAA;gBACvB,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,CAAC,CAAC;YAEF,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBACjC,MAAM,EAAC,KAAK,EAAC,GAAG,KAAK,EAAE,CAAA;gBACvB,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC/B,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACnB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,CAAC,CAAC;YAEF,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBACjC,MAAM,EAAC,KAAK,EAAC,GAAG,KAAK,EAAE,CAAA;gBACvB,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC/B,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACnB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC/B,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACnB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,CAAC,CAAC;YAEF,iCAAiC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAG,EAAE;gBACzD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;oBACzB,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC;wBACvB,KAAK,EAAE,EAAC,KAAK,EAAE,CAAC,EAAC;qBACjB,CAAC;iBACF,CAAC,CAAA;gBACF,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;gBAClD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;gBAC3C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC/B,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAA;gBACtC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;gBACjC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChC,CAAC,CAAC;SACF,CAAC,CAAA;IACH,CAAC,CAAC,EAAE;CACJ,CAAC,CAAA"}