@ngstato/angular 0.1.2 → 0.1.3

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,345 @@
1
+ import { Component, signal, inject } from '@angular/core';
2
+ import { devTools } from '@ngstato/core';
3
+ import { STATO_CONFIG } from './provide-ngstato';
4
+ import { JsonPipe } from '@angular/common';
5
+ import * as i0 from "@angular/core";
6
+ export class StatoDevToolsComponent {
7
+ config = inject(STATO_CONFIG, { optional: true });
8
+ unsub;
9
+ // State UI
10
+ isOpen = signal(false);
11
+ isMinimized = signal(false);
12
+ activeTab = signal('actions');
13
+ logs = signal([]);
14
+ selectedLog = signal(null);
15
+ // Position et taille
16
+ posX = signal(24);
17
+ posY = signal(window.innerHeight - 500);
18
+ panelWidth = signal(420);
19
+ panelHeight = signal(460);
20
+ // Drag state
21
+ isDragging = false;
22
+ isResizing = false;
23
+ dragOffsetX = 0;
24
+ dragOffsetY = 0;
25
+ startW = 0;
26
+ startH = 0;
27
+ startX = 0;
28
+ startY = 0;
29
+ // Bound listeners
30
+ boundMouseMove = this.onMouseMove.bind(this);
31
+ boundMouseUp = this.onMouseUp.bind(this);
32
+ ngOnInit() {
33
+ this.unsub = devTools.subscribe((state) => {
34
+ this.logs.set(state.logs);
35
+ this.isOpen.set(state.isOpen);
36
+ });
37
+ document.addEventListener('mousemove', this.boundMouseMove);
38
+ document.addEventListener('mouseup', this.boundMouseUp);
39
+ }
40
+ ngOnDestroy() {
41
+ this.unsub?.();
42
+ document.removeEventListener('mousemove', this.boundMouseMove);
43
+ document.removeEventListener('mouseup', this.boundMouseUp);
44
+ }
45
+ // ── Toggle ─────────────────────────────────────────
46
+ toggle() { devTools.toggle(); }
47
+ toggleMinimize() { this.isMinimized.update(v => !v); }
48
+ clear() { devTools.clear(); this.selectedLog.set(null); }
49
+ selectLog(log) {
50
+ this.selectedLog.set(this.selectedLog()?.id === log.id ? null : log);
51
+ }
52
+ formatTime(iso) {
53
+ return new Date(iso).toTimeString().slice(0, 8);
54
+ }
55
+ // ── Drag ───────────────────────────────────────────
56
+ onDragStart(e) {
57
+ if (e.target.classList.contains('btn-icon'))
58
+ return;
59
+ this.isDragging = true;
60
+ this.dragOffsetX = e.clientX - this.posX();
61
+ this.dragOffsetY = e.clientY - this.posY();
62
+ e.preventDefault();
63
+ }
64
+ // ── Resize ─────────────────────────────────────────
65
+ onResizeStart(e) {
66
+ this.isResizing = true;
67
+ this.startW = this.panelWidth();
68
+ this.startH = this.panelHeight();
69
+ this.startX = e.clientX;
70
+ this.startY = e.clientY;
71
+ e.preventDefault();
72
+ e.stopPropagation();
73
+ }
74
+ // ── Mouse Move ─────────────────────────────────────
75
+ onMouseMove(e) {
76
+ if (this.isDragging) {
77
+ this.posX.set(Math.max(0, e.clientX - this.dragOffsetX));
78
+ this.posY.set(Math.max(0, e.clientY - this.dragOffsetY));
79
+ }
80
+ if (this.isResizing) {
81
+ const newW = Math.max(300, this.startW + e.clientX - this.startX);
82
+ const newH = Math.max(200, this.startH + e.clientY - this.startY);
83
+ this.panelWidth.set(newW);
84
+ this.panelHeight.set(newH);
85
+ }
86
+ }
87
+ // ── Mouse Up ───────────────────────────────────────
88
+ onMouseUp() {
89
+ this.isDragging = false;
90
+ this.isResizing = false;
91
+ }
92
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StatoDevToolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
93
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: StatoDevToolsComponent, isStandalone: true, selector: "ngstato-devtools", ngImport: i0, template: `
94
+ <!-- Bouton flottant -->
95
+ @if (!isOpen()) {
96
+ <button class="devtools-fab" (click)="toggle()">
97
+ 🛠 Stato
98
+ </button>
99
+ }
100
+
101
+ <!-- Panel -->
102
+ @if (isOpen()) {
103
+ <div
104
+ class="devtools-panel"
105
+ [class.devtools-panel--minimized]="isMinimized()"
106
+ [style.left.px]="posX()"
107
+ [style.top.px]="posY()"
108
+ [style.width.px]="isMinimized() ? 200 : panelWidth()"
109
+ [style.height]="isMinimized() ? 'auto' : panelHeight() + 'px'"
110
+ >
111
+
112
+ <!-- Header — draggable -->
113
+ <div
114
+ class="devtools-header"
115
+ (mousedown)="onDragStart($event)"
116
+ >
117
+ <span class="devtools-title">🛠 Stato</span>
118
+ <div class="devtools-header-actions">
119
+ @if (!isMinimized()) {
120
+ <button class="btn-icon" (click)="clear()" title="Vider">🗑</button>
121
+ }
122
+ <button class="btn-icon" (click)="toggleMinimize()" title="Minimiser/Agrandir">
123
+ {{ isMinimized() ? '▲' : '▼' }}
124
+ </button>
125
+ <button class="btn-icon" (click)="toggle()" title="Fermer">✕</button>
126
+ </div>
127
+ </div>
128
+
129
+ <!-- Resize handle — coin bas droite -->
130
+ @if (!isMinimized()) {
131
+ <div
132
+ class="devtools-resize"
133
+ (mousedown)="onResizeStart($event)"
134
+ >⊿</div>
135
+ }
136
+
137
+ @if (!isMinimized()) {
138
+
139
+ <!-- Tabs -->
140
+ <div class="devtools-tabs">
141
+ <button
142
+ class="tab"
143
+ [class.tab--active]="activeTab() === 'actions'"
144
+ (click)="activeTab.set('actions')"
145
+ >
146
+ Actions ({{ logs().length }})
147
+ </button>
148
+ <button
149
+ class="tab"
150
+ [class.tab--active]="activeTab() === 'state'"
151
+ (click)="activeTab.set('state')"
152
+ >
153
+ State
154
+ </button>
155
+ </div>
156
+
157
+ <!-- Tab Actions -->
158
+ @if (activeTab() === 'actions') {
159
+ <div class="devtools-content">
160
+ @if (!logs().length) {
161
+ <div class="devtools-empty">Aucune action pour l'instant</div>
162
+ }
163
+ @for (log of logs(); track log.id) {
164
+ <div
165
+ class="log-item"
166
+ [class.log-item--error]="log.status === 'error'"
167
+ (click)="selectLog(log)"
168
+ >
169
+ <div class="log-item__left">
170
+ <span class="log-status">{{ log.status === 'success' ? '✓' : '✗' }}</span>
171
+ <span class="log-name">{{ log.name }}</span>
172
+ </div>
173
+ <div class="log-item__right">
174
+ @if (log.status === 'error') {
175
+ <span class="log-error-badge">erreur</span>
176
+ } @else {
177
+ <span class="log-duration">{{ log.duration }}ms</span>
178
+ }
179
+ <span class="log-time">{{ formatTime(log.at) }}</span>
180
+ </div>
181
+ </div>
182
+
183
+ @if (selectedLog()?.id === log.id) {
184
+ <div class="log-detail">
185
+ @if (log.error) {
186
+ <div class="log-detail__error">{{ log.error }}</div>
187
+ }
188
+ <div class="log-detail__section">
189
+ <span class="log-detail__label">Avant</span>
190
+ <pre>{{ log.prevState | json }}</pre>
191
+ </div>
192
+ <div class="log-detail__section">
193
+ <span class="log-detail__label">Après</span>
194
+ <pre>{{ log.nextState | json }}</pre>
195
+ </div>
196
+ </div>
197
+ }
198
+ }
199
+ </div>
200
+ }
201
+
202
+ <!-- Tab State -->
203
+ @if (activeTab() === 'state') {
204
+ <div class="devtools-content">
205
+ @if (logs().length) {
206
+ <pre class="state-view">{{ logs()[0].nextState | json }}</pre>
207
+ } @else {
208
+ <div class="devtools-empty">Aucun state disponible</div>
209
+ }
210
+ </div>
211
+ }
212
+ }
213
+
214
+ </div>
215
+ }
216
+ `, isInline: true, styles: [".devtools-fab{position:fixed;bottom:1.5rem;left:1.5rem;background:#1e293b;color:#fff;border:none;border-radius:999px;padding:.5rem 1rem;font-size:.85rem;font-weight:600;cursor:pointer;z-index:9999;box-shadow:0 4px 12px #0000004d;transition:background .15s}.devtools-fab:hover{background:#334155}.devtools-panel{position:fixed;background:#0f172a;border-radius:12px;box-shadow:0 8px 32px #0006;z-index:9999;display:flex;flex-direction:column;overflow:hidden;font-family:Courier New,monospace;min-width:200px;min-height:40px}.devtools-panel--minimized{border-radius:8px}.devtools-header{display:flex;justify-content:space-between;align-items:center;padding:.6rem .75rem;background:#1e293b;border-bottom:1px solid #334155;cursor:grab;-webkit-user-select:none;user-select:none}.devtools-header:active{cursor:grabbing}.devtools-title{color:#e2e8f0;font-size:.82rem;font-weight:600;font-family:system-ui}.devtools-header-actions{display:flex;gap:.25rem}.btn-icon{background:transparent;color:#64748b;border:none;cursor:pointer;font-size:.8rem;padding:.15rem .35rem;border-radius:4px;line-height:1}.btn-icon:hover{background:#334155;color:#fff}.devtools-resize{position:absolute;bottom:2px;right:4px;color:#334155;font-size:.9rem;cursor:nwse-resize;-webkit-user-select:none;user-select:none;line-height:1}.devtools-resize:hover{color:#64748b}.devtools-tabs{display:flex;background:#1e293b;border-bottom:1px solid #334155}.tab{padding:.4rem .75rem;background:transparent;color:#64748b;border:none;cursor:pointer;font-size:.78rem;font-family:system-ui}.tab:hover{color:#e2e8f0}.tab--active{color:#3b82f6;border-bottom:2px solid #3b82f6}.devtools-content{overflow-y:auto;flex:1;padding:.25rem 0}.devtools-empty{padding:2rem;text-align:center;color:#475569;font-size:.78rem;font-family:system-ui}.log-item{display:flex;justify-content:space-between;align-items:center;padding:.35rem .75rem;cursor:pointer;border-bottom:1px solid #1e293b}.log-item:hover{background:#1e293b}.log-item--error{background:#1a0a0a}.log-item__left{display:flex;align-items:center;gap:.4rem;overflow:hidden}.log-item__right{display:flex;align-items:center;gap:.4rem;flex-shrink:0}.log-status{font-size:.72rem;color:#22c55e;flex-shrink:0}.log-item--error .log-status{color:#ef4444}.log-name{color:#e2e8f0;font-size:.75rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.log-duration{color:#64748b;font-size:.7rem}.log-time{color:#475569;font-size:.68rem}.log-error-badge{background:#7f1d1d;color:#fca5a5;font-size:.68rem;padding:.1rem .35rem;border-radius:4px}.log-detail{background:#0a0f1a;padding:.6rem .75rem;border-left:3px solid #3b82f6;margin:0 .4rem .4rem;border-radius:0 4px 4px 0}.log-detail__error{color:#fca5a5;font-size:.72rem;margin-bottom:.4rem}.log-detail__section{margin-bottom:.4rem}.log-detail__label{color:#64748b;font-size:.68rem;display:block;margin-bottom:.2rem;font-family:system-ui}pre{color:#86efac;font-size:.7rem;margin:0;white-space:pre-wrap;word-break:break-all;max-height:140px;overflow-y:auto}.state-view{color:#86efac;font-size:.7rem;padding:.75rem;margin:0;white-space:pre-wrap;word-break:break-all}\n"], dependencies: [{ kind: "pipe", type: JsonPipe, name: "json" }] });
217
+ }
218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StatoDevToolsComponent, decorators: [{
219
+ type: Component,
220
+ args: [{ selector: 'ngstato-devtools', standalone: true, imports: [JsonPipe], template: `
221
+ <!-- Bouton flottant -->
222
+ @if (!isOpen()) {
223
+ <button class="devtools-fab" (click)="toggle()">
224
+ 🛠 Stato
225
+ </button>
226
+ }
227
+
228
+ <!-- Panel -->
229
+ @if (isOpen()) {
230
+ <div
231
+ class="devtools-panel"
232
+ [class.devtools-panel--minimized]="isMinimized()"
233
+ [style.left.px]="posX()"
234
+ [style.top.px]="posY()"
235
+ [style.width.px]="isMinimized() ? 200 : panelWidth()"
236
+ [style.height]="isMinimized() ? 'auto' : panelHeight() + 'px'"
237
+ >
238
+
239
+ <!-- Header — draggable -->
240
+ <div
241
+ class="devtools-header"
242
+ (mousedown)="onDragStart($event)"
243
+ >
244
+ <span class="devtools-title">🛠 Stato</span>
245
+ <div class="devtools-header-actions">
246
+ @if (!isMinimized()) {
247
+ <button class="btn-icon" (click)="clear()" title="Vider">🗑</button>
248
+ }
249
+ <button class="btn-icon" (click)="toggleMinimize()" title="Minimiser/Agrandir">
250
+ {{ isMinimized() ? '▲' : '▼' }}
251
+ </button>
252
+ <button class="btn-icon" (click)="toggle()" title="Fermer">✕</button>
253
+ </div>
254
+ </div>
255
+
256
+ <!-- Resize handle — coin bas droite -->
257
+ @if (!isMinimized()) {
258
+ <div
259
+ class="devtools-resize"
260
+ (mousedown)="onResizeStart($event)"
261
+ >⊿</div>
262
+ }
263
+
264
+ @if (!isMinimized()) {
265
+
266
+ <!-- Tabs -->
267
+ <div class="devtools-tabs">
268
+ <button
269
+ class="tab"
270
+ [class.tab--active]="activeTab() === 'actions'"
271
+ (click)="activeTab.set('actions')"
272
+ >
273
+ Actions ({{ logs().length }})
274
+ </button>
275
+ <button
276
+ class="tab"
277
+ [class.tab--active]="activeTab() === 'state'"
278
+ (click)="activeTab.set('state')"
279
+ >
280
+ State
281
+ </button>
282
+ </div>
283
+
284
+ <!-- Tab Actions -->
285
+ @if (activeTab() === 'actions') {
286
+ <div class="devtools-content">
287
+ @if (!logs().length) {
288
+ <div class="devtools-empty">Aucune action pour l'instant</div>
289
+ }
290
+ @for (log of logs(); track log.id) {
291
+ <div
292
+ class="log-item"
293
+ [class.log-item--error]="log.status === 'error'"
294
+ (click)="selectLog(log)"
295
+ >
296
+ <div class="log-item__left">
297
+ <span class="log-status">{{ log.status === 'success' ? '✓' : '✗' }}</span>
298
+ <span class="log-name">{{ log.name }}</span>
299
+ </div>
300
+ <div class="log-item__right">
301
+ @if (log.status === 'error') {
302
+ <span class="log-error-badge">erreur</span>
303
+ } @else {
304
+ <span class="log-duration">{{ log.duration }}ms</span>
305
+ }
306
+ <span class="log-time">{{ formatTime(log.at) }}</span>
307
+ </div>
308
+ </div>
309
+
310
+ @if (selectedLog()?.id === log.id) {
311
+ <div class="log-detail">
312
+ @if (log.error) {
313
+ <div class="log-detail__error">{{ log.error }}</div>
314
+ }
315
+ <div class="log-detail__section">
316
+ <span class="log-detail__label">Avant</span>
317
+ <pre>{{ log.prevState | json }}</pre>
318
+ </div>
319
+ <div class="log-detail__section">
320
+ <span class="log-detail__label">Après</span>
321
+ <pre>{{ log.nextState | json }}</pre>
322
+ </div>
323
+ </div>
324
+ }
325
+ }
326
+ </div>
327
+ }
328
+
329
+ <!-- Tab State -->
330
+ @if (activeTab() === 'state') {
331
+ <div class="devtools-content">
332
+ @if (logs().length) {
333
+ <pre class="state-view">{{ logs()[0].nextState | json }}</pre>
334
+ } @else {
335
+ <div class="devtools-empty">Aucun state disponible</div>
336
+ }
337
+ </div>
338
+ }
339
+ }
340
+
341
+ </div>
342
+ }
343
+ `, styles: [".devtools-fab{position:fixed;bottom:1.5rem;left:1.5rem;background:#1e293b;color:#fff;border:none;border-radius:999px;padding:.5rem 1rem;font-size:.85rem;font-weight:600;cursor:pointer;z-index:9999;box-shadow:0 4px 12px #0000004d;transition:background .15s}.devtools-fab:hover{background:#334155}.devtools-panel{position:fixed;background:#0f172a;border-radius:12px;box-shadow:0 8px 32px #0006;z-index:9999;display:flex;flex-direction:column;overflow:hidden;font-family:Courier New,monospace;min-width:200px;min-height:40px}.devtools-panel--minimized{border-radius:8px}.devtools-header{display:flex;justify-content:space-between;align-items:center;padding:.6rem .75rem;background:#1e293b;border-bottom:1px solid #334155;cursor:grab;-webkit-user-select:none;user-select:none}.devtools-header:active{cursor:grabbing}.devtools-title{color:#e2e8f0;font-size:.82rem;font-weight:600;font-family:system-ui}.devtools-header-actions{display:flex;gap:.25rem}.btn-icon{background:transparent;color:#64748b;border:none;cursor:pointer;font-size:.8rem;padding:.15rem .35rem;border-radius:4px;line-height:1}.btn-icon:hover{background:#334155;color:#fff}.devtools-resize{position:absolute;bottom:2px;right:4px;color:#334155;font-size:.9rem;cursor:nwse-resize;-webkit-user-select:none;user-select:none;line-height:1}.devtools-resize:hover{color:#64748b}.devtools-tabs{display:flex;background:#1e293b;border-bottom:1px solid #334155}.tab{padding:.4rem .75rem;background:transparent;color:#64748b;border:none;cursor:pointer;font-size:.78rem;font-family:system-ui}.tab:hover{color:#e2e8f0}.tab--active{color:#3b82f6;border-bottom:2px solid #3b82f6}.devtools-content{overflow-y:auto;flex:1;padding:.25rem 0}.devtools-empty{padding:2rem;text-align:center;color:#475569;font-size:.78rem;font-family:system-ui}.log-item{display:flex;justify-content:space-between;align-items:center;padding:.35rem .75rem;cursor:pointer;border-bottom:1px solid #1e293b}.log-item:hover{background:#1e293b}.log-item--error{background:#1a0a0a}.log-item__left{display:flex;align-items:center;gap:.4rem;overflow:hidden}.log-item__right{display:flex;align-items:center;gap:.4rem;flex-shrink:0}.log-status{font-size:.72rem;color:#22c55e;flex-shrink:0}.log-item--error .log-status{color:#ef4444}.log-name{color:#e2e8f0;font-size:.75rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.log-duration{color:#64748b;font-size:.7rem}.log-time{color:#475569;font-size:.68rem}.log-error-badge{background:#7f1d1d;color:#fca5a5;font-size:.68rem;padding:.1rem .35rem;border-radius:4px}.log-detail{background:#0a0f1a;padding:.6rem .75rem;border-left:3px solid #3b82f6;margin:0 .4rem .4rem;border-radius:0 4px 4px 0}.log-detail__error{color:#fca5a5;font-size:.72rem;margin-bottom:.4rem}.log-detail__section{margin-bottom:.4rem}.log-detail__label{color:#64748b;font-size:.68rem;display:block;margin-bottom:.2rem;font-family:system-ui}pre{color:#86efac;font-size:.7rem;margin:0;white-space:pre-wrap;word-break:break-all;max-height:140px;overflow-y:auto}.state-view{color:#86efac;font-size:.7rem;padding:.75rem;margin:0;white-space:pre-wrap;word-break:break-all}\n"] }]
344
+ }] });
345
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV2dG9vbHMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RldnRvb2xzLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUdULE1BQU0sRUFDTixNQUFNLEVBSVAsTUFBNkIsZUFBZSxDQUFBO0FBQzdDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBVyxlQUFlLENBQUE7QUFFN0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFPLG1CQUFtQixDQUFBO0FBQ2pELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTs7QUFrVDFDLE1BQU0sT0FBTyxzQkFBc0I7SUFFekIsTUFBTSxHQUFJLE1BQU0sQ0FBQyxZQUFZLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUNsRCxLQUFLLENBQWE7SUFFMUIsV0FBVztJQUNYLE1BQU0sR0FBUSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDM0IsV0FBVyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUMzQixTQUFTLEdBQUssTUFBTSxDQUFzQixTQUFTLENBQUMsQ0FBQTtJQUNwRCxJQUFJLEdBQVUsTUFBTSxDQUFjLEVBQUUsQ0FBQyxDQUFBO0lBQ3JDLFdBQVcsR0FBRyxNQUFNLENBQW1CLElBQUksQ0FBQyxDQUFBO0lBRTVDLHFCQUFxQjtJQUNyQixJQUFJLEdBQVUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ3hCLElBQUksR0FBVSxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsQ0FBQTtJQUM5QyxVQUFVLEdBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ3pCLFdBQVcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7SUFFekIsYUFBYTtJQUNMLFVBQVUsR0FBSSxLQUFLLENBQUE7SUFDbkIsVUFBVSxHQUFJLEtBQUss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QUMsSUFBSSxDQUFDLENBQUE7UUFDNUIsQ0FBQztJQUNILENBQUM7SUFFRCxzREFBc0Q7SUFDdEQsU0FBUztRQUNQLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFBO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFBO0lBQ3pCLENBQUM7d0dBakdVLHNCQUFzQjs0RkFBdEIsc0JBQXNCLDRFQTVTdkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJIVCx3bUdBNUhZLFFBQVE7OzRGQTZTVixzQkFBc0I7a0JBaFRsQyxTQUFTOytCQUNJLGtCQUFrQixjQUNsQixJQUFJLFdBQ0osQ0FBQyxRQUFRLENBQUMsWUFDWjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkhUIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgT25Jbml0LFxyXG4gIE9uRGVzdHJveSxcclxuICBzaWduYWwsXHJcbiAgaW5qZWN0LFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgVmlld0NoaWxkLFxyXG4gIEFmdGVyVmlld0luaXRcclxufSAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gJ0Bhbmd1bGFyL2NvcmUnXHJcbmltcG9ydCB7IGRldlRvb2xzIH0gICAgICBmcm9tICdAbmdzdGF0by9jb3JlJ1xyXG5pbXBvcnQgdHlwZSB7IEFjdGlvbkxvZyB9IGZyb20gJ0BuZ3N0YXRvL2NvcmUnXHJcbmltcG9ydCB7IFNUQVRPX0NPTkZJRyB9ICBmcm9tICcuL3Byb3ZpZGUtbmdzdGF0bydcclxuaW1wb3J0IHsgSnNvblBpcGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nXHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogICAnbmdzdGF0by1kZXZ0b29scycsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiAgICBbSnNvblBpcGVdLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8IS0tIEJvdXRvbiBmbG90dGFudCAtLT5cclxuICAgIEBpZiAoIWlzT3BlbigpKSB7XHJcbiAgICAgIDxidXR0b24gY2xhc3M9XCJkZXZ0b29scy1mYWJcIiAoY2xpY2spPVwidG9nZ2xlKClcIj5cclxuICAgICAgICDwn5ugIFN0YXRvXHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgfVxyXG5cclxuICAgIDwhLS0gUGFuZWwgLS0+XHJcbiAgICBAaWYgKGlzT3BlbigpKSB7XHJcbiAgICAgIDxkaXZcclxuICAgICAgICBjbGFzcz1cImRldnRvb2xzLXBhbmVsXCJcclxuICAgICAgICBbY2xhc3MuZGV2dG9vbHMtcGFuZWwtLW1pbmltaXplZF09XCJpc01pbmltaXplZCgpXCJcclxuICAgICAgICBbc3R5bGUubGVmdC5weF09XCJwb3NYKClcIlxyXG4gICAgICAgIFtzdHlsZS50b3AucHhdPVwicG9zWSgpXCJcclxuICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwiaXNNaW5pbWl6ZWQoKSA/IDIwMCA6IHBhbmVsV2lkdGgoKVwiXHJcbiAgICAgICAgW3N0eWxlLmhlaWdodF09XCJpc01pbmltaXplZCgpID8gJ2F1dG8nIDogcGFuZWxIZWlnaHQoKSArICdweCdcIlxyXG4gICAgICA+XHJcblxyXG4gICAgICAgIDwhLS0gSGVhZGVyIOKAlCBkcmFnZ2FibGUgLS0+XHJcbiAgICAgICAgPGRpdlxyXG4gICAgICAgICAgY2xhc3M9XCJkZXZ0b29scy1oZWFkZXJcIlxyXG4gICAgICAgICAgKG1vdXNlZG93bik9XCJvbkRyYWdTdGFydCgkZXZlbnQpXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldnRvb2xzLXRpdGxlXCI+8J+boCBTdGF0bzwvc3Bhbj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXZ0b29scy1oZWFkZXItYWN0aW9uc1wiPlxyXG4gICAgICAgICAgICBAaWYgKCFpc01pbmltaXplZCgpKSB7XHJcbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0bi1pY29uXCIgKGNsaWNrKT1cImNsZWFyKClcIiB0aXRsZT1cIlZpZGVyXCI+8J+XkTwvYnV0dG9uPlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4taWNvblwiIChjbGljayk9XCJ0b2dnbGVNaW5pbWl6ZSgpXCIgdGl0bGU9XCJNaW5pbWlzZXIvQWdyYW5kaXJcIj5cclxuICAgICAgICAgICAgICB7eyBpc01pbmltaXplZCgpID8gJ+KWsicgOiAn4pa8JyB9fVxyXG4gICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0bi1pY29uXCIgKGNsaWNrKT1cInRvZ2dsZSgpXCIgdGl0bGU9XCJGZXJtZXJcIj7inJU8L2J1dHRvbj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8IS0tIFJlc2l6ZSBoYW5kbGUg4oCUIGNvaW4gYmFzIGRyb2l0ZSAtLT5cclxuICAgICAgICBAaWYgKCFpc01pbmltaXplZCgpKSB7XHJcbiAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgIGNsYXNzPVwiZGV2dG9vbHMtcmVzaXplXCJcclxuICAgICAgICAgICAgKG1vdXNlZG93bik9XCJvblJlc2l6ZVN0YXJ0KCRldmVudClcIlxyXG4gICAgICAgICAgPuKKvzwvZGl2PlxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgQGlmICghaXNNaW5pbWl6ZWQoKSkge1xyXG5cclxuICAgICAgICAgIDwhLS0gVGFicyAtLT5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXZ0b29scy10YWJzXCI+XHJcbiAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICBjbGFzcz1cInRhYlwiXHJcbiAgICAgICAgICAgICAgW2NsYXNzLnRhYi0tYWN0aXZlXT1cImFjdGl2ZVRhYigpID09PSAnYWN0aW9ucydcIlxyXG4gICAgICAgICAgICAgIChjbGljayk9XCJhY3RpdmVUYWIuc2V0KCdhY3Rpb25zJylcIlxyXG4gICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgQWN0aW9ucyAoe3sgbG9ncygpLmxlbmd0aCB9fSlcclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICBjbGFzcz1cInRhYlwiXHJcbiAgICAgICAgICAgICAgW2NsYXNzLnRhYi0tYWN0aXZlXT1cImFjdGl2ZVRhYigpID09PSAnc3RhdGUnXCJcclxuICAgICAgICAgICAgICAoY2xpY2spPVwiYWN0aXZlVGFiLnNldCgnc3RhdGUnKVwiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICBTdGF0ZVxyXG4gICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgIDwhLS0gVGFiIEFjdGlvbnMgLS0+XHJcbiAgICAgICAgICBAaWYgKGFjdGl2ZVRhYigpID09PSAnYWN0aW9ucycpIHtcclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldnRvb2xzLWNvbnRlbnRcIj5cclxuICAgICAgICAgICAgICBAaWYgKCFsb2dzKCkubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV2dG9vbHMtZW1wdHlcIj5BdWN1bmUgYWN0aW9uIHBvdXIgbCdpbnN0YW50PC9kaXY+XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIEBmb3IgKGxvZyBvZiBsb2dzKCk7IHRyYWNrIGxvZy5pZCkge1xyXG4gICAgICAgICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImxvZy1pdGVtXCJcclxuICAgICAgICAgICAgICAgICAgW2NsYXNzLmxvZy1pdGVtLS1lcnJvcl09XCJsb2cuc3RhdHVzID09PSAnZXJyb3InXCJcclxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdExvZyhsb2cpXCJcclxuICAgICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvZy1pdGVtX19sZWZ0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsb2ctc3RhdHVzXCI+e3sgbG9nLnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnID8gJ+KckycgOiAn4pyXJyB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvZy1uYW1lXCI+e3sgbG9nLm5hbWUgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9nLWl0ZW1fX3JpZ2h0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgQGlmIChsb2cuc3RhdHVzID09PSAnZXJyb3InKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvZy1lcnJvci1iYWRnZVwiPmVycmV1cjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9nLWR1cmF0aW9uXCI+e3sgbG9nLmR1cmF0aW9uIH19bXM8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9nLXRpbWVcIj57eyBmb3JtYXRUaW1lKGxvZy5hdCkgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgQGlmIChzZWxlY3RlZExvZygpPy5pZCA9PT0gbG9nLmlkKSB7XHJcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2ctZGV0YWlsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgQGlmIChsb2cuZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2ctZGV0YWlsX19lcnJvclwiPnt7IGxvZy5lcnJvciB9fTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9nLWRldGFpbF9fc2VjdGlvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsb2ctZGV0YWlsX19sYWJlbFwiPkF2YW50PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPHByZT57eyBsb2cucHJldlN0YXRlIHwganNvbiB9fTwvcHJlPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2ctZGV0YWlsX19zZWN0aW9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvZy1kZXRhaWxfX2xhYmVsXCI+QXByw6hzPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPHByZT57eyBsb2cubmV4dFN0YXRlIHwganNvbiB9fTwvcHJlPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIDwhLS0gVGFiIFN0YXRlIC0tPlxyXG4gICAgICAgICAgQGlmIChhY3RpdmVUYWIoKSA9PT0gJ3N0YXRlJykge1xyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV2dG9vbHMtY29udGVudFwiPlxyXG4gICAgICAgICAgICAgIEBpZiAobG9ncygpLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgPHByZSBjbGFzcz1cInN0YXRlLXZpZXdcIj57eyBsb2dzKClbMF0ubmV4dFN0YXRlIHwganNvbiB9fTwvcHJlPlxyXG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldnRvb2xzLWVtcHR5XCI+QXVjdW4gc3RhdGUgZGlzcG9uaWJsZTwvZGl2PlxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgPC9kaXY+XHJcbiAgICB9XHJcbiAgYCxcclxuICBzdHlsZXM6IFtgXHJcbiAgICAuZGV2dG9vbHMtZmFiIHtcclxuICAgICAgcG9zaXRpb246ICAgICAgZml4ZWQ7XHJcbiAgICAgIGJvdHRvbTogICAgICAgIDEuNXJlbTtcclxuICAgICAgbGVmdDogICAgICAgICAgMS41cmVtO1xyXG4gICAgICBiYWNrZ3JvdW5kOiAgICAjMWUyOTNiO1xyXG4gICAgICBjb2xvcjogICAgICAgICB3aGl0ZTtcclxuICAgICAgYm9yZGVyOiAgICAgICAgbm9uZTtcclxuICAgICAgYm9yZGVyLXJhZGl1czogOTk5cHg7XHJcbiAgICAgIHBhZGRpbmc6ICAgICAgIDAuNXJlbSAxcmVtO1xyXG4gICAgICBmb250LXNpemU6ICAgICAwLjg1cmVtO1xyXG4gICAgICBmb250LXdlaWdodDogICA2MDA7XHJcbiAgICAgIGN1cnNvcjogICAgICAgIHBvaW50ZXI7XHJcbiAgICAgIHotaW5kZXg6ICAgICAgIDk5OTk7XHJcbiAgICAgIGJveC1zaGFkb3c6ICAgIDAgNHB4IDEycHggcmdiYSgwLDAsMCwwLjMpO1xyXG4gICAgICB0cmFuc2l0aW9uOiAgICBiYWNrZ3JvdW5kIDAuMTVzO1xyXG4gICAgfVxyXG4gICAgLmRldnRvb2xzLWZhYjpob3ZlciB7IGJhY2tncm91bmQ6ICMzMzQxNTU7IH1cclxuXHJcbiAgICAuZGV2dG9vbHMtcGFuZWwge1xyXG4gICAgICBwb3NpdGlvbjogICAgICAgZml4ZWQ7XHJcbiAgICAgIGJhY2tncm91bmQ6ICAgICAjMGYxNzJhO1xyXG4gICAgICBib3JkZXItcmFkaXVzOiAgMTJweDtcclxuICAgICAgYm94LXNoYWRvdzogICAgIDAgOHB4IDMycHggcmdiYSgwLDAsMCwwLjQpO1xyXG4gICAgICB6LWluZGV4OiAgICAgICAgOTk5OTtcclxuICAgICAgZGlzcGxheTogICAgICAgIGZsZXg7XHJcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XHJcbiAgICAgIG92ZXJmbG93OiAgICAgICBoaWRkZW47XHJcbiAgICAgIGZvbnQtZmFtaWx5OiAgICAnQ291cmllciBOZXcnLCBtb25vc3BhY2U7XHJcbiAgICAgIG1pbi13aWR0aDogICAgICAyMDBweDtcclxuICAgICAgbWluLWhlaWdodDogICAgIDQwcHg7XHJcbiAgICB9XHJcblxyXG4gICAgLmRldnRvb2xzLXBhbmVsLS1taW5pbWl6ZWQge1xyXG4gICAgICBib3JkZXItcmFkaXVzOiA4cHg7XHJcbiAgICB9XHJcblxyXG4gICAgLmRldnRvb2xzLWhlYWRlciB7XHJcbiAgICAgIGRpc3BsYXk6ICAgICAgICAgZmxleDtcclxuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xyXG4gICAgICBhbGlnbi1pdGVtczogICAgIGNlbnRlcjtcclxuICAgICAgcGFkZGluZzogICAgICAgICAwLjZyZW0gMC43NXJlbTtcclxuICAgICAgYmFja2dyb3VuZDogICAgICAjMWUyOTNiO1xyXG4gICAgICBib3JkZXItYm90dG9tOiAgIDFweCBzb2xpZCAjMzM0MTU1O1xyXG4gICAgICBjdXJzb3I6ICAgICAgICAgIGdyYWI7XHJcbiAgICAgIHVzZXItc2VsZWN0OiAgICAgbm9uZTtcclxuICAgIH1cclxuICAgIC5kZXZ0b29scy1oZWFkZXI6YWN0aXZlIHsgY3Vyc29yOiBncmFiYmluZzsgfVxyXG5cclxuICAgIC5kZXZ0b29scy10aXRsZSB7XHJcbiAgICAgIGNvbG9yOiAgICAgICAjZTJlOGYwO1xyXG4gICAgICBmb250LXNpemU6ICAgMC44MnJlbTtcclxuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcclxuICAgICAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTtcclxuICAgIH1cclxuXHJcbiAgICAuZGV2dG9vbHMtaGVhZGVyLWFjdGlvbnMgeyBkaXNwbGF5OiBmbGV4OyBnYXA6IDAuMjVyZW07IH1cclxuXHJcbiAgICAuYnRuLWljb24ge1xyXG4gICAgICBiYWNrZ3JvdW5kOiAgICB0cmFuc3BhcmVudDtcclxuICAgICAgY29sb3I6ICAgICAgICAgIzY0NzQ4YjtcclxuICAgICAgYm9yZGVyOiAgICAgICAgbm9uZTtcclxuICAgICAgY3Vyc29yOiAgICAgICAgcG9pbnRlcjtcclxuICAgICAgZm9udC1zaXplOiAgICAgMC44cmVtO1xyXG4gICAgICBwYWRkaW5nOiAgICAgICAwLjE1cmVtIDAuMzVyZW07XHJcbiAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcclxuICAgICAgbGluZS1oZWlnaHQ6ICAgMTtcclxuICAgIH1cclxuICAgIC5idG4taWNvbjpob3ZlciB7IGJhY2tncm91bmQ6ICMzMzQxNTU7IGNvbG9yOiB3aGl0ZTsgfVxyXG5cclxuICAgIC5kZXZ0b29scy1yZXNpemUge1xyXG4gICAgICBwb3NpdGlvbjogIGFic29sdXRlO1xyXG4gICAgICBib3R0b206ICAgIDJweDtcclxuICAgICAgcmlnaHQ6ICAgICA0cHg7XHJcbiAgICAgIGNvbG9yOiAgICAgIzMzNDE1NTtcclxuICAgICAgZm9udC1zaXplOiAwLjlyZW07XHJcbiAgICAgIGN1cnNvcjogICAgbndzZS1yZXNpemU7XHJcbiAgICAgIHVzZXItc2VsZWN0OiBub25lO1xyXG4gICAgICBsaW5lLWhlaWdodDogMTtcclxuICAgIH1cclxuICAgIC5kZXZ0b29scy1yZXNpemU6aG92ZXIgeyBjb2xvcjogIzY0NzQ4YjsgfVxyXG5cclxuICAgIC5kZXZ0b29scy10YWJzIHtcclxuICAgICAgZGlzcGxheTogICAgICAgZmxleDtcclxuICAgICAgYmFja2dyb3VuZDogICAgIzFlMjkzYjtcclxuICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICMzMzQxNTU7XHJcbiAgICB9XHJcbiAgICAudGFiIHtcclxuICAgICAgcGFkZGluZzogICAgIDAuNHJlbSAwLjc1cmVtO1xyXG4gICAgICBiYWNrZ3JvdW5kOiAgdHJhbnNwYXJlbnQ7XHJcbiAgICAgIGNvbG9yOiAgICAgICAjNjQ3NDhiO1xyXG4gICAgICBib3JkZXI6ICAgICAgbm9uZTtcclxuICAgICAgY3Vyc29yOiAgICAgIHBvaW50ZXI7XHJcbiAgICAgIGZvbnQtc2l6ZTogICAwLjc4cmVtO1xyXG4gICAgICBmb250LWZhbWlseTogc3lzdGVtLXVpO1xyXG4gICAgfVxyXG4gICAgLnRhYjpob3ZlciAgICB7IGNvbG9yOiAjZTJlOGYwOyB9XHJcbiAgICAudGFiLS1hY3RpdmUgIHsgY29sb3I6ICMzYjgyZjY7IGJvcmRlci1ib3R0b206IDJweCBzb2xpZCAjM2I4MmY2OyB9XHJcblxyXG4gICAgLmRldnRvb2xzLWNvbnRlbnQge1xyXG4gICAgICBvdmVyZmxvdy15OiBhdXRvO1xyXG4gICAgICBmbGV4OiAgICAgICAxO1xyXG4gICAgICBwYWRkaW5nOiAgICAwLjI1cmVtIDA7XHJcbiAgICB9XHJcblxyXG4gICAgLmRldnRvb2xzLWVtcHR5IHtcclxuICAgICAgcGFkZGluZzogICAgIDJyZW07XHJcbiAgICAgIHRleHQtYWxpZ246ICBjZW50ZXI7XHJcbiAgICAgIGNvbG9yOiAgICAgICAjNDc1NTY5O1xyXG4gICAgICBmb250LXNpemU6ICAgMC43OHJlbTtcclxuICAgICAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTtcclxuICAgIH1cclxuXHJcbiAgICAubG9nLWl0ZW0ge1xyXG4gICAgICBkaXNwbGF5OiAgICAgICAgIGZsZXg7XHJcbiAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcclxuICAgICAgYWxpZ24taXRlbXM6ICAgICBjZW50ZXI7XHJcbiAgICAgIHBhZGRpbmc6ICAgICAgICAgMC4zNXJlbSAwLjc1cmVtO1xyXG4gICAgICBjdXJzb3I6ICAgICAgICAgIHBvaW50ZXI7XHJcbiAgICAgIGJvcmRlci1ib3R0b206ICAgMXB4IHNvbGlkICMxZTI5M2I7XHJcbiAgICB9XHJcbiAgICAubG9nLWl0ZW06aG92ZXIgICAgICAgIHsgYmFja2dyb3VuZDogIzFlMjkzYjsgfVxyXG4gICAgLmxvZy1pdGVtLS1lcnJvciAgICAgICB7IGJhY2tncm91bmQ6ICMxYTBhMGE7IH1cclxuXHJcbiAgICAubG9nLWl0ZW1fX2xlZnQgIHsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAwLjRyZW07IG92ZXJmbG93OiBoaWRkZW47IH1cclxuICAgIC5sb2ctaXRlbV9fcmlnaHQgeyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDAuNHJlbTsgZmxleC1zaHJpbms6IDA7IH1cclxuXHJcbiAgICAubG9nLXN0YXR1cyAgeyBmb250LXNpemU6IDAuNzJyZW07IGNvbG9yOiAjMjJjNTVlOyBmbGV4LXNocmluazogMDsgfVxyXG4gICAgLmxvZy1pdGVtLS1lcnJvciAubG9nLXN0YXR1cyB7IGNvbG9yOiAjZWY0NDQ0OyB9XHJcbiAgICAubG9nLW5hbWUgICAgeyBjb2xvcjogI2UyZThmMDsgZm9udC1zaXplOiAwLjc1cmVtOyB3aGl0ZS1zcGFjZTogbm93cmFwOyBvdmVyZmxvdzogaGlkZGVuOyB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpczsgfVxyXG4gICAgLmxvZy1kdXJhdGlvbiB7IGNvbG9yOiAjNjQ3NDhiOyBmb250LXNpemU6IDAuN3JlbTsgfVxyXG4gICAgLmxvZy10aW1lICAgIHsgY29sb3I6ICM0NzU1Njk7IGZvbnQtc2l6ZTogMC42OHJlbTsgfVxyXG5cclxuICAgIC5sb2ctZXJyb3ItYmFkZ2Uge1xyXG4gICAgICBiYWNrZ3JvdW5kOiAgICAjN2YxZDFkO1xyXG4gICAgICBjb2xvcjogICAgICAgICAjZmNhNWE1O1xyXG4gICAgICBmb250LXNpemU6ICAgICAwLjY4cmVtO1xyXG4gICAgICBwYWRkaW5nOiAgICAgICAwLjFyZW0gMC4zNXJlbTtcclxuICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xyXG4gICAgfVxyXG5cclxuICAgIC5sb2ctZGV0YWlsIHtcclxuICAgICAgYmFja2dyb3VuZDogICAgIzBhMGYxYTtcclxuICAgICAgcGFkZGluZzogICAgICAgMC42cmVtIDAuNzVyZW07XHJcbiAgICAgIGJvcmRlci1sZWZ0OiAgIDNweCBzb2xpZCAjM2I4MmY2O1xyXG4gICAgICBtYXJnaW46ICAgICAgICAwIDAuNHJlbSAwLjRyZW07XHJcbiAgICAgIGJvcmRlci1yYWRpdXM6IDAgNHB4IDRweCAwO1xyXG4gICAgfVxyXG4gICAgLmxvZy1kZXRhaWxfX2Vycm9yICAgeyBjb2xvcjogI2ZjYTVhNTsgZm9udC1zaXplOiAwLjcycmVtOyBtYXJnaW4tYm90dG9tOiAwLjRyZW07IH1cclxuICAgIC5sb2ctZGV0YWlsX19zZWN0aW9uIHsgbWFyZ2luLWJvdHRvbTogMC40cmVtOyB9XHJcbiAgICAubG9nLWRldGFpbF9fbGFiZWwgICB7XHJcbiAgICAgIGNvbG9yOiAgICAgICAgICM2NDc0OGI7XHJcbiAgICAgIGZvbnQtc2l6ZTogICAgIDAuNjhyZW07XHJcbiAgICAgIGRpc3BsYXk6ICAgICAgIGJsb2NrO1xyXG4gICAgICBtYXJnaW4tYm90dG9tOiAwLjJyZW07XHJcbiAgICAgIGZvbnQtZmFtaWx5OiAgIHN5c3RlbS11aTtcclxuICAgIH1cclxuICAgIHByZSB7XHJcbiAgICAgIGNvbG9yOiAgICAgICAjODZlZmFjO1xyXG4gICAgICBmb250LXNpemU6ICAgMC43cmVtO1xyXG4gICAgICBtYXJnaW46ICAgICAgMDtcclxuICAgICAgd2hpdGUtc3BhY2U6IHByZS13cmFwO1xyXG4gICAgICB3b3JkLWJyZWFrOiAgYnJlYWstYWxsO1xyXG4gICAgICBtYXgtaGVpZ2h0OiAgMTQwcHg7XHJcbiAgICAgIG92ZXJmbG93LXk6ICBhdXRvO1xyXG4gICAgfVxyXG4gICAgLnN0YXRlLXZpZXcge1xyXG4gICAgICBjb2xvcjogICAgICAgIzg2ZWZhYztcclxuICAgICAgZm9udC1zaXplOiAgIDAuN3JlbTtcclxuICAgICAgcGFkZGluZzogICAgIDAuNzVyZW07XHJcbiAgICAgIG1hcmdpbjogICAgICAwO1xyXG4gICAgICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XHJcbiAgICAgIHdvcmQtYnJlYWs6ICBicmVhay1hbGw7XHJcbiAgICB9XHJcbiAgYF1cclxufSlcclxuZXhwb3J0IGNsYXNzIFN0YXRvRGV2VG9vbHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XHJcblxyXG4gIHByaXZhdGUgY29uZmlnICA9IGluamVjdChTVEFUT19DT05GSUcsIHsgb3B0aW9uYWw6IHRydWUgfSlcclxuICBwcml2YXRlIHVuc3ViPzogKCkgPT4gdm9pZFxyXG5cclxuICAvLyBTdGF0ZSBVSVxyXG4gIGlzT3BlbiAgICAgID0gc2lnbmFsKGZhbHNlKVxyXG4gIGlzTWluaW1pemVkID0gc2lnbmFsKGZhbHNlKVxyXG4gIGFjdGl2ZVRhYiAgID0gc2lnbmFsPCdhY3Rpb25zJyB8ICdzdGF0ZSc+KCdhY3Rpb25zJylcclxuICBsb2dzICAgICAgICA9IHNpZ25hbDxBY3Rpb25Mb2dbXT4oW10pXHJcbiAgc2VsZWN0ZWRMb2cgPSBzaWduYWw8QWN0aW9uTG9nIHwgbnVsbD4obnVsbClcclxuXHJcbiAgLy8gUG9zaXRpb24gZXQgdGFpbGxlXHJcbiAgcG9zWCAgICAgICAgPSBzaWduYWwoMjQpXHJcbiAgcG9zWSAgICAgICAgPSBzaWduYWwod2luZG93LmlubmVySGVpZ2h0IC0gNTAwKVxyXG4gIHBhbmVsV2lkdGggID0gc2lnbmFsKDQyMClcclxuICBwYW5lbEhlaWdodCA9IHNpZ25hbCg0NjApXHJcblxyXG4gIC8vIERyYWcgc3RhdGVcclxuICBwcml2YXRlIGlzRHJhZ2dpbmcgID0gZmFsc2VcclxuICBwcml2YXRlIGlzUmVzaXppbmcgID0gZmFsc2VcclxuICBwcml2YXRlIGRyYWdPZmZzZXRYID0gMFxyXG4gIHByaXZhdGUgZHJhZ09mZnNldFkgPSAwXHJcbiAgcHJpdmF0ZSBzdGFydFcgICAgICA9IDBcclxuICBwcml2YXRlIHN0YXJ0SCAgICAgID0gMFxyXG4gIHByaXZhdGUgc3RhcnRYICAgICAgPSAwXHJcbiAgcHJpdmF0ZSBzdGFydFkgICAgICA9IDBcclxuXHJcbiAgLy8gQm91bmQgbGlzdGVuZXJzXHJcbiAgcHJpdmF0ZSBib3VuZE1vdXNlTW92ZSA9IHRoaXMub25Nb3VzZU1vdmUuYmluZCh0aGlzKVxyXG4gIHByaXZhdGUgYm91bmRNb3VzZVVwICAgPSB0aGlzLm9uTW91c2VVcC5iaW5kKHRoaXMpXHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy51bnN1YiA9IGRldlRvb2xzLnN1YnNjcmliZSgoc3RhdGUpID0+IHtcclxuICAgICAgdGhpcy5sb2dzLnNldChzdGF0ZS5sb2dzKVxyXG4gICAgICB0aGlzLmlzT3Blbi5zZXQoc3RhdGUuaXNPcGVuKVxyXG4gICAgfSlcclxuXHJcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmJvdW5kTW91c2VNb3ZlKVxyXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsICAgdGhpcy5ib3VuZE1vdXNlVXApXHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIHRoaXMudW5zdWI/LigpXHJcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmJvdW5kTW91c2VNb3ZlKVxyXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsICAgdGhpcy5ib3VuZE1vdXNlVXApXHJcbiAgfVxyXG5cclxuICAvLyDilIDilIAgVG9nZ2xlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG4gIHRvZ2dsZSgpICAgICAgICAgeyBkZXZUb29scy50b2dnbGUoKSB9XHJcbiAgdG9nZ2xlTWluaW1pemUoKSB7IHRoaXMuaXNNaW5pbWl6ZWQudXBkYXRlKHYgPT4gIXYpIH1cclxuICBjbGVhcigpICAgICAgICAgIHsgZGV2VG9vbHMuY2xlYXIoKTsgdGhpcy5zZWxlY3RlZExvZy5zZXQobnVsbCkgfVxyXG4gIHNlbGVjdExvZyhsb2c6IEFjdGlvbkxvZykge1xyXG4gICAgdGhpcy5zZWxlY3RlZExvZy5zZXQodGhpcy5zZWxlY3RlZExvZygpPy5pZCA9PT0gbG9nLmlkID8gbnVsbCA6IGxvZylcclxuICB9XHJcbiAgZm9ybWF0VGltZShpc286IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gbmV3IERhdGUoaXNvKS50b1RpbWVTdHJpbmcoKS5zbGljZSgwLCA4KVxyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSAIERyYWcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcbiAgb25EcmFnU3RhcnQoZTogTW91c2VFdmVudCkge1xyXG4gICAgaWYgKChlLnRhcmdldCBhcyBIVE1MRWxlbWVudCkuY2xhc3NMaXN0LmNvbnRhaW5zKCdidG4taWNvbicpKSByZXR1cm5cclxuICAgIHRoaXMuaXNEcmFnZ2luZyAgPSB0cnVlXHJcbiAgICB0aGlzLmRyYWdPZmZzZXRYID0gZS5jbGllbnRYIC0gdGhpcy5wb3NYKClcclxuICAgIHRoaXMuZHJhZ09mZnNldFkgPSBlLmNsaWVudFkgLSB0aGlzLnBvc1koKVxyXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXHJcbiAgfVxyXG5cclxuICAvLyDilIDilIAgUmVzaXplIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG4gIG9uUmVzaXplU3RhcnQoZTogTW91c2VFdmVudCkge1xyXG4gICAgdGhpcy5pc1Jlc2l6aW5nID0gdHJ1ZVxyXG4gICAgdGhpcy5zdGFydFcgICAgID0gdGhpcy5wYW5lbFdpZHRoKClcclxuICAgIHRoaXMuc3RhcnRIICAgICA9IHRoaXMucGFuZWxIZWlnaHQoKVxyXG4gICAgdGhpcy5zdGFydFggICAgID0gZS5jbGllbnRYXHJcbiAgICB0aGlzLnN0YXJ0WSAgICAgPSBlLmNsaWVudFlcclxuICAgIGUucHJldmVudERlZmF1bHQoKVxyXG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKVxyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSAIE1vdXNlIE1vdmUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcbiAgb25Nb3VzZU1vdmUoZTogTW91c2VFdmVudCkge1xyXG4gICAgaWYgKHRoaXMuaXNEcmFnZ2luZykge1xyXG4gICAgICB0aGlzLnBvc1guc2V0KE1hdGgubWF4KDAsIGUuY2xpZW50WCAtIHRoaXMuZHJhZ09mZnNldFgpKVxyXG4gICAgICB0aGlzLnBvc1kuc2V0KE1hdGgubWF4KDAsIGUuY2xpZW50WSAtIHRoaXMuZHJhZ09mZnNldFkpKVxyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuaXNSZXNpemluZykge1xyXG4gICAgICBjb25zdCBuZXdXID0gTWF0aC5tYXgoMzAwLCB0aGlzLnN0YXJ0VyArIGUuY2xpZW50WCAtIHRoaXMuc3RhcnRYKVxyXG4gICAgICBjb25zdCBuZXdIID0gTWF0aC5tYXgoMjAwLCB0aGlzLnN0YXJ0SCArIGUuY2xpZW50WSAtIHRoaXMuc3RhcnRZKVxyXG4gICAgICB0aGlzLnBhbmVsV2lkdGguc2V0KG5ld1cpXHJcbiAgICAgIHRoaXMucGFuZWxIZWlnaHQuc2V0KG5ld0gpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyDilIDilIAgTW91c2UgVXAg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcbiAgb25Nb3VzZVVwKCkge1xyXG4gICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2VcclxuICAgIHRoaXMuaXNSZXNpemluZyA9IGZhbHNlXHJcbiAgfVxyXG59Il19
@@ -0,0 +1,8 @@
1
+ // ─────────────────────────────────────────────────────
2
+ // @ngstato/angular — API publique
3
+ // ─────────────────────────────────────────────────────
4
+ export { injectStore } from './inject-store';
5
+ export { provideStato } from './provide-ngstato';
6
+ export { createAngularStore } from './create-angular-store';
7
+ export { StatoDevToolsComponent } from './devtools.component';
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsd0RBQXdEO0FBQ3hELGtDQUFrQztBQUNsQyx3REFBd0Q7QUFFeEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUF5QixnQkFBZ0IsQ0FBQTtBQUMvRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQXdCLG1CQUFtQixDQUFBO0FBQ2xFLE9BQU8sRUFBRSxrQkFBa0IsRUFBQyxNQUFrQix3QkFBd0IsQ0FBQTtBQUV0RSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG4vLyBAbmdzdGF0by9hbmd1bGFyIOKAlCBBUEkgcHVibGlxdWVcclxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcblxyXG5leHBvcnQgeyBpbmplY3RTdG9yZSB9ICAgICAgICAgICAgICAgICAgICBmcm9tICcuL2luamVjdC1zdG9yZSdcclxuZXhwb3J0IHsgcHJvdmlkZVN0YXRvIH0gICAgICAgICAgICAgICAgICAgZnJvbSAnLi9wcm92aWRlLW5nc3RhdG8nXHJcbmV4cG9ydCB7IGNyZWF0ZUFuZ3VsYXJTdG9yZX0gICAgICAgICAgICAgZnJvbSAnLi9jcmVhdGUtYW5ndWxhci1zdG9yZSdcclxuZXhwb3J0IHR5cGUgeyBTdGF0b0FuZ3VsYXJDb25maWcgfSAgICAgICAgZnJvbSAnLi9wcm92aWRlLW5nc3RhdG8nXHJcbmV4cG9ydCB7IFN0YXRvRGV2VG9vbHNDb21wb25lbnQgfSBmcm9tICcuL2RldnRvb2xzLmNvbXBvbmVudCciXX0=
@@ -0,0 +1,9 @@
1
+ // ─────────────────────────────────────────────────────
2
+ // @ngstato/angular — injectStore()
3
+ // Helper pour injecter un store dans un composant
4
+ // ─────────────────────────────────────────────────────
5
+ import { inject } from '@angular/core';
6
+ export function injectStore(store) {
7
+ return inject(store);
8
+ }
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5qZWN0LXN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2luamVjdC1zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx3REFBd0Q7QUFDeEQsbUNBQW1DO0FBQ25DLGtEQUFrRDtBQUNsRCx3REFBd0Q7QUFFeEQsT0FBTyxFQUFFLE1BQU0sRUFBYSxNQUFNLGVBQWUsQ0FBQTtBQUVqRCxNQUFNLFVBQVUsV0FBVyxDQUFJLEtBQWM7SUFDM0MsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7QUFDdEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG4vLyBAbmdzdGF0by9hbmd1bGFyIOKAlCBpbmplY3RTdG9yZSgpXHJcbi8vIEhlbHBlciBwb3VyIGluamVjdGVyIHVuIHN0b3JlIGRhbnMgdW4gY29tcG9zYW50XHJcbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuaW1wb3J0IHsgaW5qZWN0LCB0eXBlIFR5cGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGluamVjdFN0b3JlPFQ+KHN0b3JlOiBUeXBlPFQ+KTogVCB7XHJcbiAgcmV0dXJuIGluamVjdChzdG9yZSlcclxufSJdfQ==
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './index';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdzdGF0by1hbmd1bGFyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL25nc3RhdG8tYW5ndWxhci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsU0FBUyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHZW5lcmF0ZWQgYnVuZGxlIGluZGV4LiBEbyBub3QgZWRpdC5cbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2luZGV4JztcbiJdfQ==
@@ -0,0 +1,22 @@
1
+ import { makeEnvironmentProviders, InjectionToken, isDevMode } from '@angular/core';
2
+ import { configureHttp, devTools } from '@ngstato/core';
3
+ export const STATO_CONFIG = new InjectionToken('STATO_CONFIG');
4
+ export function provideStato(config = {}) {
5
+ if (config.http) {
6
+ configureHttp(config.http);
7
+ }
8
+ // DevTools — ignorés automatiquement en production
9
+ // isDevMode() est géré par Angular au build
10
+ // → false en prod même si devtools: true
11
+ if (config.devtools && isDevMode()) {
12
+ console.info('%c[Stato] 🛠 DevTools activés', 'background:#1e40af;color:white;padding:4px 8px;border-radius:4px;font-weight:bold');
13
+ devTools.open();
14
+ }
15
+ return makeEnvironmentProviders([
16
+ {
17
+ provide: STATO_CONFIG,
18
+ useValue: config
19
+ }
20
+ ]);
21
+ }
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZS1uZ3N0YXRvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Byb3ZpZGUtbmdzdGF0by50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsd0JBQXdCLEVBQ3hCLGNBQWMsRUFDZCxTQUFTLEVBQ1YsTUFBK0IsZUFBZSxDQUFBO0FBQy9DLE9BQU8sRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBUXZELE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxJQUFJLGNBQWMsQ0FBcUIsY0FBYyxDQUFDLENBQUE7QUFFbEYsTUFBTSxVQUFVLFlBQVksQ0FBQyxTQUE2QixFQUFFO0lBRTFELElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2hCLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDNUIsQ0FBQztJQUVELG1EQUFtRDtJQUNuRCw0Q0FBNEM7SUFDNUMseUNBQXlDO0lBQ3pDLElBQUksTUFBTSxDQUFDLFFBQVEsSUFBSSxTQUFTLEVBQUUsRUFBRSxDQUFDO1FBQ25DLE9BQU8sQ0FBQyxJQUFJLENBQ1YsK0JBQStCLEVBQy9CLG1GQUFtRixDQUNwRixDQUFBO1FBQ0QsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFBO0lBQ2pCLENBQUM7SUFFRCxPQUFPLHdCQUF3QixDQUFDO1FBQzlCO1lBQ0UsT0FBTyxFQUFHLFlBQVk7WUFDdEIsUUFBUSxFQUFFLE1BQU07U0FDakI7S0FDRixDQUFDLENBQUE7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBtYWtlRW52aXJvbm1lbnRQcm92aWRlcnMsXHJcbiAgSW5qZWN0aW9uVG9rZW4sXHJcbiAgaXNEZXZNb2RlXHJcbn0gICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gJ0Bhbmd1bGFyL2NvcmUnXHJcbmltcG9ydCB7IGNvbmZpZ3VyZUh0dHAsIGRldlRvb2xzIH0gZnJvbSAnQG5nc3RhdG8vY29yZSdcclxuaW1wb3J0IHR5cGUgeyBTdGF0b0NvbmZpZyB9ICAgICAgICBmcm9tICdAbmdzdGF0by9jb3JlJ1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBTdGF0b0FuZ3VsYXJDb25maWcge1xyXG4gIGh0dHA/OiAgICAgU3RhdG9Db25maWdcclxuICBkZXZ0b29scz86IGJvb2xlYW5cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IFNUQVRPX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxTdGF0b0FuZ3VsYXJDb25maWc+KCdTVEFUT19DT05GSUcnKVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHByb3ZpZGVTdGF0byhjb25maWc6IFN0YXRvQW5ndWxhckNvbmZpZyA9IHt9KSB7XHJcblxyXG4gIGlmIChjb25maWcuaHR0cCkge1xyXG4gICAgY29uZmlndXJlSHR0cChjb25maWcuaHR0cClcclxuICB9XHJcblxyXG4gIC8vIERldlRvb2xzIOKAlCBpZ25vcsOpcyBhdXRvbWF0aXF1ZW1lbnQgZW4gcHJvZHVjdGlvblxyXG4gIC8vIGlzRGV2TW9kZSgpIGVzdCBnw6lyw6kgcGFyIEFuZ3VsYXIgYXUgYnVpbGRcclxuICAvLyDihpIgZmFsc2UgZW4gcHJvZCBtw6ptZSBzaSBkZXZ0b29sczogdHJ1ZVxyXG4gIGlmIChjb25maWcuZGV2dG9vbHMgJiYgaXNEZXZNb2RlKCkpIHtcclxuICAgIGNvbnNvbGUuaW5mbyhcclxuICAgICAgJyVjW1N0YXRvXSDwn5ugIERldlRvb2xzIGFjdGl2w6lzJyxcclxuICAgICAgJ2JhY2tncm91bmQ6IzFlNDBhZjtjb2xvcjp3aGl0ZTtwYWRkaW5nOjRweCA4cHg7Ym9yZGVyLXJhZGl1czo0cHg7Zm9udC13ZWlnaHQ6Ym9sZCdcclxuICAgIClcclxuICAgIGRldlRvb2xzLm9wZW4oKVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbXHJcbiAgICB7XHJcbiAgICAgIHByb3ZpZGU6ICBTVEFUT19DT05GSUcsXHJcbiAgICAgIHVzZVZhbHVlOiBjb25maWdcclxuICAgIH1cclxuICBdKVxyXG59Il19