angular-debug-recorder 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,166 @@
1
+ import { Component, ViewChild, inject, signal, } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { RrwebRecorderService } from '../services/rrweb-recorder.service';
4
+ import * as i0 from "@angular/core";
5
+ export class SessionReplayComponent {
6
+ constructor() {
7
+ this.rrweb = inject(RrwebRecorderService);
8
+ this.overlayOpen = signal(false);
9
+ this.isPlaying = signal(false);
10
+ }
11
+ async openOverlay() {
12
+ this.overlayOpen.set(true);
13
+ this.isPlaying.set(false);
14
+ // Wait for the DOM to render the overlay
15
+ await new Promise(r => setTimeout(r, 50));
16
+ await this.startPlay();
17
+ }
18
+ closeOverlay() {
19
+ this.rrweb.destroyReplayer();
20
+ this.overlayOpen.set(false);
21
+ this.isPlaying.set(false);
22
+ }
23
+ async pauseResume() {
24
+ if (this.isPlaying()) {
25
+ this.rrweb.pauseReplay();
26
+ this.isPlaying.set(false);
27
+ }
28
+ else {
29
+ this.rrweb.resumeReplay();
30
+ this.isPlaying.set(true);
31
+ }
32
+ }
33
+ async restart() {
34
+ this.rrweb.destroyReplayer();
35
+ await new Promise(r => setTimeout(r, 50));
36
+ await this.startPlay();
37
+ }
38
+ exportSession() {
39
+ this.rrweb.downloadEvents();
40
+ }
41
+ async startPlay() {
42
+ if (!this.replayContainer)
43
+ return;
44
+ const container = this.replayContainer.nativeElement;
45
+ await this.rrweb.startReplay(container);
46
+ // Scale iframe to fill the stage container
47
+ this.scaleReplayer(container);
48
+ this.isPlaying.set(true);
49
+ }
50
+ scaleReplayer(container) {
51
+ // rrweb injects .replayer-wrapper with an iframe sized to the recorded viewport
52
+ setTimeout(() => {
53
+ const wrapper = container.querySelector('.replayer-wrapper');
54
+ if (!wrapper)
55
+ return;
56
+ const iframe = wrapper.querySelector('iframe');
57
+ const wrapW = iframe?.offsetWidth || wrapper.offsetWidth || 1280;
58
+ const wrapH = iframe?.offsetHeight || wrapper.offsetHeight || 720;
59
+ const stageW = container.offsetWidth;
60
+ const stageH = container.offsetHeight;
61
+ if (!stageW || !stageH || !wrapW || !wrapH)
62
+ return;
63
+ const scale = Math.min(stageW / wrapW, stageH / wrapH);
64
+ const offsetX = (stageW - wrapW * scale) / 2;
65
+ const offsetY = (stageH - wrapH * scale) / 2;
66
+ wrapper.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
67
+ }, 300);
68
+ }
69
+ ngOnDestroy() {
70
+ this.rrweb.destroyReplayer();
71
+ }
72
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SessionReplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
73
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: SessionReplayComponent, isStandalone: true, selector: "app-session-replay", viewQueries: [{ propertyName: "replayContainer", first: true, predicate: ["replayContainer"], descendants: true }], ngImport: i0, template: `
74
+ <div class="replay-panel" data-debug-panel>
75
+ @if (!rrweb.hasEvents()) {
76
+ <div class="replay-empty">
77
+ <div class="replay-icon">📽️</div>
78
+ <p>Kein Replay verfügbar.</p>
79
+ <p class="hint">Starte eine Aufnahme — rrweb zeichnet den DOM parallel mit.</p>
80
+ </div>
81
+ } @else {
82
+ <div class="replay-info">
83
+ <span class="event-count">{{ rrweb.events().length }} Events aufgezeichnet</span>
84
+ </div>
85
+ <div class="replay-actions">
86
+ <button class="replay-btn primary" (click)="openOverlay()">
87
+ ▶ Replay abspielen
88
+ </button>
89
+ <button class="replay-btn" (click)="exportSession()">
90
+ 💾 JSON exportieren
91
+ </button>
92
+ </div>
93
+ <p class="replay-hint">
94
+ Der Replay öffnet sich als Vollbild-Overlay über der aktuellen Seite.
95
+ </p>
96
+ }
97
+ </div>
98
+
99
+ <!-- Fullscreen Replay Overlay -->
100
+ @if (overlayOpen()) {
101
+ <div class="replay-overlay" data-debug-panel>
102
+ <div class="overlay-header" data-debug-panel>
103
+ <span class="overlay-title">📽️ Session Replay</span>
104
+ <div class="overlay-controls" data-debug-panel>
105
+ <button class="ovl-btn" (click)="pauseResume()">
106
+ {{ isPlaying() ? '⏸ Pause' : '▶ Play' }}
107
+ </button>
108
+ <button class="ovl-btn" (click)="restart()">⟳ Neustart</button>
109
+ <button class="ovl-btn close-ovl" (click)="closeOverlay()">✕ Schließen</button>
110
+ </div>
111
+ </div>
112
+ <div #replayContainer class="overlay-stage" data-debug-panel></div>
113
+ </div>
114
+ }
115
+ `, isInline: true, styles: [".replay-panel{padding:20px 16px;display:flex;flex-direction:column;gap:14px}.replay-empty{text-align:center;padding:20px 0;color:#64748b}.replay-icon{font-size:36px;margin-bottom:8px}.replay-empty p{margin:4px 0;font-size:13px}.hint{font-size:11px;color:#475569}.replay-info{background:#1e293b;border-radius:6px;padding:8px 12px}.event-count{font-size:12px;color:#6ee7b7;font-weight:600}.replay-actions{display:flex;gap:8px}.replay-btn{background:#334155;border:none;color:#cbd5e1;padding:8px 14px;border-radius:6px;font-size:12px;font-weight:600;cursor:pointer;transition:background .15s}.replay-btn:hover{background:#475569}.replay-btn.primary{background:#1d4ed8;color:#fff}.replay-btn.primary:hover{background:#2563eb}.replay-hint{font-size:11px;color:#475569;margin:0}.replay-overlay{position:fixed;inset:0;z-index:99997;background:#000;display:flex;flex-direction:column}.overlay-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:#0f172a;border-bottom:1px solid #1e293b;flex-shrink:0}.overlay-title{font-size:14px;font-weight:600;color:#f1f5f9}.overlay-controls{display:flex;gap:8px}.ovl-btn{background:#1e293b;border:1px solid #334155;color:#cbd5e1;padding:5px 12px;border-radius:5px;font-size:12px;font-weight:600;cursor:pointer;transition:background .15s}.ovl-btn:hover{background:#334155}.close-ovl{color:#fca5a5}.close-ovl:hover{background:#dc262633}.overlay-stage{flex:1;overflow:hidden;position:relative;background:#f8fafc}:host ::ng-deep .replayer-wrapper{position:absolute!important;top:0!important;left:0!important;transform-origin:top left!important}:host ::ng-deep .replayer-wrapper iframe{pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
116
+ }
117
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SessionReplayComponent, decorators: [{
118
+ type: Component,
119
+ args: [{ selector: 'app-session-replay', standalone: true, imports: [CommonModule], template: `
120
+ <div class="replay-panel" data-debug-panel>
121
+ @if (!rrweb.hasEvents()) {
122
+ <div class="replay-empty">
123
+ <div class="replay-icon">📽️</div>
124
+ <p>Kein Replay verfügbar.</p>
125
+ <p class="hint">Starte eine Aufnahme — rrweb zeichnet den DOM parallel mit.</p>
126
+ </div>
127
+ } @else {
128
+ <div class="replay-info">
129
+ <span class="event-count">{{ rrweb.events().length }} Events aufgezeichnet</span>
130
+ </div>
131
+ <div class="replay-actions">
132
+ <button class="replay-btn primary" (click)="openOverlay()">
133
+ ▶ Replay abspielen
134
+ </button>
135
+ <button class="replay-btn" (click)="exportSession()">
136
+ 💾 JSON exportieren
137
+ </button>
138
+ </div>
139
+ <p class="replay-hint">
140
+ Der Replay öffnet sich als Vollbild-Overlay über der aktuellen Seite.
141
+ </p>
142
+ }
143
+ </div>
144
+
145
+ <!-- Fullscreen Replay Overlay -->
146
+ @if (overlayOpen()) {
147
+ <div class="replay-overlay" data-debug-panel>
148
+ <div class="overlay-header" data-debug-panel>
149
+ <span class="overlay-title">📽️ Session Replay</span>
150
+ <div class="overlay-controls" data-debug-panel>
151
+ <button class="ovl-btn" (click)="pauseResume()">
152
+ {{ isPlaying() ? '⏸ Pause' : '▶ Play' }}
153
+ </button>
154
+ <button class="ovl-btn" (click)="restart()">⟳ Neustart</button>
155
+ <button class="ovl-btn close-ovl" (click)="closeOverlay()">✕ Schließen</button>
156
+ </div>
157
+ </div>
158
+ <div #replayContainer class="overlay-stage" data-debug-panel></div>
159
+ </div>
160
+ }
161
+ `, styles: [".replay-panel{padding:20px 16px;display:flex;flex-direction:column;gap:14px}.replay-empty{text-align:center;padding:20px 0;color:#64748b}.replay-icon{font-size:36px;margin-bottom:8px}.replay-empty p{margin:4px 0;font-size:13px}.hint{font-size:11px;color:#475569}.replay-info{background:#1e293b;border-radius:6px;padding:8px 12px}.event-count{font-size:12px;color:#6ee7b7;font-weight:600}.replay-actions{display:flex;gap:8px}.replay-btn{background:#334155;border:none;color:#cbd5e1;padding:8px 14px;border-radius:6px;font-size:12px;font-weight:600;cursor:pointer;transition:background .15s}.replay-btn:hover{background:#475569}.replay-btn.primary{background:#1d4ed8;color:#fff}.replay-btn.primary:hover{background:#2563eb}.replay-hint{font-size:11px;color:#475569;margin:0}.replay-overlay{position:fixed;inset:0;z-index:99997;background:#000;display:flex;flex-direction:column}.overlay-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:#0f172a;border-bottom:1px solid #1e293b;flex-shrink:0}.overlay-title{font-size:14px;font-weight:600;color:#f1f5f9}.overlay-controls{display:flex;gap:8px}.ovl-btn{background:#1e293b;border:1px solid #334155;color:#cbd5e1;padding:5px 12px;border-radius:5px;font-size:12px;font-weight:600;cursor:pointer;transition:background .15s}.ovl-btn:hover{background:#334155}.close-ovl{color:#fca5a5}.close-ovl:hover{background:#dc262633}.overlay-stage{flex:1;overflow:hidden;position:relative;background:#f8fafc}:host ::ng-deep .replayer-wrapper{position:absolute!important;top:0!important;left:0!important;transform-origin:top left!important}:host ::ng-deep .replayer-wrapper iframe{pointer-events:none}\n"] }]
162
+ }], propDecorators: { replayContainer: [{
163
+ type: ViewChild,
164
+ args: ['replayContainer']
165
+ }] } });
166
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi1yZXBsYXkuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVidWctcmVjb3JkZXIvc3JjL2xpYi9zZXNzaW9uLXJlcGxheS9zZXNzaW9uLXJlcGxheS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFBYyxTQUFTLEVBQWEsTUFBTSxFQUFFLE1BQU0sR0FDNUQsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDOztBQWlKMUUsTUFBTSxPQUFPLHNCQUFzQjtJQS9JbkM7UUFrSkUsVUFBSyxHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3JDLGdCQUFXLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVCLGNBQVMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7S0F3RTNCO0lBdEVDLEtBQUssQ0FBQyxXQUFXO1FBQ2YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIseUNBQXlDO1FBQ3pDLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUMsTUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDekIsQ0FBQztJQUVELFlBQVk7UUFDVixJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVztRQUNmLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0IsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsT0FBTztRQUNYLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDN0IsTUFBTSxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxQyxNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVPLEtBQUssQ0FBQyxTQUFTO1FBQ3JCLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZTtZQUFFLE9BQU87UUFDbEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUM7UUFFckQsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUV4QywyQ0FBMkM7UUFDM0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRU8sYUFBYSxDQUFDLFNBQXNCO1FBQzFDLGdGQUFnRjtRQUNoRixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBZ0IsQ0FBQztZQUM1RSxJQUFJLENBQUMsT0FBTztnQkFBRSxPQUFPO1lBRXJCLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFzQixDQUFDO1lBQ3BFLE1BQU0sS0FBSyxHQUFHLE1BQU0sRUFBRSxXQUFXLElBQUssT0FBTyxDQUFDLFdBQVcsSUFBSyxJQUFJLENBQUM7WUFDbkUsTUFBTSxLQUFLLEdBQUcsTUFBTSxFQUFFLFlBQVksSUFBSSxPQUFPLENBQUMsWUFBWSxJQUFJLEdBQUcsQ0FBQztZQUNsRSxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsV0FBVyxDQUFDO1lBQ3JDLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxZQUFZLENBQUM7WUFFdEMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUs7Z0JBQUUsT0FBTztZQUVuRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxLQUFLLEVBQUUsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sT0FBTyxHQUFHLENBQUMsTUFBTSxHQUFHLEtBQUssR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDN0MsTUFBTSxPQUFPLEdBQUcsQ0FBQyxNQUFNLEdBQUcsS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUU3QyxPQUFPLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxhQUFhLE9BQU8sT0FBTyxPQUFPLGFBQWEsS0FBSyxHQUFHLENBQUM7UUFDcEYsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQy9CLENBQUM7K0dBNUVVLHNCQUFzQjttR0FBdEIsc0JBQXNCLGtNQTNJdkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBDVCxzdERBM0NTLFlBQVk7OzRGQTRJWCxzQkFBc0I7a0JBL0lsQyxTQUFTOytCQUNFLG9CQUFvQixjQUNsQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLENBQUMsWUFDYjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMENUOzhCQWtHNkIsZUFBZTtzQkFBNUMsU0FBUzt1QkFBQyxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZCwgT25EZXN0cm95LCBpbmplY3QsIHNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgUnJ3ZWJSZWNvcmRlclNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9ycndlYi1yZWNvcmRlci5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXNlc3Npb24tcmVwbGF5JyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cInJlcGxheS1wYW5lbFwiIGRhdGEtZGVidWctcGFuZWw+XG4gICAgICBAaWYgKCFycndlYi5oYXNFdmVudHMoKSkge1xuICAgICAgICA8ZGl2IGNsYXNzPVwicmVwbGF5LWVtcHR5XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInJlcGxheS1pY29uXCI+8J+Tve+4jzwvZGl2PlxuICAgICAgICAgIDxwPktlaW4gUmVwbGF5IHZlcmbDvGdiYXIuPC9wPlxuICAgICAgICAgIDxwIGNsYXNzPVwiaGludFwiPlN0YXJ0ZSBlaW5lIEF1Zm5haG1lIOKAlCBycndlYiB6ZWljaG5ldCBkZW4gRE9NIHBhcmFsbGVsIG1pdC48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyZXBsYXktaW5mb1wiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZXZlbnQtY291bnRcIj57eyBycndlYi5ldmVudHMoKS5sZW5ndGggfX0gRXZlbnRzIGF1ZmdlemVpY2huZXQ8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwicmVwbGF5LWFjdGlvbnNcIj5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwicmVwbGF5LWJ0biBwcmltYXJ5XCIgKGNsaWNrKT1cIm9wZW5PdmVybGF5KClcIj5cbiAgICAgICAgICAgIOKWtiBSZXBsYXkgYWJzcGllbGVuXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInJlcGxheS1idG5cIiAoY2xpY2spPVwiZXhwb3J0U2Vzc2lvbigpXCI+XG4gICAgICAgICAgICDwn5K+IEpTT04gZXhwb3J0aWVyZW5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxwIGNsYXNzPVwicmVwbGF5LWhpbnRcIj5cbiAgICAgICAgICBEZXIgUmVwbGF5IMO2ZmZuZXQgc2ljaCBhbHMgVm9sbGJpbGQtT3ZlcmxheSDDvGJlciBkZXIgYWt0dWVsbGVuIFNlaXRlLlxuICAgICAgICA8L3A+XG4gICAgICB9XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIEZ1bGxzY3JlZW4gUmVwbGF5IE92ZXJsYXkgLS0+XG4gICAgQGlmIChvdmVybGF5T3BlbigpKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwicmVwbGF5LW92ZXJsYXlcIiBkYXRhLWRlYnVnLXBhbmVsPlxuICAgICAgICA8ZGl2IGNsYXNzPVwib3ZlcmxheS1oZWFkZXJcIiBkYXRhLWRlYnVnLXBhbmVsPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwib3ZlcmxheS10aXRsZVwiPvCfk73vuI8gU2Vzc2lvbiBSZXBsYXk8L3NwYW4+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm92ZXJsYXktY29udHJvbHNcIiBkYXRhLWRlYnVnLXBhbmVsPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cIm92bC1idG5cIiAoY2xpY2spPVwicGF1c2VSZXN1bWUoKVwiPlxuICAgICAgICAgICAgICB7eyBpc1BsYXlpbmcoKSA/ICfij7ggUGF1c2UnIDogJ+KWtiBQbGF5JyB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwib3ZsLWJ0blwiIChjbGljayk9XCJyZXN0YXJ0KClcIj7in7MgTmV1c3RhcnQ8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJvdmwtYnRuIGNsb3NlLW92bFwiIChjbGljayk9XCJjbG9zZU92ZXJsYXkoKVwiPuKclSBTY2hsaWXDn2VuPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICNyZXBsYXlDb250YWluZXIgY2xhc3M9XCJvdmVybGF5LXN0YWdlXCIgZGF0YS1kZWJ1Zy1wYW5lbD48L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgYCxcbiAgc3R5bGVzOiBbYFxuICAgIC5yZXBsYXktcGFuZWwge1xuICAgICAgcGFkZGluZzogMjBweCAxNnB4O1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICBnYXA6IDE0cHg7XG4gICAgfVxuXG4gICAgLnJlcGxheS1lbXB0eSB7XG4gICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICBwYWRkaW5nOiAyMHB4IDA7XG4gICAgICBjb2xvcjogIzY0NzQ4YjtcbiAgICB9XG4gICAgLnJlcGxheS1pY29uIHsgZm9udC1zaXplOiAzNnB4OyBtYXJnaW4tYm90dG9tOiA4cHg7IH1cbiAgICAucmVwbGF5LWVtcHR5IHAgeyBtYXJnaW46IDRweCAwOyBmb250LXNpemU6IDEzcHg7IH1cbiAgICAuaGludCB7IGZvbnQtc2l6ZTogMTFweDsgY29sb3I6ICM0NzU1Njk7IH1cblxuICAgIC5yZXBsYXktaW5mbyB7XG4gICAgICBiYWNrZ3JvdW5kOiAjMWUyOTNiO1xuICAgICAgYm9yZGVyLXJhZGl1czogNnB4O1xuICAgICAgcGFkZGluZzogOHB4IDEycHg7XG4gICAgfVxuICAgIC5ldmVudC1jb3VudCB7IGZvbnQtc2l6ZTogMTJweDsgY29sb3I6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OiA2MDA7IH1cblxuICAgIC5yZXBsYXktYWN0aW9ucyB7IGRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyB9XG4gICAgLnJlcGxheS1idG4ge1xuICAgICAgYmFja2dyb3VuZDogIzMzNDE1NTtcbiAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgIGNvbG9yOiAjY2JkNWUxO1xuICAgICAgcGFkZGluZzogOHB4IDE0cHg7XG4gICAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgICBmb250LXNpemU6IDEycHg7XG4gICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAwLjE1cztcbiAgICB9XG4gICAgLnJlcGxheS1idG46aG92ZXIgeyBiYWNrZ3JvdW5kOiAjNDc1NTY5OyB9XG4gICAgLnJlcGxheS1idG4ucHJpbWFyeSB7IGJhY2tncm91bmQ6ICMxZDRlZDg7IGNvbG9yOiAjZmZmOyB9XG4gICAgLnJlcGxheS1idG4ucHJpbWFyeTpob3ZlciB7IGJhY2tncm91bmQ6ICMyNTYzZWI7IH1cblxuICAgIC5yZXBsYXktaGludCB7IGZvbnQtc2l6ZTogMTFweDsgY29sb3I6ICM0NzU1Njk7IG1hcmdpbjogMDsgfVxuXG4gICAgLyog4pSA4pSAIEZ1bGxzY3JlZW4gT3ZlcmxheSDilIDilIAgKi9cbiAgICAucmVwbGF5LW92ZXJsYXkge1xuICAgICAgcG9zaXRpb246IGZpeGVkO1xuICAgICAgaW5zZXQ6IDA7XG4gICAgICB6LWluZGV4OiA5OTk5NztcbiAgICAgIGJhY2tncm91bmQ6ICMwMDA7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICB9XG4gICAgLm92ZXJsYXktaGVhZGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgcGFkZGluZzogMTBweCAxNnB4O1xuICAgICAgYmFja2dyb3VuZDogIzBmMTcyYTtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjMWUyOTNiO1xuICAgICAgZmxleC1zaHJpbms6IDA7XG4gICAgfVxuICAgIC5vdmVybGF5LXRpdGxlIHsgZm9udC1zaXplOiAxNHB4OyBmb250LXdlaWdodDogNjAwOyBjb2xvcjogI2YxZjVmOTsgfVxuICAgIC5vdmVybGF5LWNvbnRyb2xzIHsgZGlzcGxheTogZmxleDsgZ2FwOiA4cHg7IH1cbiAgICAub3ZsLWJ0biB7XG4gICAgICBiYWNrZ3JvdW5kOiAjMWUyOTNiO1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgIzMzNDE1NTtcbiAgICAgIGNvbG9yOiAjY2JkNWUxO1xuICAgICAgcGFkZGluZzogNXB4IDEycHg7XG4gICAgICBib3JkZXItcmFkaXVzOiA1cHg7XG4gICAgICBmb250LXNpemU6IDEycHg7XG4gICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAwLjE1cztcbiAgICB9XG4gICAgLm92bC1idG46aG92ZXIgeyBiYWNrZ3JvdW5kOiAjMzM0MTU1OyB9XG4gICAgLmNsb3NlLW92bCB7IGNvbG9yOiAjZmNhNWE1OyB9XG4gICAgLmNsb3NlLW92bDpob3ZlciB7IGJhY2tncm91bmQ6IHJnYmEoMjIwLDM4LDM4LDAuMik7IH1cblxuICAgIC5vdmVybGF5LXN0YWdlIHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgYmFja2dyb3VuZDogI2Y4ZmFmYztcbiAgICB9XG5cbiAgICAvKiBTY2FsZSB0aGUgcnJ3ZWIgaWZyYW1lIHRvIGZpbGwgYXZhaWxhYmxlIHNwYWNlICovXG4gICAgOmhvc3QgOjpuZy1kZWVwIC5yZXBsYXllci13cmFwcGVyIHtcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZSAhaW1wb3J0YW50O1xuICAgICAgdG9wOiAwICFpbXBvcnRhbnQ7XG4gICAgICBsZWZ0OiAwICFpbXBvcnRhbnQ7XG4gICAgICB0cmFuc2Zvcm0tb3JpZ2luOiB0b3AgbGVmdCAhaW1wb3J0YW50O1xuICAgIH1cbiAgICA6aG9zdCA6Om5nLWRlZXAgLnJlcGxheWVyLXdyYXBwZXIgaWZyYW1lIHtcbiAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIH1cbiAgYF0sXG59KVxuZXhwb3J0IGNsYXNzIFNlc3Npb25SZXBsYXlDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBAVmlld0NoaWxkKCdyZXBsYXlDb250YWluZXInKSByZXBsYXlDb250YWluZXI/OiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcblxuICBycndlYiA9IGluamVjdChScndlYlJlY29yZGVyU2VydmljZSk7XG4gIG92ZXJsYXlPcGVuID0gc2lnbmFsKGZhbHNlKTtcbiAgaXNQbGF5aW5nID0gc2lnbmFsKGZhbHNlKTtcblxuICBhc3luYyBvcGVuT3ZlcmxheSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLm92ZXJsYXlPcGVuLnNldCh0cnVlKTtcbiAgICB0aGlzLmlzUGxheWluZy5zZXQoZmFsc2UpO1xuICAgIC8vIFdhaXQgZm9yIHRoZSBET00gdG8gcmVuZGVyIHRoZSBvdmVybGF5XG4gICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIDUwKSk7XG4gICAgYXdhaXQgdGhpcy5zdGFydFBsYXkoKTtcbiAgfVxuXG4gIGNsb3NlT3ZlcmxheSgpOiB2b2lkIHtcbiAgICB0aGlzLnJyd2ViLmRlc3Ryb3lSZXBsYXllcigpO1xuICAgIHRoaXMub3ZlcmxheU9wZW4uc2V0KGZhbHNlKTtcbiAgICB0aGlzLmlzUGxheWluZy5zZXQoZmFsc2UpO1xuICB9XG5cbiAgYXN5bmMgcGF1c2VSZXN1bWUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNQbGF5aW5nKCkpIHtcbiAgICAgIHRoaXMucnJ3ZWIucGF1c2VSZXBsYXkoKTtcbiAgICAgIHRoaXMuaXNQbGF5aW5nLnNldChmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucnJ3ZWIucmVzdW1lUmVwbGF5KCk7XG4gICAgICB0aGlzLmlzUGxheWluZy5zZXQodHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgcmVzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnJyd2ViLmRlc3Ryb3lSZXBsYXllcigpO1xuICAgIGF3YWl0IG5ldyBQcm9taXNlKHIgPT4gc2V0VGltZW91dChyLCA1MCkpO1xuICAgIGF3YWl0IHRoaXMuc3RhcnRQbGF5KCk7XG4gIH1cblxuICBleHBvcnRTZXNzaW9uKCk6IHZvaWQge1xuICAgIHRoaXMucnJ3ZWIuZG93bmxvYWRFdmVudHMoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc3RhcnRQbGF5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5yZXBsYXlDb250YWluZXIpIHJldHVybjtcbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLnJlcGxheUNvbnRhaW5lci5uYXRpdmVFbGVtZW50O1xuXG4gICAgYXdhaXQgdGhpcy5ycndlYi5zdGFydFJlcGxheShjb250YWluZXIpO1xuXG4gICAgLy8gU2NhbGUgaWZyYW1lIHRvIGZpbGwgdGhlIHN0YWdlIGNvbnRhaW5lclxuICAgIHRoaXMuc2NhbGVSZXBsYXllcihjb250YWluZXIpO1xuICAgIHRoaXMuaXNQbGF5aW5nLnNldCh0cnVlKTtcbiAgfVxuXG4gIHByaXZhdGUgc2NhbGVSZXBsYXllcihjb250YWluZXI6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgLy8gcnJ3ZWIgaW5qZWN0cyAucmVwbGF5ZXItd3JhcHBlciB3aXRoIGFuIGlmcmFtZSBzaXplZCB0byB0aGUgcmVjb3JkZWQgdmlld3BvcnRcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNvbnN0IHdyYXBwZXIgPSBjb250YWluZXIucXVlcnlTZWxlY3RvcignLnJlcGxheWVyLXdyYXBwZXInKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGlmICghd3JhcHBlcikgcmV0dXJuO1xuXG4gICAgICBjb25zdCBpZnJhbWUgPSB3cmFwcGVyLnF1ZXJ5U2VsZWN0b3IoJ2lmcmFtZScpIGFzIEhUTUxJRnJhbWVFbGVtZW50O1xuICAgICAgY29uc3Qgd3JhcFcgPSBpZnJhbWU/Lm9mZnNldFdpZHRoICB8fCB3cmFwcGVyLm9mZnNldFdpZHRoICB8fCAxMjgwO1xuICAgICAgY29uc3Qgd3JhcEggPSBpZnJhbWU/Lm9mZnNldEhlaWdodCB8fCB3cmFwcGVyLm9mZnNldEhlaWdodCB8fCA3MjA7XG4gICAgICBjb25zdCBzdGFnZVcgPSBjb250YWluZXIub2Zmc2V0V2lkdGg7XG4gICAgICBjb25zdCBzdGFnZUggPSBjb250YWluZXIub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICBpZiAoIXN0YWdlVyB8fCAhc3RhZ2VIIHx8ICF3cmFwVyB8fCAhd3JhcEgpIHJldHVybjtcblxuICAgICAgY29uc3Qgc2NhbGUgPSBNYXRoLm1pbihzdGFnZVcgLyB3cmFwVywgc3RhZ2VIIC8gd3JhcEgpO1xuICAgICAgY29uc3Qgb2Zmc2V0WCA9IChzdGFnZVcgLSB3cmFwVyAqIHNjYWxlKSAvIDI7XG4gICAgICBjb25zdCBvZmZzZXRZID0gKHN0YWdlSCAtIHdyYXBIICogc2NhbGUpIC8gMjtcblxuICAgICAgd3JhcHBlci5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7b2Zmc2V0WH1weCwgJHtvZmZzZXRZfXB4KSBzY2FsZSgke3NjYWxlfSlgO1xuICAgIH0sIDMwMCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnJyd2ViLmRlc3Ryb3lSZXBsYXllcigpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,105 @@
1
+ import { Component, Output, EventEmitter, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { AiGeneratorService } from '../services/ai-generator.service';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "@angular/forms";
7
+ export class SettingsDialogComponent {
8
+ constructor() {
9
+ this.close = new EventEmitter();
10
+ this.ai = inject(AiGeneratorService);
11
+ this.localUrl = this.ai.webhookUrl();
12
+ }
13
+ save() {
14
+ this.ai.setWebhookUrl(this.localUrl.trim());
15
+ this.close.emit();
16
+ }
17
+ onOverlayClick(e) {
18
+ if (e.target.classList.contains('overlay')) {
19
+ this.close.emit();
20
+ }
21
+ }
22
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SettingsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
23
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SettingsDialogComponent, isStandalone: true, selector: "app-settings-dialog", outputs: { close: "close" }, ngImport: i0, template: `
24
+ <div class="overlay" data-debug-panel (click)="onOverlayClick($event)">
25
+ <div class="dialog" data-debug-panel>
26
+ <div class="dialog-header">
27
+ <h2>⚙️ Einstellungen</h2>
28
+ <button class="close-btn" (click)="close.emit()">✕</button>
29
+ </div>
30
+
31
+ <div class="dialog-body">
32
+ <div class="field-group">
33
+ <label>KI Webhook-URL</label>
34
+ <input
35
+ data-debug-panel
36
+ class="field-input"
37
+ type="url"
38
+ [(ngModel)]="localUrl"
39
+ placeholder="https://deine-ki-api.de/generate"
40
+ />
41
+ <p class="field-hint">
42
+ Die aufgezeichnete Session wird als JSON per POST an diese URL gesendet.
43
+ Die Antwort wird als Cypress-Test angezeigt.
44
+ </p>
45
+ </div>
46
+
47
+ <div class="info-box">
48
+ <p>📦 POST-Body: Die Session als JSON (<code>actions</code>, <code>startUrl</code>, ...)</p>
49
+ <p>📄 Erwartete Antwort: Cypress-Test-Code als Plain-Text</p>
50
+ <p>⌨️ Shortcuts: <kbd>Ctrl+Shift+D</kbd> Panel &nbsp; <kbd>Ctrl+Shift+R</kbd> Aufnahme</p>
51
+ </div>
52
+ </div>
53
+
54
+ <div class="dialog-footer">
55
+ <button class="btn-cancel" (click)="close.emit()">Abbrechen</button>
56
+ <button class="btn-save" (click)="save()">💾 Speichern</button>
57
+ </div>
58
+ </div>
59
+ </div>
60
+ `, isInline: true, styles: [".overlay{position:fixed;inset:0;background:#000000b3;z-index:100000;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.dialog{background:#0f172a;border:1px solid #1e3a5f;border-radius:12px;width:440px;max-width:95vw;display:flex;flex-direction:column;box-shadow:0 25px 60px #0009;overflow:hidden}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;background:#1e293b;border-bottom:1px solid #334155}.dialog-header h2{margin:0;font-size:15px;color:#f1f5f9;font-weight:600}.close-btn{background:none;border:none;color:#94a3b8;cursor:pointer;font-size:16px;padding:4px;border-radius:4px}.close-btn:hover{color:#f1f5f9;background:#334155}.dialog-body{padding:18px;display:flex;flex-direction:column;gap:16px}.field-group{display:flex;flex-direction:column;gap:6px}label{font-size:12px;font-weight:600;color:#94a3b8;text-transform:uppercase;letter-spacing:.05em}.field-input{background:#1e293b;border:1px solid #334155;color:#e2e8f0;border-radius:6px;padding:10px 12px;font-size:13px;width:100%;box-sizing:border-box}.field-input:focus{outline:none;border-color:#3b82f6}.field-hint{font-size:11px;color:#64748b;margin:0;line-height:1.5}.info-box{background:#1e293b80;border:1px solid #1e3a5f;border-radius:8px;padding:12px;display:flex;flex-direction:column;gap:6px}.info-box p{margin:0;font-size:11px;color:#64748b}.info-box code{background:#1e293b;color:#34d399;padding:1px 4px;border-radius:3px;font-family:monospace}kbd{background:#1e293b;border:1px solid #334155;color:#94a3b8;padding:1px 5px;border-radius:3px;font-size:10px}.dialog-footer{display:flex;gap:8px;justify-content:flex-end;padding:14px 18px;background:#1e293b;border-top:1px solid #334155}.btn-cancel,.btn-save{padding:8px 20px;border-radius:6px;font-size:13px;font-weight:600;cursor:pointer;border:none;transition:filter .15s}.btn-cancel{background:#334155;color:#94a3b8}.btn-cancel:hover{filter:brightness(1.2)}.btn-save{background:#2563eb;color:#fff}.btn-save:hover{filter:brightness(1.1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
61
+ }
62
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SettingsDialogComponent, decorators: [{
63
+ type: Component,
64
+ args: [{ selector: 'app-settings-dialog', standalone: true, imports: [CommonModule, FormsModule], template: `
65
+ <div class="overlay" data-debug-panel (click)="onOverlayClick($event)">
66
+ <div class="dialog" data-debug-panel>
67
+ <div class="dialog-header">
68
+ <h2>⚙️ Einstellungen</h2>
69
+ <button class="close-btn" (click)="close.emit()">✕</button>
70
+ </div>
71
+
72
+ <div class="dialog-body">
73
+ <div class="field-group">
74
+ <label>KI Webhook-URL</label>
75
+ <input
76
+ data-debug-panel
77
+ class="field-input"
78
+ type="url"
79
+ [(ngModel)]="localUrl"
80
+ placeholder="https://deine-ki-api.de/generate"
81
+ />
82
+ <p class="field-hint">
83
+ Die aufgezeichnete Session wird als JSON per POST an diese URL gesendet.
84
+ Die Antwort wird als Cypress-Test angezeigt.
85
+ </p>
86
+ </div>
87
+
88
+ <div class="info-box">
89
+ <p>📦 POST-Body: Die Session als JSON (<code>actions</code>, <code>startUrl</code>, ...)</p>
90
+ <p>📄 Erwartete Antwort: Cypress-Test-Code als Plain-Text</p>
91
+ <p>⌨️ Shortcuts: <kbd>Ctrl+Shift+D</kbd> Panel &nbsp; <kbd>Ctrl+Shift+R</kbd> Aufnahme</p>
92
+ </div>
93
+ </div>
94
+
95
+ <div class="dialog-footer">
96
+ <button class="btn-cancel" (click)="close.emit()">Abbrechen</button>
97
+ <button class="btn-save" (click)="save()">💾 Speichern</button>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ `, styles: [".overlay{position:fixed;inset:0;background:#000000b3;z-index:100000;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.dialog{background:#0f172a;border:1px solid #1e3a5f;border-radius:12px;width:440px;max-width:95vw;display:flex;flex-direction:column;box-shadow:0 25px 60px #0009;overflow:hidden}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;background:#1e293b;border-bottom:1px solid #334155}.dialog-header h2{margin:0;font-size:15px;color:#f1f5f9;font-weight:600}.close-btn{background:none;border:none;color:#94a3b8;cursor:pointer;font-size:16px;padding:4px;border-radius:4px}.close-btn:hover{color:#f1f5f9;background:#334155}.dialog-body{padding:18px;display:flex;flex-direction:column;gap:16px}.field-group{display:flex;flex-direction:column;gap:6px}label{font-size:12px;font-weight:600;color:#94a3b8;text-transform:uppercase;letter-spacing:.05em}.field-input{background:#1e293b;border:1px solid #334155;color:#e2e8f0;border-radius:6px;padding:10px 12px;font-size:13px;width:100%;box-sizing:border-box}.field-input:focus{outline:none;border-color:#3b82f6}.field-hint{font-size:11px;color:#64748b;margin:0;line-height:1.5}.info-box{background:#1e293b80;border:1px solid #1e3a5f;border-radius:8px;padding:12px;display:flex;flex-direction:column;gap:6px}.info-box p{margin:0;font-size:11px;color:#64748b}.info-box code{background:#1e293b;color:#34d399;padding:1px 4px;border-radius:3px;font-family:monospace}kbd{background:#1e293b;border:1px solid #334155;color:#94a3b8;padding:1px 5px;border-radius:3px;font-size:10px}.dialog-footer{display:flex;gap:8px;justify-content:flex-end;padding:14px 18px;background:#1e293b;border-top:1px solid #334155}.btn-cancel,.btn-save{padding:8px 20px;border-radius:6px;font-size:13px;font-weight:600;cursor:pointer;border:none;transition:filter .15s}.btn-cancel{background:#334155;color:#94a3b8}.btn-cancel:hover{filter:brightness(1.2)}.btn-save{background:#2563eb;color:#fff}.btn-save:hover{filter:brightness(1.1)}\n"] }]
102
+ }], propDecorators: { close: [{
103
+ type: Output
104
+ }] } });
105
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MtZGlhbG9nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2RlYnVnLXJlY29yZGVyL3NyYy9saWIvc2V0dGluZ3MtZGlhbG9nL3NldHRpbmdzLWRpYWxvZy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDOzs7QUF5R3RFLE1BQU0sT0FBTyx1QkFBdUI7SUF2R3BDO1FBd0dZLFVBQUssR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ25DLE9BQUUsR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUN4QyxhQUFRLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsQ0FBQztLQVlqQztJQVZDLElBQUk7UUFDRixJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRUQsY0FBYyxDQUFDLENBQWE7UUFDMUIsSUFBSyxDQUFDLENBQUMsTUFBc0IsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDNUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNwQixDQUFDO0lBQ0gsQ0FBQzsrR0FkVSx1QkFBdUI7bUdBQXZCLHVCQUF1Qiw0R0FuR3hCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUNULDJsRUF0Q1MsWUFBWSw4QkFBRSxXQUFXOzs0RkFvR3hCLHVCQUF1QjtrQkF2R25DLFNBQVM7K0JBQ0UscUJBQXFCLGNBQ25CLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxXQUFXLENBQUMsWUFDMUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQ1Q7OEJBK0RTLEtBQUs7c0JBQWQsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWlHZW5lcmF0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvYWktZ2VuZXJhdG9yLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtc2V0dGluZ3MtZGlhbG9nJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJvdmVybGF5XCIgZGF0YS1kZWJ1Zy1wYW5lbCAoY2xpY2spPVwib25PdmVybGF5Q2xpY2soJGV2ZW50KVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImRpYWxvZ1wiIGRhdGEtZGVidWctcGFuZWw+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkaWFsb2ctaGVhZGVyXCI+XG4gICAgICAgICAgPGgyPuKame+4jyBFaW5zdGVsbHVuZ2VuPC9oMj5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiY2xvc2UtYnRuXCIgKGNsaWNrKT1cImNsb3NlLmVtaXQoKVwiPuKclTwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWJvZHlcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtZ3JvdXBcIj5cbiAgICAgICAgICAgIDxsYWJlbD5LSSBXZWJob29rLVVSTDwvbGFiZWw+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgZGF0YS1kZWJ1Zy1wYW5lbFxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLWlucHV0XCJcbiAgICAgICAgICAgICAgdHlwZT1cInVybFwiXG4gICAgICAgICAgICAgIFsobmdNb2RlbCldPVwibG9jYWxVcmxcIlxuICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImh0dHBzOi8vZGVpbmUta2ktYXBpLmRlL2dlbmVyYXRlXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8cCBjbGFzcz1cImZpZWxkLWhpbnRcIj5cbiAgICAgICAgICAgICAgRGllIGF1ZmdlemVpY2huZXRlIFNlc3Npb24gd2lyZCBhbHMgSlNPTiBwZXIgUE9TVCBhbiBkaWVzZSBVUkwgZ2VzZW5kZXQuXG4gICAgICAgICAgICAgIERpZSBBbnR3b3J0IHdpcmQgYWxzIEN5cHJlc3MtVGVzdCBhbmdlemVpZ3QuXG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5mby1ib3hcIj5cbiAgICAgICAgICAgIDxwPvCfk6YgUE9TVC1Cb2R5OiBEaWUgU2Vzc2lvbiBhbHMgSlNPTiAoPGNvZGU+YWN0aW9uczwvY29kZT4sIDxjb2RlPnN0YXJ0VXJsPC9jb2RlPiwgLi4uKTwvcD5cbiAgICAgICAgICAgIDxwPvCfk4QgRXJ3YXJ0ZXRlIEFudHdvcnQ6IEN5cHJlc3MtVGVzdC1Db2RlIGFscyBQbGFpbi1UZXh0PC9wPlxuICAgICAgICAgICAgPHA+4oyo77iPIFNob3J0Y3V0czogPGtiZD5DdHJsK1NoaWZ0K0Q8L2tiZD4gUGFuZWwgJm5ic3A7IDxrYmQ+Q3RybCtTaGlmdCtSPC9rYmQ+IEF1Zm5haG1lPC9wPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWZvb3RlclwiPlxuICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4tY2FuY2VsXCIgKGNsaWNrKT1cImNsb3NlLmVtaXQoKVwiPkFiYnJlY2hlbjwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4tc2F2ZVwiIChjbGljayk9XCJzYXZlKClcIj7wn5K+IFNwZWljaGVybjwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgLm92ZXJsYXkge1xuICAgICAgcG9zaXRpb246IGZpeGVkOyBpbnNldDogMDsgYmFja2dyb3VuZDogcmdiYSgwLDAsMCwwLjcpO1xuICAgICAgei1pbmRleDogMTAwMDAwOyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cig0cHgpO1xuICAgIH1cbiAgICAuZGlhbG9nIHtcbiAgICAgIGJhY2tncm91bmQ6ICMwZjE3MmE7IGJvcmRlcjogMXB4IHNvbGlkICMxZTNhNWY7IGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgICB3aWR0aDogNDQwcHg7IG1heC13aWR0aDogOTV2dzsgZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGJveC1zaGFkb3c6IDAgMjVweCA2MHB4IHJnYmEoMCwwLDAsMC42KTsgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICB9XG4gICAgLmRpYWxvZy1oZWFkZXIge1xuICAgICAgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgcGFkZGluZzogMTRweCAxOHB4OyBiYWNrZ3JvdW5kOiAjMWUyOTNiOyBib3JkZXItYm90dG9tOiAxcHggc29saWQgIzMzNDE1NTtcbiAgICB9XG4gICAgLmRpYWxvZy1oZWFkZXIgaDIgeyBtYXJnaW46IDA7IGZvbnQtc2l6ZTogMTVweDsgY29sb3I6ICNmMWY1Zjk7IGZvbnQtd2VpZ2h0OiA2MDA7IH1cbiAgICAuY2xvc2UtYnRuIHtcbiAgICAgIGJhY2tncm91bmQ6IG5vbmU7IGJvcmRlcjogbm9uZTsgY29sb3I6ICM5NGEzYjg7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtc2l6ZTogMTZweDsgcGFkZGluZzogNHB4OyBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgfVxuICAgIC5jbG9zZS1idG46aG92ZXIgeyBjb2xvcjogI2YxZjVmOTsgYmFja2dyb3VuZDogIzMzNDE1NTsgfVxuICAgIC5kaWFsb2ctYm9keSB7IHBhZGRpbmc6IDE4cHg7IGRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGdhcDogMTZweDsgfVxuICAgIC5maWVsZC1ncm91cCB7IGRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGdhcDogNnB4OyB9XG4gICAgbGFiZWwge1xuICAgICAgZm9udC1zaXplOiAxMnB4OyBmb250LXdlaWdodDogNjAwOyBjb2xvcjogIzk0YTNiODtcbiAgICAgIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7IGxldHRlci1zcGFjaW5nOiAwLjA1ZW07XG4gICAgfVxuICAgIC5maWVsZC1pbnB1dCB7XG4gICAgICBiYWNrZ3JvdW5kOiAjMWUyOTNiOyBib3JkZXI6IDFweCBzb2xpZCAjMzM0MTU1OyBjb2xvcjogI2UyZThmMDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDZweDsgcGFkZGluZzogMTBweCAxMnB4OyBmb250LXNpemU6IDEzcHg7XG4gICAgICB3aWR0aDogMTAwJTsgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICB9XG4gICAgLmZpZWxkLWlucHV0OmZvY3VzIHsgb3V0bGluZTogbm9uZTsgYm9yZGVyLWNvbG9yOiAjM2I4MmY2OyB9XG4gICAgLmZpZWxkLWhpbnQgeyBmb250LXNpemU6IDExcHg7IGNvbG9yOiAjNjQ3NDhiOyBtYXJnaW46IDA7IGxpbmUtaGVpZ2h0OiAxLjU7IH1cbiAgICAuaW5mby1ib3gge1xuICAgICAgYmFja2dyb3VuZDogcmdiYSgzMCw0MSw1OSwwLjUpOyBib3JkZXI6IDFweCBzb2xpZCAjMWUzYTVmO1xuICAgICAgYm9yZGVyLXJhZGl1czogOHB4OyBwYWRkaW5nOiAxMnB4OyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDZweDtcbiAgICB9XG4gICAgLmluZm8tYm94IHAgeyBtYXJnaW46IDA7IGZvbnQtc2l6ZTogMTFweDsgY29sb3I6ICM2NDc0OGI7IH1cbiAgICAuaW5mby1ib3ggY29kZSB7XG4gICAgICBiYWNrZ3JvdW5kOiAjMWUyOTNiOyBjb2xvcjogIzM0ZDM5OTsgcGFkZGluZzogMXB4IDRweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDNweDsgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTtcbiAgICB9XG4gICAga2JkIHtcbiAgICAgIGJhY2tncm91bmQ6ICMxZTI5M2I7IGJvcmRlcjogMXB4IHNvbGlkICMzMzQxNTU7IGNvbG9yOiAjOTRhM2I4O1xuICAgICAgcGFkZGluZzogMXB4IDVweDsgYm9yZGVyLXJhZGl1czogM3B4OyBmb250LXNpemU6IDEwcHg7XG4gICAgfVxuICAgIC5kaWFsb2ctZm9vdGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7IGdhcDogOHB4OyBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xuICAgICAgcGFkZGluZzogMTRweCAxOHB4OyBiYWNrZ3JvdW5kOiAjMWUyOTNiOyBib3JkZXItdG9wOiAxcHggc29saWQgIzMzNDE1NTtcbiAgICB9XG4gICAgLmJ0bi1jYW5jZWwsIC5idG4tc2F2ZSB7XG4gICAgICBwYWRkaW5nOiA4cHggMjBweDsgYm9yZGVyLXJhZGl1czogNnB4OyBmb250LXNpemU6IDEzcHg7XG4gICAgICBmb250LXdlaWdodDogNjAwOyBjdXJzb3I6IHBvaW50ZXI7IGJvcmRlcjogbm9uZTsgdHJhbnNpdGlvbjogZmlsdGVyIDAuMTVzO1xuICAgIH1cbiAgICAuYnRuLWNhbmNlbCB7IGJhY2tncm91bmQ6ICMzMzQxNTU7IGNvbG9yOiAjOTRhM2I4OyB9XG4gICAgLmJ0bi1jYW5jZWw6aG92ZXIgeyBmaWx0ZXI6IGJyaWdodG5lc3MoMS4yKTsgfVxuICAgIC5idG4tc2F2ZSB7IGJhY2tncm91bmQ6ICMyNTYzZWI7IGNvbG9yOiAjZmZmOyB9XG4gICAgLmJ0bi1zYXZlOmhvdmVyIHsgZmlsdGVyOiBicmlnaHRuZXNzKDEuMSk7IH1cbiAgYF0sXG59KVxuZXhwb3J0IGNsYXNzIFNldHRpbmdzRGlhbG9nQ29tcG9uZW50IHtcbiAgQE91dHB1dCgpIGNsb3NlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBwcml2YXRlIGFpID0gaW5qZWN0KEFpR2VuZXJhdG9yU2VydmljZSk7XG4gIGxvY2FsVXJsID0gdGhpcy5haS53ZWJob29rVXJsKCk7XG5cbiAgc2F2ZSgpOiB2b2lkIHtcbiAgICB0aGlzLmFpLnNldFdlYmhvb2tVcmwodGhpcy5sb2NhbFVybC50cmltKCkpO1xuICAgIHRoaXMuY2xvc2UuZW1pdCgpO1xuICB9XG5cbiAgb25PdmVybGF5Q2xpY2soZTogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICgoZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLmNsYXNzTGlzdC5jb250YWlucygnb3ZlcmxheScpKSB7XG4gICAgICB0aGlzLmNsb3NlLmVtaXQoKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,120 @@
1
+ import { Component, Input, signal, computed } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import * as i0 from "@angular/core";
4
+ export class TestPreviewComponent {
5
+ constructor() {
6
+ this.test = null;
7
+ this.copied = signal(false);
8
+ this.highlightedCode = computed(() => {
9
+ if (!this.test)
10
+ return '';
11
+ return this.syntaxHighlight(this.test.code);
12
+ });
13
+ }
14
+ syntaxHighlight(code) {
15
+ return code
16
+ .replace(/&/g, '&amp;')
17
+ .replace(/</g, '&lt;')
18
+ .replace(/>/g, '&gt;')
19
+ // Comments
20
+ .replace(/(\/\/[^\n]*)/g, '<span class="cm">$1</span>')
21
+ // cy. commands
22
+ .replace(/\b(cy)\b/g, '<span class="cy">$1</span>')
23
+ // Keywords
24
+ .replace(/\b(describe|it|beforeEach|afterEach|before|after|context|specify|const|let|var|function|return|import|export|from|async|await|new)\b/g, '<span class="kw">$1</span>')
25
+ // Strings
26
+ .replace(/('[^']*'|"[^"]*"|`[^`]*`)/g, '<span class="str">$1</span>')
27
+ // Numbers
28
+ .replace(/\b(\d+)\b/g, '<span class="num">$1</span>');
29
+ }
30
+ async copyCode() {
31
+ if (!this.test)
32
+ return;
33
+ await navigator.clipboard.writeText(this.test.code);
34
+ this.copied.set(true);
35
+ setTimeout(() => this.copied.set(false), 2000);
36
+ }
37
+ downloadCode() {
38
+ if (!this.test)
39
+ return;
40
+ const blob = new Blob([this.test.code], { type: 'text/typescript' });
41
+ const url = URL.createObjectURL(blob);
42
+ const a = document.createElement('a');
43
+ a.href = url;
44
+ a.download = `cypress-test-${new Date().toISOString().slice(0, 10)}.cy.ts`;
45
+ a.click();
46
+ URL.revokeObjectURL(url);
47
+ }
48
+ formatDate(ts) {
49
+ return new Date(ts).toLocaleString('de-DE', {
50
+ day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit',
51
+ });
52
+ }
53
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TestPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
54
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: TestPreviewComponent, isStandalone: true, selector: "app-test-preview", inputs: { test: "test" }, ngImport: i0, template: `
55
+ <div class="test-preview" data-debug-panel>
56
+ @if (!test) {
57
+ <div class="empty-state">
58
+ <div class="empty-icon">🤖</div>
59
+ <p>Noch kein Test generiert.</p>
60
+ <p class="hint">Zeichne Aktionen auf und klicke „🤖 → Cypress Test".</p>
61
+ </div>
62
+ } @else {
63
+ <div class="test-toolbar" data-debug-panel>
64
+ <div class="test-meta">
65
+ <span class="model-tag">{{ test.model }}</span>
66
+ <span class="gen-time">{{ formatDate(test.generatedAt) }}</span>
67
+ </div>
68
+ <div class="test-actions">
69
+ <button class="action-btn" title="Kopieren" (click)="copyCode()">
70
+ {{ copied() ? '✅ Kopiert!' : '📋 Kopieren' }}
71
+ </button>
72
+ <button class="action-btn" title="Herunterladen" (click)="downloadCode()">
73
+ 💾 Download
74
+ </button>
75
+ </div>
76
+ </div>
77
+
78
+ <div class="code-container">
79
+ <pre class="code-block"><code [innerHTML]="highlightedCode()"></code></pre>
80
+ </div>
81
+ }
82
+ </div>
83
+ `, isInline: true, styles: [".test-preview{height:100%;display:flex;flex-direction:column}.empty-state{text-align:center;padding:32px 20px;color:#64748b}.empty-icon{font-size:40px;margin-bottom:10px}.empty-state p{margin:4px 0;font-size:13px}.hint{font-size:11px;color:#475569}.test-toolbar{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;background:#1e293b;border-bottom:1px solid #334155;flex-shrink:0;gap:8px}.test-meta{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.model-tag{background:#312e81;color:#a5b4fc;font-size:10px;padding:2px 7px;border-radius:4px;font-weight:600;white-space:nowrap}.gen-time{font-size:10px;color:#64748b;white-space:nowrap}.test-actions{display:flex;gap:6px;flex-shrink:0}.action-btn{background:#334155;border:none;color:#cbd5e1;padding:4px 10px;border-radius:5px;font-size:11px;cursor:pointer;white-space:nowrap;transition:background .15s}.action-btn:hover{background:#475569}.code-container{flex:1;overflow:auto}.code-container::-webkit-scrollbar{width:5px;height:5px}.code-container::-webkit-scrollbar-thumb{background:#334155;border-radius:3px}.code-block{margin:0;padding:14px;font-family:Cascadia Code,Consolas,Fira Code,monospace;font-size:11px;line-height:1.7;color:#e2e8f0;white-space:pre;tab-size:2}:global(.kw){color:#c084fc}:global(.str){color:#86efac}:global(.fn){color:#67e8f9}:global(.cm){color:#64748b;font-style:italic}:global(.num){color:#fb923c}:global(.cy){color:#fbbf24;font-weight:600}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
84
+ }
85
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TestPreviewComponent, decorators: [{
86
+ type: Component,
87
+ args: [{ selector: 'app-test-preview', standalone: true, imports: [CommonModule], template: `
88
+ <div class="test-preview" data-debug-panel>
89
+ @if (!test) {
90
+ <div class="empty-state">
91
+ <div class="empty-icon">🤖</div>
92
+ <p>Noch kein Test generiert.</p>
93
+ <p class="hint">Zeichne Aktionen auf und klicke „🤖 → Cypress Test".</p>
94
+ </div>
95
+ } @else {
96
+ <div class="test-toolbar" data-debug-panel>
97
+ <div class="test-meta">
98
+ <span class="model-tag">{{ test.model }}</span>
99
+ <span class="gen-time">{{ formatDate(test.generatedAt) }}</span>
100
+ </div>
101
+ <div class="test-actions">
102
+ <button class="action-btn" title="Kopieren" (click)="copyCode()">
103
+ {{ copied() ? '✅ Kopiert!' : '📋 Kopieren' }}
104
+ </button>
105
+ <button class="action-btn" title="Herunterladen" (click)="downloadCode()">
106
+ 💾 Download
107
+ </button>
108
+ </div>
109
+ </div>
110
+
111
+ <div class="code-container">
112
+ <pre class="code-block"><code [innerHTML]="highlightedCode()"></code></pre>
113
+ </div>
114
+ }
115
+ </div>
116
+ `, styles: [".test-preview{height:100%;display:flex;flex-direction:column}.empty-state{text-align:center;padding:32px 20px;color:#64748b}.empty-icon{font-size:40px;margin-bottom:10px}.empty-state p{margin:4px 0;font-size:13px}.hint{font-size:11px;color:#475569}.test-toolbar{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;background:#1e293b;border-bottom:1px solid #334155;flex-shrink:0;gap:8px}.test-meta{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.model-tag{background:#312e81;color:#a5b4fc;font-size:10px;padding:2px 7px;border-radius:4px;font-weight:600;white-space:nowrap}.gen-time{font-size:10px;color:#64748b;white-space:nowrap}.test-actions{display:flex;gap:6px;flex-shrink:0}.action-btn{background:#334155;border:none;color:#cbd5e1;padding:4px 10px;border-radius:5px;font-size:11px;cursor:pointer;white-space:nowrap;transition:background .15s}.action-btn:hover{background:#475569}.code-container{flex:1;overflow:auto}.code-container::-webkit-scrollbar{width:5px;height:5px}.code-container::-webkit-scrollbar-thumb{background:#334155;border-radius:3px}.code-block{margin:0;padding:14px;font-family:Cascadia Code,Consolas,Fira Code,monospace;font-size:11px;line-height:1.7;color:#e2e8f0;white-space:pre;tab-size:2}:global(.kw){color:#c084fc}:global(.str){color:#86efac}:global(.fn){color:#67e8f9}:global(.cm){color:#64748b;font-style:italic}:global(.num){color:#fb923c}:global(.cy){color:#fbbf24;font-weight:600}\n"] }]
117
+ }], propDecorators: { test: [{
118
+ type: Input
119
+ }] } });
120
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1wcmV2aWV3LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2RlYnVnLXJlY29yZGVyL3NyYy9saWIvdGVzdC1wcmV2aWV3L3Rlc3QtcHJldmlldy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBK0cvQyxNQUFNLE9BQU8sb0JBQW9CO0lBNUdqQztRQTZHVyxTQUFJLEdBQXlCLElBQUksQ0FBQztRQUUzQyxXQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXZCLG9CQUFlLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk7Z0JBQUUsT0FBTyxFQUFFLENBQUM7WUFDMUIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDLENBQUM7S0EwQ0o7SUF4Q1MsZUFBZSxDQUFDLElBQVk7UUFDbEMsT0FBTyxJQUFJO2FBQ1IsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7YUFDdEIsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7YUFDckIsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7WUFDdEIsV0FBVzthQUNWLE9BQU8sQ0FBQyxlQUFlLEVBQUUsNEJBQTRCLENBQUM7WUFDdkQsZUFBZTthQUNkLE9BQU8sQ0FBQyxXQUFXLEVBQUUsNEJBQTRCLENBQUM7WUFDbkQsV0FBVzthQUNWLE9BQU8sQ0FBQyx1SUFBdUksRUFBRSw0QkFBNEIsQ0FBQztZQUMvSyxVQUFVO2FBQ1QsT0FBTyxDQUFDLDRCQUE0QixFQUFFLDZCQUE2QixDQUFDO1lBQ3JFLFVBQVU7YUFDVCxPQUFPLENBQUMsWUFBWSxFQUFFLDZCQUE2QixDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELEtBQUssQ0FBQyxRQUFRO1FBQ1osSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUN2QixNQUFNLFNBQVMsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEIsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRCxZQUFZO1FBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUN2QixNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN0QyxDQUFDLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztRQUNiLENBQUMsQ0FBQyxRQUFRLEdBQUcsZ0JBQWdCLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDO1FBQzNFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNWLEdBQUcsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUVELFVBQVUsQ0FBQyxFQUFVO1FBQ25CLE9BQU8sSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRTtZQUMxQyxHQUFHLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsU0FBUztTQUNyRSxDQUFDLENBQUM7SUFDTCxDQUFDOytHQWpEVSxvQkFBb0I7bUdBQXBCLG9CQUFvQixzR0F4R3JCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZCVCx5L0NBOUJTLFlBQVk7OzRGQXlHWCxvQkFBb0I7a0JBNUdoQyxTQUFTOytCQUNFLGtCQUFrQixjQUNoQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLENBQUMsWUFDYjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2QlQ7OEJBNEVRLElBQUk7c0JBQVosS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIHNpZ25hbCwgY29tcHV0ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBHZW5lcmF0ZWRUZXN0IH0gZnJvbSAnLi4vbW9kZWxzL3JlY29yZGVkLWFjdGlvbi5tb2RlbCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC10ZXN0LXByZXZpZXcnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwidGVzdC1wcmV2aWV3XCIgZGF0YS1kZWJ1Zy1wYW5lbD5cbiAgICAgIEBpZiAoIXRlc3QpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LXN0YXRlXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LWljb25cIj7wn6SWPC9kaXY+XG4gICAgICAgICAgPHA+Tm9jaCBrZWluIFRlc3QgZ2VuZXJpZXJ0LjwvcD5cbiAgICAgICAgICA8cCBjbGFzcz1cImhpbnRcIj5aZWljaG5lIEFrdGlvbmVuIGF1ZiB1bmQga2xpY2tlIOKAnvCfpJYg4oaSIEN5cHJlc3MgVGVzdFwiLjwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9IEBlbHNlIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cInRlc3QtdG9vbGJhclwiIGRhdGEtZGVidWctcGFuZWw+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRlc3QtbWV0YVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2RlbC10YWdcIj57eyB0ZXN0Lm1vZGVsIH19PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJnZW4tdGltZVwiPnt7IGZvcm1hdERhdGUodGVzdC5nZW5lcmF0ZWRBdCkgfX08L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRlc3QtYWN0aW9uc1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImFjdGlvbi1idG5cIiB0aXRsZT1cIktvcGllcmVuXCIgKGNsaWNrKT1cImNvcHlDb2RlKClcIj5cbiAgICAgICAgICAgICAge3sgY29waWVkKCkgPyAn4pyFIEtvcGllcnQhJyA6ICfwn5OLIEtvcGllcmVuJyB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYWN0aW9uLWJ0blwiIHRpdGxlPVwiSGVydW50ZXJsYWRlblwiIChjbGljayk9XCJkb3dubG9hZENvZGUoKVwiPlxuICAgICAgICAgICAgICDwn5K+IERvd25sb2FkXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvZGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgPHByZSBjbGFzcz1cImNvZGUtYmxvY2tcIj48Y29kZSBbaW5uZXJIVE1MXT1cImhpZ2hsaWdodGVkQ29kZSgpXCI+PC9jb2RlPjwvcHJlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBbYFxuICAgIC50ZXN0LXByZXZpZXcgeyBoZWlnaHQ6IDEwMCU7IGRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IH1cblxuICAgIC5lbXB0eS1zdGF0ZSB7XG4gICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICBwYWRkaW5nOiAzMnB4IDIwcHg7XG4gICAgICBjb2xvcjogIzY0NzQ4YjtcbiAgICB9XG4gICAgLmVtcHR5LWljb24geyBmb250LXNpemU6IDQwcHg7IG1hcmdpbi1ib3R0b206IDEwcHg7IH1cbiAgICAuZW1wdHktc3RhdGUgcCB7IG1hcmdpbjogNHB4IDA7IGZvbnQtc2l6ZTogMTNweDsgfVxuICAgIC5oaW50IHsgZm9udC1zaXplOiAxMXB4OyBjb2xvcjogIzQ3NTU2OTsgfVxuXG4gICAgLnRlc3QtdG9vbGJhciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIHBhZGRpbmc6IDhweCAxMnB4O1xuICAgICAgYmFja2dyb3VuZDogIzFlMjkzYjtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjMzM0MTU1O1xuICAgICAgZmxleC1zaHJpbms6IDA7XG4gICAgICBnYXA6IDhweDtcbiAgICB9XG4gICAgLnRlc3QtbWV0YSB7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBmbGV4OiAxOyBtaW4td2lkdGg6IDA7IH1cbiAgICAubW9kZWwtdGFnIHtcbiAgICAgIGJhY2tncm91bmQ6ICMzMTJlODE7XG4gICAgICBjb2xvcjogI2E1YjRmYztcbiAgICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICAgIHBhZGRpbmc6IDJweCA3cHg7XG4gICAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICB9XG4gICAgLmdlbi10aW1lIHsgZm9udC1zaXplOiAxMHB4OyBjb2xvcjogIzY0NzQ4Yjsgd2hpdGUtc3BhY2U6IG5vd3JhcDsgfVxuICAgIC50ZXN0LWFjdGlvbnMgeyBkaXNwbGF5OiBmbGV4OyBnYXA6IDZweDsgZmxleC1zaHJpbms6IDA7IH1cbiAgICAuYWN0aW9uLWJ0biB7XG4gICAgICBiYWNrZ3JvdW5kOiAjMzM0MTU1O1xuICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgY29sb3I6ICNjYmQ1ZTE7XG4gICAgICBwYWRkaW5nOiA0cHggMTBweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDVweDtcbiAgICAgIGZvbnQtc2l6ZTogMTFweDtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICB0cmFuc2l0aW9uOiBiYWNrZ3JvdW5kIDAuMTVzO1xuICAgIH1cbiAgICAuYWN0aW9uLWJ0bjpob3ZlciB7IGJhY2tncm91bmQ6ICM0NzU1Njk7IH1cblxuICAgIC5jb2RlLWNvbnRhaW5lciB7XG4gICAgICBmbGV4OiAxO1xuICAgICAgb3ZlcmZsb3c6IGF1dG87XG4gICAgfVxuICAgIC5jb2RlLWNvbnRhaW5lcjo6LXdlYmtpdC1zY3JvbGxiYXIgeyB3aWR0aDogNXB4OyBoZWlnaHQ6IDVweDsgfVxuICAgIC5jb2RlLWNvbnRhaW5lcjo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWIgeyBiYWNrZ3JvdW5kOiAjMzM0MTU1OyBib3JkZXItcmFkaXVzOiAzcHg7IH1cblxuICAgIC5jb2RlLWJsb2NrIHtcbiAgICAgIG1hcmdpbjogMDtcbiAgICAgIHBhZGRpbmc6IDE0cHg7XG4gICAgICBmb250LWZhbWlseTogJ0Nhc2NhZGlhIENvZGUnLCAnQ29uc29sYXMnLCAnRmlyYSBDb2RlJywgbW9ub3NwYWNlO1xuICAgICAgZm9udC1zaXplOiAxMXB4O1xuICAgICAgbGluZS1oZWlnaHQ6IDEuNztcbiAgICAgIGNvbG9yOiAjZTJlOGYwO1xuICAgICAgd2hpdGUtc3BhY2U6IHByZTtcbiAgICAgIHRhYi1zaXplOiAyO1xuICAgIH1cblxuICAgIC8qIFN5bnRheCBIaWdobGlnaHRpbmcgKi9cbiAgICA6Z2xvYmFsKC5rdykgIHsgY29sb3I6ICNjMDg0ZmM7IH1cbiAgICA6Z2xvYmFsKC5zdHIpIHsgY29sb3I6ICM4NmVmYWM7IH1cbiAgICA6Z2xvYmFsKC5mbikgIHsgY29sb3I6ICM2N2U4Zjk7IH1cbiAgICA6Z2xvYmFsKC5jbSkgIHsgY29sb3I6ICM2NDc0OGI7IGZvbnQtc3R5bGU6IGl0YWxpYzsgfVxuICAgIDpnbG9iYWwoLm51bSkgeyBjb2xvcjogI2ZiOTIzYzsgfVxuICAgIDpnbG9iYWwoLmN5KSAgeyBjb2xvcjogI2ZiYmYyNDsgZm9udC13ZWlnaHQ6IDYwMDsgfVxuICBgXSxcbn0pXG5leHBvcnQgY2xhc3MgVGVzdFByZXZpZXdDb21wb25lbnQge1xuICBASW5wdXQoKSB0ZXN0OiBHZW5lcmF0ZWRUZXN0IHwgbnVsbCA9IG51bGw7XG5cbiAgY29waWVkID0gc2lnbmFsKGZhbHNlKTtcblxuICBoaWdobGlnaHRlZENvZGUgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgaWYgKCF0aGlzLnRlc3QpIHJldHVybiAnJztcbiAgICByZXR1cm4gdGhpcy5zeW50YXhIaWdobGlnaHQodGhpcy50ZXN0LmNvZGUpO1xuICB9KTtcblxuICBwcml2YXRlIHN5bnRheEhpZ2hsaWdodChjb2RlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBjb2RlXG4gICAgICAucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgICAgLnJlcGxhY2UoLzwvZywgJyZsdDsnKVxuICAgICAgLnJlcGxhY2UoLz4vZywgJyZndDsnKVxuICAgICAgLy8gQ29tbWVudHNcbiAgICAgIC5yZXBsYWNlKC8oXFwvXFwvW15cXG5dKikvZywgJzxzcGFuIGNsYXNzPVwiY21cIj4kMTwvc3Bhbj4nKVxuICAgICAgLy8gY3kuIGNvbW1hbmRzXG4gICAgICAucmVwbGFjZSgvXFxiKGN5KVxcYi9nLCAnPHNwYW4gY2xhc3M9XCJjeVwiPiQxPC9zcGFuPicpXG4gICAgICAvLyBLZXl3b3Jkc1xuICAgICAgLnJlcGxhY2UoL1xcYihkZXNjcmliZXxpdHxiZWZvcmVFYWNofGFmdGVyRWFjaHxiZWZvcmV8YWZ0ZXJ8Y29udGV4dHxzcGVjaWZ5fGNvbnN0fGxldHx2YXJ8ZnVuY3Rpb258cmV0dXJufGltcG9ydHxleHBvcnR8ZnJvbXxhc3luY3xhd2FpdHxuZXcpXFxiL2csICc8c3BhbiBjbGFzcz1cImt3XCI+JDE8L3NwYW4+JylcbiAgICAgIC8vIFN0cmluZ3NcbiAgICAgIC5yZXBsYWNlKC8oJ1teJ10qJ3xcIlteXCJdKlwifGBbXmBdKmApL2csICc8c3BhbiBjbGFzcz1cInN0clwiPiQxPC9zcGFuPicpXG4gICAgICAvLyBOdW1iZXJzXG4gICAgICAucmVwbGFjZSgvXFxiKFxcZCspXFxiL2csICc8c3BhbiBjbGFzcz1cIm51bVwiPiQxPC9zcGFuPicpO1xuICB9XG5cbiAgYXN5bmMgY29weUNvZGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLnRlc3QpIHJldHVybjtcbiAgICBhd2FpdCBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dCh0aGlzLnRlc3QuY29kZSk7XG4gICAgdGhpcy5jb3BpZWQuc2V0KHRydWUpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jb3BpZWQuc2V0KGZhbHNlKSwgMjAwMCk7XG4gIH1cblxuICBkb3dubG9hZENvZGUoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnRlc3QpIHJldHVybjtcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3RoaXMudGVzdC5jb2RlXSwgeyB0eXBlOiAndGV4dC90eXBlc2NyaXB0JyB9KTtcbiAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgIGNvbnN0IGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgYS5ocmVmID0gdXJsO1xuICAgIGEuZG93bmxvYWQgPSBgY3lwcmVzcy10ZXN0LSR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpLnNsaWNlKDAsIDEwKX0uY3kudHNgO1xuICAgIGEuY2xpY2soKTtcbiAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gIH1cblxuICBmb3JtYXREYXRlKHRzOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBuZXcgRGF0ZSh0cykudG9Mb2NhbGVTdHJpbmcoJ2RlLURFJywge1xuICAgICAgZGF5OiAnMi1kaWdpdCcsIG1vbnRoOiAnMi1kaWdpdCcsIGhvdXI6ICcyLWRpZ2l0JywgbWludXRlOiAnMi1kaWdpdCcsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Public API Surface of debug-recorder
3
+ */
4
+ // Main entry component — add this to your Angular app
5
+ export * from './lib/debug-panel/debug-panel.component';
6
+ // Sub-components (if you need them individually)
7
+ export * from './lib/action-list/action-list.component';
8
+ export * from './lib/test-preview/test-preview.component';
9
+ export * from './lib/session-replay/session-replay.component';
10
+ export * from './lib/settings-dialog/settings-dialog.component';
11
+ // Services
12
+ export * from './lib/services/recorder.service';
13
+ export * from './lib/services/ai-generator.service';
14
+ export * from './lib/services/rrweb-recorder.service';
15
+ // Models / interfaces
16
+ export * from './lib/models/recorded-action.model';
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2RlYnVnLXJlY29yZGVyL3NyYy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsc0RBQXNEO0FBQ3RELGNBQWMseUNBQXlDLENBQUM7QUFFeEQsaURBQWlEO0FBQ2pELGNBQWMseUNBQXlDLENBQUM7QUFDeEQsY0FBYywyQ0FBMkMsQ0FBQztBQUMxRCxjQUFjLCtDQUErQyxDQUFDO0FBQzlELGNBQWMsaURBQWlELENBQUM7QUFFaEUsV0FBVztBQUNYLGNBQWMsaUNBQWlDLENBQUM7QUFDaEQsY0FBYyxxQ0FBcUMsQ0FBQztBQUNwRCxjQUFjLHVDQUF1QyxDQUFDO0FBRXRELHNCQUFzQjtBQUN0QixjQUFjLG9DQUFvQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIGRlYnVnLXJlY29yZGVyXHJcbiAqL1xyXG5cclxuLy8gTWFpbiBlbnRyeSBjb21wb25lbnQg4oCUIGFkZCB0aGlzIHRvIHlvdXIgQW5ndWxhciBhcHBcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvZGVidWctcGFuZWwvZGVidWctcGFuZWwuY29tcG9uZW50JztcclxuXHJcbi8vIFN1Yi1jb21wb25lbnRzIChpZiB5b3UgbmVlZCB0aGVtIGluZGl2aWR1YWxseSlcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvYWN0aW9uLWxpc3QvYWN0aW9uLWxpc3QuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvdGVzdC1wcmV2aWV3L3Rlc3QtcHJldmlldy5jb21wb25lbnQnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9zZXNzaW9uLXJlcGxheS9zZXNzaW9uLXJlcGxheS5jb21wb25lbnQnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9zZXR0aW5ncy1kaWFsb2cvc2V0dGluZ3MtZGlhbG9nLmNvbXBvbmVudCc7XHJcblxyXG4vLyBTZXJ2aWNlc1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9zZXJ2aWNlcy9yZWNvcmRlci5zZXJ2aWNlJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvc2VydmljZXMvYWktZ2VuZXJhdG9yLnNlcnZpY2UnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9zZXJ2aWNlcy9ycndlYi1yZWNvcmRlci5zZXJ2aWNlJztcclxuXHJcbi8vIE1vZGVscyAvIGludGVyZmFjZXNcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL3JlY29yZGVkLWFjdGlvbi5tb2RlbCc7XHJcbiJdfQ==