PageSourceSearch

https://stridenavigation.com/chunk-XEWI7JQG.js

js stridenavigation.com collected 2026-09-24 14:53:42 UTC 139,430 bytes, 2,750 lines download raw bytes

1import {
2  RigaDateTimeService
3} from "./chunk-RAL4KSWL.js";
4import {
5  Clipboard
6} from "./chunk-Q4KBCFNF.js";
7import {
8  AlertController,
9  IonBadge,
10  IonButton,
11  IonButtons,
12  IonCard,
13  IonCardContent,
14  IonCardHeader,
15  IonCardTitle,
16  IonChip,
17  IonCol,
18  IonContent,
19  IonGrid,
20  IonHeader,
21  IonInput,
22  IonItem,
23  IonLabel,
24  IonList,
25  IonMenuButton,
26  IonNote,
27  IonProgressBar,
28  IonRefresher,
29  IonRefresherContent,
30  IonRow,
31  IonSegment,
32  IonSegmentButton,
33  IonSelect,
34  IonSelectOption,
35  IonSpinner,
36  IonTextarea,
37  IonTitle,
38  IonToggle,
39  IonToolbar
40} from "./chunk-RLZ522BW.js";
41import {
42  ToastService
43} from "./chunk-GR5DEE5Y.js";
44import {
45  TranslateModule,
46  TranslatePipe,
47  TranslateService
48} from "./chunk-O5XYYQCR.js";
49import {
50  ApiUrlService
51} from "./chunk-MAIAEXGG.js";
52import "./chunk-L4O6SE3A.js";
53import "./chunk-INK5THDW.js";
54import {
55  NgIcon,
56  lucideActivity,
57  lucideCheck,
58  lucideChevronDown,
59  lucideChevronUp,
60  lucideCircle,
61  lucideCircleDot,
62  lucideClock,
63  lucideCopy,
64  lucideExternalLink,
65  lucideEye,
66  lucideEyeOff,
67  lucideFilter,
68  lucideFlaskConical,
69  lucidePencil,
70  lucidePlay,
71  lucidePlus,
72  lucideRefreshCw,
73  lucideRotateCw,
74  lucideTrash2,
75  lucideTriangleAlert,
76  lucideWebhook,
77  lucideX,
78  lucideZap,
79  provideIcons
80} from "./chunk-GMPIA5L4.js";
81import {
82  CommonModule,
83  Component,
84  DecimalPipe,
85  FormBuilder,
86  FormControlName,
87  FormGroupDirective,
88  HttpClient,
89  HttpParams,
90  Injectable,
91  NgControlStatus,
92  NgControlStatusGroup,
93  ReactiveFormsModule,
94  Validators,
95  delay,
96  finalize,
97  of,
98  setClassMetadata,
99  ɵNgNoValidate,
100  ɵsetClassDebugInfo,
101  ɵɵProvidersFeature,
102  ɵɵadvance,
103  ɵɵclassProp,
104  ɵɵconditional,
105  ɵɵdefineComponent,
106  ɵɵdefineInjectable,
107  ɵɵdirectiveInject,
108  ɵɵelement,
109  ɵɵelementEnd,
110  ɵɵelementStart,
111  ɵɵgetCurrentView,
112  ɵɵinject,
113  ɵɵlistener,
114  ɵɵnextContext,
115  ɵɵpipe,
116  ɵɵpipeBind1,
117  ɵɵpipeBind2,
118  ɵɵproperty,
119  ɵɵpropertyInterpolate,
120  ɵɵrepeater,
121  ɵɵrepeaterCreate,
122  ɵɵrepeaterTrackByIdentity,
123  ɵɵresetView,
124  ɵɵrestoreView,
125  ɵɵsanitizeUrl,
126  ɵɵtemplate,
127  ɵɵtext,
128  ɵɵtextInterpolate,
129  ɵɵtextInterpolate1,
130  ɵɵtextInterpolate2
131} from "./chunk-UQ6LLOJ6.js";
132import "./chunk-BD3NMR2S.js";
133import "./chunk-6HPUB4U6.js";
134import "./chunk-WGFJL45C.js";
135import "./chunk-7WVISTDL.js";
136import "./chunk-2S57T3GS.js";
137import "./chunk-R4QHACMO.js";
138import "./chunk-4MEJEBWM.js";
139import "./chunk-RIBVNXHQ.js";
140import "./chunk-Z42OVMMO.js";
141import "./chunk-O5S42IXR.js";
142import "./chunk-QBR2RTFG.js";
143import "./chunk-MIOLVGSM.js";
144import "./chunk-V3YFOG6Q.js";
145import "./chunk-LPMBLWVS.js";
146import "./chunk-5LKHIIQE.js";
147import "./chunk-ITE2OHLM.js";
148import "./chunk-C46CB72A.js";
149import "./chunk-SRPSML5O.js";
150import "./chunk-NRSVX4KN.js";
151import "./chunk-T4GYAOTA.js";
152import "./chunk-2VHYZHLL.js";
153import "./chunk-S6LHOZ5A.js";
154import "./chunk-Y6HZOH3Q.js";
155import "./chunk-TWQHADEW.js";
156import "./chunk-3J4L7S6G.js";
157import "./chunk-IL42VKT6.js";
158import "./chunk-LONO5O5R.js";
159import "./chunk-KFBF5L4X.js";
160import "./chunk-PWC4K6CW.js";
161import "./chunk-R6JLIESI.js";
162import "./chunk-UG6K57PI.js";
163import "./chunk-UR6VIRNL.js";
164import "./chunk-OJO5RD3M.js";
165import {
166  __async
167} from "./chunk-CO64IJQE.js";
168
169// src/app/pages/webhook-sandbox/webhook-mock-data.ts
170var _WebhookMockData = class _WebhookMockData {
171  static generateDeliveries() {
172    const deliveries = [];
173    const entityTypes = ["Room", "Person", "PersonRoom", "Building", "Floor"];
174    const eventTypes = ["Created", "Updated", "Deleted"];
175    const statuses = ["Delivered", "Delivered", "Delivered", "Delivered", "Failed", "Retrying", "Pending"];
176    const targetUrls = [
177      "https://med.stridenavigation.com/api/v2/webhooks/ehr",
178      "https://med.stridenavigation.com/api/nurse-station/location",
179      "https://med.stridenavigation.com/analytics/ingest"
180    ];
181    for (let i = 0; i < 25; i++) {
182      const status = statuses[Math.floor(Math.random() * statuses.length)];
183      const entityType = entityTypes[Math.floor(Math.random() * entityTypes.length)];
184      const eventType = eventTypes[Math.floor(Math.random() * eventTypes.length)];
185      const targetUrl = targetUrls[Math.floor(Math.random() * targetUrls.length)];
186      const createdAt = new Date(Date.now() - i * 8 * 60 * 1e3);
187      const delivery = {
188        id: `mock-delivery-${i + 1}`,
189        webhookSubscriptionId: "mock-sub-1",
190        subscriptionTargetUrl: targetUrl,
191        entityType,
192        eventType,
193        entityId: `entity-${1e3 + i}`,
194        campusId: "campus-1",
195        status,
196        attemptCount: status === "Retrying" ? Math.floor(Math.random() * 4) + 1 : 1,
197        createdAt: createdAt.toISOString()
198      };
199      if (status === "Delivered") {
200        delivery.httpStatusCode = Math.random() > 0.3 ? 200 : 201;
201        delivery.responseTimeMs = Math.floor(Math.random() * 200) + 20;
202        delivery.deliveredAt = new Date(createdAt.getTime() + delivery.responseTimeMs).toISOString();
203      } else if (status === "Failed") {
204        delivery.httpStatusCode = [500, 502, 503, 504, 408][Math.floor(Math.random() * 5)];
205        delivery.errorMessage = _WebhookMockData.getErrorMessage(delivery.httpStatusCode);
206        delivery.responseTimeMs = Math.floor(Math.random() * 5e3) + 1e3;
207      } else if (status === "Retrying") {
208        delivery.httpStatusCode = 503;
209        delivery.errorMessage = "Service temporarily unavailable";
210        delivery.nextRetryAt = new Date(Date.now() + Math.floor(Math.random() * 300) * 1e3).toISOString();
211      }
212      deliveries.push(delivery);
213    }
214    return deliveries;
215  }
216  static getErrorMessage(statusCode) {
217    const messages = {
218      500: "Internal server error: upstream service crashed",
219      502: "Bad gateway: load balancer could not reach backend",
220      503: "Service unavailable: server is under maintenance",
221      504: "Gateway timeout: request exceeded 30s limit",
222      408: "Request timeout: connection timed out after 10s"
223    };
224    return messages[statusCode] || "Unknown error";
225  }
226  static getSubscriptions() {
227    return {
228      items: [...this.MOCK_SUBSCRIPTIONS],
229      totalCount: this.MOCK_SUBSCRIPTIONS.length,
230      page: 1,
231      pageSize: 100,
232      totalPages: 1,
233      hasNextPage: false,
234      hasPreviousPage: false
235    };
236  }
237  static getDeliveries(status, page = 1, pageSize = 20) {
238    let items = this.generateDeliveries();
239    if (status && status !== "all") {
240      items = items.filter((d) => d.status === status);
241    }
242    const start = (page - 1) * pageSize;
243    const paginatedItems = items.slice(start, start + pageSize);
244    return {
245      items: paginatedItems,
246      totalCount: items.length,
247      page,
248      pageSize,
249      totalPages: Math.ceil(items.length / pageSize),
250      hasNextPage: start + pageSize < items.length,
251      hasPreviousPage: page > 1
252    };
253  }
254  static getStats() {
255    return {
256      subscriptions: {
257        total: 4,
258        active: 3,
259        circuitOpen: 1
260      },
261      deliveries: {
262        last24Hours: {
263          total: 1247,
264          delivered: 1176,
265          failed: 42,
266          retrying: 18,
267          pending: 11
268        },
269        last7Days: {
270          total: 8432,
271          delivered: 7891,
272          failed: 541
273        }
274      },
275      events: {
276        pending: 23,
277        processedLast24Hours: 4521
278      }
279    };
280  }
281};
282_WebhookMockData.MOCK_SUBSCRIPTIONS = [
283  {
284    id: "mock-sub-1",
285    targetUrl: "https://med.stridenavigation.com/api/v2/webhooks/ehr",
286    description: "EHR patient location sync - production",
287    entityTypes: ["Room", "Person", "PersonRoom"],
288    eventTypes: ["Created", "Updated", "Deleted"],
289    isActive: true,
290    secretPrefix: "whsec_prod",
291    totalDeliveries: 1247,
292    totalFailures: 42,
293    consecutiveFailures: 0,
294    lastDeliveryAt: new Date(Date.now() - 2 * 60 * 1e3).toISOString(),
295    lastSuccessAt: new Date(Date.now() - 2 * 60 * 1e3).toISOString(),
296    createdAt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3).toISOString(),
297    apiKeyName: "EHR Integration Key"
298  },
299  {
300    id: "mock-sub-2",
301    targetUrl: "https://med.stridenavigation.com/api/nurse-station/location",
302    description: "Nurse station display - real-time updates",
303    entityTypes: ["PersonRoom"],
304    eventTypes: ["Created", "Updated"],
305    isActive: true,
306    secretPrefix: "whsec_nurse",
307    totalDeliveries: 3891,
308    totalFailures: 12,
309    consecutiveFailures: 0,
310    lastDeliveryAt: new Date(Date.now() - 45 * 1e3).toISOString(),
311    lastSuccessAt: new Date(Date.now() - 45 * 1e3).toISOString(),
312    createdAt: new Date(Date.now() - 14 * 24 * 60 * 60 * 1e3).toISOString(),
313    apiKeyName: "Nurse Station API"
314  },
315  {
316    id: "mock-sub-3",
317    targetUrl: "https://med.stridenavigation.com/legacy/webhook-bridge",
318    description: "Legacy system bridge (deprecated)",
319    entityTypes: ["Room", "Building", "Floor"],
320    eventTypes: ["Updated"],
321    isActive: false,
322    secretPrefix: "whsec_legacy",
323    totalDeliveries: 156,
324    totalFailures: 89,
325    consecutiveFailures: 5,
326    lastDeliveryAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1e3).toISOString(),
327    lastSuccessAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1e3).toISOString(),
328    circuitBrokenUntil: new Date(Date.now() + 15 * 60 * 1e3).toISOString(),
329    createdAt: new Date(Date.now() - 90 * 24 * 60 * 60 * 1e3).toISOString(),
330    apiKeyName: "Legacy Bridge"
331  },
332  {
333    id: "mock-sub-4",
334    targetUrl: "https://med.stridenavigation.com/analytics/ingest",
335    description: "Analytics data pipeline",
336    entityTypes: ["Room", "Person", "PersonRoom", "Building", "Floor"],
337    eventTypes: ["Created", "Updated", "Deleted"],
338    isActive: true,
339    secretPrefix: "whsec_analytics",
340    totalDeliveries: 8432,
341    totalFailures: 23,
342    consecutiveFailures: 0,
343    lastDeliveryAt: new Date(Date.now() - 5 * 60 * 1e3).toISOString(),
344    lastSuccessAt: new Date(Date.now() - 5 * 60 * 1e3).toISOString(),
345    createdAt: new Date(Date.now() - 60 * 24 * 60 * 60 * 1e3).toISOString(),
346    apiKeyName: "Analytics Pipeline"
347  }
348];
349var WebhookMockData = _WebhookMockData;
350
351// src/app/services/webhook/webhook.models.ts
352var ENTITY_TYPES = ["Room", "Person", "PersonRoom", "Building", "Floor"];
353var EVENT_TYPES = ["Created", "Updated", "Deleted"];
354
355// src/app/services/webhook/webhook.service.ts
356var _WebhookService = class _WebhookService {
357  constructor(http, apiUrlService) {
358    this.http = http;
359    this.apiUrlService = apiUrlService;
360    this.adminBaseUrl = this.apiUrlService.getSelectedUrl() + "/api/admin/webhooks";
361    this.apiUrlService.selectedUrl$.subscribe((url) => {
362      this.adminBaseUrl = url + "/api/admin/webhooks";
363    });
364  }
365  // Subscriptions
366  getSubscriptions(params) {
367    let httpParams = new HttpParams();
368    if (params) {
369      if (params.apiKeyId)
370        httpParams = httpParams.set("apiKeyId", params.apiKeyId);
371      if (params.isActive !== void 0)
372        httpParams = httpParams.set("isActive", params.isActive.toString());
373      if (params.page)
374        httpParams = httpParams.set("page", params.page.toString());
375      if (params.pageSize)
376        httpParams = httpParams.set("pageSize", params.pageSize.toString());
377    }
378    return this.http.get(`${this.adminBaseUrl}/subscriptions`, { params: httpParams });
379  }
380  getSubscription(id) {
381    return this.http.get(`${this.adminBaseUrl}/subscriptions/${id}`);
382  }
383  createSubscription(request) {
384    return this.http.post(`${this.adminBaseUrl}/subscriptions`, request);
385  }
386  updateSubscription(id, request) {
387    return this.http.put(`${this.adminBaseUrl}/subscriptions/${id}`, request);
388  }
389  deleteSubscription(id) {
390    return this.http.delete(`${this.adminBaseUrl}/subscriptions/${id}`);
391  }
392  testSubscription(id) {
393    return this.http.post(`${this.adminBaseUrl}/subscriptions/${id}/test`, {});
394  }
395  resetCircuitBreaker(id) {
396    return this.http.post(`${this.adminBaseUrl}/subscriptions/${id}/reset-circuit`, {});
397  }
398  // Deliveries
399  getDeliveries(params) {
400    let httpParams = new HttpParams();
401    if (params) {
402      if (params.subscriptionId)
403        httpParams = httpParams.set("subscriptionId", params.subscriptionId);
404      if (params.status)
405        httpParams = httpParams.set("status", params.status);
406      if (params.entityType)
407        httpParams = httpParams.set("entityType", params.entityType);
408      if (params.from)
409        httpParams = httpParams.set("from", params.from);
410      if (params.to)
411        httpParams = httpParams.set("to", params.to);
412      if (params.page)
413        httpParams = httpParams.set("page", params.page.toString());
414      if (params.pageSize)
415        httpParams = httpParams.set("pageSize", params.pageSize.toString());
416    }
417    return this.http.get(`${this.adminBaseUrl}/deliveries`, { params: httpParams });
418  }
419  retryDelivery(id) {
420    return this.http.post(`${this.adminBaseUrl}/deliveries/${id}/retry`, {});
421  }
422  // Statistics
423  getStats() {
424    return this.http.get(`${this.adminBaseUrl}/stats`);
425  }
426};
427_WebhookService.\u0275fac = function WebhookService_Factory(__ngFactoryType__) {
428  return new (__ngFactoryType__ || _WebhookService)(\u0275\u0275inject(HttpClient), \u0275\u0275inject(ApiUrlService));
429};
430_WebhookService.\u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _WebhookService, factory: _WebhookService.\u0275fac, providedIn: "root" });
431var WebhookService = _WebhookService;
432(() => {
433  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(WebhookService, [{
434    type: Injectable,
435    args: [{
436      providedIn: "root"
437    }]
438  }], () => [{ type: HttpClient }, { type: ApiUrlService }], null);
439})();
440
441// src/app/pages/webhook-sandbox/webhook-sandbox.page.ts
442var _forTrack0 = ($index, $item) => $item.id;
443function WebhookSandboxPage_Conditional_30_Conditional_1_Template(rf, ctx) {
444  if (rf & 1) {
445    \u0275\u0275elementStart(0, "div", 14);
446    \u0275\u0275element(1, "ion-spinner", 19);
447    \u0275\u0275elementEnd();
448  }
449}
450function WebhookSandboxPage_Conditional_30_Conditional_2_Template(rf, ctx) {
451  if (rf & 1) {
452    \u0275\u0275elementStart(0, "div", 15);
453    \u0275\u0275element(1, "ng-icon", 20);
454    \u0275\u0275elementStart(2, "p");
455    \u0275\u0275text(3);
456    \u0275\u0275pipe(4, "translate");
457    \u0275\u0275elementEnd()();
458  }
459  if (rf & 2) {
460    \u0275\u0275advance(3);
461    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(4, 1, "webhookSandbox.subscriptions.noSubscriptions"));
462  }
463}
464function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_14_Template(rf, ctx) {
465  if (rf & 1) {
466    \u0275\u0275element(0, "ng-icon", 32);
467  }
468}
469function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_15_Template(rf, ctx) {
470  if (rf & 1) {
471    \u0275\u0275element(0, "ng-icon", 33);
472  }
473}
474function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_16_Template(rf, ctx) {
475  if (rf & 1) {
476    \u0275\u0275elementStart(0, "ion-card-title", 34);
477    \u0275\u0275text(1);
478    \u0275\u0275elementEnd();
479  }
480  if (rf & 2) {
481    const sub_r3 = \u0275\u0275nextContext().$implicit;
482    \u0275\u0275advance();
483    \u0275\u0275textInterpolate(sub_r3.description);
484  }
485}
486function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_For_21_Template(rf, ctx) {
487  if (rf & 1) {
488    \u0275\u0275elementStart(0, "ion-chip", 37);
489    \u0275\u0275text(1);
490    \u0275\u0275pipe(2, "translate");
491    \u0275\u0275elementEnd();
492  }
493  if (rf & 2) {
494    const et_r5 = ctx.$implicit;
495    \u0275\u0275advance();
496    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(2, 1, "webhookSandbox.entityTypes." + et_r5));
497  }
498}
499function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_For_26_Template(rf, ctx) {
500  if (rf & 1) {
501    \u0275\u0275elementStart(0, "ion-chip", 39);
502    \u0275\u0275text(1);
503    \u0275\u0275pipe(2, "translate");
504    \u0275\u0275elementEnd();
505  }
506  if (rf & 2) {
507    const evt_r6 = ctx.$implicit;
508    \u0275\u0275advance();
509    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(2, 1, "webhookSandbox.eventTypes." + evt_r6));
510  }
511}
512function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_28_Template(rf, ctx) {
513  if (rf & 1) {
514    \u0275\u0275elementStart(0, "ion-badge", 41);
515    \u0275\u0275element(1, "ng-icon", 47);
516    \u0275\u0275text(2);
517    \u0275\u0275pipe(3, "translate");
518    \u0275\u0275elementEnd();
519  }
520  if (rf & 2) {
521    const sub_r3 = \u0275\u0275nextContext().$implicit;
522    const ctx_r3 = \u0275\u0275nextContext(3);
523    \u0275\u0275advance(2);
524    \u0275\u0275textInterpolate2(" ", \u0275\u0275pipeBind1(3, 2, "webhookSandbox.subscriptions.circuitOpen"), " (", ctx_r3.getCircuitOpenUntil(sub_r3), ") ");
525  }
526}
527function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_29_Template(rf, ctx) {
528  if (rf & 1) {
529    \u0275\u0275elementStart(0, "ion-badge", 42);
530    \u0275\u0275element(1, "ng-icon", 48);
531    \u0275\u0275text(2);
532    \u0275\u0275pipe(3, "translate");
533    \u0275\u0275elementEnd();
534  }
535  if (rf & 2) {
536    \u0275\u0275advance(2);
537    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(3, 1, "webhookSandbox.subscriptions.active"), " ");
538  }
539}
540function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_30_Template(rf, ctx) {
541  if (rf & 1) {
542    \u0275\u0275elementStart(0, "ion-badge", 43);
543    \u0275\u0275text(1);
544    \u0275\u0275pipe(2, "translate");
545    \u0275\u0275elementEnd();
546  }
547  if (rf & 2) {
548    \u0275\u0275advance();
549    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(2, 1, "webhookSandbox.subscriptions.inactive"), " ");
550  }
551}
552function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_33_Template(rf, ctx) {
553  if (rf & 1) {
554    \u0275\u0275elementStart(0, "span", 45);
555    \u0275\u0275text(1);
556    \u0275\u0275elementEnd();
557  }
558  if (rf & 2) {
559    const sub_r3 = \u0275\u0275nextContext().$implicit;
560    \u0275\u0275advance();
561    \u0275\u0275textInterpolate1("", sub_r3.totalFailures, " failed");
562  }
563}
564function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Conditional_6_Template(rf, ctx) {
565  if (rf & 1) {
566    \u0275\u0275elementStart(0, "p", 51);
567    \u0275\u0275text(1);
568    \u0275\u0275elementEnd();
569  }
570  if (rf & 2) {
571    const sub_r3 = \u0275\u0275nextContext(2).$implicit;
572    const ctx_r3 = \u0275\u0275nextContext(3);
573    \u0275\u0275advance();
574    \u0275\u0275textInterpolate1("Last delivery: ", ctx_r3.formatTimeAgo(sub_r3.lastDeliveryAt), "");
575  }
576}
577function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Conditional_7_Template(rf, ctx) {
578  if (rf & 1) {
579    \u0275\u0275elementStart(0, "p", 51);
580    \u0275\u0275text(1);
581    \u0275\u0275elementEnd();
582  }
583  if (rf & 2) {
584    const sub_r3 = \u0275\u0275nextContext(2).$implicit;
585    const ctx_r3 = \u0275\u0275nextContext(3);
586    \u0275\u0275advance();
587    \u0275\u0275textInterpolate1("Last success: ", ctx_r3.formatTimeAgo(sub_r3.lastSuccessAt), "");
588  }
589}
590function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Conditional_8_Template(rf, ctx) {
591  if (rf & 1) {
592    \u0275\u0275elementStart(0, "p", 51);
593    \u0275\u0275text(1);
594    \u0275\u0275elementEnd();
595  }
596  if (rf & 2) {
597    const sub_r3 = \u0275\u0275nextContext(2).$implicit;
598    \u0275\u0275advance();
599    \u0275\u0275textInterpolate1("Secret: ", sub_r3.secretPrefix, "...");
600  }
601}
602function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Conditional_10_Template(rf, ctx) {
603  if (rf & 1) {
604    const _r8 = \u0275\u0275getCurrentView();
605    \u0275\u0275elementStart(0, "ion-button", 56);
606    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Conditional_10_Template_ion_button_click_0_listener() {
607      \u0275\u0275restoreView(_r8);
608      const sub_r3 = \u0275\u0275nextContext(2).$implicit;
609      const ctx_r3 = \u0275\u0275nextContext(3);
610      return \u0275\u0275resetView(ctx_r3.resetCircuitBreaker(sub_r3));
611    });
612    \u0275\u0275element(1, "ng-icon", 57);
613    \u0275\u0275text(2, " Reset Circuit ");
614    \u0275\u0275elementEnd();
615  }
616}
617function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Template(rf, ctx) {
618  if (rf & 1) {
619    const _r7 = \u0275\u0275getCurrentView();
620    \u0275\u0275elementStart(0, "div", 46)(1, "ion-item", 49)(2, "ion-label");
621    \u0275\u0275text(3);
622    \u0275\u0275pipe(4, "translate");
623    \u0275\u0275elementEnd();
624    \u0275\u0275elementStart(5, "ion-toggle", 50);
625    \u0275\u0275listener("ionChange", function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Template_ion_toggle_ionChange_5_listener() {
626      \u0275\u0275restoreView(_r7);
627      const sub_r3 = \u0275\u0275nextContext().$implicit;
628      const ctx_r3 = \u0275\u0275nextContext(3);
629      return \u0275\u0275resetView(ctx_r3.toggleSubscriptionActive(sub_r3));
630    });
631    \u0275\u0275elementEnd()();
632    \u0275\u0275template(6, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Conditional_6_Template, 2, 1, "p", 51)(7, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Conditional_7_Template, 2, 1, "p", 51)(8, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Conditional_8_Template, 2, 1, "p", 51);
633    \u0275\u0275elementStart(9, "div", 52);
634    \u0275\u0275template(10, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Conditional_10_Template, 3, 0, "ion-button", 53);
635    \u0275\u0275elementStart(11, "ion-button", 54);
636    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Template_ion_button_click_11_listener() {
637      \u0275\u0275restoreView(_r7);
638      const sub_r3 = \u0275\u0275nextContext().$implicit;
639      const ctx_r3 = \u0275\u0275nextContext(3);
640      return \u0275\u0275resetView(ctx_r3.confirmDeleteSubscription(sub_r3));
641    });
642    \u0275\u0275element(12, "ng-icon", 55);
643    \u0275\u0275text(13);
644    \u0275\u0275pipe(14, "translate");
645    \u0275\u0275elementEnd()()();
646  }
647  if (rf & 2) {
648    const sub_r3 = \u0275\u0275nextContext().$implicit;
649    const ctx_r3 = \u0275\u0275nextContext(3);
650    \u0275\u0275advance(3);
651    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(4, 7, "webhookSandbox.subscriptions.active"));
652    \u0275\u0275advance(2);
653    \u0275\u0275property("checked", sub_r3.isActive);
654    \u0275\u0275advance();
655    \u0275\u0275conditional(sub_r3.lastDeliveryAt ? 6 : -1);
656    \u0275\u0275advance();
657    \u0275\u0275conditional(sub_r3.lastSuccessAt ? 7 : -1);
658    \u0275\u0275advance();
659    \u0275\u0275conditional(sub_r3.secretPrefix ? 8 : -1);
660    \u0275\u0275advance(2);
661    \u0275\u0275conditional(ctx_r3.isCircuitOpen(sub_r3) ? 10 : -1);
662    \u0275\u0275advance(3);
663    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(14, 9, "webhookSandbox.subscriptions.delete"), " ");
664  }
665}
666function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Template(rf, ctx) {
667  if (rf & 1) {
668    const _r2 = \u0275\u0275getCurrentView();
669    \u0275\u0275elementStart(0, "ion-card", 22)(1, "ion-card-header")(2, "div", 23)(3, "div", 24)(4, "span", 25);
670    \u0275\u0275text(5);
671    \u0275\u0275elementEnd();
672    \u0275\u0275elementStart(6, "a", 26);
673    \u0275\u0275element(7, "ng-icon", 27);
674    \u0275\u0275elementEnd()();
675    \u0275\u0275elementStart(8, "div", 28)(9, "ion-button", 29);
676    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Template_ion_button_click_9_listener() {
677      const sub_r3 = \u0275\u0275restoreView(_r2).$implicit;
678      const ctx_r3 = \u0275\u0275nextContext(3);
679      return \u0275\u0275resetView(ctx_r3.testSubscription(sub_r3));
680    });
681    \u0275\u0275element(10, "ng-icon", 30);
682    \u0275\u0275elementEnd();
683    \u0275\u0275elementStart(11, "ion-button", 29);
684    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Template_ion_button_click_11_listener() {
685      const sub_r3 = \u0275\u0275restoreView(_r2).$implicit;
686      const ctx_r3 = \u0275\u0275nextContext(3);
687      return \u0275\u0275resetView(ctx_r3.openEditForm(sub_r3));
688    });
689    \u0275\u0275element(12, "ng-icon", 31);
690    \u0275\u0275elementEnd();
691    \u0275\u0275elementStart(13, "ion-button", 29);
692    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Template_ion_button_click_13_listener() {
693      const sub_r3 = \u0275\u0275restoreView(_r2).$implicit;
694      const ctx_r3 = \u0275\u0275nextContext(3);
695      return \u0275\u0275resetView(ctx_r3.toggleSubscriptionExpand(sub_r3.id));
696    });
697    \u0275\u0275template(14, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_14_Template, 1, 0, "ng-icon", 32)(15, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_15_Template, 1, 0, "ng-icon", 33);
698    \u0275\u0275elementEnd()()();
699    \u0275\u0275template(16, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_16_Template, 2, 1, "ion-card-title", 34);
700    \u0275\u0275elementEnd();
701    \u0275\u0275elementStart(17, "ion-card-content")(18, "div", 35)(19, "div", 36);
702    \u0275\u0275repeaterCreate(20, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_For_21_Template, 3, 3, "ion-chip", 37, \u0275\u0275repeaterTrackByIdentity);
703    \u0275\u0275elementEnd();
704    \u0275\u0275elementStart(22, "span", 38);
705    \u0275\u0275text(23, "|");
706    \u0275\u0275elementEnd();
707    \u0275\u0275elementStart(24, "div", 36);
708    \u0275\u0275repeaterCreate(25, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_For_26_Template, 3, 3, "ion-chip", 39, \u0275\u0275repeaterTrackByIdentity);
709    \u0275\u0275elementEnd()();
710    \u0275\u0275elementStart(27, "div", 40);
711    \u0275\u0275template(28, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_28_Template, 4, 4, "ion-badge", 41)(29, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_29_Template, 4, 3, "ion-badge", 42)(30, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_30_Template, 3, 3, "ion-badge", 43);
712    \u0275\u0275elementStart(31, "span", 44);
713    \u0275\u0275text(32);
714    \u0275\u0275elementEnd();
715    \u0275\u0275template(33, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_33_Template, 2, 1, "span", 45);
716    \u0275\u0275elementEnd();
717    \u0275\u0275template(34, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Conditional_34_Template, 15, 11, "div", 46);
718    \u0275\u0275elementEnd()();
719  }
720  if (rf & 2) {
721    const sub_r3 = ctx.$implicit;
722    const ctx_r3 = \u0275\u0275nextContext(3);
723    \u0275\u0275classProp("circuit-open", ctx_r3.isCircuitOpen(sub_r3));
724    \u0275\u0275advance(5);
725    \u0275\u0275textInterpolate(sub_r3.targetUrl);
726    \u0275\u0275advance();
727    \u0275\u0275property("href", sub_r3.targetUrl, \u0275\u0275sanitizeUrl);
728    \u0275\u0275advance(8);
729    \u0275\u0275conditional(ctx_r3.expandedSubscriptionId === sub_r3.id ? 14 : 15);
730    \u0275\u0275advance(2);
731    \u0275\u0275conditional(sub_r3.description ? 16 : -1);
732    \u0275\u0275advance(4);
733    \u0275\u0275repeater(sub_r3.entityTypes);
734    \u0275\u0275advance(5);
735    \u0275\u0275repeater(sub_r3.eventTypes);
736    \u0275\u0275advance(3);
737    \u0275\u0275conditional(ctx_r3.isCircuitOpen(sub_r3) ? 28 : sub_r3.isActive ? 29 : 30);
738    \u0275\u0275advance(4);
739    \u0275\u0275textInterpolate1("", sub_r3.totalDeliveries, " delivered");
740    \u0275\u0275advance();
741    \u0275\u0275conditional(sub_r3.totalFailures > 0 ? 33 : -1);
742    \u0275\u0275advance();
743    \u0275\u0275conditional(ctx_r3.expandedSubscriptionId === sub_r3.id ? 34 : -1);
744  }
745}
746function WebhookSandboxPage_Conditional_30_Conditional_3_Template(rf, ctx) {
747  if (rf & 1) {
748    \u0275\u0275elementStart(0, "ion-list");
749    \u0275\u0275repeaterCreate(1, WebhookSandboxPage_Conditional_30_Conditional_3_For_2_Template, 35, 10, "ion-card", 21, _forTrack0);
750    \u0275\u0275elementEnd();
751  }
752  if (rf & 2) {
753    const ctx_r3 = \u0275\u0275nextContext(2);
754    \u0275\u0275advance();
755    \u0275\u0275repeater(ctx_r3.subscriptions);
756  }
757}
758function WebhookSandboxPage_Conditional_30_Template(rf, ctx) {
759  if (rf & 1) {
760    const _r1 = \u0275\u0275getCurrentView();
761    \u0275\u0275elementStart(0, "div", 12);
762    \u0275\u0275template(1, WebhookSandboxPage_Conditional_30_Conditional_1_Template, 2, 0, "div", 14)(2, WebhookSandboxPage_Conditional_30_Conditional_2_Template, 5, 3, "div", 15)(3, WebhookSandboxPage_Conditional_30_Conditional_3_Template, 3, 0, "ion-list");
763    \u0275\u0275elementStart(4, "div", 16)(5, "ion-button", 17);
764    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_30_Template_ion_button_click_5_listener() {
765      \u0275\u0275restoreView(_r1);
766      const ctx_r3 = \u0275\u0275nextContext();
767      return \u0275\u0275resetView(ctx_r3.openCreateForm());
768    });
769    \u0275\u0275element(6, "ng-icon", 18);
770    \u0275\u0275text(7);
771    \u0275\u0275pipe(8, "translate");
772    \u0275\u0275elementEnd()()();
773  }
774  if (rf & 2) {
775    const ctx_r3 = \u0275\u0275nextContext();
776    \u0275\u0275advance();
777    \u0275\u0275conditional(ctx_r3.isLoadingSubscriptions ? 1 : ctx_r3.subscriptions.length === 0 ? 2 : 3);
778    \u0275\u0275advance(6);
779    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(8, 2, "webhookSandbox.subscriptions.create"), " ");
780  }
781}
782function WebhookSandboxPage_Conditional_31_Conditional_19_Template(rf, ctx) {
783  if (rf & 1) {
784    \u0275\u0275elementStart(0, "div", 14);
785    \u0275\u0275element(1, "ion-spinner", 19);
786    \u0275\u0275elementEnd();
787  }
788}
789function WebhookSandboxPage_Conditional_31_Conditional_20_Template(rf, ctx) {
790  if (rf & 1) {
791    \u0275\u0275elementStart(0, "div", 15);
792    \u0275\u0275element(1, "ng-icon", 65);
793    \u0275\u0275elementStart(2, "p");
794    \u0275\u0275text(3);
795    \u0275\u0275pipe(4, "translate");
796    \u0275\u0275elementEnd()();
797  }
798  if (rf & 2) {
799    \u0275\u0275advance(3);
800    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(4, 1, "webhookSandbox.deliveries.noDeliveries"));
801  }
802}
803function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_6_Template(rf, ctx) {
804  if (rf & 1) {
805    \u0275\u0275element(0, "ng-icon", 48);
806  }
807}
808function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_7_Template(rf, ctx) {
809  if (rf & 1) {
810    \u0275\u0275element(0, "ng-icon", 71);
811  }
812}
813function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_8_Template(rf, ctx) {
814  if (rf & 1) {
815    \u0275\u0275element(0, "ng-icon", 72);
816  }
817}
818function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_9_Template(rf, ctx) {
819  if (rf & 1) {
820    \u0275\u0275element(0, "ng-icon", 73);
821  }
822}
823function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_11_Template(rf, ctx) {
824  if (rf & 1) {
825    \u0275\u0275text(0);
826  }
827  if (rf & 2) {
828    const delivery_r10 = \u0275\u0275nextContext().$implicit;
829    \u0275\u0275textInterpolate1(" (", delivery_r10.httpStatusCode, ") ");
830  }
831}
832function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_13_Template(rf, ctx) {
833  if (rf & 1) {
834    \u0275\u0275elementStart(0, "span", 75);
835    \u0275\u0275text(1);
836    \u0275\u0275elementEnd();
837  }
838  if (rf & 2) {
839    const delivery_r10 = \u0275\u0275nextContext().$implicit;
840    \u0275\u0275advance();
841    \u0275\u0275textInterpolate(delivery_r10.subscriptionTargetUrl);
842  }
843}
844function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_14_Template(rf, ctx) {
845  if (rf & 1) {
846    \u0275\u0275elementStart(0, "span", 76);
847    \u0275\u0275text(1);
848    \u0275\u0275elementEnd();
849  }
850  if (rf & 2) {
851    const delivery_r10 = \u0275\u0275nextContext().$implicit;
852    \u0275\u0275advance();
853    \u0275\u0275textInterpolate1("", delivery_r10.responseTimeMs, "ms");
854  }
855}
856function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_17_Template(rf, ctx) {
857  if (rf & 1) {
858    \u0275\u0275elementStart(0, "div", 78);
859    \u0275\u0275text(1);
860    \u0275\u0275elementEnd();
861  }
862  if (rf & 2) {
863    const delivery_r10 = \u0275\u0275nextContext().$implicit;
864    \u0275\u0275advance();
865    \u0275\u0275textInterpolate(delivery_r10.errorMessage);
866  }
867}
868function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_18_Template(rf, ctx) {
869  if (rf & 1) {
870    const _r11 = \u0275\u0275getCurrentView();
871    \u0275\u0275elementStart(0, "ion-button", 81);
872    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_18_Template_ion_button_click_0_listener() {
873      \u0275\u0275restoreView(_r11);
874      const delivery_r10 = \u0275\u0275nextContext().$implicit;
875      const ctx_r3 = \u0275\u0275nextContext(3);
876      return \u0275\u0275resetView(ctx_r3.retryDelivery(delivery_r10));
877    });
878    \u0275\u0275element(1, "ng-icon", 57);
879    \u0275\u0275text(2);
880    \u0275\u0275pipe(3, "translate");
881    \u0275\u0275elementEnd();
882  }
883  if (rf & 2) {
884    \u0275\u0275advance(2);
885    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(3, 1, "webhookSandbox.deliveries.retry"), " ");
886  }
887}
888function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_19_Template(rf, ctx) {
889  if (rf & 1) {
890    \u0275\u0275elementStart(0, "div", 80);
891    \u0275\u0275text(1);
892    \u0275\u0275elementEnd();
893  }
894  if (rf & 2) {
895    const delivery_r10 = \u0275\u0275nextContext().$implicit;
896    const ctx_r3 = \u0275\u0275nextContext(3);
897    \u0275\u0275advance();
898    \u0275\u0275textInterpolate2(" Attempt ", delivery_r10.attemptCount, "/8 | Next: ", ctx_r3.formatTimeAgo(delivery_r10.nextRetryAt), " ");
899  }
900}
901function WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Template(rf, ctx) {
902  if (rf & 1) {
903    \u0275\u0275elementStart(0, "ion-item")(1, "div", 67)(2, "div", 68)(3, "span", 69);
904    \u0275\u0275text(4);
905    \u0275\u0275elementEnd();
906    \u0275\u0275elementStart(5, "ion-badge", 70);
907    \u0275\u0275template(6, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_6_Template, 1, 0, "ng-icon", 48)(7, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_7_Template, 1, 0, "ng-icon", 71)(8, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_8_Template, 1, 0, "ng-icon", 72)(9, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_9_Template, 1, 0, "ng-icon", 73);
908    \u0275\u0275text(10);
909    \u0275\u0275template(11, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_11_Template, 1, 1);
910    \u0275\u0275elementEnd()();
911    \u0275\u0275elementStart(12, "div", 74);
912    \u0275\u0275template(13, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_13_Template, 2, 1, "span", 75)(14, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_14_Template, 2, 1, "span", 76);
913    \u0275\u0275elementStart(15, "span", 77);
914    \u0275\u0275text(16);
915    \u0275\u0275elementEnd()();
916    \u0275\u0275template(17, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_17_Template, 2, 1, "div", 78)(18, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_18_Template, 4, 3, "ion-button", 79)(19, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Conditional_19_Template, 2, 2, "div", 80);
917    \u0275\u0275elementEnd()();
918  }
919  if (rf & 2) {
920    const delivery_r10 = ctx.$implicit;
921    const ctx_r3 = \u0275\u0275nextContext(3);
922    \u0275\u0275advance(4);
923    \u0275\u0275textInterpolate2("", delivery_r10.entityType, ".", delivery_r10.eventType, "");
924    \u0275\u0275advance();
925    \u0275\u0275property("color", ctx_r3.getDeliveryStatusColor(delivery_r10.status));
926    \u0275\u0275advance();
927    \u0275\u0275conditional(delivery_r10.status === "Delivered" ? 6 : delivery_r10.status === "Failed" ? 7 : delivery_r10.status === "Retrying" ? 8 : 9);
928    \u0275\u0275advance(4);
929    \u0275\u0275textInterpolate1(" ", delivery_r10.status, " ");
930    \u0275\u0275advance();
931    \u0275\u0275conditional(delivery_r10.httpStatusCode ? 11 : -1);
932    \u0275\u0275advance(2);
933    \u0275\u0275conditional(delivery_r10.subscriptionTargetUrl ? 13 : -1);
934    \u0275\u0275advance();
935    \u0275\u0275conditional(delivery_r10.responseTimeMs ? 14 : -1);
936    \u0275\u0275advance(2);
937    \u0275\u0275textInterpolate(ctx_r3.formatTimeAgo(delivery_r10.createdAt));
938    \u0275\u0275advance();
939    \u0275\u0275conditional(delivery_r10.errorMessage ? 17 : -1);
940    \u0275\u0275advance();
941    \u0275\u0275conditional(delivery_r10.status === "Failed" ? 18 : -1);
942    \u0275\u0275advance();
943    \u0275\u0275conditional(delivery_r10.status === "Retrying" && delivery_r10.nextRetryAt ? 19 : -1);
944  }
945}
946function WebhookSandboxPage_Conditional_31_Conditional_21_Conditional_3_Conditional_2_Template(rf, ctx) {
947  if (rf & 1) {
948    \u0275\u0275element(0, "ion-spinner", 83);
949  }
950}
951function WebhookSandboxPage_Conditional_31_Conditional_21_Conditional_3_Template(rf, ctx) {
952  if (rf & 1) {
953    const _r12 = \u0275\u0275getCurrentView();
954    \u0275\u0275elementStart(0, "div", 66)(1, "ion-button", 82);
955    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_31_Conditional_21_Conditional_3_Template_ion_button_click_1_listener() {
956      \u0275\u0275restoreView(_r12);
957      const ctx_r3 = \u0275\u0275nextContext(3);
958      return \u0275\u0275resetView(ctx_r3.loadMoreDeliveries());
959    });
960    \u0275\u0275template(2, WebhookSandboxPage_Conditional_31_Conditional_21_Conditional_3_Conditional_2_Template, 1, 0, "ion-spinner", 83);
961    \u0275\u0275text(3, " Load More ");
962    \u0275\u0275elementEnd()();
963  }
964  if (rf & 2) {
965    const ctx_r3 = \u0275\u0275nextContext(3);
966    \u0275\u0275advance();
967    \u0275\u0275property("disabled", ctx_r3.isLoadingDeliveries);
968    \u0275\u0275advance();
969    \u0275\u0275conditional(ctx_r3.isLoadingDeliveries ? 2 : -1);
970  }
971}
972function WebhookSandboxPage_Conditional_31_Conditional_21_Template(rf, ctx) {
973  if (rf & 1) {
974    \u0275\u0275elementStart(0, "ion-list");
975    \u0275\u0275repeaterCreate(1, WebhookSandboxPage_Conditional_31_Conditional_21_For_2_Template, 20, 12, "ion-item", null, _forTrack0);
976    \u0275\u0275elementEnd();
977    \u0275\u0275template(3, WebhookSandboxPage_Conditional_31_Conditional_21_Conditional_3_Template, 4, 2, "div", 66);
978  }
979  if (rf & 2) {
980    const ctx_r3 = \u0275\u0275nextContext(2);
981    \u0275\u0275advance();
982    \u0275\u0275repeater(ctx_r3.deliveries);
983    \u0275\u0275advance(2);
984    \u0275\u0275conditional(ctx_r3.hasMoreDeliveries ? 3 : -1);
985  }
986}
987function WebhookSandboxPage_Conditional_31_Template(rf, ctx) {
988  if (rf & 1) {
989    const _r9 = \u0275\u0275getCurrentView();
990    \u0275\u0275elementStart(0, "div", 12)(1, "div", 58)(2, "ion-select", 59);
991    \u0275\u0275pipe(3, "translate");
992    \u0275\u0275listener("ionChange", function WebhookSandboxPage_Conditional_31_Template_ion_select_ionChange_2_listener($event) {
993      \u0275\u0275restoreView(_r9);
994      const ctx_r3 = \u0275\u0275nextContext();
995      return \u0275\u0275resetView(ctx_r3.onDeliveryFilterChange($event));
996    });
997    \u0275\u0275elementStart(4, "ion-select-option", 60);
998    \u0275\u0275text(5);
999    \u0275\u0275pipe(6, "translate");
1000    \u0275\u0275elementEnd();
1001    \u0275\u0275elementStart(7, "ion-select-option", 61);
1002    \u0275\u0275text(8);
1003    \u0275\u0275pipe(9, "translate");
1004    \u0275\u0275elementEnd();
1005    \u0275\u0275elementStart(10, "ion-select-option", 62);
1006    \u0275\u0275text(11);
1007    \u0275\u0275pipe(12, "translate");
1008    \u0275\u0275elementEnd();
1009    \u0275\u0275elementStart(13, "ion-select-option", 63);
1010    \u0275\u0275text(14);
1011    \u0275\u0275pipe(15, "translate");
1012    \u0275\u0275elementEnd();
1013    \u0275\u0275elementStart(16, "ion-select-option", 64);
1014    \u0275\u0275text(17);
1015    \u0275\u0275pipe(18, "translate");
1016    \u0275\u0275elementEnd()()();
1017    \u0275\u0275template(19, WebhookSandboxPage_Conditional_31_Conditional_19_Template, 2, 0, "div", 14)(20, WebhookSandboxPage_Conditional_31_Conditional_20_Template, 5, 3, "div", 15)(21, WebhookSandboxPage_Conditional_31_Conditional_21_Template, 4, 1);
1018    \u0275\u0275elementEnd();
1019  }
1020  if (rf & 2) {
1021    const ctx_r3 = \u0275\u0275nextContext();
1022    \u0275\u0275advance(2);
1023    \u0275\u0275propertyInterpolate("label", \u0275\u0275pipeBind1(3, 8, "webhookSandbox.deliveries.status"));
1024    \u0275\u0275property("value", ctx_r3.deliveryStatusFilter);
1025    \u0275\u0275advance(3);
1026    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(6, 10, "webhookSandbox.deliveries.filter.all"));
1027    \u0275\u0275advance(3);
1028    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(9, 12, "webhookSandbox.deliveries.delivered"));
1029    \u0275\u0275advance(3);
1030    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(12, 14, "webhookSandbox.deliveries.failed"));
1031    \u0275\u0275advance(3);
1032    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(15, 16, "webhookSandbox.deliveries.retrying"));
1033    \u0275\u0275advance(3);
1034    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(18, 18, "webhookSandbox.deliveries.pending"));
1035    \u0275\u0275advance(2);
1036    \u0275\u0275conditional(ctx_r3.isLoadingDeliveries && ctx_r3.deliveries.length === 0 ? 19 : ctx_r3.deliveries.length === 0 ? 20 : 21);
1037  }
1038}
1039function WebhookSandboxPage_Conditional_32_Conditional_1_Template(rf, ctx) {
1040  if (rf & 1) {
1041    \u0275\u0275elementStart(0, "div", 14);
1042    \u0275\u0275element(1, "ion-spinner", 19);
1043    \u0275\u0275elementEnd();
1044  }
1045}
1046function WebhookSandboxPage_Conditional_32_Conditional_2_Conditional_30_Template(rf, ctx) {
1047  if (rf & 1) {
1048    const _r13 = \u0275\u0275getCurrentView();
1049    \u0275\u0275elementStart(0, "ion-button", 105);
1050    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_32_Conditional_2_Conditional_30_Template_ion_button_click_0_listener() {
1051      \u0275\u0275restoreView(_r13);
1052      const ctx_r3 = \u0275\u0275nextContext(3);
1053      return \u0275\u0275resetView(ctx_r3.resetAllCircuitBreakers());
1054    });
1055    \u0275\u0275text(1);
1056    \u0275\u0275pipe(2, "translate");
1057    \u0275\u0275elementEnd();
1058  }
1059  if (rf & 2) {
1060    \u0275\u0275advance();
1061    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(2, 1, "webhookSandbox.stats.resetAll"), " ");
1062  }
1063}
1064function WebhookSandboxPage_Conditional_32_Conditional_2_Template(rf, ctx) {
1065  if (rf & 1) {
1066    \u0275\u0275elementStart(0, "ion-grid")(1, "ion-row")(2, "ion-col", 84)(3, "ion-card", 85)(4, "ion-card-header")(5, "ion-card-title");
1067    \u0275\u0275text(6);
1068    \u0275\u0275pipe(7, "translate");
1069    \u0275\u0275elementEnd()();
1070    \u0275\u0275elementStart(8, "ion-card-content")(9, "div", 86);
1071    \u0275\u0275text(10);
1072    \u0275\u0275elementEnd();
1073    \u0275\u0275elementStart(11, "div", 87)(12, "span", 88);
1074    \u0275\u0275text(13);
1075    \u0275\u0275pipe(14, "translate");
1076    \u0275\u0275elementEnd();
1077    \u0275\u0275elementStart(15, "span", 89);
1078    \u0275\u0275text(16);
1079    \u0275\u0275pipe(17, "translate");
1080    \u0275\u0275elementEnd()()()()();
1081    \u0275\u0275elementStart(18, "ion-col", 84)(19, "ion-card", 85)(20, "ion-card-header")(21, "ion-card-title");
1082    \u0275\u0275text(22);
1083    \u0275\u0275pipe(23, "translate");
1084    \u0275\u0275elementEnd()();
1085    \u0275\u0275elementStart(24, "ion-card-content")(25, "div", 86);
1086    \u0275\u0275text(26);
1087    \u0275\u0275elementEnd();
1088    \u0275\u0275elementStart(27, "div", 90);
1089    \u0275\u0275text(28);
1090    \u0275\u0275pipe(29, "translate");
1091    \u0275\u0275elementEnd();
1092    \u0275\u0275template(30, WebhookSandboxPage_Conditional_32_Conditional_2_Conditional_30_Template, 3, 3, "ion-button", 91);
1093    \u0275\u0275elementEnd()()()();
1094    \u0275\u0275elementStart(31, "ion-row")(32, "ion-col", 92)(33, "ion-card", 85)(34, "ion-card-header")(35, "ion-card-title");
1095    \u0275\u0275text(36);
1096    \u0275\u0275pipe(37, "translate");
1097    \u0275\u0275elementEnd()();
1098    \u0275\u0275elementStart(38, "ion-card-content")(39, "div", 93);
1099    \u0275\u0275text(40);
1100    \u0275\u0275elementEnd();
1101    \u0275\u0275element(41, "ion-progress-bar", 94);
1102    \u0275\u0275elementStart(42, "div", 95);
1103    \u0275\u0275text(43);
1104    \u0275\u0275pipe(44, "number");
1105    \u0275\u0275pipe(45, "translate");
1106    \u0275\u0275elementEnd();
1107    \u0275\u0275elementStart(46, "div", 96)(47, "span", 97);
1108    \u0275\u0275element(48, "ng-icon", 98);
1109    \u0275\u0275text(49);
1110    \u0275\u0275elementEnd();
1111    \u0275\u0275elementStart(50, "span", 99);
1112    \u0275\u0275element(51, "ng-icon", 100);
1113    \u0275\u0275text(52);
1114    \u0275\u0275elementEnd();
1115    \u0275\u0275elementStart(53, "span", 101);
1116    \u0275\u0275element(54, "ng-icon", 102);
1117    \u0275\u0275text(55);
1118    \u0275\u0275elementEnd();
1119    \u0275\u0275elementStart(56, "span", 103);
1120    \u0275\u0275element(57, "ng-icon", 104);
1121    \u0275\u0275text(58);
1122    \u0275\u0275elementEnd()()()()()();
1123    \u0275\u0275elementStart(59, "ion-row")(60, "ion-col", 84)(61, "ion-card", 85)(62, "ion-card-header")(63, "ion-card-title");
1124    \u0275\u0275text(64);
1125    \u0275\u0275pipe(65, "translate");
1126    \u0275\u0275elementEnd()();
1127    \u0275\u0275elementStart(66, "ion-card-content")(67, "div", 86);
1128    \u0275\u0275text(68);
1129    \u0275\u0275elementEnd();
1130    \u0275\u0275elementStart(69, "div", 87)(70, "span", 97);
1131    \u0275\u0275text(71);
1132    \u0275\u0275elementEnd();
1133    \u0275\u0275elementStart(72, "span", 99);
1134    \u0275\u0275text(73);
1135    \u0275\u0275elementEnd()();
1136    \u0275\u0275elementStart(74, "div", 95);
1137    \u0275\u0275text(75);
1138    \u0275\u0275pipe(76, "number");
1139    \u0275\u0275elementEnd()()()();
1140    \u0275\u0275elementStart(77, "ion-col", 84)(78, "ion-card", 85)(79, "ion-card-header")(80, "ion-card-title");
1141    \u0275\u0275text(81);
1142    \u0275\u0275pipe(82, "translate");
1143    \u0275\u0275elementEnd()();
1144    \u0275\u0275elementStart(83, "ion-card-content")(84, "div", 86);
1145    \u0275\u0275text(85);
1146    \u0275\u0275elementEnd();
1147    \u0275\u0275elementStart(86, "div", 90);
1148    \u0275\u0275text(87);
1149    \u0275\u0275pipe(88, "translate");
1150    \u0275\u0275elementEnd();
1151    \u0275\u0275elementStart(89, "ion-note");
1152    \u0275\u0275text(90);
1153    \u0275\u0275elementEnd()()()()()();
1154  }
1155  if (rf & 2) {
1156    const ctx_r3 = \u0275\u0275nextContext(2);
1157    \u0275\u0275advance(6);
1158    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(7, 30, "webhookSandbox.stats.subscriptions"));
1159    \u0275\u0275advance(4);
1160    \u0275\u0275textInterpolate(ctx_r3.stats.subscriptions.total);
1161    \u0275\u0275advance(3);
1162    \u0275\u0275textInterpolate2("", ctx_r3.stats.subscriptions.active, " ", \u0275\u0275pipeBind1(14, 32, "webhookSandbox.stats.active"), "");
1163    \u0275\u0275advance(3);
1164    \u0275\u0275textInterpolate2("", ctx_r3.stats.subscriptions.total - ctx_r3.stats.subscriptions.active, " ", \u0275\u0275pipeBind1(17, 34, "webhookSandbox.stats.inactive"), "");
1165    \u0275\u0275advance(3);
1166    \u0275\u0275classProp("warning", ctx_r3.stats.subscriptions.circuitOpen > 0);
1167    \u0275\u0275advance(3);
1168    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(23, 36, "webhookSandbox.stats.circuitBreakers"));
1169    \u0275\u0275advance(4);
1170    \u0275\u0275textInterpolate(ctx_r3.stats.subscriptions.circuitOpen);
1171    \u0275\u0275advance(2);
1172    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(29, 38, "webhookSandbox.stats.open"));
1173    \u0275\u0275advance(2);
1174    \u0275\u0275conditional(ctx_r3.stats.subscriptions.circuitOpen > 0 ? 30 : -1);
1175    \u0275\u0275advance(6);
1176    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(37, 40, "webhookSandbox.stats.deliveries24h"));
1177    \u0275\u0275advance(4);
1178    \u0275\u0275textInterpolate(ctx_r3.stats.deliveries.last24Hours.total);
1179    \u0275\u0275advance();
1180    \u0275\u0275property("value", ctx_r3.getSuccessRate24h() / 100);
1181    \u0275\u0275advance(2);
1182    \u0275\u0275textInterpolate2("", \u0275\u0275pipeBind2(44, 42, ctx_r3.getSuccessRate24h(), "1.1-1"), "% ", \u0275\u0275pipeBind1(45, 45, "webhookSandbox.stats.successRate"), "");
1183    \u0275\u0275advance(6);
1184    \u0275\u0275textInterpolate1(" ", ctx_r3.stats.deliveries.last24Hours.delivered, " ");
1185    \u0275\u0275advance(3);
1186    \u0275\u0275textInterpolate1(" ", ctx_r3.stats.deliveries.last24Hours.failed, " ");
1187    \u0275\u0275advance(3);
1188    \u0275\u0275textInterpolate1(" ", ctx_r3.stats.deliveries.last24Hours.retrying, " ");
1189    \u0275\u0275advance(3);
1190    \u0275\u0275textInterpolate1(" ", ctx_r3.stats.deliveries.last24Hours.pending, " ");
1191    \u0275\u0275advance(6);
1192    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(65, 47, "webhookSandbox.stats.deliveries7d"));
1193    \u0275\u0275advance(4);
1194    \u0275\u0275textInterpolate(ctx_r3.stats.deliveries.last7Days.total);
1195    \u0275\u0275advance(3);
1196    \u0275\u0275textInterpolate1("", ctx_r3.stats.deliveries.last7Days.delivered, " delivered");
1197    \u0275\u0275advance(2);
1198    \u0275\u0275textInterpolate1("", ctx_r3.stats.deliveries.last7Days.failed, " failed");
1199    \u0275\u0275advance(2);
1200    \u0275\u0275textInterpolate1("", \u0275\u0275pipeBind2(76, 49, ctx_r3.getSuccessRate7d(), "1.1-1"), "%");
1201    \u0275\u0275advance(6);
1202    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(82, 52, "webhookSandbox.stats.pendingEvents"));
1203    \u0275\u0275advance(4);
1204    \u0275\u0275textInterpolate(ctx_r3.stats.events.pending);
1205    \u0275\u0275advance(2);
1206    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(88, 54, "webhookSandbox.stats.queue"));
1207    \u0275\u0275advance(3);
1208    \u0275\u0275textInterpolate1("", ctx_r3.stats.events.processedLast24Hours, " processed (24h)");
1209  }
1210}
1211function WebhookSandboxPage_Conditional_32_Template(rf, ctx) {
1212  if (rf & 1) {
1213    \u0275\u0275elementStart(0, "div", 13);
1214    \u0275\u0275template(1, WebhookSandboxPage_Conditional_32_Conditional_1_Template, 2, 0, "div", 14)(2, WebhookSandboxPage_Conditional_32_Conditional_2_Template, 91, 56, "ion-grid");
1215    \u0275\u0275elementEnd();
1216  }
1217  if (rf & 2) {
1218    const ctx_r3 = \u0275\u0275nextContext();
1219    \u0275\u0275advance();
1220    \u0275\u0275conditional(ctx_r3.isLoadingStats ? 1 : ctx_r3.stats ? 2 : -1);
1221  }
1222}
1223function WebhookSandboxPage_Conditional_33_Conditional_4_Template(rf, ctx) {
1224  if (rf & 1) {
1225    \u0275\u0275text(0);
1226    \u0275\u0275pipe(1, "translate");
1227  }
1228  if (rf & 2) {
1229    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(1, 1, "webhookSandbox.subscriptions.edit"), " ");
1230  }
1231}
1232function WebhookSandboxPage_Conditional_33_Conditional_5_Template(rf, ctx) {
1233  if (rf & 1) {
1234    \u0275\u0275text(0);
1235    \u0275\u0275pipe(1, "translate");
1236  }
1237  if (rf & 2) {
1238    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(1, 1, "webhookSandbox.subscriptions.create"), " ");
1239  }
1240}
1241function WebhookSandboxPage_Conditional_33_Conditional_14_Template(rf, ctx) {
1242  if (rf & 1) {
1243    \u0275\u0275elementStart(0, "span", 114);
1244    \u0275\u0275text(1, "URL is required");
1245    \u0275\u0275elementEnd();
1246  }
1247}
1248function WebhookSandboxPage_Conditional_33_Conditional_15_Template(rf, ctx) {
1249  if (rf & 1) {
1250    \u0275\u0275elementStart(0, "span", 114);
1251    \u0275\u0275text(1, "Must be a valid HTTPS URL");
1252    \u0275\u0275elementEnd();
1253  }
1254}
1255function WebhookSandboxPage_Conditional_33_For_27_Template(rf, ctx) {
1256  if (rf & 1) {
1257    const _r15 = \u0275\u0275getCurrentView();
1258    \u0275\u0275elementStart(0, "ion-chip", 122);
1259    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_33_For_27_Template_ion_chip_click_0_listener() {
1260      const type_r16 = \u0275\u0275restoreView(_r15).$implicit;
1261      const ctx_r3 = \u0275\u0275nextContext(2);
1262      return \u0275\u0275resetView(ctx_r3.toggleEntityType(type_r16));
1263    });
1264    \u0275\u0275text(1);
1265    \u0275\u0275pipe(2, "translate");
1266    \u0275\u0275elementEnd();
1267  }
1268  if (rf & 2) {
1269    const type_r16 = ctx.$implicit;
1270    const ctx_r3 = \u0275\u0275nextContext(2);
1271    \u0275\u0275property("color", ctx_r3.isEntityTypeSelected(type_r16) ? "primary" : "medium")("outline", !ctx_r3.isEntityTypeSelected(type_r16));
1272    \u0275\u0275advance();
1273    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(2, 3, "webhookSandbox.entityTypes." + type_r16), " ");
1274  }
1275}
1276function WebhookSandboxPage_Conditional_33_Conditional_28_Template(rf, ctx) {
1277  if (rf & 1) {
1278    \u0275\u0275elementStart(0, "span", 118);
1279    \u0275\u0275text(1, "Select at least one entity type");
1280    \u0275\u0275elementEnd();
1281  }
1282}
1283function WebhookSandboxPage_Conditional_33_For_35_Template(rf, ctx) {
1284  if (rf & 1) {
1285    const _r17 = \u0275\u0275getCurrentView();
1286    \u0275\u0275elementStart(0, "ion-chip", 122);
1287    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_33_For_35_Template_ion_chip_click_0_listener() {
1288      const type_r18 = \u0275\u0275restoreView(_r17).$implicit;
1289      const ctx_r3 = \u0275\u0275nextContext(2);
1290      return \u0275\u0275resetView(ctx_r3.toggleEventType(type_r18));
1291    });
1292    \u0275\u0275text(1);
1293    \u0275\u0275pipe(2, "translate");
1294    \u0275\u0275elementEnd();
1295  }
1296  if (rf & 2) {
1297    const type_r18 = ctx.$implicit;
1298    const ctx_r3 = \u0275\u0275nextContext(2);
1299    \u0275\u0275property("color", ctx_r3.isEventTypeSelected(type_r18) ? "secondary" : "medium")("outline", !ctx_r3.isEventTypeSelected(type_r18));
1300    \u0275\u0275advance();
1301    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(2, 3, "webhookSandbox.eventTypes." + type_r18), " ");
1302  }
1303}
1304function WebhookSandboxPage_Conditional_33_Conditional_36_Template(rf, ctx) {
1305  if (rf & 1) {
1306    \u0275\u0275elementStart(0, "span", 118);
1307    \u0275\u0275text(1, "Select at least one event type");
1308    \u0275\u0275elementEnd();
1309  }
1310}
1311function WebhookSandboxPage_Conditional_33_Conditional_42_Template(rf, ctx) {
1312  if (rf & 1) {
1313    \u0275\u0275element(0, "ion-spinner", 83);
1314  }
1315}
1316function WebhookSandboxPage_Conditional_33_Conditional_43_Template(rf, ctx) {
1317  if (rf & 1) {
1318    \u0275\u0275text(0);
1319    \u0275\u0275pipe(1, "translate");
1320  }
1321  if (rf & 2) {
1322    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(1, 1, "common.update"), " ");
1323  }
1324}
1325function WebhookSandboxPage_Conditional_33_Conditional_44_Template(rf, ctx) {
1326  if (rf & 1) {
1327    \u0275\u0275text(0);
1328    \u0275\u0275pipe(1, "translate");
1329  }
1330  if (rf & 2) {
1331    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(1, 1, "webhookSandbox.subscriptions.create"), " ");
1332  }
1333}
1334function WebhookSandboxPage_Conditional_33_Template(rf, ctx) {
1335  if (rf & 1) {
1336    const _r14 = \u0275\u0275getCurrentView();
1337    \u0275\u0275elementStart(0, "div", 106);
1338    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_33_Template_div_click_0_listener() {
1339      \u0275\u0275restoreView(_r14);
1340      const ctx_r3 = \u0275\u0275nextContext();
1341      return \u0275\u0275resetView(ctx_r3.closeForm());
1342    });
1343    \u0275\u0275elementEnd();
1344    \u0275\u0275elementStart(1, "div", 107)(2, "div", 108)(3, "h2");
1345    \u0275\u0275template(4, WebhookSandboxPage_Conditional_33_Conditional_4_Template, 2, 3)(5, WebhookSandboxPage_Conditional_33_Conditional_5_Template, 2, 3);
1346    \u0275\u0275elementEnd();
1347    \u0275\u0275elementStart(6, "ion-button", 109);
1348    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_33_Template_ion_button_click_6_listener() {
1349      \u0275\u0275restoreView(_r14);
1350      const ctx_r3 = \u0275\u0275nextContext();
1351      return \u0275\u0275resetView(ctx_r3.closeForm());
1352    });
1353    \u0275\u0275element(7, "ng-icon", 110);
1354    \u0275\u0275elementEnd()();
1355    \u0275\u0275elementStart(8, "form", 111);
1356    \u0275\u0275listener("ngSubmit", function WebhookSandboxPage_Conditional_33_Template_form_ngSubmit_8_listener() {
1357      \u0275\u0275restoreView(_r14);
1358      const ctx_r3 = \u0275\u0275nextContext();
1359      return \u0275\u0275resetView(ctx_r3.submitForm());
1360    });
1361    \u0275\u0275elementStart(9, "div", 112)(10, "ion-label");
1362    \u0275\u0275text(11);
1363    \u0275\u0275pipe(12, "translate");
1364    \u0275\u0275elementEnd();
1365    \u0275\u0275element(13, "ion-input", 113);
1366    \u0275\u0275template(14, WebhookSandboxPage_Conditional_33_Conditional_14_Template, 2, 0, "span", 114)(15, WebhookSandboxPage_Conditional_33_Conditional_15_Template, 2, 0, "span", 114);
1367    \u0275\u0275elementEnd();
1368    \u0275\u0275elementStart(16, "div", 112)(17, "ion-label");
1369    \u0275\u0275text(18);
1370    \u0275\u0275pipe(19, "translate");
1371    \u0275\u0275elementEnd();
1372    \u0275\u0275element(20, "ion-textarea", 115);
1373    \u0275\u0275elementEnd();
1374    \u0275\u0275elementStart(21, "div", 112)(22, "ion-label");
1375    \u0275\u0275text(23);
1376    \u0275\u0275pipe(24, "translate");
1377    \u0275\u0275elementEnd();
1378    \u0275\u0275elementStart(25, "div", 116);
1379    \u0275\u0275repeaterCreate(26, WebhookSandboxPage_Conditional_33_For_27_Template, 3, 5, "ion-chip", 117, \u0275\u0275repeaterTrackByIdentity);
1380    \u0275\u0275elementEnd();
1381    \u0275\u0275template(28, WebhookSandboxPage_Conditional_33_Conditional_28_Template, 2, 0, "span", 118);
1382    \u0275\u0275elementEnd();
1383    \u0275\u0275elementStart(29, "div", 112)(30, "ion-label");
1384    \u0275\u0275text(31);
1385    \u0275\u0275pipe(32, "translate");
1386    \u0275\u0275elementEnd();
1387    \u0275\u0275elementStart(33, "div", 116);
1388    \u0275\u0275repeaterCreate(34, WebhookSandboxPage_Conditional_33_For_35_Template, 3, 5, "ion-chip", 117, \u0275\u0275repeaterTrackByIdentity);
1389    \u0275\u0275elementEnd();
1390    \u0275\u0275template(36, WebhookSandboxPage_Conditional_33_Conditional_36_Template, 2, 0, "span", 118);
1391    \u0275\u0275elementEnd();
1392    \u0275\u0275elementStart(37, "div", 119)(38, "ion-button", 120);
1393    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_33_Template_ion_button_click_38_listener() {
1394      \u0275\u0275restoreView(_r14);
1395      const ctx_r3 = \u0275\u0275nextContext();
1396      return \u0275\u0275resetView(ctx_r3.closeForm());
1397    });
1398    \u0275\u0275text(39);
1399    \u0275\u0275pipe(40, "translate");
1400    \u0275\u0275elementEnd();
1401    \u0275\u0275elementStart(41, "ion-button", 121);
1402    \u0275\u0275template(42, WebhookSandboxPage_Conditional_33_Conditional_42_Template, 1, 0, "ion-spinner", 83)(43, WebhookSandboxPage_Conditional_33_Conditional_43_Template, 2, 3)(44, WebhookSandboxPage_Conditional_33_Conditional_44_Template, 2, 3);
1403    \u0275\u0275elementEnd()()()();
1404  }
1405  if (rf & 2) {
1406    let tmp_4_0;
1407    let tmp_5_0;
1408    const ctx_r3 = \u0275\u0275nextContext();
1409    \u0275\u0275advance(4);
1410    \u0275\u0275conditional(ctx_r3.isEditMode ? 4 : 5);
1411    \u0275\u0275advance(4);
1412    \u0275\u0275property("formGroup", ctx_r3.subscriptionForm);
1413    \u0275\u0275advance(3);
1414    \u0275\u0275textInterpolate1("", \u0275\u0275pipeBind1(12, 14, "webhookSandbox.subscriptions.targetUrl"), " *");
1415    \u0275\u0275advance(3);
1416    \u0275\u0275conditional(((tmp_4_0 = ctx_r3.subscriptionForm.get("targetUrl")) == null ? null : tmp_4_0.touched) && ((tmp_4_0 = ctx_r3.subscriptionForm.get("targetUrl")) == null ? null : tmp_4_0.hasError("required")) ? 14 : -1);
1417    \u0275\u0275advance();
1418    \u0275\u0275conditional(((tmp_5_0 = ctx_r3.subscriptionForm.get("targetUrl")) == null ? null : tmp_5_0.touched) && ((tmp_5_0 = ctx_r3.subscriptionForm.get("targetUrl")) == null ? null : tmp_5_0.hasError("pattern")) ? 15 : -1);
1419    \u0275\u0275advance(3);
1420    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(19, 16, "webhookSandbox.subscriptions.description"));
1421    \u0275\u0275advance(5);
1422    \u0275\u0275textInterpolate1("", \u0275\u0275pipeBind1(24, 18, "webhookSandbox.subscriptions.entityTypes"), " *");
1423    \u0275\u0275advance(3);
1424    \u0275\u0275repeater(ctx_r3.entityTypes);
1425    \u0275\u0275advance(2);
1426    \u0275\u0275conditional(ctx_r3.selectedEntityTypes.length === 0 ? 28 : -1);
1427    \u0275\u0275advance(3);
1428    \u0275\u0275textInterpolate1("", \u0275\u0275pipeBind1(32, 20, "webhookSandbox.subscriptions.eventTypes"), " *");
1429    \u0275\u0275advance(3);
1430    \u0275\u0275repeater(ctx_r3.eventTypes);
1431    \u0275\u0275advance(2);
1432    \u0275\u0275conditional(ctx_r3.selectedEventTypes.length === 0 ? 36 : -1);
1433    \u0275\u0275advance(3);
1434    \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(40, 22, "common.cancel"), " ");
1435    \u0275\u0275advance(2);
1436    \u0275\u0275property("disabled", ctx_r3.isSubmitting);
1437    \u0275\u0275advance();
1438    \u0275\u0275conditional(ctx_r3.isSubmitting ? 42 : -1);
1439    \u0275\u0275advance();
1440    \u0275\u0275conditional(ctx_r3.isEditMode ? 43 : 44);
1441  }
1442}
1443function WebhookSandboxPage_Conditional_34_Conditional_20_Template(rf, ctx) {
1444  if (rf & 1) {
1445    \u0275\u0275element(0, "ng-icon", 131);
1446  }
1447}
1448function WebhookSandboxPage_Conditional_34_Conditional_21_Template(rf, ctx) {
1449  if (rf & 1) {
1450    \u0275\u0275element(0, "ng-icon", 132);
1451  }
1452}
1453function WebhookSandboxPage_Conditional_34_Template(rf, ctx) {
1454  if (rf & 1) {
1455    const _r19 = \u0275\u0275getCurrentView();
1456    \u0275\u0275elementStart(0, "div", 106);
1457    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_34_Template_div_click_0_listener() {
1458      \u0275\u0275restoreView(_r19);
1459      const ctx_r3 = \u0275\u0275nextContext();
1460      return \u0275\u0275resetView(ctx_r3.closeSecretModal());
1461    });
1462    \u0275\u0275elementEnd();
1463    \u0275\u0275elementStart(1, "div", 123)(2, "div", 124);
1464    \u0275\u0275element(3, "ng-icon", 125);
1465    \u0275\u0275elementStart(4, "h2");
1466    \u0275\u0275text(5);
1467    \u0275\u0275pipe(6, "translate");
1468    \u0275\u0275elementEnd()();
1469    \u0275\u0275elementStart(7, "div", 126)(8, "div", 127);
1470    \u0275\u0275element(9, "ng-icon", 128);
1471    \u0275\u0275elementStart(10, "p");
1472    \u0275\u0275text(11);
1473    \u0275\u0275pipe(12, "translate");
1474    \u0275\u0275elementEnd()();
1475    \u0275\u0275elementStart(13, "div", 112)(14, "ion-label");
1476    \u0275\u0275text(15);
1477    \u0275\u0275pipe(16, "translate");
1478    \u0275\u0275elementEnd();
1479    \u0275\u0275elementStart(17, "div", 129);
1480    \u0275\u0275element(18, "ion-input", 130);
1481    \u0275\u0275elementStart(19, "ion-button", 109);
1482    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_34_Template_ion_button_click_19_listener() {
1483      \u0275\u0275restoreView(_r19);
1484      const ctx_r3 = \u0275\u0275nextContext();
1485      return \u0275\u0275resetView(ctx_r3.toggleSecretVisibility());
1486    });
1487    \u0275\u0275template(20, WebhookSandboxPage_Conditional_34_Conditional_20_Template, 1, 0, "ng-icon", 131)(21, WebhookSandboxPage_Conditional_34_Conditional_21_Template, 1, 0, "ng-icon", 132);
1488    \u0275\u0275elementEnd();
1489    \u0275\u0275elementStart(22, "ion-button", 109);
1490    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_34_Template_ion_button_click_22_listener() {
1491      \u0275\u0275restoreView(_r19);
1492      const ctx_r3 = \u0275\u0275nextContext();
1493      return \u0275\u0275resetView(ctx_r3.copySecret());
1494    });
1495    \u0275\u0275element(23, "ng-icon", 133);
1496    \u0275\u0275elementEnd()()();
1497    \u0275\u0275elementStart(24, "p", 134);
1498    \u0275\u0275text(25, " Use this secret to verify webhook signatures.");
1499    \u0275\u0275element(26, "br");
1500    \u0275\u0275text(27, " Header: ");
1501    \u0275\u0275elementStart(28, "code");
1502    \u0275\u0275text(29, "X-Webhook-Signature: sha256={hash}");
1503    \u0275\u0275elementEnd()()();
1504    \u0275\u0275elementStart(30, "div", 119)(31, "ion-button", 17);
1505    \u0275\u0275listener("click", function WebhookSandboxPage_Conditional_34_Template_ion_button_click_31_listener() {
1506      \u0275\u0275restoreView(_r19);
1507      const ctx_r3 = \u0275\u0275nextContext();
1508      return \u0275\u0275resetView(ctx_r3.closeSecretModal());
1509    });
1510    \u0275\u0275text(32, " Done ");
1511    \u0275\u0275elementEnd()()();
1512  }
1513  if (rf & 2) {
1514    const ctx_r3 = \u0275\u0275nextContext();
1515    \u0275\u0275advance(5);
1516    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(6, 6, "webhookSandbox.subscriptions.secretTitle"));
1517    \u0275\u0275advance(6);
1518    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(12, 8, "webhookSandbox.subscriptions.secretWarning"));
1519    \u0275\u0275advance(4);
1520    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(16, 10, "webhookSandbox.subscriptions.secretLabel"));
1521    \u0275\u0275advance(3);
1522    \u0275\u0275property("value", ctx_r3.createdSecret)("type", ctx_r3.isSecretVisible ? "text" : "password");
1523    \u0275\u0275advance(2);
1524    \u0275\u0275conditional(ctx_r3.isSecretVisible ? 20 : 21);
1525  }
1526}
1527var _WebhookSandboxPage = class _WebhookSandboxPage {
1528  constructor(fb, webhookService, toastService, alertController, translateService) {
1529    this.fb = fb;
1530    this.webhookService = webhookService;
1531    this.toastService = toastService;
1532    this.alertController = alertController;
1533    this.translateService = translateService;
1534    this.isMockEnabled = true;
1535    this.activeTab = "subscriptions";
1536    this.subscriptions = [];
1537    this.isLoadingSubscriptions = false;
1538    this.expandedSubscriptionId = null;
1539    this.isFormVisible = false;
1540    this.isEditMode = false;
1541    this.editingSubscriptionId = null;
1542    this.isSubmitting = false;
1543    this.isSecretModalVisible = false;
1544    this.createdSecret = null;
1545    this.isSecretVisible = false;
1546    this.deliveries = [];
1547    this.isLoadingDeliveries = false;
1548    this.deliveryStatusFilter = "all";
1549    this.deliveryPage = 1;
1550    this.hasMoreDeliveries = true;
1551    this.stats = null;
1552    this.isLoadingStats = false;
1553    this.entityTypes = ENTITY_TYPES;
1554    this.eventTypes = EVENT_TYPES;
1555    this.selectedEntityTypes = [];
1556    this.selectedEventTypes = [];
1557  }
1558  ngOnInit() {
1559    this.initForm();
1560    this.loadMockPreference();
1561    this.loadSubscriptions();
1562  }
1563  loadMockPreference() {
1564    const stored = localStorage.getItem(_WebhookSandboxPage.MOCK_STORAGE_KEY);
1565    this.isMockEnabled = stored === null ? true : stored === "true";
1566  }
1567  toggleMockData(event) {
1568    this.isMockEnabled = event.detail.checked;
1569    localStorage.setItem(_WebhookSandboxPage.MOCK_STORAGE_KEY, String(this.isMockEnabled));
1570    this.resetAndReload();
1571  }
1572  resetAndReload() {
1573    this.subscriptions = [];
1574    this.deliveries = [];
1575    this.stats = null;
1576    this.deliveryPage = 1;
1577    if (this.activeTab === "subscriptions") {
1578      this.loadSubscriptions();
1579    } else if (this.activeTab === "deliveries") {
1580      this.loadDeliveries();
1581    } else {
1582      this.loadStats();
1583    }
1584  }
1585  ngOnDestroy() {
1586    var _a;
1587    (_a = this.subscriptionsSubscription) == null ? void 0 : _a.unsubscribe();
1588  }
1589  // Tab navigation
1590  onTabChange(event) {
1591    this.activeTab = event.detail.value;
1592    if (this.activeTab === "deliveries" && this.deliveries.length === 0) {
1593      this.loadDeliveries();
1594    } else if (this.activeTab === "statistics" && !this.stats) {
1595      this.loadStats();
1596    }
1597  }
1598  // Pull-to-refresh
1599  doRefresh(event) {
1600    const refresher = event.target;
1601    if (this.activeTab === "subscriptions") {
1602      this.loadSubscriptions(() => refresher.complete());
1603    } else if (this.activeTab === "deliveries") {
1604      this.deliveryPage = 1;
1605      this.loadDeliveries(() => refresher.complete());
1606    } else {
1607      this.loadStats(() => refresher.complete());
1608    }
1609  }
1610  // Manual refresh button
1611  manualRefresh() {
1612    if (this.activeTab === "subscriptions") {
1613      this.loadSubscriptions();
1614    } else if (this.activeTab === "deliveries") {
1615      this.deliveryPage = 1;
1616      this.loadDeliveries();
1617    } else {
1618      this.loadStats();
1619    }
1620  }
1621  // ==================== SUBSCRIPTIONS TAB ====================
1622  loadSubscriptions(callback) {
1623    this.isLoadingSubscriptions = true;
1624    if (this.isMockEnabled) {
1625      of(WebhookMockData.getSubscriptions()).pipe(delay(300), finalize(() => {
1626        this.isLoadingSubscriptions = false;
1627        callback == null ? void 0 : callback();
1628      })).subscribe((result) => {
1629        this.subscriptions = result.items;
1630      });
1631      return;
1632    }
1633    this.webhookService.getSubscriptions({ pageSize: 100 }).pipe(finalize(() => {
1634      this.isLoadingSubscriptions = false;
1635      callback == null ? void 0 : callback();
1636    })).subscribe({
1637      next: (result) => {
1638        this.subscriptions = result.items;
1639      },
1640      error: (err) => {
1641        var _a;
1642        this.toastService.showError(((_a = err.error) == null ? void 0 : _a.message) || "Failed to load subscriptions");
1643      }
1644    });
1645  }
1646  toggleSubscriptionExpand(id) {
1647    this.expandedSubscriptionId = this.expandedSubscriptionId === id ? null : id;
1648  }
1649  isCircuitOpen(sub) {
1650    if (!sub.circuitBrokenUntil)
1651      return false;
1652    return new Date(sub.circuitBrokenUntil) > /* @__PURE__ */ new Date();
1653  }
1654  getCircuitOpenUntil(sub) {
1655    if (!sub.circuitBrokenUntil)
1656      return "";
1657    return RigaDateTimeService.formatInRiga(sub.circuitBrokenUntil, {
1658      hour: "2-digit",
1659      minute: "2-digit",
1660      second: "2-digit"
1661    });
1662  }
1663  // Form handling
1664  initForm() {
1665    this.subscriptionForm = this.fb.group({
1666      targetUrl: ["", [Validators.required, Validators.pattern(/^https:\/\/.+/)]],
1667      description: ["", [Validators.maxLength(500)]]
1668    });
1669  }
1670  openCreateForm() {
1671    this.isEditMode = false;
1672    this.editingSubscriptionId = null;
1673    this.selectedEntityTypes = [];
1674    this.selectedEventTypes = [];
1675    this.subscriptionForm.reset();
1676    this.isFormVisible = true;
1677  }
1678  openEditForm(sub) {
1679    this.isEditMode = true;
1680    this.editingSubscriptionId = sub.id;
1681    this.selectedEntityTypes = [...sub.entityTypes];
1682    this.selectedEventTypes = [...sub.eventTypes];
1683    this.subscriptionForm.patchValue({
1684      targetUrl: sub.targetUrl,
1685      description: sub.description || ""
1686    });
1687    this.isFormVisible = true;
1688  }
1689  closeForm() {
1690    this.isFormVisible = false;
1691    this.subscriptionForm.reset();
1692    this.selectedEntityTypes = [];
1693    this.selectedEventTypes = [];
1694  }
1695  toggleEntityType(type) {
1696    const idx = this.selectedEntityTypes.indexOf(type);
1697    if (idx >= 0) {
1698      this.selectedEntityTypes.splice(idx, 1);
1699    } else {
1700      this.selectedEntityTypes.push(type);
1701    }
1702  }
1703  toggleEventType(type) {
1704    const idx = this.selectedEventTypes.indexOf(type);
1705    if (idx >= 0) {
1706      this.selectedEventTypes.splice(idx, 1);
1707    } else {
1708      this.selectedEventTypes.push(type);
1709    }
1710  }
1711  isEntityTypeSelected(type) {
1712    return this.selectedEntityTypes.includes(type);
1713  }
1714  isEventTypeSelected(type) {
1715    return this.selectedEventTypes.includes(type);
1716  }
1717  submitForm() {
1718    return __async(this, null, function* () {
1719      if (this.subscriptionForm.invalid || this.selectedEntityTypes.length === 0 || this.selectedEventTypes.length === 0) {
1720        this.subscriptionForm.markAllAsTouched();
1721        return;
1722      }
1723      this.isSubmitting = true;
1724      if (this.isEditMode && this.editingSubscriptionId) {
1725        const request = {
1726          targetUrl: this.subscriptionForm.value.targetUrl,
1727          description: this.subscriptionForm.value.description || void 0,
1728          entityTypes: this.selectedEntityTypes.join(","),
1729          eventTypes: this.selectedEventTypes.join(",")
1730        };
1731        this.webhookService.updateSubscription(this.editingSubscriptionId, request).pipe(finalize(() => this.isSubmitting = false)).subscribe({
1732          next: () => {
1733            this.toastService.showSuccess(this.translateService.instant("webhookSandbox.subscriptions.updateSuccess"));
1734            this.closeForm();
1735            this.loadSubscriptions();
1736          },
1737          error: (err) => {
1738            var _a;
1739            this.toastService.showError(((_a = err.error) == null ? void 0 : _a.message) || "Failed to update subscription");
1740          }
1741        });
1742      } else {
1743        const request = {
1744          targetUrl: this.subscriptionForm.value.targetUrl,
1745          description: this.subscriptionForm.value.description || void 0,
1746          entityTypes: this.selectedEntityTypes.join(","),
1747          eventTypes: this.selectedEventTypes.join(",")
1748        };
1749        this.webhookService.createSubscription(request).pipe(finalize(() => this.isSubmitting = false)).subscribe({
1750          next: (response) => {
1751            this.createdSecret = response.secret;
1752            this.isSecretModalVisible = true;
1753            this.closeForm();
1754            this.loadSubscriptions();
1755          },
1756          error: (err) => {
1757            var _a;
1758            this.toastService.showError(((_a = err.error) == null ? void 0 : _a.message) || "Failed to create subscription");
1759          }
1760        });
1761      }
1762    });
1763  }
1764  // Secret modal
1765  closeSecretModal() {
1766    this.isSecretModalVisible = false;
1767    this.createdSecret = null;
1768    this.isSecretVisible = false;
1769  }
1770  toggleSecretVisibility() {
1771    this.isSecretVisible = !this.isSecretVisible;
1772  }
1773  copySecret() {
1774    return __async(this, null, function* () {
1775      var _a;
1776      if (!this.createdSecret)
1777        return;
1778      try {
1779        yield Clipboard.write({ string: this.createdSecret });
1780        this.toastService.showSuccess(this.translateService.instant("webhookSandbox.subscriptions.secretCopied"));
1781      } catch {
1782        (_a = navigator.clipboard) == null ? void 0 : _a.writeText(this.createdSecret);
1783        this.toastService.showSuccess(this.translateService.instant("webhookSandbox.subscriptions.secretCopied"));
1784      }
1785    });
1786  }
1787  // Subscription actions
1788  testSubscription(sub) {
1789    return __async(this, null, function* () {
1790      this.webhookService.testSubscription(sub.id).subscribe({
1791        next: (result) => {
1792          if (result.success) {
1793            this.toastService.showSuccess(`${this.translateService.instant("webhookSandbox.subscriptions.testSuccess")} (${result.httpStatusCode}, ${result.responseTimeMs}ms)`);
1794          } else {
1795            this.toastService.showError(`${this.translateService.instant("webhookSandbox.subscriptions.testFailed")}: ${result.errorMessage}`);
1796          }
1797        },
1798        error: (err) => {
1799          var _a;
1800          this.toastService.showError(((_a = err.error) == null ? void 0 : _a.message) || "Test failed");
1801        }
1802      });
1803    });
1804  }
1805  toggleSubscriptionActive(sub) {
1806    return __async(this, null, function* () {
1807      this.webhookService.updateSubscription(sub.id, { isActive: !sub.isActive }).subscribe({
1808        next: () => {
1809          sub.isActive = !sub.isActive;
1810          this.toastService.showSuccess(sub.isActive ? "Subscription activated" : "Subscription deactivated");
1811        },
1812        error: (err) => {
1813          var _a;
1814          this.toastService.showError(((_a = err.error) == null ? void 0 : _a.message) || "Failed to update subscription");
1815        }
1816      });
1817    });
1818  }
1819  resetCircuitBreaker(sub) {
1820    return __async(this, null, function* () {
1821      this.webhookService.resetCircuitBreaker(sub.id).subscribe({
1822        next: () => {
1823          sub.circuitBrokenUntil = void 0;
1824          sub.consecutiveFailures = 0;
1825          this.toastService.showSuccess("Circuit breaker reset");
1826        },
1827        error: (err) => {
1828          var _a;
1829          this.toastService.showError(((_a = err.error) == null ? void 0 : _a.message) || "Failed to reset circuit breaker");
1830        }
1831      });
1832    });
1833  }
1834  confirmDeleteSubscription(sub) {
1835    return __async(this, null, function* () {
1836      const alert = yield this.alertController.create({
1837        header: this.translateService.instant("webhookSandbox.subscriptions.delete"),
1838        message: this.translateService.instant("webhookSandbox.subscriptions.deleteConfirm"),
1839        buttons: [
1840          {
1841            text: this.translateService.instant("common.cancel"),
1842            role: "cancel"
1843          },
1844          {
1845            text: this.translateService.instant("common.delete"),
1846            role: "destructive",
1847            handler: () => this.deleteSubscription(sub)
1848          }
1849        ]
1850      });
1851      yield alert.present();
1852    });
1853  }
1854  deleteSubscription(sub) {
1855    this.webhookService.deleteSubscription(sub.id).subscribe({
1856      next: () => {
1857        this.subscriptions = this.subscriptions.filter((s) => s.id !== sub.id);
1858        this.toastService.showSuccess("Subscription deleted");
1859      },
1860      error: (err) => {
1861        var _a;
1862        this.toastService.showError(((_a = err.error) == null ? void 0 : _a.message) || "Failed to delete subscription");
1863      }
1864    });
1865  }
1866  // ==================== DELIVERIES TAB ====================
1867  loadDeliveries(callback, append = false) {
1868    this.isLoadingDeliveries = true;
1869    if (this.isMockEnabled) {
1870      of(WebhookMockData.getDeliveries(this.deliveryStatusFilter, this.deliveryPage, 20)).pipe(delay(300), finalize(() => {
1871        this.isLoadingDeliveries = false;
1872        callback == null ? void 0 : callback();
1873      })).subscribe((result) => {
1874        if (append) {
1875          this.deliveries = [...this.deliveries, ...result.items];
1876        } else {
1877          this.deliveries = result.items;
1878        }
1879        this.hasMoreDeliveries = result.hasNextPage;
1880      });
1881      return;
1882    }
1883    const params = {
1884      page: this.deliveryPage,
1885      pageSize: 20
1886    };
1887    if (this.deliveryStatusFilter !== "all") {
1888      params.status = this.deliveryStatusFilter;
1889    }
1890    this.webhookService.getDeliveries(params).pipe(finalize(() => {
1891      this.isLoadingDeliveries = false;
1892      callback == null ? void 0 : callback();
1893    })).subscribe({
1894      next: (result) => {
1895        if (append) {
1896          this.deliveries = [...this.deliveries, ...result.items];
1897        } else {
1898          this.deliveries = result.items;
1899        }
1900        this.hasMoreDeliveries = result.hasNextPage;
1901      },
1902      error: (err) => {
1903        var _a;
1904        this.toastService.showError(((_a = err.error) == null ? void 0 : _a.message) || "Failed to load deliveries");
1905      }
1906    });
1907  }
1908  onDeliveryFilterChange(event) {
1909    this.deliveryStatusFilter = event.detail.value;
1910    this.deliveryPage = 1;
1911    this.loadDeliveries();
1912  }
1913  loadMoreDeliveries() {
1914    this.deliveryPage++;
1915    this.loadDeliveries(void 0, true);
1916  }
1917  retryDelivery(delivery) {
1918    this.webhookService.retryDelivery(delivery.id).subscribe({
1919      next: () => {
1920        delivery.status = "Retrying";
1921        this.toastService.showSuccess(this.translateService.instant("webhookSandbox.deliveries.retryScheduled"));
1922      },
1923      error: (err) => {
1924        var _a;
1925        this.toastService.showError(((_a = err.error) == null ? void 0 : _a.message) || "Failed to retry delivery");
1926      }
1927    });
1928  }
1929  getDeliveryStatusColor(status) {
1930    switch (status) {
1931      case "Delivered":
1932        return "success";
1933      case "Failed":
1934        return "danger";
1935      case "Retrying":
1936        return "warning";
1937      case "Pending":
1938        return "medium";
1939      default:
1940        return "medium";
1941    }
1942  }
1943  formatTimeAgo(dateStr) {
1944    const date = new Date(dateStr);
1945    const now = /* @__PURE__ */ new Date();
1946    const diffMs = now.getTime() - date.getTime();
1947    const diffMins = Math.floor(diffMs / 6e4);
1948    if (diffMins < 1)
1949      return "just now";
1950    if (diffMins < 60)
1951      return `${diffMins}m ago`;
1952    const diffHours = Math.floor(diffMins / 60);
1953    if (diffHours < 24)
1954      return `${diffHours}h ago`;
1955    const diffDays = Math.floor(diffHours / 24);
1956    return `${diffDays}d ago`;
1957  }
1958  // ==================== STATISTICS TAB ====================
1959  loadStats(callback) {
1960    this.isLoadingStats = true;
1961    if (this.isMockEnabled) {
1962      of(WebhookMockData.getStats()).pipe(delay(300), finalize(() => {
1963        this.isLoadingStats = false;
1964        callback == null ? void 0 : callback();
1965      })).subscribe((stats) => {
1966        this.stats = stats;
1967      });
1968      return;
1969    }
1970    this.webhookService.getStats().pipe(finalize(() => {
1971      this.isLoadingStats = false;
1972      callback == null ? void 0 : callback();
1973    })).subscribe({
1974      next: (stats) => {
1975        this.stats = stats;
1976      },
1977      error: (err) => {
1978        var _a;
1979        this.toastService.showError(((_a = err.error) == null ? void 0 : _a.message) || "Failed to load statistics");
1980      }
1981    });
1982  }
1983  getSuccessRate24h() {
1984    if (!this.stats || this.stats.deliveries.last24Hours.total === 0)
1985      return 0;
1986    return this.stats.deliveries.last24Hours.delivered / this.stats.deliveries.last24Hours.total * 100;
1987  }
1988  getSuccessRate7d() {
1989    if (!this.stats || this.stats.deliveries.last7Days.total === 0)
1990      return 0;
1991    return this.stats.deliveries.last7Days.delivered / this.stats.deliveries.last7Days.total * 100;
1992  }
1993  resetAllCircuitBreakers() {
1994    return __async(this, null, function* () {
1995      const alert = yield this.alertController.create({
1996        header: this.translateService.instant("webhookSandbox.stats.resetAll"),
1997        message: "Reset all open circuit breakers?",
1998        buttons: [
1999          { text: this.translateService.instant("common.cancel"), role: "cancel" },
2000          {
2001            text: this.translateService.instant("common.ok"),
2002            handler: () => {
2003              this.subscriptions.filter((s) => this.isCircuitOpen(s)).forEach((s) => this.resetCircuitBreaker(s));
2004            }
2005          }
2006        ]
2007      });
2008      yield alert.present();
2009    });
2010  }
2011};
2012_WebhookSandboxPage.MOCK_STORAGE_KEY = "webhook_sandbox_mock_enabled";
2013_WebhookSandboxPage.\u0275fac = function WebhookSandboxPage_Factory(__ngFactoryType__) {
2014  return new (__ngFactoryType__ || _WebhookSandboxPage)(\u0275\u0275directiveInject(FormBuilder), \u0275\u0275directiveInject(WebhookService), \u0275\u0275directiveInject(ToastService), \u0275\u0275directiveInject(AlertController), \u0275\u0275directiveInject(TranslateService));
2015};
2016_WebhookSandboxPage.\u0275cmp = /* @__PURE__ */ \u0275\u0275defineComponent({ type: _WebhookSandboxPage, selectors: [["app-webhook-sandbox"]], features: [\u0275\u0275ProvidersFeature([], [provideIcons({
2017  lucideWebhook,
2018  lucideRefreshCw,
2019  lucidePlus,
2020  lucidePencil,
2021  lucideTrash2,
2022  lucidePlay,
2023  lucideCheck,
2024  lucideX,
2025  lucideTriangleAlert,
2026  lucideClock,
2027  lucideRotateCw,
2028  lucideCopy,
2029  lucideEye,
2030  lucideEyeOff,
2031  lucideActivity,
2032  lucideZap,
2033  lucideCircle,
2034  lucideCircleDot,
2035  lucideExternalLink,
2036  lucideChevronDown,
2037  lucideChevronUp,
2038  lucideFilter,
2039  lucideFlaskConical
2040})])], decls: 35, vars: 21, consts: [["slot", "start"], ["slot", "end"], [1, "mock-toggle"], ["name", "lucideFlaskConical", "size", "1em"], ["labelPlacement", "start", 3, "ionChange", "checked"], [3, "click"], ["name", "lucideRefreshCw", "size", "1.25em"], [3, "ionChange", "value"], ["value", "subscriptions"], ["value", "deliveries"], ["value", "statistics"], ["slot", "fixed", 3, "ionRefresh"], [1, "tab-content"], [1, "tab-content", "stats-tab"], [1, "loading-container"], [1, "empty-state"], [1, "fab-container"], ["expand", "block", 3, "click"], ["name", "lucidePlus", "size", "1.25em", "slot", "start"], ["name", "crescent"], ["name", "lucideWebhook", "size", "3em"], [1, "subscription-card", 3, "circuit-open"], [1, "subscription-card"], [1, "card-header-row"], [1, "url-container"], [1, "target-url"], ["target", "_blank", 1, "external-link", 3, "href"], ["name", "lucideExternalLink", "size", "0.9em"], [1, "action-buttons"], ["fill", "clear", "size", "small", 3, "click"], ["name", "lucidePlay", "size", "1em"], ["name", "lucidePencil", "size", "1em"], ["name", "lucideChevronUp", "size", "1em"], ["name", "lucideChevronDown", "size", "1em"], [1, "description"], [1, "types-row"], [1, "type-chips"], ["color", "primary", "outline", "true"], [1, "separator"], ["color", "secondary", "outline", "true"], [1, "status-row"], ["color", "danger"], ["color", "success"], ["color", "medium"], [1, "stat"], [1, "stat", "failed"], [1, "expanded-content"], ["name", "lucideTriangleAlert", "size", "0.8em"], ["name", "lucideCheck", "size", "0.8em"], ["lines", "none"], [3, "ionChange", "checked"], [1, "meta"], [1, "expanded-actions"], ["size", "small", "fill", "outline", "color", "warning"], ["size", "small", "fill", "outline", "color", "danger", 3, "click"], ["name", "lucideTrash2", "size", "1em", "slot", "start"], ["size", "small", "fill", "outline", "color", "warning", 3, "click"], ["name", "lucideRotateCw", "size", "1em", "slot", "start"], [1, "filter-row"], ["interface", "popover", "labelPlacement", "start", 3, "ionChange", "value", "label"], ["value", "all"], ["value", "Delivered"], ["value", "Failed"], ["value", "Retrying"], ["value", "Pending"], ["name", "lucideActivity", "size", "3em"], [1, "load-more"], [1, "delivery-item"], [1, "delivery-header"], [1, "event-info"], [3, "color"], ["name", "lucideX", "size", "0.8em"], ["name", "lucideRotateCw", "size", "0.8em"], ["name", "lucideClock", "size", "0.8em"], [1, "delivery-details"], [1, "target"], [1, "response-time"], [1, "time-ago"], [1, "error-message"], ["size", "small", "fill", "clear"], [1, "retry-info"], ["size", "small", "fill", "clear", 3, "click"], ["fill", "outline", 3, "click", "disabled"], ["name", "crescent", "slot", "start"], ["size", "6"], [1, "stat-card"], [1, "stat-value"], [1, "stat-breakdown"], [1, "active"], [1, "inactive"], [1, "stat-label"], ["size", "small", "fill", "outline"], ["size", "12"], [1, "stat-value", "large"], ["color", "success", 3, "value"], [1, "progress-label"], [1, "stat-breakdown", "horizontal"], [1, "success"], ["name", "lucideCheck", "size", "0.9em"], [1, "failed"], ["name", "lucideX", "size", "0.9em"], [1, "retrying"], ["name", "lucideRotateCw", "size", "0.9em"], [1, "pending"], ["name", "lucideClock", "size", "0.9em"], ["size", "small", "fill", "outline", 3, "click"], [1, "modal-backdrop", 3, "click"], [1, "form-modal"], [1, "modal-header"], ["fill", "clear", 3, "click"], ["name", "lucideX", "size", "1.5em"], [3, "ngSubmit", "formGroup"], [1, "form-field"], ["formControlName", "targetUrl", "type", "url", "placeholder", "https://your-service.com/webhook"], [1, "error-text"], ["formControlName", "description", "placeholder", "Optional description for this webhook", "rows", "2"], [1, "chip-selector"], [3, "color", "outline"], [1, "hint-text"], [1, "form-actions"], ["fill", "outline", 3, "click"], ["type", "submit", 3, "disabled"], [3, "click", "color", "outline"], [1, "form-modal", "secret-modal"], [1, "modal-header", "success"], ["name", "lucideCheck", "size", "1.5em"], [1, "secret-content"], [1, "warning-box"], ["name", "lucideTriangleAlert", "size", "1.25em"], [1, "secret-input-container"], ["readonly", "", 3, "value", "type"], ["name", "lucideEyeOff", "size", "1.25em"], ["name", "lucideEye", "size", "1.25em"], ["name", "lucideCopy", "size", "1.25em"], [1, "signature-hint"]], template: function WebhookSandboxPage_Template(rf, ctx) {
2041  if (rf & 1) {
2042    \u0275\u0275elementStart(0, "ion-header")(1, "ion-toolbar")(2, "ion-buttons", 0);
2043    \u0275\u0275element(3, "ion-menu-button");
2044    \u0275\u0275elementEnd();
2045    \u0275\u0275elementStart(4, "ion-title");
2046    \u0275\u0275text(5);
2047    \u0275\u0275pipe(6, "translate");
2048    \u0275\u0275elementEnd();
2049    \u0275\u0275elementStart(7, "ion-buttons", 1)(8, "div", 2);
2050    \u0275\u0275element(9, "ng-icon", 3);
2051    \u0275\u0275elementStart(10, "ion-toggle", 4);
2052    \u0275\u0275listener("ionChange", function WebhookSandboxPage_Template_ion_toggle_ionChange_10_listener($event) {
2053      return ctx.toggleMockData($event);
2054    });
2055    \u0275\u0275elementEnd()();
2056    \u0275\u0275elementStart(11, "ion-button", 5);
2057    \u0275\u0275listener("click", function WebhookSandboxPage_Template_ion_button_click_11_listener() {
2058      return ctx.manualRefresh();
2059    });
2060    \u0275\u0275element(12, "ng-icon", 6);
2061    \u0275\u0275elementEnd()()();
2062    \u0275\u0275elementStart(13, "ion-toolbar")(14, "ion-segment", 7);
2063    \u0275\u0275listener("ionChange", function WebhookSandboxPage_Template_ion_segment_ionChange_14_listener($event) {
2064      return ctx.onTabChange($event);
2065    });
2066    \u0275\u0275elementStart(15, "ion-segment-button", 8)(16, "ion-label");
2067    \u0275\u0275text(17);
2068    \u0275\u0275pipe(18, "translate");
2069    \u0275\u0275elementEnd()();
2070    \u0275\u0275elementStart(19, "ion-segment-button", 9)(20, "ion-label");
2071    \u0275\u0275text(21);
2072    \u0275\u0275pipe(22, "translate");
2073    \u0275\u0275elementEnd()();
2074    \u0275\u0275elementStart(23, "ion-segment-button", 10)(24, "ion-label");
2075    \u0275\u0275text(25);
2076    \u0275\u0275pipe(26, "translate");
2077    \u0275\u0275elementEnd()()()()();
2078    \u0275\u0275elementStart(27, "ion-content")(28, "ion-refresher", 11);
2079    \u0275\u0275listener("ionRefresh", function WebhookSandboxPage_Template_ion_refresher_ionRefresh_28_listener($event) {
2080      return ctx.doRefresh($event);
2081    });
2082    \u0275\u0275element(29, "ion-refresher-content");
2083    \u0275\u0275elementEnd();
2084    \u0275\u0275template(30, WebhookSandboxPage_Conditional_30_Template, 9, 4, "div", 12)(31, WebhookSandboxPage_Conditional_31_Template, 22, 20, "div", 12)(32, WebhookSandboxPage_Conditional_32_Template, 3, 1, "div", 13)(33, WebhookSandboxPage_Conditional_33_Template, 45, 24)(34, WebhookSandboxPage_Conditional_34_Template, 33, 12);
2085    \u0275\u0275elementEnd();
2086  }
2087  if (rf & 2) {
2088    \u0275\u0275advance(5);
2089    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(6, 13, "webhookSandbox.title"));
2090    \u0275\u0275advance(4);
2091    \u0275\u0275classProp("active", ctx.isMockEnabled);
2092    \u0275\u0275advance();
2093    \u0275\u0275property("checked", ctx.isMockEnabled);
2094    \u0275\u0275advance(4);
2095    \u0275\u0275property("value", ctx.activeTab);
2096    \u0275\u0275advance(3);
2097    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(18, 15, "webhookSandbox.tabs.subscriptions"));
2098    \u0275\u0275advance(4);
2099    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(22, 17, "webhookSandbox.tabs.deliveries"));
2100    \u0275\u0275advance(4);
2101    \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(26, 19, "webhookSandbox.tabs.statistics"));
2102    \u0275\u0275advance(5);
2103    \u0275\u0275conditional(ctx.activeTab === "subscriptions" ? 30 : -1);
2104    \u0275\u0275advance();
2105    \u0275\u0275conditional(ctx.activeTab === "deliveries" ? 31 : -1);
2106    \u0275\u0275advance();
2107    \u0275\u0275conditional(ctx.activeTab === "statistics" ? 32 : -1);
2108    \u0275\u0275advance();
2109    \u0275\u0275conditional(ctx.isFormVisible ? 33 : -1);
2110    \u0275\u0275advance();
2111    \u0275\u0275conditional(ctx.isSecretModalVisible ? 34 : -1);
2112  }
2113}, dependencies: [
2114  CommonModule,
2115  DecimalPipe,
2116  ReactiveFormsModule,
2117  \u0275NgNoValidate,
2118  NgControlStatus,
2119  NgControlStatusGroup,
2120  FormGroupDirective,
2121  FormControlName,
2122  TranslateModule,
2123  TranslatePipe,
2124  NgIcon,
2125  IonHeader,
2126  IonToolbar,
2127  IonButtons,
2128  IonMenuButton,
2129  IonTitle,
2130  IonContent,
2131  IonSegment,
2132  IonSegmentButton,
2133  IonLabel,
2134  IonList,
2135  IonItem,
2136  IonCard,
2137  IonCardHeader,
2138  IonCardTitle,
2139  IonCardContent,
2140  IonButton,
2141  IonBadge,
2142  IonInput,
2143  IonTextarea,
2144  IonChip,
2145  IonRefresher,
2146  IonRefresherContent,
2147  IonSpinner,
2148  IonSelect,
2149  IonSelectOption,
2150  IonToggle,
2151  IonGrid,
2152  IonRow,
2153  IonCol,
2154  IonProgressBar,
2155  IonNote
2156], styles: ["\n\n.mock-toggle[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  gap: 6px;\n  padding-right: 8px;\n}\n.mock-toggle[_ngcontent-%COMP%]   ng-icon[_ngcontent-%COMP%] {\n  color: var(--ion-color-medium);\n  transition: color 0.2s ease;\n}\n.mock-toggle[_ngcontent-%COMP%]   ng-icon.active[_ngcontent-%COMP%] {\n  color: var(--ion-color-warning);\n}\n.mock-toggle[_ngcontent-%COMP%]   ion-toggle[_ngcontent-%COMP%] {\n  --track-background: var(--ion-color-medium);\n  --track-background-checked: var(--ion-color-warning);\n  --handle-background-checked: var(--ion-color-warning-contrast);\n  padding: 0;\n}\n.tab-content[_ngcontent-%COMP%] {\n  padding: 16px;\n  padding-bottom: 80px;\n}\n.loading-container[_ngcontent-%COMP%] {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  min-height: 200px;\n}\n.empty-state[_ngcontent-%COMP%] {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  min-height: 300px;\n  color: var(--ion-color-medium);\n  text-align: center;\n}\n.empty-state[_ngcontent-%COMP%]   ng-icon[_ngcontent-%COMP%] {\n  opacity: 0.5;\n  margin-bottom: 16px;\n}\n.empty-state[_ngcontent-%COMP%]   p[_ngcontent-%COMP%] {\n  font-size: 1.1em;\n}\n.subscription-card[_ngcontent-%COMP%] {\n  margin-bottom: 12px;\n}\n.subscription-card.circuit-open[_ngcontent-%COMP%] {\n  border-left: 4px solid var(--ion-color-danger);\n}\n.subscription-card[_ngcontent-%COMP%]   ion-card-header[_ngcontent-%COMP%] {\n  padding-bottom: 8px;\n}\n.subscription-card[_ngcontent-%COMP%]   .card-header-row[_ngcontent-%COMP%] {\n  display: flex;\n  justify-content: space-between;\n  align-items: flex-start;\n  gap: 8px;\n}\n.subscription-card[_ngcontent-%COMP%]   .url-container[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  flex: 1;\n  min-width: 0;\n}\n.subscription-card[_ngcontent-%COMP%]   .url-container[_ngcontent-%COMP%]   .target-url[_ngcontent-%COMP%] {\n  font-size: 0.85em;\n  font-weight: 500;\n  color: var(--ion-color-primary);\n  word-break: break-all;\n}\n.subscription-card[_ngcontent-%COMP%]   .url-container[_ngcontent-%COMP%]   .external-link[_ngcontent-%COMP%] {\n  color: var(--ion-color-medium);\n  flex-shrink: 0;\n}\n.subscription-card[_ngcontent-%COMP%]   .action-buttons[_ngcontent-%COMP%] {\n  display: flex;\n  gap: 0;\n  flex-shrink: 0;\n}\n.subscription-card[_ngcontent-%COMP%]   .action-buttons[_ngcontent-%COMP%]   ion-button[_ngcontent-%COMP%] {\n  --padding-start: 8px;\n  --padding-end: 8px;\n}\n.subscription-card[_ngcontent-%COMP%]   .description[_ngcontent-%COMP%] {\n  font-size: 0.95em;\n  font-weight: normal;\n  margin-top: 4px;\n}\n.subscription-card[_ngcontent-%COMP%]   .types-row[_ngcontent-%COMP%] {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: 4px;\n  margin-bottom: 12px;\n}\n.subscription-card[_ngcontent-%COMP%]   .types-row[_ngcontent-%COMP%]   .separator[_ng
2156content-%COMP%] {\n  color: var(--ion-color-medium);\n  margin: 0 4px;\n}\n.subscription-card[_ngcontent-%COMP%]   .types-row[_ngcontent-%COMP%]   .type-chips[_ngcontent-%COMP%] {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 4px;\n}\n.subscription-card[_ngcontent-%COMP%]   .types-row[_ngcontent-%COMP%]   ion-chip[_ngcontent-%COMP%] {\n  height: 24px;\n  font-size: 0.75em;\n  margin: 0;\n}\n.subscription-card[_ngcontent-%COMP%]   .status-row[_ngcontent-%COMP%] {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: 12px;\n}\n.subscription-card[_ngcontent-%COMP%]   .status-row[_ngcontent-%COMP%]   ion-badge[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n.subscription-card[_ngcontent-%COMP%]   .status-row[_ngcontent-%COMP%]   .stat[_ngcontent-%COMP%] {\n  font-size: 0.85em;\n  color: var(--ion-color-medium);\n}\n.subscription-card[_ngcontent-%COMP%]   .status-row[_ngcontent-%COMP%]   .stat.failed[_ngcontent-%COMP%] {\n  color: var(--ion-color-danger);\n}\n.subscription-card[_ngcontent-%COMP%]   .expanded-content[_ngcontent-%COMP%] {\n  margin-top: 16px;\n  padding-top: 16px;\n  border-top: 1px solid var(--ion-color-light);\n}\n.subscription-card[_ngcontent-%COMP%]   .expanded-content[_ngcontent-%COMP%]   .meta[_ngcontent-%COMP%] {\n  font-size: 0.85em;\n  color: var(--ion-color-medium);\n  margin: 4px 0;\n}\n.subscription-card[_ngcontent-%COMP%]   .expanded-content[_ngcontent-%COMP%]   .expanded-actions[_ngcontent-%COMP%] {\n  display: flex;\n  gap: 8px;\n  margin-top: 12px;\n}\n.fab-container[_ngcontent-%COMP%] {\n  position: fixed;\n  bottom: 16px;\n  left: 16px;\n  right: 16px;\n  z-index: 100;\n}\n.filter-row[_ngcontent-%COMP%] {\n  margin-bottom: 16px;\n}\n.filter-row[_ngcontent-%COMP%]   ion-select[_ngcontent-%COMP%] {\n  max-width: 300px;\n}\n.delivery-item[_ngcontent-%COMP%] {\n  width: 100%;\n  padding: 8px 0;\n}\n.delivery-item[_ngcontent-%COMP%]   .delivery-header[_ngcontent-%COMP%] {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: 4px;\n}\n.delivery-item[_ngcontent-%COMP%]   .delivery-header[_ngcontent-%COMP%]   .event-info[_ngcontent-%COMP%] {\n  font-weight: 500;\n  font-size: 0.95em;\n}\n.delivery-item[_ngcontent-%COMP%]   .delivery-header[_ngcontent-%COMP%]   ion-badge[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n.delivery-item[_ngcontent-%COMP%]   .delivery-details[_ngcontent-%COMP%] {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 8px;\n  font-size: 0.85em;\n  color: var(--ion-color-medium);\n}\n.delivery-item[_ngcontent-%COMP%]   .delivery-details[_ngcontent-%COMP%]   .target[_ngcontent-%COMP%] {\n  max-width: 200px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n.delivery-item[_ngcontent-%COMP%]   .delivery-details[_ngcontent-%COMP%]   .response-time[_ng
2156content-%COMP%] {\n  color: var(--ion-color-success);\n}\n.delivery-item[_ngcontent-%COMP%]   .error-message[_ngcontent-%COMP%] {\n  margin-top: 8px;\n  padding: 8px;\n  background: var(--ion-color-danger-tint);\n  border-radius: 4px;\n  font-size: 0.85em;\n  color: var(--ion-color-danger-shade);\n}\n.delivery-item[_ngcontent-%COMP%]   .retry-info[_ngcontent-%COMP%] {\n  margin-top: 4px;\n  font-size: 0.8em;\n  color: var(--ion-color-warning-shade);\n}\n.load-more[_ngcontent-%COMP%] {\n  display: flex;\n  justify-content: center;\n  padding: 16px;\n}\n.stats-tab[_ngcontent-%COMP%]   ion-grid[_ngcontent-%COMP%] {\n  padding: 0;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%] {\n  height: 100%;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card.warning[_ngcontent-%COMP%] {\n  border-left: 4px solid var(--ion-color-warning);\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   ion-card-header[_ngcontent-%COMP%] {\n  padding-bottom: 4px;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   ion-card-title[_ngcontent-%COMP%] {\n  font-size: 0.85em;\n  color: var(--ion-color-medium);\n  text-transform: uppercase;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   ion-card-content[_ngcontent-%COMP%] {\n  padding-top: 8px;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-value[_ngcontent-%COMP%] {\n  font-size: 2em;\n  font-weight: bold;\n  color: var(--ion-color-dark);\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-value.large[_ngcontent-%COMP%] {\n  font-size: 2.5em;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-label[_ngcontent-%COMP%] {\n  font-size: 0.9em;\n  color: var(--ion-color-medium);\n  margin-top: 4px;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-breakdown[_ngcontent-%COMP%] {\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n  margin-top: 8px;\n  font-size: 0.85em;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-breakdown.horizontal[_ngcontent-%COMP%] {\n  flex-direction: row;\n  flex-wrap: wrap;\n  gap: 12px;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-breakdown[_ngcontent-%COMP%]   .active[_ngcontent-%COMP%], \n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-breakdown[_ngcontent-%COMP%]   .success[_ngcontent-%COMP%] {\n  color: var(--ion-color-success);\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-breakdown[_ngcontent-%COMP%]   .inactive[_ngcontent-%COMP%] {\n  color: var(--ion-color-medium);\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-breakdown[_ngcontent-%COMP%]   .failed[_ngcontent-%COMP%] {\n  color: var(--ion-color-danger);\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-breakdown[_ngcontent-%COMP%]   .retrying[_ngcontent-%COMP%] {\n  color: var(--ion-color-warning);\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-breakdown[_ngcontent-%COMP%]   .pending[_ngcontent-%COMP%] {\n  color: var(--ion-color-medium);\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .stat-breakdown[_ngcontent-%COMP%]   span[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   ion-progress-bar[_ngcontent-%COMP%] {\n  margin: 12px 0 8px;\n  height: 8px;\n  border-radius: 4px;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   .progress-label[_ngcontent-%COMP%] {\n  font-size: 0.9em;\n  color: var(--ion-color-success);\n  font-weight: 500;\n}\n.stats-tab[_ngcontent-%COMP%]   .stat-card[_ngcontent-%COMP%]   ion-note[_ngcontent-%COMP%] {\n  display: block;\n  margin-top: 8px;\n}\n.modal-backdrop[_ngcontent-%COMP%] {\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background: rgba(0, 0, 0, 0.5);\n  z-index: 1000;\n}\n.form-modal[_ngcontent-%COMP%] {\n  position: fixed;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 90%;\n  max-width: 500px;\n  max-height: 90vh;\n  background: var(--ion-item-background, #ffffff);\n  border-radius: 12px;\n  z-index: 1001;\n  overflow-y: auto;\n  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n  animation: modalEnter 0.2s ease-out;\n}\n@media (prefers-color-scheme: dark) {\n  .form-modal[_ngcontent-%COMP%] {\n    background: var(--ion-item-background, #1e1e1e);\n    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);\n  }\n}
2156\n.form-modal[_ngcontent-%COMP%]   .modal-header[_ngcontent-%COMP%] {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 16px 20px;\n  border-bottom: 1px solid var(--ion-color-light);\n}\n.form-modal[_ngcontent-%COMP%]   .modal-header.success[_ngcontent-%COMP%] {\n  background: var(--ion-color-success);\n  color: white;\n  border-bottom: none;\n}\n.form-modal[_ngcontent-%COMP%]   .modal-header.success[_ngcontent-%COMP%]   h2[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n}\n.form-modal[_ngcontent-%COMP%]   .modal-header[_ngcontent-%COMP%]   h2[_ngcontent-%COMP%] {\n  margin: 0;\n  font-size: 1.2em;\n}\n.form-modal[_ngcontent-%COMP%]   .modal-header[_ngcontent-%COMP%]   ion-button[_ngcontent-%COMP%] {\n  --padding-start: 8px;\n  --padding-end: 8px;\n}\n.form-modal[_ngcontent-%COMP%]   form[_ngcontent-%COMP%], \n.form-modal[_ngcontent-%COMP%]   .secret-content[_ngcontent-%COMP%] {\n  padding: 20px;\n}\n.form-modal[_ngcontent-%COMP%]   .form-field[_ngcontent-%COMP%] {\n  margin-bottom: 20px;\n}\n.form-modal[_ngcontent-%COMP%]   .form-field[_ngcontent-%COMP%]   ion-label[_ngcontent-%COMP%] {\n  display: block;\n  font-size: 0.9em;\n  font-weight: 500;\n  margin-bottom: 8px;\n  color: var(--ion-color-dark);\n}\n.form-modal[_ngcontent-%COMP%]   .form-field[_ngcontent-%COMP%]   ion-input[_ngcontent-%COMP%], \n.form-modal[_ngcontent-%COMP%]   .form-field[_ngcontent-%COMP%]   ion-textarea[_ngcontent-%COMP%] {\n  --background: var(--ion-color-light);\n  --border-radius: 8px;\n  --padding-start: 12px;\n  --padding-end: 12px;\n}\n.form-modal[_ngcontent-%COMP%]   .form-field[_ngcontent-%COMP%]   .error-text[_ngcontent-%COMP%] {\n  display: block;\n  color: var(--ion-color-danger);\n  font-size: 0.8em;\n  margin-top: 4px;\n}\n.form-modal[_ngcontent-%COMP%]   .form-field[_ngcontent-%COMP%]   .hint-text[_ngcontent-%COMP%] {\n  display: block;\n  color: var(--ion-color-medium);\n  font-size: 0.8em;\n  margin-top: 4px;\n}\n.form-modal[_ngcontent-%COMP%]   .chip-selector[_ngcontent-%COMP%] {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 8px;\n}\n.form-modal[_ngcontent-%COMP%]   .chip-selector[_ngcontent-%COMP%]   ion-chip[_ngcontent-%COMP%] {\n  cursor: pointer;\n  margin: 0;\n}\n.form-modal[_ngcontent-%COMP%]   .form-actions[_ngcontent-%COMP%] {\n  display: flex;\n  justify-content: flex-end;\n  gap: 12px;\n  padding-top: 12px;\n  border-top: 1px solid var(--ion-color-light);\n  margin-top: 20px;\n}\n.secret-modal[_ngcontent-%COMP%]   .warning-box[_ngcontent-%COMP%] {\n  display: flex;\n  gap: 12px;\n  padding: 16px;\n  background: var(--ion-color-warning-tint);\n  border-radius: 8px;\n  margin-bottom: 20px;\n}\n.secret-modal[_ngcontent-%COMP%]   .warning-box[_ngcontent-%COMP%]   ng-icon[_ngcontent-%COMP%] {\n  color: var(--ion-color-warning-shade);\n  flex-shrink: 0;\n}\n.secret-modal[_ngcontent-%COMP%]   .warning-box[_ngcontent-%COMP%]   p[_ngcontent-%COMP%] {\n  margin: 0;\n  font-size: 0.9em;\n  color: var(--ion-color-warning-shade);\n}\n.secret-modal[_ngcontent-%COMP%]   .secret-input-container[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  background: var(--ion-color-light);\n  border-radius: 8px;\n  padding-right: 4px;\n}\n.secret-modal[_ngcontent-%COMP%]   .secret-input-container[_ngcontent-%COMP%]   ion-input[_ngcontent-%COMP%] {\n  flex: 1;\n  --background: transparent;\n  font-family: monospace;\n  font-size: 0.85em;\n}\n.secret-modal[_ngcontent-%COMP%]   .secret-input-container[_ngcontent-%COMP%]   ion-button[_ngcontent-%COMP%] {\n  --padding-start: 8px;\n  --padding-end: 8px;\n}\n.secret-modal[_ngcontent-%COMP%]   .signature-hint[_ngcontent-%COMP%] {\n  margin-top: 16px;\n  font-size: 0.85em;\n  color: var(--ion-color-medium);\n}\n.secret-modal[_ngcontent-%COMP%]   .signature-hint[_ngcontent-%COMP%]   code[_ngcontent-%COMP%] {\n  display: inline-block;\n  background: var(--ion-color-light);\n  padding: 2px 6px;\n  border-radius: 4px;\n  font-size: 0.9em;\n}\n.secret-modal[_ngcontent-%COMP%]   .form-actions[_ngcontent-%COMP%] {\n  border-top: none;\n  margin-top: 0;\n  padding-top: 0;\n}"] });
2157var WebhookSandboxPage = _WebhookSandboxPage;
2158(() => {
2159  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(WebhookSandboxPage, [{
2160    type: Component,
2161    args: [{ selector: "app-webhook-sandbox", standalone: true, imports: [
2162      CommonModule,
2163      ReactiveFormsModule,
2164      TranslateModule,
2165      NgIcon,
2166      IonHeader,
2167      IonToolbar,
2168      IonButtons,
2169      IonMenuButton,
2170      IonTitle,
2171      IonContent,
2172      IonSegment,
2173      IonSegmentButton,
2174      IonLabel,
2175      IonList,
2176      IonItem,
2177      IonCard,
2178      IonCardHeader,
2179      IonCardTitle,
2180      IonCardContent,
2181      IonButton,
2182      IonBadge,
2183      IonInput,
2184      IonTextarea,
2185      IonChip,
2186      IonRefresher,
2187      IonRefresherContent,
2188      IonSpinner,
2189      IonSelect,
2190      IonSelectOption,
2191      IonToggle,
2192      IonGrid,
2193      IonRow,
2194      IonCol,
2195      IonProgressBar,
2196      IonNote
2197    ], viewProviders: [provideIcons({
2198      lucideWebhook,
2199      lucideRefreshCw,
2200      lucidePlus,
2201      lucidePencil,
2202      lucideTrash2,
2203      lucidePlay,
2204      lucideCheck,
2205      lucideX,
2206      lucideTriangleAlert,
2207      lucideClock,
2208      lucideRotateCw,
2209      lucideCopy,
2210      lucideEye,
2211      lucideEyeOff,
2212      lucideActivity,
2213      lucideZap,
2214      lucideCircle,
2215      lucideCircleDot,
2216      lucideExternalLink,
2217      lucideChevronDown,
2218      lucideChevronUp,
2219      lucideFilter,
2220      lucideFlaskConical
2221    })], template: `<ion-header>
2222  <ion-toolbar>
2223    <ion-buttons slot="start">
2224      <ion-menu-button></ion-menu-button>
2225    </ion-buttons>
2226    <ion-title>{{ 'webhookSandbox.title' | translate }}</ion-title>
2227    <ion-buttons slot="end">
2228      <div class="mock-toggle">
2229        <ng-icon name="lucideFlaskConical" size="1em" [class.active]="isMockEnabled"></ng-icon>
2230        <ion-toggle
2231          [checked]="isMockEnabled"
2232          (ionChange)="toggleMockData($event)"
2233          labelPlacement="start"
2234        ></ion-toggle>
2235      </div>
2236      <ion-button (click)="manualRefresh()">
2237        <ng-icon name="lucideRefreshCw" size="1.25em"></ng-icon>
2238      </ion-button>
2239    </ion-buttons>
2240  </ion-toolbar>
2241
2242  <ion-toolbar>
2243    <ion-segment [value]="activeTab" (ionChange)="onTabChange($event)">
2244      <ion-segment-button value="subscriptions">
2245        <ion-label>{{ 'webhookSandbox.tabs.subscriptions' | translate }}</ion-label>
2246      </ion-segment-button>
2247      <ion-segment-button value="deliveries">
2248        <ion-label>{{ 'webhookSandbox.tabs.deliveries' | translate }}</ion-label>
2249      </ion-segment-button>
2250      <ion-segment-button value="statistics">
2251        <ion-label>{{ 'webhookSandbox.tabs.statistics' | translate }}</ion-label>
2252      </ion-segment-button>
2253    </ion-segment>
2254  </ion-toolbar>
2255</ion-header>
2256
2257<ion-content>
2258  <ion-refresher slot="fixed" (ionRefresh)="doRefresh($event)">
2259    <ion-refresher-content></ion-refresher-content>
2260  </ion-refresher>
2261
2262  <!-- ==================== SUBSCRIPTIONS TAB ==================== -->
2263  @if (activeTab === 'subscriptions') {
2264    <div class="tab-content">
2265      @if (isLoadingSubscriptions) {
2266        <div class="loading-container">
2267          <ion-spinner name="crescent"></ion-spinner>
2268        </div>
2269      } @else if (subscriptions.length === 0) {
2270        <div class="empty-state">
2271          <ng-icon name="lucideWebhook" size="3em"></ng-icon>
2272          <p>{{ 'webhookSandbox.subscriptions.noSubscriptions' | translate }}</p>
2273        </div>
2274      } @else {
2275        <ion-list>
2276          @for (sub of subscriptions; track sub.id) {
2277            <ion-card class="subscription-card" [class.circuit-open]="isCircuitOpen(sub)">
2278              <ion-card-header>
2279                <div class="card-header-row">
2280                  <div class="url-container">
2281                    <span class="target-url">{{ sub.targetUrl }}</span>
2282                    <a [href]="sub.targetUrl" target="_blank" class="external-link">
2283                      <ng-icon name="lucideExternalLink" size="0.9em"></ng-icon>
2284                    </a>
2285                  </div>
2286                  <div class="action-buttons">
2287                    <ion-button fill="clear" size="small" (click)="testSubscription(sub)">
2288                      <ng-icon name="lucidePlay" size="1em"></ng-icon>
2289                    </ion-button>
2290                    <ion-button fill="clear" size="small" (click)="openEditForm(sub)">
2291                      <ng-icon name="lucidePencil" size="1em"></ng-icon>
2292                    </ion-button>
2293                    <ion-button fill="clear" size="small" (click)="toggleSubscriptionExpand(sub.id)">
2294                      @if (expandedSubscriptionId === sub.id) {
2295                        <ng-icon name="lucideChevronUp" size="1em"></ng-icon>
2296                      } @else {
2297                        <ng-icon name="lucideChevronDown" size="1em"></ng-icon>
2298                      }
2299                    </ion-button>
2300                  </div>
2301                </div>
2302                @if (sub.description) {
2303                  <ion-card-title class="description">{{ sub.description }}</ion-card-title>
2304                }
2305              </ion-card-header>
2306
2307              <ion-card-content>
2308                <div class="types-row">
2309                  <div class="type-chips">
2310                    @for (et of sub.entityTypes; track et) {
2311                      <ion-chip color="primary" outline="true">{{ 'webhookSandbox.entityTypes.' + et | translate }}</ion-chip>
2312                    }
2313                  </div>
2314                  <span class="separator">|</span>
2315                  <div class="type-chips">
2316                    @for (evt of sub.eventTypes; track evt) {
2317                      <ion-chip color="secondary" outline="true">{{ 'webhookSandbox.eventTypes.' + evt | translate }}</ion-chip>
2318                    }
2319                  </div>
2320                </div>
2321
2322                <div class="status-row">
2323                  @if (isCircuitOpen(sub)) {
2324                    <ion-badge color="danger">
2325                      <ng-icon name="lucideTriangleAlert" size="0.8em"></ng-icon>
2326                      {{ 'webhookSandbox.subscriptions.circuitOpen' | translate }} ({{ getCircuitOpenUntil(sub) }})
2327                    </ion-badge>
2328                  } @else if (sub.isActive) {
2329                    <ion-badge color="success">
2330                      <ng-icon name="lucideCheck" size="0.8em"></ng-icon>
2331                      {{ 'webhookSandbox.subscriptions.active' | translate }}
2332                    </ion-badge>
2333                  } @else {
2334                    <ion-badge color="medium">
2335                      {{ 'webhookSandbox.subscriptions.inactive' | translate }}
2336                    </ion-badge>
2337                  }
2338
2339                  <span class="stat">{{ sub.totalDeliveries }} delivered</span>
2340                  @if (sub.totalFailures > 0) {
2341                    <span class="stat failed">{{ sub.totalFailures }} failed</span>
2342                  }
2343                </div>
2344
2345                @if (expandedSubscriptionId === sub.id) {
2346                  <div class="expanded-content">
2347                    <ion-item lines="none">
2348                      <ion-label>{{ 'webhookSandbox.subscriptions.active' | translate }}</ion-label>
2349                      <ion-toggle [checked]="sub.isActive" (ionChange)="toggleSubscriptionActive(sub)"></ion-toggle>
2350                    </ion-item>
2351
2352                    @if (sub.lastDeliveryAt) {
2353                      <p class="meta">Last delivery: {{ formatTimeAgo(sub.lastDeliveryAt) }}</p>
2354                    }
2355                    @if (sub.lastSuccessAt) {
2356                      <p class="meta">Last success: {{ formatTimeAgo(sub.lastSuccessAt) }}</p>
2357                    }
2358                    @if (sub.secretPrefix) {
2359                      <p class="meta">Secret: {{ sub.secretPrefix }}...</p>
2360                    }
2361
2362                    <div class="expanded-actions">
2363                      @if (isCircuitOpen(sub)) {
2364                        <ion-button size="small" fill="outline" color="warning" (click)="resetCircuitBreaker(sub)">
2365                          <ng-icon name="lucideRotateCw" size="1em" slot="start"></ng-icon>
2366                          Reset Circuit
2367                        </ion-button>
2368                      }
2369                      <ion-button size="small" fill="outline" color="danger" (click)="confirmDeleteSubscription(sub)">
2370                        <ng-icon name="lucideTrash2" size="1em" slot="start"></ng-icon>
2371                        {{ 'webhookSandbox.subscriptions.delete' | translate }}
2372                      </ion-button>
2373                    </div>
2374                  </div>
2375                }
2376              </ion-card-content>
2377            </ion-card>
2378          }
2379        </ion-list>
2380      }
2381
2382      <div class="fab-container">
2383        <ion-button expand="block" (click)="openCreateForm()">
2384          <ng-icon name="lucidePlus" size="1.25em" slot="start"></ng-icon>
2385          {{ 'webhookSandbox.subscriptions.create' | translate }}
2386        </ion-button>
2387      </div>
2388    </div>
2389  }
2390
2391  <!-- ==================== DELIVERIES TAB ==================== -->
2392  @if (activeTab === 'deliveries') {
2393    <div class="tab-content">
2394      <div class="filter-row">
2395        <ion-select
2396          [value]="deliveryStatusFilter"
2397          (ionChange)="onDeliveryFilterChange($event)"
2398          interface="popover"
2399          label="{{ 'webhookSandbox.deliveries.status' | translate }}"
2400          labelPlacement="start"
2401        >
2402          <ion-select-option value="all">{{ 'webhookSandbox.deliveries.filter.all' | translate }}</ion-select-option>
2403          <ion-select-option value="Delivered">{{ 'webhookSandbox.deliveries.delivered' | translate }}</ion-select-option>
2404          <ion-select-option value="Failed">{{ 'webhookSandbox.deliveries.failed' | translate }}</ion-select-option>
2405          <ion-select-option value="Retrying">{{ 'webhookSandbox.deliveries.retrying' | translate }}</ion-select-option>
2406          <ion-select-option value="Pending">{{ 'webhookSandbox.deliveries.pending' | translate }}</ion-select-option>
2407        </ion-select>
2408      </div>
2409
2410      @if (isLoadingDeliveries && deliveries.length === 0) {
2411        <div class="loading-container">
2412          <ion-spinner name="crescent"></ion-spinner>
2413        </div>
2414      } @else if (deliveries.length === 0) {
2415        <div class="empty-state">
2416          <ng-icon name="lucideActivity" size="3em"></ng-icon>
2417          <p>{{ 'webhookSandbox.deliveries.noDeliveries' | translate }}</p>
2418        </div>
2419      } @else {
2420        <ion-list>
2421          @for (delivery of deliveries; track delivery.id) {
2422            <ion-item>
2423              <div class="delivery-item">
2424                <div class="delivery-header">
2425                  <span class="event-info">{{ delivery.entityType }}.{{ delivery.eventType }}</span>
2426                  <ion-badge [color]="getDeliveryStatusColor(delivery.status)">
2427                    @if (delivery.status === 'Delivered') {
2428                      <ng-icon name="lucideCheck" size="0.8em"></ng-icon>
2429                    } @else if (delivery.status === 'Failed') {
2430                      <ng-icon name="lucideX" size="0.8em"></ng-icon>
2431                    } @else if (delivery.status === 'Retrying') {
2432                      <ng-icon name="lucideRotateCw" size="0.8em"></ng-icon>
2433                    } @else {
2434                      <ng-icon name="lucideClock" size="0.8em"></ng-icon>
2435                    }
2436                    {{ delivery.status }}
2437                    @if (delivery.httpStatusCode) {
2438                      ({{ delivery.httpStatusCode }})
2439                    }
2440                  </ion-badge>
2441                </div>
2442                <div class="delivery-details">
2443                  @if (delivery.subscriptionTargetUrl) {
2444                    <span class="target">{{ delivery.subscriptionTargetUrl }}</span>
2445                  }
2446                  @if (delivery.responseTimeMs) {
2447                    <span class="response-time">{{ delivery.responseTimeMs }}ms</span>
2448                  }
2449                  <span class="time-ago">{{ formatTimeAgo(delivery.createdAt) }}</span>
2450                </div>
2451                @if (delivery.errorMessage) {
2452                  <div class="error-message">{{ delivery.errorMessage }}</div>
2453                }
2454                @if (delivery.status === 'Failed') {
2455                  <ion-button size="small" fill="clear" (click)="retryDelivery(delivery)">
2456                    <ng-icon name="lucideRotateCw" size="1em" slot="start"></ng-icon>
2457                    {{ 'webhookSandbox.deliveries.retry' | translate }}
2458                  </ion-button>
2459                }
2460                @if (delivery.status === 'Retrying' && delivery.nextRetryAt) {
2461                  <div class="retry-info">
2462                    Attempt {{ delivery.attemptCount }}/8 | Next: {{ formatTimeAgo(delivery.nextRetryAt) }}
2463                  </div>
2464                }
2465              </div>
2466            </ion-item>
2467          }
2468        </ion-list>
2469
2470        @if (hasMoreDeliveries) {
2471          <div class="load-more">
2472            <ion-button fill="outline" (click)="loadMoreDeliveries()" [disabled]="isLoadingDeliveries">
2473              @if (isLoadingDeliveries) {
2474                <ion-spinner name="crescent" slot="start"></ion-spinner>
2475              }
2476              Load More
2477            </ion-button>
2478          </div>
2479        }
2480      }
2481    </div>
2482  }
2483
2484  <!-- ==================== STATISTICS TAB ==================== -->
2485  @if (activeTab === 'statistics') {
2486    <div class="tab-content stats-tab">
2487      @if (isLoadingStats) {
2488        <div class="loading-container">
2489          <ion-spinner name="crescent"></ion-spinner>
2490        </div>
2491      } @else if (stats) {
2492        <ion-grid>
2493          <ion-row>
2494            <ion-col size="6">
2495              <ion-card class="stat-card">
2496                <ion-card-header>
2497                  <ion-card-title>{{ 'webhookSandbox.stats.subscriptions' | translate }}</ion-card-title>
2498                </ion-card-header>
2499                <ion-card-content>
2500                  <div class="stat-value">{{ stats.subscriptions.total }}</div>
2501                  <div class="stat-breakdown">
2502                    <span class="active">{{ stats.subscriptions.active }} {{ 'webhookSandbox.stats.active' | translate }}</span>
2503                    <span class="inactive">{{ stats.subscriptions.total - stats.subscriptions.active }} {{ 'webhookSandbox.stats.inactive' | translate }}</span>
2504                  </div>
2505                </ion-card-content>
2506              </ion-card>
2507            </ion-col>
2508
2509            <ion-col size="6">
2510              <ion-card class="stat-card" [class.warning]="stats.subscriptions.circuitOpen > 0">
2511                <ion-card-header>
2512                  <ion-card-title>{{ 'webhookSandbox.stats.circuitBreakers' | translate }}</ion-card-title>
2513                </ion-card-header>
2514                <ion-card-content>
2515                  <div class="stat-value">{{ stats.subscriptions.circuitOpen }}</div>
2516                  <div class="stat-label">{{ 'webhookSandbox.stats.open' | translate }}</div>
2517                  @if (stats.subscriptions.circuitOpen > 0) {
2518                    <ion-button size="small" fill="outline" (click)="resetAllCircuitBreakers()">
2519                      {{ 'webhookSandbox.stats.resetAll' | translate }}
2520                    </ion-button>
2521                  }
2522                </ion-card-content>
2523              </ion-card>
2524            </ion-col>
2525          </ion-row>
2526
2527          <ion-row>
2528            <ion-col size="12">
2529              <ion-card class="stat-card">
2530                <ion-card-header>
2531                  <ion-card-title>{{ 'webhookSandbox.stats.deliveries24h' | translate }}</ion-card-title>
2532                </ion-card-header>
2533                <ion-card-content>
2534                  <div class="stat-value large">{{ stats.deliveries.last24Hours.total }}</div>
2535                  <ion-progress-bar [value]="getSuccessRate24h() / 100" color="success"></ion-progress-bar>
2536                  <div class="progress-label">{{ getSuccessRate24h() | number:'1.1-1' }}% {{ 'webhookSandbox.stats.successRate' | translate }}</div>
2537                  <div class="stat-breakdown horizontal">
2538                    <span class="success">
2539                      <ng-icon name="lucideCheck" size="0.9em"></ng-icon>
2540                      {{ stats.deliveries.last24Hours.delivered }}
2541                    </span>
2542                    <span class="failed">
2543                      <ng-icon name="lucideX" size="0.9em"></ng-icon>
2544                      {{ stats.deliveries.last24Hours.failed }}
2545                    </span>
2546                    <span class="retrying">
2547                      <ng-icon name="lucideRotateCw" size="0.9em"></ng-icon>
2548                      {{ stats.deliveries.last24Hours.retrying }}
2549                    </span>
2550                    <span class="pending">
2551                      <ng-icon name="lucideClock" size="0.9em"></ng-icon>
2552                      {{ stats.deliveries.last24Hours.pending }}
2553                    </span>
2554                  </div>
2555                </ion-card-content>
2556              </ion-card>
2557            </ion-col>
2558          </ion-row>
2559
2560          <ion-row>
2561            <ion-col size="6">
2562              <ion-card class="stat-card">
2563                <ion-card-header>
2564                  <ion-card-title>{{ 'webhookSandbox.stats.deliveries7d' | translate }}</ion-card-title>
2565                </ion-card-header>
2566                <ion-card-content>
2567                  <div class="stat-value">{{ stats.deliveries.last7Days.total }}</div>
2568                  <div class="stat-breakdown">
2569                    <span class="success">{{ stats.deliveries.last7Days.delivered }} delivered</span>
2570                    <span class="failed">{{ stats.deliveries.last7Days.failed }} failed</span>
2571                  </div>
2572                  <div class="progress-label">{{ getSuccessRate7d() | number:'1.1-1' }}%</div>
2573                </ion-card-content>
2574              </ion-card>
2575            </ion-col>
2576
2577            <ion-col size="6">
2578              <ion-card class="stat-card">
2579                <ion-card-header>
2580                  <ion-card-title>{{ 'webhookSandbox.stats.pendingEvents' | translate }}</ion-card-title>
2581                </ion-card-header>
2582                <ion-card-content>
2583                  <div class="stat-value">{{ stats.events.pending }}</div>
2584                  <div class="stat-label">{{ 'webhookSandbox.stats.queue' | translate }}</div>
2585                  <ion-note>{{ stats.events.processedLast24Hours }} processed (24h)</ion-note>
2586                </ion-card-content>
2587              </ion-card>
2588            </ion-col>
2589          </ion-row>
2590        </ion-grid>
2591      }
2592    </div>
2593  }
2594
2595  <!-- ==================== CREATE/EDIT FORM MODAL ==================== -->
2596  @if (isFormVisible) {
2597    <div class="modal-backdrop" (click)="closeForm()"></div>
2598    <div class="form-modal">
2599      <div class="modal-header">
2600        <h2>
2601          @if (isEditMode) {
2602            {{ 'webhookSandbox.subscriptions.edit' | translate }}
2603          } @else {
2604            {{ 'webhookSandbox.subscriptions.create' | translate }}
2605          }
2606        </h2>
2607        <ion-button fill="clear" (click)="closeForm()">
2608          <ng-icon name="lucideX" size="1.5em"></ng-icon>
2609        </ion-button>
2610      </div>
2611
2612      <form [formGroup]="subscriptionForm" (ngSubmit)="submitForm()">
2613        <div class="form-field">
2614          <ion-label>{{ 'webhookSandbox.subscriptions.targetUrl' | translate }} *</ion-label>
2615          <ion-input
2616            formControlName="targetUrl"
2617            type="url"
2618            placeholder="https://your-service.com/webhook"
2619          ></ion-input>
2620          @if (subscriptionForm.get('targetUrl')?.touched && subscriptionForm.get('targetUrl')?.hasError('required')) {
2621            <span class="error-text">URL is required</span>
2622          }
2623          @if (subscriptionForm.get('targetUrl')?.touched && subscriptionForm.get('targetUrl')?.hasError('pattern')) {
2624            <span class="error-text">Must be a valid HTTPS URL</span>
2625          }
2626        </div>
2627
2628        <div class="form-field">
2629          <ion-label>{{ 'webhookSandbox.subscriptions.description' | translate }}</ion-label>
2630          <ion-textarea
2631            formControlName="description"
2632            placeholder="Optional description for this webhook"
2633            rows="2"
2634          ></ion-textarea>
2635        </div>
2636
2637        <div class="form-field">
2638          <ion-label>{{ 'webhookSandbox.subscriptions.entityTypes' | translate }} *</ion-label>
2639          <div class="chip-selector">
2640            @for (type of entityTypes; track type) {
2641              <ion-chip
2642                [color]="isEntityTypeSelected(type) ? 'primary' : 'medium'"
2643                [outline]="!isEntityTypeSelected(type)"
2644                (click)="toggleEntityType(type)"
2645              >
2646                {{ 'webhookSandbox.entityTypes.' + type | translate }}
2647              </ion-chip>
2648            }
2649          </div>
2650          @if (selectedEntityTypes.length === 0) {
2651            <span class="hint-text">Select at least one entity type</span>
2652          }
2653        </div>
2654
2655        <div class="form-field">
2656          <ion-label>{{ 'webhookSandbox.subscriptions.eventTypes' | translate }} *</ion-label>
2657          <div class="chip-selector">
2658            @for (type of eventTypes; track type) {
2659              <ion-chip
2660                [color]="isEventTypeSelected(type) ? 'secondary' : 'medium'"
2661                [outline]="!isEventTypeSelected(type)"
2662                (click)="toggleEventType(type)"
2663              >
2664                {{ 'webhookSandbox.eventTypes.' + type | translate }}
2665              </ion-chip>
2666            }
2667          </div>
2668          @if (selectedEventTypes.length === 0) {
2669            <span class="hint-text">Select at least one event type</span>
2670          }
2671        </div>
2672
2673        <div class="form-actions">
2674          <ion-button fill="outline" (click)="closeForm()">
2675            {{ 'common.cancel' | translate }}
2676          </ion-button>
2677          <ion-button type="submit" [disabled]="isSubmitting">
2678            @if (isSubmitting) {
2679              <ion-spinner name="crescent" slot="start"></ion-spinner>
2680            }
2681            @if (isEditMode) {
2682              {{ 'common.update' | translate }}
2683            } @else {
2684              {{ 'webhookSandbox.subscriptions.create' | translate }}
2685            }
2686          </ion-button>
2687        </div>
2688      </form>
2689    </div>
2690  }
2691
2692  <!-- ==================== SECRET DISPLAY MODAL ==================== -->
2693  @if (isSecretModalVisible) {
2694    <div class="modal-backdrop" (click)="closeSecretModal()"></div>
2695    <div class="form-modal secret-modal">
2696      <div class="modal-header success">
2697        <ng-icon name="lucideCheck" size="1.5em"></ng-icon>
2698        <h2>{{ 'webhookSandbox.subscriptions.secretTitle' | translate }}</h2>
2699      </div>
2700
2701      <div class="secret-content">
2702        <div class="warning-box">
2703          <ng-icon name="lucideTriangleAlert" size="1.25em"></ng-icon>
2704          <p>{{ 'webhookSandbox.subscriptions.secretWarning' | translate }}</p>
2705        </div>
2706
2707        <div class="form-field">
2708          <ion-label>{{ 'webhookSandbox.subscriptions.secretLabel' | translate }}</ion-label>
2709          <div class="secret-input-container">
2710            <ion-input
2711              [value]="createdSecret"
2712              [type]="isSecretVisible ? 'text' : 'password'"
2713              readonly
2714            ></ion-input>
2715            <ion-button fill="clear" (click)="toggleSecretVisibility()">
2716              @if (isSecretVisible) {
2717                <ng-icon name="lucideEyeOff" size="1.25em"></ng-icon>
2718              } @else {
2719                <ng-icon name="lucideEye" size="1.25em"></ng-icon>
2720              }
2721            </ion-button>
2722            <ion-button fill="clear" (click)="copySecret()">
2723              <ng-icon name="lucideCopy" size="1.25em"></ng-icon>
2724            </ion-button>
2725          </div>
2726        </div>
2727
2728        <p class="signature-hint">
2729          Use this secret to verify webhook signatures.<br>
2730          Header: <code>X-Webhook-Signature: sha256=&#123;hash&#125;</code>
2731        </p>
2732      </div>
2733
2734      <div class="form-actions">
2735        <ion-button expand="block" (click)="closeSecretModal()">
2736          Done
2737        </ion-button>
2738      </div>
2739    </div>
2740  }
2741</ion-content>
2742`, styles: ["/* src/app/pages/webhook-sandbox/webhook-sandbox.page.scss */\n.mock-toggle {\n  display: flex;\n  align-items: center;\n  gap: 6px;\n  padding-right: 8px;\n}\n.mock-toggle ng-icon {\n  color: var(--ion-color-medium);\n  transition: color 0.2s ease;\n}\n.mock-toggle ng-icon.active {\n  color: var(--ion-color-warning);\n}\n.mock-toggle ion-toggle {\n  --track-background: var(--ion-color-medium);\n  --track-background-checked: var(--ion-color-warning);\n  --handle-background-checked: var(--ion-color-warning-contrast);\n  padding: 0;\n}\n.tab-content {\n  padding: 16px;\n  padding-bottom: 80px;\n}\n.loading-container {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  min-height: 200px;\n}\n.empty-state {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  min-height: 300px;\n  color: var(--ion-color-medium);\n  text-align: center;\n}\n.empty-state ng-icon {\n  opacity: 0.5;\n  margin-bottom: 16px;\n}\n.empty-state p {\n  font-size: 1.1em;\n}\n.subscription-card {\n  margin-bottom: 12px;\n}\n.subscription-card.circuit-open {\n  border-left: 4px solid var(--ion-color-danger);\n}\n.subscription-card ion-card-header {\n  padding-bottom: 8px;\n}\n.subscription-card .card-header-row {\n  display: flex;\n  justify-content: space-between;\n  align-items: flex-start;\n  gap: 8px;\n}\n.subscription-card .url-container {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  flex: 1;\n  min-width: 0;\n}\n.subscription-card .url-container .target-url {\n  font-size: 0.85em;\n  font-weight: 500;\n  color: var(--ion-color-primary);\n  word-break: break-all;\n}\n.subscription-card .url-container .external-link {\n  color: var(--ion-color-medium);\n  flex-shrink: 0;\n}\n.subscription-card .action-buttons {\n  display: flex;\n  gap: 0;\n  flex-shrink: 0;\n}\n.subscription-card .action-buttons ion-button {\n  --padding-start: 8px;\n  --padding-end: 8px;\n}\n.subscription-card .description {\n  font-size: 0.95em;\n  font-weight: normal;\n  margin-top: 4px;\n}\n.subscription-card .types-row {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: 4px;\n  margin-bottom: 12px;\n}\n.subscription-card .types-row .separator {\n  color: var(--ion-color-medium);\n  margin: 0 4px;\n}\n.subscription-card .types-row .type-chips {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 4px;\n}\n.subscription-card .types-row ion-chip {\n  height: 24px;\n  font-size: 0.75em;\n  margin: 0;\n}\n.subscription-card .status-row {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: 12px;\n}\n.subscription-card .status-row ion-badge {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n.subscription-card .status-row .stat {\n  font-size: 0.85em;\n  color: var(--ion-color-medium);\n}\n.subscription-card .status-row .stat.failed {\n  color: var(--ion-color-danger);\n}\n.subscription-card .expanded-content {\n  margin-top: 16px;\n  padding-top: 16px;\n  border-top: 1px solid var(--ion-color-light);\n}\n.subscription-card .expanded-content .meta {\n  font-size: 0.85em;\n  color: var(--ion-color-medium);\n  margin: 4px 0;\n}\n.subscription-card .expanded-content .expanded-actions {\n  display: flex;\n  gap: 8px;\n  margin-top: 12px;\n}\n.fab-container {\n  position: fixed;\n  bottom: 16px;\n  left: 16px;\n  right: 16px;\n  z-index: 100;\n}\n.filter-row {\n  margin-bottom: 16px;\n}\n.filter-row ion-select {\n  max-width: 300px;\n}\n.delivery-item {\n  width: 100%;\n  padding: 8px 0;\n}\n.delivery-item .delivery-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: 4px;\n}\n.delivery-item .delivery-header .event-info {\n  font-weight: 500;\n  font-size: 0.95em;\n}\n.delivery-item .delivery-header ion-badge {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n.delivery-item .delivery-details {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 8px;\n  font-size: 0.85em;\n  color: var(--ion-color-medium);\n}\n.delivery-item .delivery-details .target {\n  max-width: 200px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n.delivery-item .delivery-details .response-time {\n  color: var(--ion-color-success);\n}\n.delivery-item .error-message {\n  margin-top: 8px;\n  padding: 8px;\n  background: var(--ion-color-danger-tint);\n  border-radius: 4px;\n  font-size: 0.85em;
2742\n  color: var(--ion-color-danger-shade);\n}\n.delivery-item .retry-info {\n  margin-top: 4px;\n  font-size: 0.8em;\n  color: var(--ion-color-warning-shade);\n}\n.load-more {\n  display: flex;\n  justify-content: center;\n  padding: 16px;\n}\n.stats-tab ion-grid {\n  padding: 0;\n}\n.stats-tab .stat-card {\n  height: 100%;\n}\n.stats-tab .stat-card.warning {\n  border-left: 4px solid var(--ion-color-warning);\n}\n.stats-tab .stat-card ion-card-header {\n  padding-bottom: 4px;\n}\n.stats-tab .stat-card ion-card-title {\n  font-size: 0.85em;\n  color: var(--ion-color-medium);\n  text-transform: uppercase;\n}\n.stats-tab .stat-card ion-card-content {\n  padding-top: 8px;\n}\n.stats-tab .stat-card .stat-value {\n  font-size: 2em;\n  font-weight: bold;\n  color: var(--ion-color-dark);\n}\n.stats-tab .stat-card .stat-value.large {\n  font-size: 2.5em;\n}\n.stats-tab .stat-card .stat-label {\n  font-size: 0.9em;\n  color: var(--ion-color-medium);\n  margin-top: 4px;\n}\n.stats-tab .stat-card .stat-breakdown {\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n  margin-top: 8px;\n  font-size: 0.85em;\n}\n.stats-tab .stat-card .stat-breakdown.horizontal {\n  flex-direction: row;\n  flex-wrap: wrap;\n  gap: 12px;\n}\n.stats-tab .stat-card .stat-breakdown .active,\n.stats-tab .stat-card .stat-breakdown .success {\n  color: var(--ion-color-success);\n}\n.stats-tab .stat-card .stat-breakdown .inactive {\n  color: var(--ion-color-medium);\n}\n.stats-tab .stat-card .stat-breakdown .failed {\n  color: var(--ion-color-danger);\n}\n.stats-tab .stat-card .stat-breakdown .retrying {\n  color: var(--ion-color-warning);\n}\n.stats-tab .stat-card .stat-breakdown .pending {\n  color: var(--ion-color-medium);\n}\n.stats-tab .stat-card .stat-breakdown span {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n.stats-tab .stat-card ion-progress-bar {\n  margin: 12px 0 8px;\n  height: 8px;\n  border-radius: 4px;\n}\n.stats-tab .stat-card .progress-label {\n  font-size: 0.9em;\n  color: var(--ion-color-success);\n  font-weight: 500;\n}\n.stats-tab .stat-card ion-note {\n  display: block;\n  margin-top: 8px;\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background: rgba(0, 0, 0, 0.5);\n  z-index: 1000;\n}\n.form-modal {\n  position: fixed;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 90%;\n  max-width: 500px;\n  max-height: 90vh;\n  background: var(--ion-item-background, #ffffff);\n  border-radius: 12px;\n  z-index: 1001;\n  overflow-y: auto;\n  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n  animation: modalEnter 0.2s ease-out;\n}\n@media (prefers-color-scheme: dark) {\n  .form-modal {\n    background: var(--ion-item-background, #1e1e1e);\n    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);\n  }\n}\n.form-modal .modal-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 16px 20px;\n  border-bottom: 1px solid var(--ion-color-light);\n}\n.form-modal .modal-header.success {\n  background: var(--ion-color-success);\n  color: white;\n  border-bottom: none;\n}\n.form-modal .modal-header.success h2 {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n}\n.form-modal .modal-header h2 {\n  margin: 0;\n  font-size: 1.2em;\n}\n.form-modal .modal-header ion-button {\n  --padding-start: 8px;\n  --padding-end: 8px;\n}\n.form-modal form,\n.form-modal .secret-content {\n  padding: 20px;\n}\n.form-modal .form-field {\n  margin-bottom: 20px;\n}\n.form-modal .form-field ion-label {\n  display: block;\n  font-size: 0.9em;\n  font-weight: 500;\n  margin-bottom: 8px;\n  color: var(--ion-color-dark);\n}\n.form-modal .form-field ion-input,\n.form-modal .form-field ion-textarea {\n  --background: var(--ion-color-light);\n  --border-radius: 8px;\n  --padding-start: 12px;\n  --padding-end: 12px;\n}\n.form-modal .form-field .error-text {\n  display: block;\n  color: var(--ion-color-danger);\n  font-size: 0.8em;\n  margin-top: 4px;\n}\n.form-modal .form-field .hint-text {\n  display: block;\n  color: var(--ion-color-medium);\n  font-size: 0.8em;\n  margin-top: 4px;\n}\n.form-modal .chip-selector {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 8px;\n}\n.form-modal .chip-selector ion-chip {\n  cursor: pointer;\n  margin: 0;\n}\n.form-modal .form-actions {\n  display: flex;\n  justify-content: flex-end;\n  gap: 12px;\n  padding-top: 12px;\n  border-top: 1px solid var(--ion-color-light);\n  margin-top: 20px;\n}\n.secret-modal .warning-box {\n  display: flex;\n  gap: 12px;\n  padding: 16px;\n  background: var(--ion-color-warning-tint);\n  border-radius: 8px;\n  margin-bottom: 20px;\n}\n.secret-modal .warning-box ng-icon {\n  color: var(--ion-color-warning-shade);\n  flex-shrink: 0;\n}\n.secret-modal .warning-box p {\n  margin: 0;\n  font-size: 0.9em;\n  color: var(--ion-color-warning-shade);\n}\n.secret-modal .secret-input-container {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  background: var(--ion-color-light);\n  border-radius: 8px;\n  padding-right: 4px;\n}\n.secret-modal .secret-input-container ion-input {\n  flex: 1;\n  --background: transparent;\n  font-family: monospace;\n  font-size: 0.85em;\n}\n.secret-modal .secret-input-container ion-button {\n  --padding-start: 8px;\n  --padding-end: 8px;\n}\n.secret-modal .signature-hint {\n  margin-top: 16px;\n  font-size: 0.85em;\n  color: var(--ion-color-medium);\n}\n.secret-modal .signature-hint code {\n  display: inline-block;\n  background: var(--ion-color-light);\n  padding: 2px 6px;\n  border-radius: 4px;\n  font-size: 0.9em;\n}\n.secret-modal .form-actions {\n  border-top: none;\n  margin-top: 0;\n  padding-top: 0;\n}\n"] }]
2743  }], () => [{ type: FormBuilder }, { type: WebhookService }, { type: ToastService }, { type: AlertController }, { type: TranslateService }], null);
2744})();
2745(() => {
2746  (typeof ngDevMode === "undefined" || ngDevMode) && \u0275setClassDebugInfo(WebhookSandboxPage, { className: "WebhookSandboxPage", filePath: "src/app/pages/webhook-sandbox/webhook-sandbox.page.ts", lineNumber: 58 });
2747})();
2748export {
2749  WebhookSandboxPage
2750};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.