evg_observable 3.0.1 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,73 @@
1
+ #!/bin/bash
2
+ # scripts/claude-pr-prep.sh
3
+ # Run tests and generate a PR description for the current branch.
4
+ #
5
+ # Usage:
6
+ # ./scripts/claude-pr-prep.sh # auto-detect base branch
7
+ # ./scripts/claude-pr-prep.sh dev # explicit base branch
8
+
9
+ set -e
10
+
11
+ # Determine base branch
12
+ if [ -n "$1" ]; then
13
+ BASE="$1"
14
+ else
15
+ for branch in dev stage main master; do
16
+ if git rev-parse --verify "$branch" >/dev/null 2>&1; then
17
+ BASE="$branch"
18
+ break
19
+ fi
20
+ done
21
+ fi
22
+
23
+ if [ -z "$BASE" ]; then
24
+ echo "Error: no base branch found (tried: dev, stage, main, master)"
25
+ exit 1
26
+ fi
27
+
28
+ CURRENT=$(git branch --show-current)
29
+
30
+ echo "Preparing branch '$CURRENT' for PR into '$BASE'..."
31
+ echo ""
32
+
33
+ # Run tests
34
+ echo "=== Running tests ==="
35
+ TEST_OUTPUT=$(npm test 2>&1) || true
36
+ echo "$TEST_OUTPUT" | tail -5
37
+ echo ""
38
+
39
+ # Get commit log
40
+ COMMITS=$(git log "$BASE".."$CURRENT" --oneline 2>/dev/null)
41
+
42
+ if [ -z "$COMMITS" ]; then
43
+ echo "No commits between '$CURRENT' and '$BASE'. Nothing to prepare."
44
+ exit 0
45
+ fi
46
+
47
+ # Generate PR description
48
+ echo "=== Generating PR description ==="
49
+ echo ""
50
+
51
+ claude -p "Generate a pull request description for the EVG Observable library.
52
+
53
+ Branch: $CURRENT -> $BASE
54
+
55
+ Commits:
56
+ $COMMITS
57
+
58
+ Test results (last 5 lines):
59
+ $(echo "$TEST_OUTPUT" | tail -5)
60
+
61
+ Write a PR description in this format:
62
+ ## Summary
63
+ <2-4 bullet points describing what changed and why>
64
+
65
+ ## Changes
66
+ <list of key changes grouped by category>
67
+
68
+ ## Test plan
69
+ <what was tested, test results summary>
70
+
71
+ Be concise and specific to this library." \
72
+ --print \
73
+ --max-turns 3
@@ -0,0 +1,61 @@
1
+ #!/bin/bash
2
+ # scripts/claude-review-files.sh
3
+ # Review current branch changes against base branch using Claude headless mode.
4
+ # Checks: correctness, types, naming, resource cleanup, regression risk.
5
+ #
6
+ # Usage:
7
+ # ./scripts/claude-review-files.sh # auto-detect base branch
8
+ # ./scripts/claude-review-files.sh dev # explicit base branch
9
+
10
+ set -e
11
+
12
+ # Determine base branch
13
+ if [ -n "$1" ]; then
14
+ BASE="$1"
15
+ else
16
+ for branch in dev stage main master; do
17
+ if git rev-parse --verify "$branch" >/dev/null 2>&1; then
18
+ BASE="$branch"
19
+ break
20
+ fi
21
+ done
22
+ fi
23
+
24
+ if [ -z "$BASE" ]; then
25
+ echo "Error: no base branch found (tried: dev, stage, main, master)"
26
+ exit 1
27
+ fi
28
+
29
+ CURRENT=$(git branch --show-current)
30
+ DIFF=$(git diff "$BASE"..."$CURRENT" 2>/dev/null)
31
+
32
+ if [ -z "$DIFF" ]; then
33
+ echo "No changes between '$CURRENT' and '$BASE'. Nothing to review."
34
+ exit 0
35
+ fi
36
+
37
+ echo "Reviewing branch '$CURRENT' against '$BASE'..."
38
+ echo ""
39
+
40
+ claude -p "You are reviewing a code diff for the EVG Observable library.
41
+
42
+ Base branch: $BASE
43
+ Current branch: $CURRENT
44
+
45
+ Here is the diff:
46
+
47
+ $DIFF
48
+
49
+ Review this diff. For each changed file evaluate:
50
+ - **Correctness**: Does the code do what it should?
51
+ - **Edge cases**: Boundary conditions handled? (null, undefined, empty arrays)
52
+ - **Type safety**: Proper TypeScript types, no unnecessary \`any\`
53
+ - **Naming**: PascalCase classes, camelCase methods, \`I\` prefix for interfaces, \`\$\` suffix for observables
54
+ - **Style**: 2-space indent, JSDoc on public methods
55
+ - **Resource cleanup**: Are subscriptions cleaned up? destroy()/unsubscribe() where needed?
56
+ - **Regression risk**: Could this break existing behavior?
57
+
58
+ Output a table of issues found with severity (critical/major/minor), file, line, and description.
59
+ If no issues found, say so. Be specific and concise." \
60
+ --print \
61
+ --max-turns 5
@@ -0,0 +1,42 @@
1
+ export type ICallback<T> = (value?: T) => any;
2
+ export type IErrorCallback = (errorData: any, errorMessage: any) => void;
3
+ export type IListener<T> = ICallback<T>;
4
+ export type IDestroy = {
5
+ destroy(): void;
6
+ isDestroyed: boolean;
7
+ };
8
+ export type IOrder = {
9
+ order: number;
10
+ };
11
+ export type ISetObservableValue = {
12
+ next(value: any): void;
13
+ };
14
+ export type IPause = {
15
+ pause(): void;
16
+ resume(): void;
17
+ };
18
+ export type ISubscribeCounter = {
19
+ size(): number;
20
+ };
21
+ export type IStream<T> = {
22
+ of(value: T[]): void;
23
+ };
24
+ export type ISend<T> = {
25
+ send(value: T): void;
26
+ };
27
+ export type IChainContainer = {
28
+ chain: any[];
29
+ };
30
+ export type IPipePayload = {
31
+ isBreak: boolean;
32
+ isUnsubscribe: boolean;
33
+ isAvailable: boolean;
34
+ debounceMs: number;
35
+ debounceTimer: any;
36
+ debounceValue: any;
37
+ debounceIndex: number;
38
+ payload: any;
39
+ };
40
+ export type IChainCallback = (data: IPipePayload) => void;
41
+ export type ICombinedSubscriber<T> = IListener<T> | ISetObservableValue;
42
+ export type ISubscribeGroup<T> = ICombinedSubscriber<T> | ICombinedSubscriber<T>[];
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -15,7 +15,8 @@ class FilterCollection {
15
15
  return this;
16
16
  }
17
17
  and(condition) {
18
- return this.push((data) => condition(data.payload) && (data.isAvailable = true));
18
+ return this.push((data) => { if (condition(data.payload))
19
+ data.isAvailable = true; });
19
20
  }
20
21
  allOf(conditions) {
21
22
  if (!Array.isArray(conditions))
@@ -0,0 +1,27 @@
1
+ import { FilterSwitchCase } from "./FilterCollection";
2
+ import { ICallback } from "./CoreTypes";
3
+ export type IFilterPayload = {
4
+ isBreak: boolean;
5
+ isAvailable: boolean;
6
+ payload: any;
7
+ };
8
+ export type IFilterChainCallback = (data: IFilterPayload) => void;
9
+ export type IFilterResponse = {
10
+ isOK: boolean;
11
+ payload: any;
12
+ };
13
+ export type IFilter<T> = {
14
+ and(condition: ICallback<any>): IFilterSetup<T>;
15
+ allOf(conditions: ICallback<any>[]): IFilterSetup<T>;
16
+ };
17
+ export type IFilterSetup<T> = IFilter<T> & IFilterSwitch<T>;
18
+ export type IFilterSwitch<T> = {
19
+ choice(): FilterSwitchCase<T>;
20
+ };
21
+ export type IFilterCase<T> = {
22
+ or(condition: ICallback<any>): IFilterCase<T>;
23
+ anyOf(conditions: ICallback<any>[]): IFilterCase<T>;
24
+ };
25
+ export type IAddFilter<T> = {
26
+ addFilter(): IFilterSetup<T>;
27
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -36,11 +36,12 @@ function quickDeleteFromArray(arr, component) {
36
36
  }
37
37
  function getListener(listenerGroup) {
38
38
  if (Array.isArray(listenerGroup)) {
39
- const group = [];
40
- for (let i = 0; i < listenerGroup.length; i++)
41
- group.push(wrapListener(listenerGroup[i]));
39
+ const len = listenerGroup.length;
40
+ const group = new Array(len);
41
+ for (let i = 0; i < len; i++)
42
+ group[i] = wrapListener(listenerGroup[i]);
42
43
  return (data) => {
43
- for (let i = 0; i < group.length; i++)
44
+ for (let i = 0; i < len; i++)
44
45
  group[i](data);
45
46
  };
46
47
  }
@@ -8,7 +8,7 @@ export declare class Observable<T> implements IObserver<T>, IStream<T>, IAddFilt
8
8
  protected process: boolean;
9
9
  protected trash: ISubscriptionLike[];
10
10
  protected filters: FilterCollection<T>;
11
- protected _value: T;
11
+ protected _value: T | null;
12
12
  constructor(value: T);
13
13
  addFilter(errorHandler?: IErrorCallback): IFilterSetup<T>;
14
14
  disable(): void;
@@ -21,6 +21,7 @@ export declare class Observable<T> implements IObserver<T>, IStream<T>, IAddFilt
21
21
  unSubscribe(listener: ISubscriptionLike): void;
22
22
  destroy(): void;
23
23
  unsubscribeAll(): void;
24
+ protected clearDebounceTimers(): void;
24
25
  getValue(): T | undefined;
25
26
  size(): number;
26
27
  subscribe(observer: ISubscribeGroup<T>, errorHandler?: IErrorCallback): ISubscriptionLike | undefined;
@@ -45,6 +45,12 @@ class Observable {
45
45
  for (let i = 0; i < len; i++)
46
46
  subs[i].send(value);
47
47
  this.process = false;
48
+ if (this.killed) {
49
+ this.clearDebounceTimers();
50
+ this._value = null;
51
+ this.subs.length = 0;
52
+ return;
53
+ }
48
54
  this.trash.length && this.clearTrash();
49
55
  }
50
56
  of(values) {
@@ -86,26 +92,29 @@ class Observable {
86
92
  return;
87
93
  this.killed = true;
88
94
  if (!this.process) {
95
+ this.clearDebounceTimers();
89
96
  this._value = null;
90
97
  this.subs.length = 0;
91
- return;
92
98
  }
93
- Promise.resolve().then(() => {
94
- this._value = null;
95
- this.subs.length = 0;
96
- });
97
99
  }
98
100
  unsubscribeAll() {
99
101
  if (this.killed)
100
102
  return;
101
103
  if (this.process) {
104
+ this.clearDebounceTimers();
102
105
  const subs = this.subs;
103
106
  for (let i = 0; i < subs.length; i++)
104
107
  this.trash.push(subs[i]);
105
108
  return;
106
109
  }
110
+ this.clearDebounceTimers();
107
111
  this.subs.length = 0;
108
112
  }
113
+ clearDebounceTimers() {
114
+ const subs = this.subs;
115
+ for (let i = 0; i < subs.length; i++)
116
+ clearTimeout(subs[i].flow.debounceTimer);
117
+ }
109
118
  getValue() {
110
119
  if (this.killed)
111
120
  return undefined;
@@ -7,4 +7,7 @@ export declare class OrderedSubscribeObject<T> extends SubscribeObject<T> implem
7
7
  set order(value: number);
8
8
  subscribe(observer: IListener<T> | ISetObservableValue, errorHandler?: IErrorCallback): IOrderedSubscriptionLike;
9
9
  once(): IOrderedSubscribe<T>;
10
+ take(n: number): IOrderedSubscribe<T>;
11
+ skip(n: number): IOrderedSetup<T>;
12
+ scan<K>(fn: (accumulator: K, value: T) => K, seed: K): IOrderedSetup<K>;
10
13
  }
@@ -25,5 +25,14 @@ class OrderedSubscribeObject extends SubscribeObject_1.SubscribeObject {
25
25
  once() {
26
26
  return super.once();
27
27
  }
28
+ take(n) {
29
+ return super.take(n);
30
+ }
31
+ skip(n) {
32
+ return super.skip(n);
33
+ }
34
+ scan(fn, seed) {
35
+ return super.scan(fn, seed);
36
+ }
28
37
  }
29
38
  exports.OrderedSubscribeObject = OrderedSubscribeObject;
@@ -6,15 +6,22 @@ export declare abstract class Pipe<T> implements ISubscribe<T> {
6
6
  abstract subscribe(listener: IListener<T> | ISetObservableValue, errorHandler?: IErrorCallback): ISubscriptionLike | undefined;
7
7
  private push;
8
8
  once(): ISubscribe<T>;
9
+ take(n: number): ISubscribe<T>;
10
+ skip(n: number): ISetup<T>;
9
11
  unsubscribeBy(condition: ICallback<T>): ISetup<T>;
10
12
  and(condition: ICallback<T>): ISetup<T>;
11
13
  allOf(conditions: ICallback<any>[]): ISetup<T>;
12
14
  choice(): PipeSwitchCase<T>;
13
15
  map<K>(condition: ICallback<T>): ISetup<K>;
16
+ scan<K>(fn: (accumulator: K, value: T) => K, seed: K): ISetup<K>;
17
+ tap(fn: ICallback<T>): ISetup<T>;
18
+ throttle(ms: number): ISetup<T>;
19
+ debounce(ms: number): ISetup<T>;
20
+ distinctUntilChanged(comparator?: (previous: T, current: T) => boolean): ISetup<T>;
14
21
  toJson(): ISetup<string>;
15
22
  fromJson<K>(): ISetup<K>;
16
23
  group(): IGroupSubscription<T>;
17
- processChain(listener: IListener<T>): void;
24
+ processChain(listener?: IListener<T>): void;
18
25
  }
19
26
  export declare class PipeSwitchCase<T> extends SwitchCase<T, Pipe<T>, IPipeCase<T>> implements ISubscribe<T> {
20
27
  subscribe(listener: IListener<T> | ISetObservableValue, errorHandler?: IErrorCallback): ISubscriptionLike | undefined;
@@ -4,7 +4,16 @@ exports.PipeSwitchCase = exports.Pipe = void 0;
4
4
  const AbstractSwitchCase_1 = require("./AbstractSwitchCase");
5
5
  class Pipe {
6
6
  chain = [];
7
- flow = { isBreak: false, isUnsubscribe: false, isAvailable: false, payload: null };
7
+ flow = {
8
+ isBreak: false,
9
+ isUnsubscribe: false,
10
+ isAvailable: false,
11
+ debounceMs: 0,
12
+ debounceTimer: 0,
13
+ debounceValue: undefined,
14
+ debounceIndex: 0,
15
+ payload: null
16
+ };
8
17
  push(callback) {
9
18
  this.chain.push(callback);
10
19
  return this;
@@ -15,6 +24,33 @@ class Pipe {
15
24
  data.isUnsubscribe = true;
16
25
  });
17
26
  }
27
+ take(n) {
28
+ if (n < 0)
29
+ n = 0;
30
+ let count = 0;
31
+ return this.push((data) => {
32
+ if (count >= n) {
33
+ data.isUnsubscribe = true;
34
+ return;
35
+ }
36
+ count++;
37
+ this.listener(data.payload);
38
+ if (count >= n)
39
+ data.isUnsubscribe = true;
40
+ });
41
+ }
42
+ skip(n) {
43
+ if (n < 0)
44
+ n = 0;
45
+ let count = 0;
46
+ return this.push((data) => {
47
+ if (count < n) {
48
+ count++;
49
+ return;
50
+ }
51
+ data.isAvailable = true;
52
+ });
53
+ }
18
54
  unsubscribeBy(condition) {
19
55
  return this.push((data) => {
20
56
  data.isAvailable = true;
@@ -23,7 +59,8 @@ class Pipe {
23
59
  });
24
60
  }
25
61
  and(condition) {
26
- return this.push((data) => condition(data.payload) && (data.isAvailable = true));
62
+ return this.push((data) => { if (condition(data.payload))
63
+ data.isAvailable = true; });
27
64
  }
28
65
  allOf(conditions) {
29
66
  if (!Array.isArray(conditions))
@@ -41,6 +78,53 @@ class Pipe {
41
78
  data.isAvailable = true;
42
79
  });
43
80
  }
81
+ scan(fn, seed) {
82
+ let accumulator = seed;
83
+ return this.push((data) => {
84
+ accumulator = fn(accumulator, data.payload);
85
+ data.payload = accumulator;
86
+ data.isAvailable = true;
87
+ });
88
+ }
89
+ tap(fn) {
90
+ return this.push((data) => {
91
+ fn(data.payload);
92
+ data.isAvailable = true;
93
+ });
94
+ }
95
+ throttle(ms) {
96
+ let lastEmitTime = 0;
97
+ return this.push((data) => {
98
+ const now = Date.now();
99
+ if (now - lastEmitTime >= ms) {
100
+ lastEmitTime = now;
101
+ data.isAvailable = true;
102
+ }
103
+ });
104
+ }
105
+ debounce(ms) {
106
+ return this.push((data) => {
107
+ data.isAvailable = true;
108
+ data.debounceMs = ms;
109
+ });
110
+ }
111
+ distinctUntilChanged(comparator) {
112
+ let hasPrevious = false;
113
+ let previousValue;
114
+ return this.push((data) => {
115
+ const current = data.payload;
116
+ if (hasPrevious) {
117
+ const isSame = comparator
118
+ ? comparator(previousValue, current)
119
+ : previousValue === current;
120
+ if (isSame)
121
+ return;
122
+ }
123
+ hasPrevious = true;
124
+ previousValue = current;
125
+ data.isAvailable = true;
126
+ });
127
+ }
44
128
  toJson() {
45
129
  return this.push((data) => {
46
130
  data.payload = JSON.stringify(data.payload);
@@ -63,15 +147,51 @@ class Pipe {
63
147
  for (let i = 0; i < len; i++) {
64
148
  data.isUnsubscribe = false;
65
149
  data.isAvailable = false;
150
+ data.debounceMs = 0;
66
151
  chain[i](data);
67
152
  if (data.isUnsubscribe)
68
153
  return this.unsubscribe();
154
+ if (data.debounceMs > 0) {
155
+ data.debounceValue = data.payload;
156
+ data.debounceIndex = i + 1;
157
+ const continueChain = () => {
158
+ data.debounceTimer = 0;
159
+ data.payload = data.debounceValue;
160
+ data.isBreak = false;
161
+ for (let j = data.debounceIndex; j < len; j++) {
162
+ data.isUnsubscribe = false;
163
+ data.isAvailable = false;
164
+ data.debounceMs = 0;
165
+ chain[j](data);
166
+ if (data.isUnsubscribe)
167
+ return this.unsubscribe();
168
+ if (data.debounceMs > 0) {
169
+ data.debounceValue = data.payload;
170
+ data.debounceIndex = j + 1;
171
+ clearTimeout(data.debounceTimer);
172
+ data.debounceTimer = setTimeout(continueChain, data.debounceMs);
173
+ return;
174
+ }
175
+ if (!data.isAvailable)
176
+ return;
177
+ if (data.isBreak)
178
+ break;
179
+ }
180
+ if (listener)
181
+ listener(data.payload);
182
+ };
183
+ clearTimeout(data.debounceTimer);
184
+ data.debounceTimer = setTimeout(continueChain, data.debounceMs);
185
+ return;
186
+ }
69
187
  if (!data.isAvailable)
70
188
  return;
71
189
  if (data.isBreak)
72
190
  break;
73
191
  }
74
- return listener(data.payload);
192
+ data.isAvailable = true;
193
+ if (listener)
194
+ listener(data.payload);
75
195
  }
76
196
  }
77
197
  exports.Pipe = Pipe;
@@ -0,0 +1,77 @@
1
+ import { PipeSwitchCase } from "./Pipe";
2
+ import { ICallback, IPause, IOrder, ISend } from "./CoreTypes";
3
+ import { ISubscribe, IOrderedSubscribe, ISubscriptionLike, IGroupSubscription } from "./SubscriptionTypes";
4
+ export type ISwitch<T> = {
5
+ choice(): PipeSwitchCase<T>;
6
+ };
7
+ export type IGroup<T> = {
8
+ group(): IGroupSubscription<T>;
9
+ };
10
+ export type IOrderedGroup<T> = {
11
+ group(): IGroupSubscription<T>;
12
+ };
13
+ export type IOnce<T> = {
14
+ once(): ISubscribe<T>;
15
+ };
16
+ export type IOrderedOnce<T> = {
17
+ once(): IOrderedSubscribe<T>;
18
+ };
19
+ export type ITake<T> = {
20
+ take(n: number): ISubscribe<T>;
21
+ };
22
+ export type IOrderedTake<T> = {
23
+ take(n: number): IOrderedSubscribe<T>;
24
+ };
25
+ export type ISkip<T> = {
26
+ skip(n: number): ISetup<T>;
27
+ };
28
+ export type IOrderedSkip<T> = {
29
+ skip(n: number): IOrderedSetup<T>;
30
+ };
31
+ export type IScan<T> = {
32
+ scan<K>(fn: (accumulator: K, value: T) => K, seed: K): ISetup<K>;
33
+ };
34
+ export type IOrderedScan<T> = {
35
+ scan<K>(fn: (accumulator: K, value: T) => K, seed: K): IOrderedSetup<K>;
36
+ };
37
+ export type IUnsubscribeByPositive<T> = {
38
+ unsubscribeBy(condition: ICallback<T>): ISetup<T>;
39
+ };
40
+ export type IOrderedUnsubscribeByPositive<T> = {
41
+ unsubscribeBy(condition: ICallback<T>): ISetup<T>;
42
+ };
43
+ export type IEmitByPositive<T> = {
44
+ and(condition: ICallback<T>): ISetup<T>;
45
+ allOf(conditions: ICallback<T>[]): ISetup<T>;
46
+ };
47
+ export type IOrderedEmitByPositive<T> = {
48
+ and(condition: ICallback<any>): ISetup<T>;
49
+ allOf(conditions: ICallback<any>[]): ISetup<T>;
50
+ };
51
+ export type ITransform<T> = {
52
+ map<K>(condition: ICallback<T>): ISetup<K>;
53
+ };
54
+ export type IThrottle<T> = {
55
+ throttle(ms: number): ISetup<T>;
56
+ };
57
+ export type IDebounce<T> = {
58
+ debounce(ms: number): ISetup<T>;
59
+ };
60
+ export type IDistinctUntilChanged<T> = {
61
+ distinctUntilChanged(comparator?: (previous: T, current: T) => boolean): ISetup<T>;
62
+ };
63
+ export type ITap<T> = {
64
+ tap(fn: ICallback<T>): ISetup<T>;
65
+ };
66
+ export type ISerialisation = {
67
+ toJson(): ISetup<string>;
68
+ fromJson<K>(): ISetup<K>;
69
+ };
70
+ export type ISetup<T> = IUnsubscribeByPositive<T> & IEmitByPositive<T> & IOnce<T> & ITake<T> & ISkip<T> & IScan<T> & ISwitch<T> & ITransform<T> & IThrottle<T> & IDebounce<T> & IDistinctUntilChanged<T> & ITap<T> & ISerialisation & IGroup<T> & ISubscribe<T>;
71
+ export type IOrderedSetup<T> = IOrderedUnsubscribeByPositive<T> & IOrderedEmitByPositive<T> & IOrderedOnce<T> & IOrderedTake<T> & IOrderedSkip<T> & IOrderedScan<T> & ISwitch<T> & ITransform<T> & IThrottle<T> & IDebounce<T> & IDistinctUntilChanged<T> & ITap<T> & ISerialisation & IOrderedGroup<T> & IOrderedSubscribe<T>;
72
+ export type ISubscribeObject<T> = ISubscriptionLike & IPause & IOrder & ISend<T> & ISetup<T>;
73
+ export type IPipeCase<T> = ISubscribe<T> & {
74
+ or(condition: ICallback<any>): IPipeCase<T> & ISubscribe<T>;
75
+ anyOf(conditions: ICallback<any>[]): IPipeCase<T> & ISubscribe<T>;
76
+ group(): IGroupSubscription<T>;
77
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });