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,61 @@
1
+ import { Injectable, signal } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/common/http";
4
+ export class AiGeneratorService {
5
+ constructor(http) {
6
+ this.http = http;
7
+ this._webhookUrl = signal(localStorage.getItem('debugRecorder_webhookUrl') ?? '');
8
+ this._isGenerating = signal(false);
9
+ this._error = signal(null);
10
+ this._lastTest = signal(null);
11
+ this.webhookUrl = this._webhookUrl.asReadonly();
12
+ this.isGenerating = this._isGenerating.asReadonly();
13
+ this.error = this._error.asReadonly();
14
+ this.lastTest = this._lastTest.asReadonly();
15
+ }
16
+ setWebhookUrl(url) {
17
+ this._webhookUrl.set(url);
18
+ localStorage.setItem('debugRecorder_webhookUrl', url);
19
+ }
20
+ async generateCypressTest(session) {
21
+ const url = this._webhookUrl();
22
+ if (!url)
23
+ throw new Error('Keine Webhook-URL konfiguriert');
24
+ this._isGenerating.set(true);
25
+ this._error.set(null);
26
+ try {
27
+ const code = await this.postSession(url, session);
28
+ const test = {
29
+ code,
30
+ generatedAt: Date.now(),
31
+ model: url,
32
+ sessionId: session.id,
33
+ };
34
+ this._lastTest.set(test);
35
+ return test;
36
+ }
37
+ catch (err) {
38
+ const msg = err?.error?.message || err?.message || 'Fehler beim Senden';
39
+ this._error.set(msg);
40
+ throw err;
41
+ }
42
+ finally {
43
+ this._isGenerating.set(false);
44
+ }
45
+ }
46
+ postSession(url, session) {
47
+ return new Promise((resolve, reject) => {
48
+ this.http.post(url, session, { responseType: 'text' }).subscribe({
49
+ next: (res) => resolve(res),
50
+ error: reject,
51
+ });
52
+ });
53
+ }
54
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AiGeneratorService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
55
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AiGeneratorService, providedIn: 'root' }); }
56
+ }
57
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AiGeneratorService, decorators: [{
58
+ type: Injectable,
59
+ args: [{ providedIn: 'root' }]
60
+ }], ctorParameters: () => [{ type: i1.HttpClient }] });
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWktZ2VuZXJhdG9yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kZWJ1Zy1yZWNvcmRlci9zcmMvbGliL3NlcnZpY2VzL2FpLWdlbmVyYXRvci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7QUFLbkQsTUFBTSxPQUFPLGtCQUFrQjtJQVc3QixZQUFvQixJQUFnQjtRQUFoQixTQUFJLEdBQUosSUFBSSxDQUFZO1FBVjVCLGdCQUFXLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsMEJBQTBCLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM3RSxrQkFBYSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QixXQUFNLEdBQUcsTUFBTSxDQUFnQixJQUFJLENBQUMsQ0FBQztRQUNyQyxjQUFTLEdBQUcsTUFBTSxDQUF1QixJQUFJLENBQUMsQ0FBQztRQUV2RCxlQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUMzQyxpQkFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDL0MsVUFBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDakMsYUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLENBQUM7SUFFQSxDQUFDO0lBRXhDLGFBQWEsQ0FBQyxHQUFXO1FBQ3ZCLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFCLFlBQVksQ0FBQyxPQUFPLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxPQUF5QjtRQUNqRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLEdBQUc7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7UUFFNUQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFdEIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNsRCxNQUFNLElBQUksR0FBa0I7Z0JBQzFCLElBQUk7Z0JBQ0osV0FBVyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7Z0JBQ3ZCLEtBQUssRUFBRSxHQUFHO2dCQUNWLFNBQVMsRUFBRSxPQUFPLENBQUMsRUFBRTthQUN0QixDQUFDO1lBQ0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekIsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztZQUNsQixNQUFNLEdBQUcsR0FBRyxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQUUsT0FBTyxJQUFJLG9CQUFvQixDQUFDO1lBQ3hFLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLE1BQU0sR0FBRyxDQUFDO1FBQ1osQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEMsQ0FBQztJQUNILENBQUM7SUFFTyxXQUFXLENBQUMsR0FBVyxFQUFFLE9BQXlCO1FBQ3hELE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLE9BQU8sRUFBRSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDL0QsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDO2dCQUMzQixLQUFLLEVBQUUsTUFBTTthQUNkLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzsrR0FuRFUsa0JBQWtCO21IQUFsQixrQkFBa0IsY0FETCxNQUFNOzs0RkFDbkIsa0JBQWtCO2tCQUQ5QixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBHZW5lcmF0ZWRUZXN0LCBSZWNvcmRpbmdTZXNzaW9uIH0gZnJvbSAnLi4vbW9kZWxzL3JlY29yZGVkLWFjdGlvbi5tb2RlbCc7XHJcblxyXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxyXG5leHBvcnQgY2xhc3MgQWlHZW5lcmF0b3JTZXJ2aWNlIHtcclxuICBwcml2YXRlIF93ZWJob29rVXJsID0gc2lnbmFsKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdkZWJ1Z1JlY29yZGVyX3dlYmhvb2tVcmwnKSA/PyAnJyk7XHJcbiAgcHJpdmF0ZSBfaXNHZW5lcmF0aW5nID0gc2lnbmFsKGZhbHNlKTtcclxuICBwcml2YXRlIF9lcnJvciA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcclxuICBwcml2YXRlIF9sYXN0VGVzdCA9IHNpZ25hbDxHZW5lcmF0ZWRUZXN0IHwgbnVsbD4obnVsbCk7XHJcblxyXG4gIHdlYmhvb2tVcmwgPSB0aGlzLl93ZWJob29rVXJsLmFzUmVhZG9ubHkoKTtcclxuICBpc0dlbmVyYXRpbmcgPSB0aGlzLl9pc0dlbmVyYXRpbmcuYXNSZWFkb25seSgpO1xyXG4gIGVycm9yID0gdGhpcy5fZXJyb3IuYXNSZWFkb25seSgpO1xyXG4gIGxhc3RUZXN0ID0gdGhpcy5fbGFzdFRlc3QuYXNSZWFkb25seSgpO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQpIHt9XHJcblxyXG4gIHNldFdlYmhvb2tVcmwodXJsOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMuX3dlYmhvb2tVcmwuc2V0KHVybCk7XHJcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnZGVidWdSZWNvcmRlcl93ZWJob29rVXJsJywgdXJsKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGdlbmVyYXRlQ3lwcmVzc1Rlc3Qoc2Vzc2lvbjogUmVjb3JkaW5nU2Vzc2lvbik6IFByb21pc2U8R2VuZXJhdGVkVGVzdD4ge1xyXG4gICAgY29uc3QgdXJsID0gdGhpcy5fd2ViaG9va1VybCgpO1xyXG4gICAgaWYgKCF1cmwpIHRocm93IG5ldyBFcnJvcignS2VpbmUgV2ViaG9vay1VUkwga29uZmlndXJpZXJ0Jyk7XHJcblxyXG4gICAgdGhpcy5faXNHZW5lcmF0aW5nLnNldCh0cnVlKTtcclxuICAgIHRoaXMuX2Vycm9yLnNldChudWxsKTtcclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCBjb2RlID0gYXdhaXQgdGhpcy5wb3N0U2Vzc2lvbih1cmwsIHNlc3Npb24pO1xyXG4gICAgICBjb25zdCB0ZXN0OiBHZW5lcmF0ZWRUZXN0ID0ge1xyXG4gICAgICAgIGNvZGUsXHJcbiAgICAgICAgZ2VuZXJhdGVkQXQ6IERhdGUubm93KCksXHJcbiAgICAgICAgbW9kZWw6IHVybCxcclxuICAgICAgICBzZXNzaW9uSWQ6IHNlc3Npb24uaWQsXHJcbiAgICAgIH07XHJcbiAgICAgIHRoaXMuX2xhc3RUZXN0LnNldCh0ZXN0KTtcclxuICAgICAgcmV0dXJuIHRlc3Q7XHJcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xyXG4gICAgICBjb25zdCBtc2cgPSBlcnI/LmVycm9yPy5tZXNzYWdlIHx8IGVycj8ubWVzc2FnZSB8fCAnRmVobGVyIGJlaW0gU2VuZGVuJztcclxuICAgICAgdGhpcy5fZXJyb3Iuc2V0KG1zZyk7XHJcbiAgICAgIHRocm93IGVycjtcclxuICAgIH0gZmluYWxseSB7XHJcbiAgICAgIHRoaXMuX2lzR2VuZXJhdGluZy5zZXQoZmFsc2UpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBwb3N0U2Vzc2lvbih1cmw6IHN0cmluZywgc2Vzc2lvbjogUmVjb3JkaW5nU2Vzc2lvbik6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICB0aGlzLmh0dHAucG9zdCh1cmwsIHNlc3Npb24sIHsgcmVzcG9uc2VUeXBlOiAndGV4dCcgfSkuc3Vic2NyaWJlKHtcclxuICAgICAgICBuZXh0OiAocmVzKSA9PiByZXNvbHZlKHJlcyksXHJcbiAgICAgICAgZXJyb3I6IHJlamVjdCxcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuIl19
@@ -0,0 +1,354 @@
1
+ import { Injectable, signal, computed } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export class RecorderService {
4
+ constructor(zone) {
5
+ this.zone = zone;
6
+ this._isRecording = signal(false);
7
+ this._currentSession = signal(null);
8
+ this._sessions = signal([]);
9
+ this._isPaused = signal(false);
10
+ this.isRecording = computed(() => this._isRecording());
11
+ this.isPaused = computed(() => this._isPaused());
12
+ this.currentSession = computed(() => this._currentSession());
13
+ this.sessions = computed(() => this._sessions());
14
+ this.actionCount = computed(() => this._currentSession()?.actions.length ?? 0);
15
+ this.listeners = [];
16
+ this.lastScrollTime = 0;
17
+ }
18
+ startRecording(name, description) {
19
+ const session = {
20
+ id: this.generateId(),
21
+ name: name || `Session ${new Date().toLocaleTimeString()}`,
22
+ description,
23
+ startTime: Date.now(),
24
+ startUrl: window.location.href,
25
+ actions: [],
26
+ tags: [],
27
+ };
28
+ this._currentSession.set(session);
29
+ this._isRecording.set(true);
30
+ this._isPaused.set(false);
31
+ this.attachListeners();
32
+ this.recordNavigation('navigation', window.location.href);
33
+ }
34
+ stopRecording() {
35
+ const session = this._currentSession();
36
+ if (!session)
37
+ return null;
38
+ const completed = { ...session, endTime: Date.now() };
39
+ this._sessions.update(s => [...s, completed]);
40
+ this._currentSession.set(null);
41
+ this._isRecording.set(false);
42
+ this._isPaused.set(false);
43
+ this.detachListeners();
44
+ return completed;
45
+ }
46
+ pauseRecording() {
47
+ if (this._isRecording()) {
48
+ this._isPaused.set(!this._isPaused());
49
+ }
50
+ }
51
+ clearCurrentSession() {
52
+ this._currentSession.update(s => s ? { ...s, actions: [] } : null);
53
+ }
54
+ removeAction(actionId) {
55
+ this._currentSession.update(s => s ? { ...s, actions: s.actions.filter(a => a.id !== actionId) } : null);
56
+ }
57
+ addNote(actionId, note) {
58
+ this._currentSession.update(s => s ? {
59
+ ...s,
60
+ actions: s.actions.map(a => a.id === actionId ? { ...a, note } : a)
61
+ } : null);
62
+ }
63
+ deleteSession(sessionId) {
64
+ this._sessions.update(s => s.filter(x => x.id !== sessionId));
65
+ }
66
+ loadSession(session) {
67
+ this._currentSession.set(session);
68
+ }
69
+ // ─── Event Listeners ──────────────────────────────────────────────────────
70
+ attachListeners() {
71
+ const opts = { capture: true, passive: true };
72
+ const onClick = (e) => this.zone.run(() => this.handleClick(e));
73
+ const onDblClick = (e) => this.zone.run(() => this.handleDblClick(e));
74
+ const onInput = (e) => this.zone.run(() => this.handleInput(e));
75
+ const onChange = (e) => this.zone.run(() => this.handleChange(e));
76
+ const onSubmit = (e) => this.zone.run(() => this.handleSubmit(e));
77
+ const onKeydown = (e) => this.zone.run(() => this.handleKeydown(e));
78
+ const onScroll = (e) => this.zone.run(() => this.handleScroll(e));
79
+ document.addEventListener('click', onClick, opts);
80
+ document.addEventListener('dblclick', onDblClick, opts);
81
+ document.addEventListener('input', onInput, opts);
82
+ document.addEventListener('change', onChange, opts);
83
+ document.addEventListener('submit', onSubmit, opts);
84
+ document.addEventListener('keydown', onKeydown, opts);
85
+ document.addEventListener('scroll', onScroll, { capture: true, passive: true });
86
+ this.listeners = [
87
+ { type: 'click', fn: onClick },
88
+ { type: 'dblclick', fn: onDblClick },
89
+ { type: 'input', fn: onInput },
90
+ { type: 'change', fn: onChange },
91
+ { type: 'submit', fn: onSubmit },
92
+ { type: 'keydown', fn: onKeydown },
93
+ { type: 'scroll', fn: onScroll },
94
+ ];
95
+ }
96
+ detachListeners() {
97
+ this.listeners.forEach(({ type, fn }) => document.removeEventListener(type, fn, true));
98
+ this.listeners = [];
99
+ this.mutationObserver?.disconnect();
100
+ }
101
+ // ─── Handlers ─────────────────────────────────────────────────────────────
102
+ handleClick(e) {
103
+ if (!this.shouldRecord(e.target))
104
+ return;
105
+ const el = e.target;
106
+ const info = this.getElementInfo(el);
107
+ const selector = this.buildSelector(el);
108
+ this.addAction({
109
+ type: 'click',
110
+ selector,
111
+ selectorStrategy: this.getSelectorStrategy(el),
112
+ element: info,
113
+ description: `Click on ${this.describeElement(info)}`,
114
+ });
115
+ }
116
+ handleDblClick(e) {
117
+ if (!this.shouldRecord(e.target))
118
+ return;
119
+ const el = e.target;
120
+ const info = this.getElementInfo(el);
121
+ const selector = this.buildSelector(el);
122
+ this.addAction({
123
+ type: 'dblclick',
124
+ selector,
125
+ selectorStrategy: this.getSelectorStrategy(el),
126
+ element: info,
127
+ description: `Double-click on ${this.describeElement(info)}`,
128
+ });
129
+ }
130
+ handleInput(e) {
131
+ if (!this.shouldRecord(e.target))
132
+ return;
133
+ const el = e.target;
134
+ if (['checkbox', 'radio'].includes(el.type))
135
+ return; // handled by change
136
+ const info = this.getElementInfo(el);
137
+ const selector = this.buildSelector(el);
138
+ this.addAction({
139
+ type: 'input',
140
+ selector,
141
+ selectorStrategy: this.getSelectorStrategy(el),
142
+ element: info,
143
+ value: el.value,
144
+ description: `Type "${el.value}" in ${this.describeElement(info)}`,
145
+ });
146
+ }
147
+ handleChange(e) {
148
+ if (!this.shouldRecord(e.target))
149
+ return;
150
+ const el = e.target;
151
+ const info = this.getElementInfo(el);
152
+ const selector = this.buildSelector(el);
153
+ if (el.tagName === 'SELECT') {
154
+ this.addAction({
155
+ type: 'select',
156
+ selector,
157
+ selectorStrategy: this.getSelectorStrategy(el),
158
+ element: info,
159
+ value: el.value,
160
+ description: `Select "${el.value}" in ${this.describeElement(info)}`,
161
+ });
162
+ }
163
+ else if (el.type === 'checkbox') {
164
+ this.addAction({
165
+ type: 'click',
166
+ selector,
167
+ selectorStrategy: this.getSelectorStrategy(el),
168
+ element: info,
169
+ value: String(el.checked),
170
+ description: `${el.checked ? 'Check' : 'Uncheck'} ${this.describeElement(info)}`,
171
+ });
172
+ }
173
+ }
174
+ handleSubmit(e) {
175
+ if (!this.shouldRecord(e.target))
176
+ return;
177
+ const form = e.target;
178
+ const info = this.getElementInfo(form);
179
+ const selector = this.buildSelector(form);
180
+ this.addAction({
181
+ type: 'submit',
182
+ selector,
183
+ selectorStrategy: this.getSelectorStrategy(form),
184
+ element: info,
185
+ description: `Submit form ${info.id ? '#' + info.id : info.name ? info.name : ''}`.trim(),
186
+ });
187
+ }
188
+ handleScroll(e) {
189
+ if (!this.shouldRecord(e.target))
190
+ return;
191
+ const now = Date.now();
192
+ if (now - this.lastScrollTime < 1000)
193
+ return; // debounce 1s
194
+ this.lastScrollTime = now;
195
+ const el = e.target;
196
+ const isDoc = !el.tagName || el.tagName === 'HTML';
197
+ const scrollY = isDoc ? window.scrollY : el.scrollTop;
198
+ const scrollX = isDoc ? window.scrollX : el.scrollLeft;
199
+ const selector = el.tagName === 'HTML' || el.tagName === 'BODY'
200
+ ? 'window'
201
+ : this.buildSelector(el);
202
+ this.addAction({
203
+ type: 'scroll',
204
+ selector,
205
+ selectorStrategy: 'combined',
206
+ value: `${scrollX},${scrollY}`,
207
+ description: `Scroll to (${scrollX}, ${scrollY})`,
208
+ });
209
+ }
210
+ handleKeydown(e) {
211
+ const specialKeys = ['Enter', 'Escape', 'Tab', 'F5', 'F12'];
212
+ if (!specialKeys.includes(e.key))
213
+ return;
214
+ if (!this.shouldRecord(e.target))
215
+ return;
216
+ const el = e.target;
217
+ const selector = this.buildSelector(el);
218
+ this.addAction({
219
+ type: 'keypress',
220
+ selector,
221
+ selectorStrategy: this.getSelectorStrategy(el),
222
+ value: e.key,
223
+ description: `Press "${e.key}" on ${el.tagName.toLowerCase()}`,
224
+ });
225
+ }
226
+ recordNavigation(type, navUrl) {
227
+ const action = {
228
+ id: this.generateId(),
229
+ timestamp: Date.now(),
230
+ url: navUrl,
231
+ type,
232
+ selector: 'window',
233
+ selectorStrategy: 'combined',
234
+ description: `Navigate to ${navUrl}`,
235
+ };
236
+ this._currentSession.update(s => s ? { ...s, actions: [...s.actions, action] } : s);
237
+ }
238
+ // ─── Selector Building ────────────────────────────────────────────────────
239
+ buildSelector(el) {
240
+ // Priority: data-testid > data-cy > id > name > aria-label > combined
241
+ const testId = el.getAttribute('data-testid');
242
+ if (testId)
243
+ return `[data-testid="${testId}"]`;
244
+ const cy = el.getAttribute('data-cy');
245
+ if (cy)
246
+ return `[data-cy="${cy}"]`;
247
+ if (el.id && !el.id.includes(':'))
248
+ return `#${el.id}`;
249
+ const name = el.getAttribute('name');
250
+ if (name)
251
+ return `${el.tagName.toLowerCase()}[name="${name}"]`;
252
+ const ariaLabel = el.getAttribute('aria-label');
253
+ if (ariaLabel)
254
+ return `[aria-label="${ariaLabel}"]`;
255
+ // Class-based fallback
256
+ const relevantClasses = Array.from(el.classList)
257
+ .filter(c => !c.startsWith('ng-') && !c.startsWith('cdk-') && c.length > 0)
258
+ .slice(0, 3);
259
+ if (relevantClasses.length > 0) {
260
+ return `${el.tagName.toLowerCase()}.${relevantClasses.join('.')}`;
261
+ }
262
+ // Text content for buttons/links
263
+ if (['BUTTON', 'A'].includes(el.tagName)) {
264
+ const text = el.textContent?.trim().slice(0, 30);
265
+ if (text)
266
+ return `${el.tagName.toLowerCase()}:contains("${text}")`;
267
+ }
268
+ return el.tagName.toLowerCase();
269
+ }
270
+ getSelectorStrategy(el) {
271
+ if (el.getAttribute('data-testid'))
272
+ return 'data-testid';
273
+ if (el.getAttribute('data-cy'))
274
+ return 'data-cy';
275
+ if (el.id)
276
+ return 'id';
277
+ if (el.getAttribute('name'))
278
+ return 'name';
279
+ return 'class';
280
+ }
281
+ getElementInfo(el) {
282
+ return {
283
+ tagName: el.tagName.toLowerCase(),
284
+ id: el.id || undefined,
285
+ classes: Array.from(el.classList).filter(c => !c.startsWith('ng-')),
286
+ dataTestId: el.getAttribute('data-testid') || undefined,
287
+ dataCy: el.getAttribute('data-cy') || undefined,
288
+ name: el.getAttribute('name') || undefined,
289
+ type: el.getAttribute('type') || undefined,
290
+ placeholder: el.getAttribute('placeholder') || undefined,
291
+ text: el.textContent?.trim().slice(0, 50) || undefined,
292
+ href: el.href || undefined,
293
+ ariaLabel: el.getAttribute('aria-label') || undefined,
294
+ };
295
+ }
296
+ describeElement(info) {
297
+ if (info.dataTestId)
298
+ return `[data-testid="${info.dataTestId}"]`;
299
+ if (info.dataCy)
300
+ return `[data-cy="${info.dataCy}"]`;
301
+ if (info.id)
302
+ return `#${info.id}`;
303
+ if (info.ariaLabel)
304
+ return `"${info.ariaLabel}"`;
305
+ if (info.placeholder)
306
+ return `"${info.placeholder}" input`;
307
+ if (info.text)
308
+ return `"${info.text}"`;
309
+ return info.tagName;
310
+ }
311
+ // ─── Helpers ──────────────────────────────────────────────────────────────
312
+ shouldRecord(target) {
313
+ if (!this._isRecording() || this._isPaused())
314
+ return false;
315
+ if (!target)
316
+ return false;
317
+ // Ignore the debug panel itself
318
+ if (target.closest('[data-debug-panel]'))
319
+ return false;
320
+ return true;
321
+ }
322
+ addAction(partial) {
323
+ const action = {
324
+ id: this.generateId(),
325
+ timestamp: Date.now(),
326
+ url: window.location.href,
327
+ ...partial,
328
+ };
329
+ // Deduplicate consecutive identical inputs (keep only latest value)
330
+ if (action.type === 'input') {
331
+ this._currentSession.update(s => {
332
+ if (!s)
333
+ return s;
334
+ const last = s.actions[s.actions.length - 1];
335
+ if (last?.type === 'input' && last.selector === action.selector) {
336
+ return { ...s, actions: [...s.actions.slice(0, -1), action] };
337
+ }
338
+ return { ...s, actions: [...s.actions, action] };
339
+ });
340
+ return;
341
+ }
342
+ this._currentSession.update(s => s ? { ...s, actions: [...s.actions, action] } : s);
343
+ }
344
+ generateId() {
345
+ return Math.random().toString(36).slice(2, 11);
346
+ }
347
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RecorderService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); }
348
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RecorderService, providedIn: 'root' }); }
349
+ }
350
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RecorderService, decorators: [{
351
+ type: Injectable,
352
+ args: [{ providedIn: 'root' }]
353
+ }], ctorParameters: () => [{ type: i0.NgZone }] });
354
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2RlYnVnLXJlY29yZGVyL3NyYy9saWIvc2VydmljZXMvcmVjb3JkZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFVLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBSXJFLE1BQU0sT0FBTyxlQUFlO0lBZTFCLFlBQW9CLElBQVk7UUFBWixTQUFJLEdBQUosSUFBSSxDQUFRO1FBZHhCLGlCQUFZLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdCLG9CQUFlLEdBQUcsTUFBTSxDQUEwQixJQUFJLENBQUMsQ0FBQztRQUN4RCxjQUFTLEdBQUcsTUFBTSxDQUFxQixFQUFFLENBQUMsQ0FBQztRQUMzQyxjQUFTLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWxDLGdCQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQ2xELGFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDNUMsbUJBQWMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUM7UUFDeEQsYUFBUSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUM1QyxnQkFBVyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUUsT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQztRQUVsRSxjQUFTLEdBQStDLEVBQUUsQ0FBQztRQXdNM0QsbUJBQWMsR0FBRyxDQUFD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TUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgTmdab25lLCBzaWduYWwsIGNvbXB1dGVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFjdGlvblR5cGUsIEVsZW1lbnRJbmZvLCBSZWNvcmRlZEFjdGlvbiwgUmVjb3JkaW5nU2Vzc2lvbiB9IGZyb20gJy4uL21vZGVscy9yZWNvcmRlZC1hY3Rpb24ubW9kZWwnO1xyXG5cclxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcclxuZXhwb3J0IGNsYXNzIFJlY29yZGVyU2VydmljZSB7XHJcbiAgcHJpdmF0ZSBfaXNSZWNvcmRpbmcgPSBzaWduYWwoZmFsc2UpO1xyXG4gIHByaXZhdGUgX2N1cnJlbnRTZXNzaW9uID0gc2lnbmFsPFJlY29yZGluZ1Nlc3Npb24gfCBudWxsPihudWxsKTtcclxuICBwcml2YXRlIF9zZXNzaW9ucyA9IHNpZ25hbDxSZWNvcmRpbmdTZXNzaW9uW10+KFtdKTtcclxuICBwcml2YXRlIF9pc1BhdXNlZCA9IHNpZ25hbChmYWxzZSk7XHJcblxyXG4gIGlzUmVjb3JkaW5nID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5faXNSZWNvcmRpbmcoKSk7XHJcbiAgaXNQYXVzZWQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9pc1BhdXNlZCgpKTtcclxuICBjdXJyZW50U2Vzc2lvbiA9IGNvbXB1dGVkKCgpID0+IHRoaXMuX2N1cnJlbnRTZXNzaW9uKCkpO1xyXG4gIHNlc3Npb25zID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5fc2Vzc2lvbnMoKSk7XHJcbiAgYWN0aW9uQ291bnQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9jdXJyZW50U2Vzc2lvbigpPy5hY3Rpb25zLmxlbmd0aCA/PyAwKTtcclxuXHJcbiAgcHJpdmF0ZSBsaXN0ZW5lcnM6IEFycmF5PHsgdHlwZTogc3RyaW5nOyBmbjogRXZlbnRMaXN0ZW5lciB9PiA9IFtdO1xyXG4gIHByaXZhdGUgbXV0YXRpb25PYnNlcnZlcj86IE11dGF0aW9uT2JzZXJ2ZXI7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgem9uZTogTmdab25lKSB7fVxyXG5cclxuICBzdGFydFJlY29yZGluZyhuYW1lPzogc3RyaW5nLCBkZXNjcmlwdGlvbj86IHN0cmluZyk6IHZvaWQge1xyXG4gICAgY29uc3Qgc2Vzc2lvbjogUmVjb3JkaW5nU2Vzc2lvbiA9IHtcclxuICAgICAgaWQ6IHRoaXMuZ2VuZXJhdGVJZCgpLFxyXG4gICAgICBuYW1lOiBuYW1lIHx8IGBTZXNzaW9uICR7bmV3IERhdGUoKS50b0xvY2FsZVRpbWVTdHJpbmcoKX1gLFxyXG4gICAgICBkZXNjcmlwdGlvbixcclxuICAgICAgc3RhcnRUaW1lOiBEYXRlLm5vdygpLFxyXG4gICAgICBzdGFydFVybDogd2luZG93LmxvY2F0aW9uLmhyZWYsXHJcbiAgICAgIGFjdGlvbnM6IFtdLFxyXG4gICAgICB0YWdzOiBbXSxcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5fY3VycmVudFNlc3Npb24uc2V0KHNlc3Npb24pO1xyXG4gICAgdGhpcy5faXNSZWNvcmRpbmcuc2V0KHRydWUpO1xyXG4gICAgdGhpcy5faXNQYXVzZWQuc2V0KGZhbHNlKTtcclxuICAgIHRoaXMuYXR0YWNoTGlzdGVuZXJzKCk7XHJcbiAgICB0aGlzLnJlY29yZE5hdmlnYXRpb24oJ25hdmlnYXRpb24nLCB3aW5kb3cubG9jYXRpb24uaHJlZik7XHJcbiAgfVxyXG5cclxuICBzdG9wUmVjb3JkaW5nKCk6IFJlY29yZGluZ1Nlc3Npb24gfCBudWxsIHtcclxuICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLl9jdXJyZW50U2Vzc2lvbigpO1xyXG4gICAgaWYgKCFzZXNzaW9uKSByZXR1cm4gbnVsbDtcclxuXHJcbiAgICBjb25zdCBjb21wbGV0ZWQgPSB7IC4uLnNlc3Npb24sIGVuZFRpbWU6IERhdGUubm93KCkgfTtcclxuICAgIHRoaXMuX3Nlc3Npb25zLnVwZGF0ZShzID0+IFsuLi5zLCBjb21wbGV0ZWRdKTtcclxuICAgIHRoaXMuX2N1cnJlbnRTZXNzaW9uLnNldChudWxsKTtcclxuICAgIHRoaXMuX2lzUmVjb3JkaW5nLnNldChmYWxzZSk7XHJcbiAgICB0aGlzLl9pc1BhdXNlZC5zZXQoZmFsc2UpO1xyXG4gICAgdGhpcy5kZXRhY2hMaXN0ZW5lcnMoKTtcclxuICAgIHJldHVybiBjb21wbGV0ZWQ7XHJcbiAgfVxyXG5cclxuICBwYXVzZVJlY29yZGluZygpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLl9pc1JlY29yZGluZygpKSB7XHJcbiAgICAgIHRoaXMuX2lzUGF1c2VkLnNldCghdGhpcy5faXNQYXVzZWQoKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjbGVhckN1cnJlbnRTZXNzaW9uKCk6IHZvaWQge1xyXG4gICAgdGhpcy5fY3VycmVudFNlc3Npb24udXBkYXRlKHMgPT4gcyA/IHsgLi4ucywgYWN0aW9uczogW10gfSA6IG51bGwpO1xyXG4gIH1cclxuXHJcbiAgcmVtb3ZlQWN0aW9uKGFjdGlvbklkOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMuX2N1cnJlbnRTZXNzaW9uLnVwZGF0ZShzID0+XHJcbiAgICAgIHMgPyB7IC4uLnMsIGFjdGlvbnM6IHMuYWN0aW9ucy5maWx0ZXIoYSA9PiBhLmlkICE9PSBhY3Rpb25JZCkgfSA6IG51bGxcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBhZGROb3RlKGFjdGlvbklkOiBzdHJpbmcsIG5vdGU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy5fY3VycmVudFNlc3Npb24udXBkYXRlKHMgPT5cclxuICAgICAgcyA/IHtcclxuICAgICAgICAuLi5zLFxyXG4gICAgICAgIGFjdGlvbnM6IHMuYWN0aW9ucy5tYXAoYSA9PiBhLmlkID09PSBhY3Rpb25JZCA/IHsgLi4uYSwgbm90ZSB9IDogYSlcclxuICAgICAgfSA6IG51bGxcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBkZWxldGVTZXNzaW9uKHNlc3Npb25JZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICB0aGlzLl9zZXNzaW9ucy51cGRhdGUocyA9PiBzLmZpbHRlcih4ID0+IHguaWQgIT09IHNlc3Npb25JZCkpO1xyXG4gIH1cclxuXHJcbiAgbG9hZFNlc3Npb24oc2Vzc2lvbjogUmVjb3JkaW5nU2Vzc2lvbik6IHZvaWQge1xyXG4gICAgdGhpcy5fY3VycmVudFNlc3Npb24uc2V0KHNlc3Npb24pO1xyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSA4pSAIEV2ZW50IExpc3RlbmVycyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbiAgcHJpdmF0ZSBhdHRhY2hMaXN0ZW5lcnMoKTogdm9pZCB7XHJcbiAgICBjb25zdCBvcHRzID0geyBjYXB0dXJlOiB0cnVlLCBwYXNzaXZlOiB0cnVlIH07XHJcblxyXG4gICAgY29uc3Qgb25DbGljayA9IChlOiBNb3VzZUV2ZW50KSA9PiB0aGlzLnpvbmUucnVuKCgpID0+IHRoaXMuaGFuZGxlQ2xpY2soZSkpO1xyXG4gICAgY29uc3Qgb25EYmxDbGljayA9IChlOiBNb3VzZUV2ZW50KSA9PiB0aGlzLnpvbmUucnVuKCgpID0+IHRoaXMuaGFuZGxlRGJsQ2xpY2soZSkpO1xyXG4gICAgY29uc3Qgb25JbnB1dCA9IChlOiBFdmVudCkgPT4gdGhpcy56b25lLnJ1bigoKSA9PiB0aGlzLmhhbmRsZUlucHV0KGUpKTtcclxuICAgIGNvbnN0IG9uQ2hhbmdlID0gKGU6IEV2ZW50KSA9PiB0aGlzLnpvbmUucnVuKCgpID0+IHRoaXMuaGFuZGxlQ2hhbmdlKGUpKTtcclxuICAgIGNvbnN0IG9uU3VibWl0ID0gKGU6IFN1Ym1pdEV2ZW50KSA9PiB0aGlzLnpvbmUucnVuKCgpID0+IHRoaXMuaGFuZGxlU3VibWl0KGUpKTtcclxuICAgIGNvbnN0IG9uS2V5ZG93biA9IChlOiBLZXlib2FyZEV2ZW50KSA9PiB0aGlzLnpvbmUucnVuKCgpID0+IHRoaXMuaGFuZGxlS2V5ZG93bihlKSk7XHJcbiAgICBjb25zdCBvblNjcm9sbCA9IChlOiBFdmVudCkgPT4gdGhpcy56b25lLnJ1bigoKSA9PiB0aGlzLmhhbmRsZVNjcm9sbChlKSk7XHJcblxyXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvbkNsaWNrLCBvcHRzKTtcclxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RibGNsaWNrJywgb25EYmxDbGljaywgb3B0cyk7XHJcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIG9uSW5wdXQsIG9wdHMpO1xyXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgb25DaGFuZ2UsIG9wdHMpO1xyXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignc3VibWl0Jywgb25TdWJtaXQsIG9wdHMpO1xyXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5ZG93biwgb3B0cyk7XHJcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBvblNjcm9sbCwgeyBjYXB0dXJlOiB0cnVlLCBwYXNzaXZlOiB0cnVlIH0pO1xyXG5cclxuICAgIHRoaXMubGlzdGVuZXJzID0gW1xyXG4gICAgICB7IHR5cGU6ICdjbGljaycsIGZuOiBvbkNsaWNrIGFzIEV2ZW50TGlzdGVuZXIgfSxcclxuICAgICAgeyB0eXBlOiAnZGJsY2xpY2snLCBmbjogb25EYmxDbGljayBhcyBFdmVudExpc3RlbmVyIH0sXHJcbiAgICAgIHsgdHlwZTogJ2lucHV0JywgZm46IG9uSW5wdXQgYXMgRXZlbnRMaXN0ZW5lciB9LFxyXG4gICAgICB7IHR5cGU6ICdjaGFuZ2UnLCBmbjogb25DaGFuZ2UgYXMgRXZlbnRMaXN0ZW5lciB9LFxyXG4gICAgICB7IHR5cGU6ICdzdWJtaXQnLCBmbjogb25TdWJtaXQgYXMgRXZlbnRMaXN0ZW5lciB9LFxyXG4gICAgICB7IHR5cGU6ICdrZXlkb3duJywgZm46IG9uS2V5ZG93biBhcyBFdmVudExpc3RlbmVyIH0sXHJcbiAgICAgIHsgdHlwZTogJ3Njcm9sbCcsIGZuOiBvblNjcm9sbCBhcyBFdmVudExpc3RlbmVyIH0sXHJcbiAgICBdO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkZXRhY2hMaXN0ZW5lcnMoKTogdm9pZCB7XHJcbiAgICB0aGlzLmxpc3RlbmVycy5mb3JFYWNoKCh7IHR5cGUsIGZuIH0pID0+XHJcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgZm4sIHRydWUpXHJcbiAgICApO1xyXG4gICAgdGhpcy5saXN0ZW5lcnMgPSBbXTtcclxuICAgIHRoaXMubXV0YXRpb25PYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSA4pSAIEhhbmRsZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICBwcml2YXRlIGhhbmRsZUNsaWNrKGU6IE1vdXNlRXZlbnQpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5zaG91bGRSZWNvcmQoZS50YXJnZXQgYXMgRWxlbWVudCkpIHJldHVybjtcclxuICAgIGNvbnN0IGVsID0gZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBjb25zdCBpbmZvID0gdGhpcy5nZXRFbGVtZW50SW5mbyhlbCk7XHJcbiAgICBjb25zdCBzZWxlY3RvciA9IHRoaXMuYnVpbGRTZWxlY3RvcihlbCk7XHJcblxyXG4gICAgdGhpcy5hZGRBY3Rpb24oe1xyXG4gICAgICB0eXBlOiAnY2xpY2snLFxyXG4gICAgICBzZWxlY3RvcixcclxuICAgICAgc2VsZWN0b3JTdHJhdGVneTogdGhpcy5nZXRTZWxlY3RvclN0cmF0ZWd5KGVsKSxcclxuICAgICAgZWxlbWVudDogaW5mbyxcclxuICAgICAgZGVzY3JpcHRpb246IGBDbGljayBvbiAke3RoaXMuZGVzY3JpYmVFbGVtZW50KGluZm8pfWAsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGFuZGxlRGJsQ2xpY2soZTogTW91c2VFdmVudCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLnNob3VsZFJlY29yZChlLnRhcmdldCBhcyBFbGVtZW50KSkgcmV0dXJuO1xyXG4gICAgY29uc3QgZWwgPSBlLnRhcmdldCBhcyBIVE1MRWxlbWVudDtcclxuICAgIGNvbnN0IGluZm8gPSB0aGlzLmdldEVsZW1lbnRJbmZvKGVsKTtcclxuICAgIGNvbnN0IHNlbGVjdG9yID0gdGhpcy5idWlsZFNlbGVjdG9yKGVsKTtcclxuXHJcbiAgICB0aGlzLmFkZEFjdGlvbih7XHJcbiAgICAgIHR5cGU6ICdkYmxjbGljaycsXHJcbiAgICAgIHNlbGVjdG9yLFxyXG4gICAgICBzZWxlY3RvclN0cmF0ZWd5OiB0aGlzLmdldFNlbGVjdG9yU3RyYXRlZ3koZWwpLFxyXG4gICAgICBlbGVtZW50OiBpbmZvLFxyXG4gICAgICBkZXNjcmlwdGlvbjogYERvdWJsZS1jbGljayBvbiAke3RoaXMuZGVzY3JpYmVFbGVtZW50KGluZm8pfWAsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGFuZGxlSW5wdXQoZTogRXZlbnQpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5zaG91bGRSZWNvcmQoZS50YXJnZXQgYXMgRWxlbWVudCkpIHJldHVybjtcclxuICAgIGNvbnN0IGVsID0gZS50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCB8IEhUTUxUZXh0QXJlYUVsZW1lbnQ7XHJcbiAgICBpZiAoWydjaGVja2JveCcsICdyYWRpbyddLmluY2x1ZGVzKGVsLnR5cGUpKSByZXR1cm47IC8vIGhhbmRsZWQgYnkgY2hhbmdlXHJcbiAgICBjb25zdCBpbmZvID0gdGhpcy5nZXRFbGVtZW50SW5mbyhlbCk7XHJcbiAgICBjb25zdCBzZWxlY3RvciA9IHRoaXMuYnVpbGRTZWxlY3RvcihlbCk7XHJcblxyXG4gICAgdGhpcy5hZGRBY3Rpb24oe1xyXG4gICAgICB0eXBlOiAnaW5wdXQnLFxyXG4gICAgICBzZWxlY3RvcixcclxuICAgICAgc2VsZWN0b3JTdHJhdGVneTogdGhpcy5nZXRTZWxlY3RvclN0cmF0ZWd5KGVsKSxcclxuICAgICAgZWxlbWVudDogaW5mbyxcclxuICAgICAgdmFsdWU6IGVsLnZhbHVlLFxyXG4gICAgICBkZXNjcmlwdGlvbjogYFR5cGUgXCIke2VsLnZhbHVlfVwiIGluICR7dGhpcy5kZXNjcmliZUVsZW1lbnQoaW5mbyl9YCxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBoYW5kbGVDaGFuZ2UoZTogRXZlbnQpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5zaG91bGRSZWNvcmQoZS50YXJnZXQgYXMgRWxlbWVudCkpIHJldHVybjtcclxuICAgIGNvbnN0IGVsID0gZS50YXJnZXQgYXMgSFRNTFNlbGVjdEVsZW1lbnQgfCBIVE1MSW5wdXRFbGVtZW50O1xyXG4gICAgY29uc3QgaW5mbyA9IHRoaXMuZ2V0RWxlbWVudEluZm8oZWwpO1xyXG4gICAgY29uc3Qgc2VsZWN0b3IgPSB0aGlzLmJ1aWxkU2VsZWN0b3IoZWwpO1xyXG5cclxuICAgIGlmIChlbC50YWdOYW1lID09PSAnU0VMRUNUJykge1xyXG4gICAgICB0aGlzLmFkZEFjdGlvbih7XHJcbiAgICAgICAgdHlwZTogJ3NlbGVjdCcsXHJcbiAgICAgICAgc2VsZWN0b3IsXHJcbiAgICAgICAgc2VsZWN0b3JTdHJhdGVneTogdGhpcy5nZXRTZWxlY3RvclN0cmF0ZWd5KGVsKSxcclxuICAgICAgICBlbGVtZW50OiBpbmZvLFxyXG4gICAgICAgIHZhbHVlOiBlbC52YWx1ZSxcclxuICAgICAgICBkZXNjcmlwdGlvbjogYFNlbGVjdCBcIiR7ZWwudmFsdWV9XCIgaW4gJHt0aGlzLmRlc2NyaWJlRWxlbWVudChpbmZvKX1gLFxyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSBpZiAoKGVsIGFzIEhUTUxJbnB1dEVsZW1lbnQpLnR5cGUgPT09ICdjaGVja2JveCcpIHtcclxuICAgICAgdGhpcy5hZGRBY3Rpb24oe1xyXG4gICAgICAgIHR5cGU6ICdjbGljaycsXHJcbiAgICAgICAgc2VsZWN0b3IsXHJcbiAgICAgICAgc2VsZWN0b3JTdHJhdGVneTogdGhpcy5nZXRTZWxlY3RvclN0cmF0ZWd5KGVsKSxcclxuICAgICAgICBlbGVtZW50OiBpbmZvLFxyXG4gICAgICAgIHZhbHVlOiBTdHJpbmcoKGVsIGFzIEhUTUxJbnB1dEVsZW1lbnQpLmNoZWNrZWQpLFxyXG4gICAgICAgIGRlc2NyaXB0aW9uOiBgJHsoZWwgYXMgSFRNTElucHV0RWxlbWVudCkuY2hlY2tlZCA/ICdDaGVjaycgOiAnVW5jaGVjayd9ICR7dGhpcy5kZXNjcmliZUVsZW1lbnQoaW5mbyl9YCxcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGhhbmRsZVN1Ym1pdChlOiBTdWJtaXRFdmVudCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLnNob3VsZFJlY29yZChlLnRhcmdldCBhcyBFbGVtZW50KSkgcmV0dXJuO1xyXG4gICAgY29uc3QgZm9ybSA9IGUudGFyZ2V0IGFzIEhUTUxGb3JtRWxlbWVudDtcclxuICAgIGNvbnN0IGluZm8gPSB0aGlzLmdldEVsZW1lbnRJbmZvKGZvcm0pO1xyXG4gICAgY29uc3Qgc2VsZWN0b3IgPSB0aGlzLmJ1aWxkU2VsZWN0b3IoZm9ybSk7XHJcblxyXG4gICAgdGhpcy5hZGRBY3Rpb24oe1xyXG4gICAgICB0eXBlOiAnc3VibWl0JyxcclxuICAgICAgc2VsZWN0b3IsXHJcbiAgICAgIHNlbGVjdG9yU3RyYXRlZ3k6IHRoaXMuZ2V0U2VsZWN0b3JTdHJhdGVneShmb3JtKSxcclxuICAgICAgZWxlbWVudDogaW5mbyxcclxuICAgICAgZGVzY3JpcHRpb246IGBTdWJtaXQgZm9ybSAke2luZm8uaWQgPyAnIycgKyBpbmZvLmlkIDogaW5mby5uYW1lID8gaW5mby5uYW1lIDogJyd9YC50cmltKCksXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgbGFzdFNjcm9sbFRpbWUgPSAwO1xyXG4gIHByaXZhdGUgaGFuZGxlU2Nyb2xsKGU6IEV2ZW50KTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuc2hvdWxkUmVjb3JkKGUudGFyZ2V0IGFzIEVsZW1lbnQpKSByZXR1cm47XHJcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xyXG4gICAgaWYgKG5vdyAtIHRoaXMubGFzdFNjcm9sbFRpbWUgPCAxMDAwKSByZXR1cm47IC8vIGRlYm91bmNlIDFzXHJcbiAgICB0aGlzLmxhc3RTY3JvbGxUaW1lID0gbm93O1xyXG5cclxuICAgIGNvbnN0IGVsID0gZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBjb25zdCBpc0RvYyA9ICFlbC50YWdOYW1lIHx8IGVsLnRhZ05hbWUgPT09ICdIVE1MJztcclxuICAgIGNvbnN0IHNjcm9sbFkgPSBpc0RvYyA/IHdpbmRvdy5zY3JvbGxZIDogZWwuc2Nyb2xsVG9wO1xyXG4gICAgY29uc3Qgc2Nyb2xsWCA9IGlzRG9jID8gd2luZG93LnNjcm9sbFggOiBlbC5zY3JvbGxMZWZ0O1xyXG5cclxuICAgIGNvbnN0IHNlbGVjdG9yID0gZWwudGFnTmFtZSA9PT0gJ0hUTUwnIHx8IGVsLnRhZ05hbWUgPT09ICdCT0RZJ1xyXG4gICAgICA/ICd3aW5kb3cnXHJcbiAgICAgIDogdGhpcy5idWlsZFNlbGVjdG9yKGVsKTtcclxuXHJcbiAgICB0aGlzLmFkZEFjdGlvbih7XHJcbiAgICAgIHR5cGU6ICdzY3JvbGwnLFxyXG4gICAgICBzZWxlY3RvcixcclxuICAgICAgc2VsZWN0b3JTdHJhdGVneTogJ2NvbWJpbmVkJyxcclxuICAgICAgdmFsdWU6IGAke3Njcm9sbFh9LCR7c2Nyb2xsWX1gLFxyXG4gICAgICBkZXNjcmlwdGlvbjogYFNjcm9sbCB0byAoJHtzY3JvbGxYfSwgJHtzY3JvbGxZfSlgLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGhhbmRsZUtleWRvd24oZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xyXG4gICAgY29uc3Qgc3BlY2lhbEtleXMgPSBbJ0VudGVyJywgJ0VzY2FwZScsICdUYWInLCAnRjUnLCAnRjEyJ107XHJcbiAgICBpZiAoIXNwZWNpYWxLZXlzLmluY2x1ZGVzKGUua2V5KSkgcmV0dXJuO1xyXG4gICAgaWYgKCF0aGlzLnNob3VsZFJlY29yZChlLnRhcmdldCBhcyBFbGVtZW50KSkgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IGVsID0gZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBjb25zdCBzZWxlY3RvciA9IHRoaXMuYnVpbGRTZWxlY3RvcihlbCk7XHJcblxyXG4gICAgdGhpcy5hZGRBY3Rpb24oe1xyXG4gICAgICB0eXBlOiAna2V5cHJlc3MnLFxyXG4gICAgICBzZWxlY3RvcixcclxuICAgICAgc2VsZWN0b3JTdHJhdGVneTogdGhpcy5nZXRTZWxlY3RvclN0cmF0ZWd5KGVsKSxcclxuICAgICAgdmFsdWU6IGUua2V5LFxyXG4gICAgICBkZXNjcmlwdGlvbjogYFByZXNzIFwiJHtlLmtleX1cIiBvbiAke2VsLnRhZ05hbWUudG9Mb3dlckNhc2UoKX1gLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlY29yZE5hdmlnYXRpb24odHlwZTogQWN0aW9uVHlwZSwgbmF2VXJsOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGNvbnN0IGFjdGlvbjogUmVjb3JkZWRBY3Rpb24gPSB7XHJcbiAgICAgIGlkOiB0aGlzLmdlbmVyYXRlSWQoKSxcclxuICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxyXG4gICAgICB1cmw6IG5hdlVybCxcclxuICAgICAgdHlwZSxcclxuICAgICAgc2VsZWN0b3I6ICd3aW5kb3cnLFxyXG4gICAgICBzZWxlY3RvclN0cmF0ZWd5OiAnY29tYmluZWQnLFxyXG4gICAgICBkZXNjcmlwdGlvbjogYE5hdmlnYXRlIHRvICR7bmF2VXJsfWAsXHJcbiAgICB9O1xyXG4gICAgdGhpcy5fY3VycmVudFNlc3Npb24udXBkYXRlKHMgPT5cclxuICAgICAgcyA/IHsgLi4ucywgYWN0aW9uczogWy4uLnMuYWN0aW9ucywgYWN0aW9uXSB9IDogc1xyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8vIOKUgOKUgOKUgCBTZWxlY3RvciBCdWlsZGluZyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbiAgcHJpdmF0ZSBidWlsZFNlbGVjdG9yKGVsOiBIVE1MRWxlbWVudCk6IHN0cmluZyB7XHJcbiAgICAvLyBQcmlvcml0eTogZGF0YS10ZXN0aWQgPiBkYXRhLWN5ID4gaWQgPiBuYW1lID4gYXJpYS1sYWJlbCA+IGNvbWJpbmVkXHJcbiAgICBjb25zdCB0ZXN0SWQgPSBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdGVzdGlkJyk7XHJcbiAgICBpZiAodGVzdElkKSByZXR1cm4gYFtkYXRhLXRlc3RpZD1cIiR7dGVzdElkfVwiXWA7XHJcblxyXG4gICAgY29uc3QgY3kgPSBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY3knKTtcclxuICAgIGlmIChjeSkgcmV0dXJuIGBbZGF0YS1jeT1cIiR7Y3l9XCJdYDtcclxuXHJcbiAgICBpZiAoZWwuaWQgJiYgIWVsLmlkLmluY2x1ZGVzKCc6JykpIHJldHVybiBgIyR7ZWwuaWR9YDtcclxuXHJcbiAgICBjb25zdCBuYW1lID0gZWwuZ2V0QXR0cmlidXRlKCduYW1lJyk7XHJcbiAgICBpZiAobmFtZSkgcmV0dXJuIGAke2VsLnRhZ05hbWUudG9Mb3dlckNhc2UoKX1bbmFtZT1cIiR7bmFtZX1cIl1gO1xyXG5cclxuICAgIGNvbnN0IGFyaWFMYWJlbCA9IGVsLmdldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcpO1xyXG4gICAgaWYgKGFyaWFMYWJlbCkgcmV0dXJuIGBbYXJpYS1sYWJlbD1cIiR7YXJpYUxhYmVsfVwiXWA7XHJcblxyXG4gICAgLy8gQ2xhc3MtYmFzZWQgZmFsbGJhY2tcclxuICAgIGNvbnN0IHJlbGV2YW50Q2xhc3NlcyA9IEFycmF5LmZyb20oZWwuY2xhc3NMaXN0KVxyXG4gICAgICAuZmlsdGVyKGMgPT4gIWMuc3RhcnRzV2l0aCgnbmctJykgJiYgIWMuc3RhcnRzV2l0aCgnY2RrLScpICYmIGMubGVuZ3RoID4gMClcclxuICAgICAgLnNsaWNlKDAsIDMpO1xyXG4gICAgaWYgKHJlbGV2YW50Q2xhc3Nlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHJldHVybiBgJHtlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCl9LiR7cmVsZXZhbnRDbGFzc2VzLmpvaW4oJy4nKX1gO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFRleHQgY29udGVudCBmb3IgYnV0dG9ucy9saW5rc1xyXG4gICAgaWYgKFsnQlVUVE9OJywgJ0EnXS5pbmNsdWRlcyhlbC50YWdOYW1lKSkge1xyXG4gICAgICBjb25zdCB0ZXh0ID0gZWwudGV4dENvbnRlbnQ/LnRyaW0oKS5zbGljZSgwLCAzMCk7XHJcbiAgICAgIGlmICh0ZXh0KSByZXR1cm4gYCR7ZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpfTpjb250YWlucyhcIiR7dGV4dH1cIilgO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldFNlbGVjdG9yU3RyYXRlZ3koZWw6IEhUTUxFbGVtZW50KTogUmVjb3JkZWRBY3Rpb25bJ3NlbGVjdG9yU3RyYXRlZ3knXSB7XHJcbiAgICBpZiAoZWwuZ2V0QXR0cmlidXRlKCdkYXRhLXRlc3RpZCcpKSByZXR1cm4gJ2RhdGEtdGVzdGlkJztcclxuICAgIGlmIChlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY3knKSkgcmV0dXJuICdkYXRhLWN5JztcclxuICAgIGlmIChlbC5pZCkgcmV0dXJuICdpZCc7XHJcbiAgICBpZiAoZWwuZ2V0QXR0cmlidXRlKCduYW1lJykpIHJldHVybiAnbmFtZSc7XHJcbiAgICByZXR1cm4gJ2NsYXNzJztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0RWxlbWVudEluZm8oZWw6IEhUTUxFbGVtZW50KTogRWxlbWVudEluZm8ge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgdGFnTmFtZTogZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpLFxyXG4gICAgICBpZDogZWwuaWQgfHwgdW5kZWZpbmVkLFxyXG4gICAgICBjbGFzc2VzOiBBcnJheS5mcm9tKGVsLmNsYXNzTGlzdCkuZmlsdGVyKGMgPT4gIWMuc3RhcnRzV2l0aCgnbmctJykpLFxyXG4gICAgICBkYXRhVGVzdElkOiBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdGVzdGlkJykgfHwgdW5kZWZpbmVkLFxyXG4gICAgICBkYXRhQ3k6IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS1jeScpIHx8IHVuZGVmaW5lZCxcclxuICAgICAgbmFtZTogZWwuZ2V0QXR0cmlidXRlKCduYW1lJykgfHwgdW5kZWZpbmVkLFxyXG4gICAgICB0eXBlOiBlbC5nZXRBdHRyaWJ1dGUoJ3R5cGUnKSB8fCB1bmRlZmluZWQsXHJcbiAgICAgIHBsYWNlaG9sZGVyOiBlbC5nZXRBdHRyaWJ1dGUoJ3BsYWNlaG9sZGVyJykgfHwgdW5kZWZpbmVkLFxyXG4gICAgICB0ZXh0OiBlbC50ZXh0Q29udGVudD8udHJpbSgpLnNsaWNlKDAsIDUwKSB8fCB1bmRlZmluZWQsXHJcbiAgICAgIGhyZWY6IChlbCBhcyBIVE1MQW5jaG9yRWxlbWVudCkuaHJlZiB8fCB1bmRlZmluZWQsXHJcbiAgICAgIGFyaWFMYWJlbDogZWwuZ2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsJykgfHwgdW5kZWZpbmVkLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZGVzY3JpYmVFbGVtZW50KGluZm86IEVsZW1lbnRJbmZvKTogc3RyaW5nIHtcclxuICAgIGlmIChpbmZvLmRhdGFUZXN0SWQpIHJldHVybiBgW2RhdGEtdGVzdGlkPVwiJHtpbmZvLmRhdGFUZXN0SWR9XCJdYDtcclxuICAgIGlmIChpbmZvLmRhdGFDeSkgcmV0dXJuIGBbZGF0YS1jeT1cIiR7aW5mby5kYXRhQ3l9XCJdYDtcclxuICAgIGlmIChpbmZvLmlkKSByZXR1cm4gYCMke2luZm8uaWR9YDtcclxuICAgIGlmIChpbmZvLmFyaWFMYWJlbCkgcmV0dXJuIGBcIiR7aW5mby5hcmlhTGFiZWx9XCJgO1xyXG4gICAgaWYgKGluZm8ucGxhY2Vob2xkZXIpIHJldHVybiBgXCIke2luZm8ucGxhY2Vob2xkZXJ9XCIgaW5wdXRgO1xyXG4gICAgaWYgKGluZm8udGV4dCkgcmV0dXJuIGBcIiR7aW5mby50ZXh0fVwiYDtcclxuICAgIHJldHVybiBpbmZvLnRhZ05hbWU7XHJcbiAgfVxyXG5cclxuICAvLyDilIDilIDilIAgSGVscGVycyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbiAgcHJpdmF0ZSBzaG91bGRSZWNvcmQodGFyZ2V0OiBFbGVtZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKCF0aGlzLl9pc1JlY29yZGluZygpIHx8IHRoaXMuX2lzUGF1c2VkKCkpIHJldHVybiBmYWxzZTtcclxuICAgIGlmICghdGFyZ2V0KSByZXR1cm4gZmFsc2U7XHJcbiAgICAvLyBJZ25vcmUgdGhlIGRlYnVnIHBhbmVsIGl0c2VsZlxyXG4gICAgaWYgKHRhcmdldC5jbG9zZXN0KCdbZGF0YS1kZWJ1Zy1wYW5lbF0nKSkgcmV0dXJuIGZhbHNlO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFkZEFjdGlvbihwYXJ0aWFsOiBPbWl0PFJlY29yZGVkQWN0aW9uLCAnaWQnIHwgJ3RpbWVzdGFtcCcgfCAndXJsJz4pOiB2b2lkIHtcclxuICAgIGNvbnN0IGFjdGlvbjogUmVjb3JkZWRBY3Rpb24gPSB7XHJcbiAgICAgIGlkOiB0aGlzLmdlbmVyYXRlSWQoKSxcclxuICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxyXG4gICAgICB1cmw6IHdpbmRvdy5sb2NhdGlvbi5ocmVmLFxyXG4gICAgICAuLi5wYXJ0aWFsLFxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBEZWR1cGxpY2F0ZSBjb25zZWN1dGl2ZSBpZGVudGljYWwgaW5wdXRzIChrZWVwIG9ubHkgbGF0ZXN0IHZhbHVlKVxyXG4gICAgaWYgKGFjdGlvbi50eXBlID09PSAnaW5wdXQnKSB7XHJcbiAgICAgIHRoaXMuX2N1cnJlbnRTZXNzaW9uLnVwZGF0ZShzID0+IHtcclxuICAgICAgICBpZiAoIXMpIHJldHVybiBzO1xyXG4gICAgICAgIGNvbnN0IGxhc3QgPSBzLmFjdGlvbnNbcy5hY3Rpb25zLmxlbmd0aCAtIDFdO1xyXG4gICAgICAgIGlmIChsYXN0Py50eXBlID09PSAnaW5wdXQnICYmIGxhc3Quc2VsZWN0b3IgPT09IGFjdGlvbi5zZWxlY3Rvcikge1xyXG4gICAgICAgICAgcmV0dXJuIHsgLi4ucywgYWN0aW9uczogWy4uLnMuYWN0aW9ucy5zbGljZSgwLCAtMSksIGFjdGlvbl0gfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHsgLi4ucywgYWN0aW9uczogWy4uLnMuYWN0aW9ucywgYWN0aW9uXSB9O1xyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2N1cnJlbnRTZXNzaW9uLnVwZGF0ZShzID0+XHJcbiAgICAgIHMgPyB7IC4uLnMsIGFjdGlvbnM6IFsuLi5zLmFjdGlvbnMsIGFjdGlvbl0gfSA6IHNcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdlbmVyYXRlSWQoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCAxMSk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
@@ -0,0 +1,108 @@
1
+ import { Injectable, signal } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export class RrwebRecorderService {
4
+ constructor(zone) {
5
+ this.zone = zone;
6
+ this._events = signal([]);
7
+ this._isRecording = signal(false);
8
+ this.events = this._events.asReadonly();
9
+ this.isRecording = this._isRecording.asReadonly();
10
+ }
11
+ async startRecording() {
12
+ // Dynamically import rrweb to avoid SSR issues and reduce initial bundle
13
+ const { record } = await import('rrweb');
14
+ this._events.set([]);
15
+ this._isRecording.set(true);
16
+ this.stopFn = record({
17
+ emit: (event) => {
18
+ this.zone.run(() => {
19
+ this._events.update(ev => [...ev, event]);
20
+ });
21
+ },
22
+ // Note: blockSelector is omitted — rrweb 2.0.0-alpha.4 calls node.matches()
23
+ // on TextNodes/CommentNodes which don't have that method, crashing the recorder.
24
+ maskTextSelector: 'input[type="password"]',
25
+ checkoutEveryNth: 200,
26
+ });
27
+ }
28
+ stopRecording() {
29
+ if (this.stopFn) {
30
+ this.stopFn();
31
+ this.stopFn = undefined;
32
+ }
33
+ this._isRecording.set(false);
34
+ return this._events();
35
+ }
36
+ getEvents() {
37
+ return this._events();
38
+ }
39
+ clearEvents() {
40
+ this._events.set([]);
41
+ }
42
+ hasEvents() {
43
+ return this._events().length > 0;
44
+ }
45
+ // ─── Replay ──────────────────────────────────────────────────────────────
46
+ async startReplay(container, events) {
47
+ const { Replayer } = await import('rrweb');
48
+ const eventsToReplay = events ?? this._events();
49
+ if (eventsToReplay.length === 0)
50
+ return;
51
+ // Destroy previous replayer
52
+ this.destroyReplayer();
53
+ this.replayer = new Replayer(eventsToReplay, {
54
+ root: container,
55
+ skipInactive: true,
56
+ showWarning: false,
57
+ showDebug: false,
58
+ blockClass: 'debug-panel',
59
+ });
60
+ this.replayer.play();
61
+ }
62
+ pauseReplay() {
63
+ this.replayer?.pause();
64
+ }
65
+ resumeReplay() {
66
+ this.replayer?.play();
67
+ }
68
+ destroyReplayer() {
69
+ if (this.replayer) {
70
+ try {
71
+ this.replayer.pause();
72
+ }
73
+ catch { }
74
+ this.replayer = undefined;
75
+ }
76
+ }
77
+ // ─── Export ───────────────────────────────────────────────────────────────
78
+ exportEvents() {
79
+ return JSON.stringify(this._events(), null, 2);
80
+ }
81
+ downloadEvents(filename = 'rrweb-session.json') {
82
+ const blob = new Blob([this.exportEvents()], { type: 'application/json' });
83
+ const url = URL.createObjectURL(blob);
84
+ const a = document.createElement('a');
85
+ a.href = url;
86
+ a.download = filename;
87
+ a.click();
88
+ URL.revokeObjectURL(url);
89
+ }
90
+ importEvents(json) {
91
+ try {
92
+ const events = JSON.parse(json);
93
+ this._events.set(events);
94
+ return events;
95
+ }
96
+ catch {
97
+ console.error('Invalid rrweb events JSON');
98
+ return [];
99
+ }
100
+ }
101
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RrwebRecorderService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); }
102
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RrwebRecorderService, providedIn: 'root' }); }
103
+ }
104
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RrwebRecorderService, decorators: [{
105
+ type: Injectable,
106
+ args: [{ providedIn: 'root' }]
107
+ }], ctorParameters: () => [{ type: i0.NgZone }] });
108
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnJ3ZWItcmVjb3JkZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2RlYnVnLXJlY29yZGVyL3NyYy9saWIvc2VydmljZXMvcnJ3ZWItcmVjb3JkZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFJM0QsTUFBTSxPQUFPLG9CQUFvQjtJQVMvQixZQUFvQixJQUFZO1FBQVosU0FBSSxHQUFKLElBQUksQ0FBUTtRQVJ4QixZQUFPLEdBQUcsTUFBTSxDQUFrQixFQUFFLENBQUMsQ0FBQztRQUN0QyxpQkFBWSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUlyQyxXQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNuQyxnQkFBVyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLENBQUM7SUFFVixDQUFDO0lBRXBDLEtBQUssQ0FBQyxjQUFjO1FBQ2xCLHlFQUF5RTtRQUN6RSxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDckIsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFNUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7WUFDbkIsSUFBSSxFQUFFLENBQUMsS0FBb0IsRUFBRSxFQUFFO2dCQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7b0JBQ2pCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxLQUFLLENBQUMs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UUFDdEIsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1YsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQsWUFBWSxDQUFDLElBQVk7UUFDdkIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQW9CLENBQUM7WUFDbkQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDekIsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztZQUMzQyxPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUM7SUFDSCxDQUFDOytHQWpIVSxvQkFBb0I7bUhBQXBCLG9CQUFvQixjQURQLE1BQU07OzRGQUNuQixvQkFBb0I7a0JBRGhDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgTmdab25lLCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHR5cGUgeyBldmVudFdpdGhUaW1lIH0gZnJvbSAnQHJyd2ViL3R5cGVzJztcclxuXHJcbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbmV4cG9ydCBjbGFzcyBScndlYlJlY29yZGVyU2VydmljZSB7XHJcbiAgcHJpdmF0ZSBfZXZlbnRzID0gc2lnbmFsPGV2ZW50V2l0aFRpbWVbXT4oW10pO1xyXG4gIHByaXZhdGUgX2lzUmVjb3JkaW5nID0gc2lnbmFsKGZhbHNlKTtcclxuICBwcml2YXRlIHN0b3BGbj86ICgpID0+IHZvaWQ7XHJcbiAgcHJpdmF0ZSByZXBsYXllcj86IGFueTtcclxuXHJcbiAgZXZlbnRzID0gdGhpcy5fZXZlbnRzLmFzUmVhZG9ubHkoKTtcclxuICBpc1JlY29yZGluZyA9IHRoaXMuX2lzUmVjb3JkaW5nLmFzUmVhZG9ubHkoKTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB6b25lOiBOZ1pvbmUpIHt9XHJcblxyXG4gIGFzeW5jIHN0YXJ0UmVjb3JkaW5nKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgLy8gRHluYW1pY2FsbHkgaW1wb3J0IHJyd2ViIHRvIGF2b2lkIFNTUiBpc3N1ZXMgYW5kIHJlZHVjZSBpbml0aWFsIGJ1bmRsZVxyXG4gICAgY29uc3QgeyByZWNvcmQgfSA9IGF3YWl0IGltcG9ydCgncnJ3ZWInKTtcclxuICAgIHRoaXMuX2V2ZW50cy5zZXQoW10pO1xyXG4gICAgdGhpcy5faXNSZWNvcmRpbmcuc2V0KHRydWUpO1xyXG5cclxuICAgIHRoaXMuc3RvcEZuID0gcmVjb3JkKHtcclxuICAgICAgZW1pdDogKGV2ZW50OiBldmVudFdpdGhUaW1lKSA9PiB7XHJcbiAgICAgICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLl9ldmVudHMudXBkYXRlKGV2ID0+IFsuLi5ldiwgZXZlbnRdKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSxcclxuICAgICAgLy8gTm90ZTogYmxvY2tTZWxlY3RvciBpcyBvbWl0dGVkIOKAlCBycndlYiAyLjAuMC1hbHBoYS40IGNhbGxzIG5vZGUubWF0Y2hlcygpXHJcbiAgICAgIC8vIG9uIFRleHROb2Rlcy9Db21tZW50Tm9kZXMgd2hpY2ggZG9uJ3QgaGF2ZSB0aGF0IG1ldGhvZCwgY3Jhc2hpbmcgdGhlIHJlY29yZGVyLlxyXG4gICAgICBtYXNrVGV4dFNlbGVjdG9yOiAnaW5wdXRbdHlwZT1cInBhc3N3b3JkXCJdJyxcclxuICAgICAgY2hlY2tvdXRFdmVyeU50aDogMjAwLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBzdG9wUmVjb3JkaW5nKCk6IGV2ZW50V2l0aFRpbWVbXSB7XHJcbiAgICBpZiAodGhpcy5zdG9wRm4pIHtcclxuICAgICAgdGhpcy5zdG9wRm4oKTtcclxuICAgICAgdGhpcy5zdG9wRm4gPSB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9pc1JlY29yZGluZy5zZXQoZmFsc2UpO1xyXG4gICAgcmV0dXJuIHRoaXMuX2V2ZW50cygpO1xyXG4gIH1cclxuXHJcbiAgZ2V0RXZlbnRzKCk6IGV2ZW50V2l0aFRpbWVbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5fZXZlbnRzKCk7XHJcbiAgfVxyXG5cclxuICBjbGVhckV2ZW50cygpOiB2b2lkIHtcclxuICAgIHRoaXMuX2V2ZW50cy5zZXQoW10pO1xyXG4gIH1cclxuXHJcbiAgaGFzRXZlbnRzKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2V2ZW50cygpLmxlbmd0aCA+IDA7XHJcbiAgfVxyXG5cclxuICAvLyDilIDilIDilIAgUmVwbGF5IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICBhc3luYyBzdGFydFJlcGxheShjb250YWluZXI6IEhUTUxFbGVtZW50LCBldmVudHM/OiBldmVudFdpdGhUaW1lW10pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IHsgUmVwbGF5ZXIgfSA9IGF3YWl0IGltcG9ydCgncnJ3ZWInKTtcclxuICAgIGNvbnN0IGV2ZW50c1RvUmVwbGF5ID0gZXZlbnRzID8/IHRoaXMuX2V2ZW50cygpO1xyXG5cclxuICAgIGlmIChldmVudHNUb1JlcGxheS5sZW5ndGggPT09IDApIHJldHVybjtcclxuXHJcbiAgICAvLyBEZXN0cm95IHByZXZpb3VzIHJlcGxheWVyXHJcbiAgICB0aGlzLmRlc3Ryb3lSZXBsYXllcigpO1xyXG5cclxuICAgIHRoaXMucmVwbGF5ZXIgPSBuZXcgUmVwbGF5ZXIoZXZlbnRzVG9SZXBsYXksIHtcclxuICAgICAgcm9vdDogY29udGFpbmVyLFxyXG4gICAgICBza2lwSW5hY3RpdmU6IHRydWUsXHJcbiAgICAgIHNob3dXYXJuaW5nOiBmYWxzZSxcclxuICAgICAgc2hvd0RlYnVnOiBmYWxzZSxcclxuICAgICAgYmxvY2tDbGFzczogJ2RlYnVnLXBhbmVsJyxcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMucmVwbGF5ZXIucGxheSgpO1xyXG4gIH1cclxuXHJcbiAgcGF1c2VSZXBsYXkoKTogdm9pZCB7XHJcbiAgICB0aGlzLnJlcGxheWVyPy5wYXVzZSgpO1xyXG4gIH1cclxuXHJcbiAgcmVzdW1lUmVwbGF5KCk6IHZvaWQge1xyXG4gICAgdGhpcy5yZXBsYXllcj8ucGxheSgpO1xyXG4gIH1cclxuXHJcbiAgZGVzdHJveVJlcGxheWVyKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMucmVwbGF5ZXIpIHtcclxuICAgICAgdHJ5IHsgdGhpcy5yZXBsYXllci5wYXVzZSgpOyB9IGNhdGNoIHt9XHJcbiAgICAgIHRoaXMucmVwbGF5ZXIgPSB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyDilIDilIDilIAgRXhwb3J0IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICBleHBvcnRFdmVudHMoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLl9ldmVudHMoKSwgbnVsbCwgMik7XHJcbiAgfVxyXG5cclxuICBkb3dubG9hZEV2ZW50cyhmaWxlbmFtZSA9ICdycndlYi1zZXNzaW9uLmpzb24nKTogdm9pZCB7XHJcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3RoaXMuZXhwb3J0RXZlbnRzKCldLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyB9KTtcclxuICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XHJcbiAgICBjb25zdCBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xyXG4gICAgYS5ocmVmID0gdXJsO1xyXG4gICAgYS5kb3dubG9hZCA9IGZpbGVuYW1lO1xyXG4gICAgYS5jbGljaygpO1xyXG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xyXG4gIH1cclxuXHJcbiAgaW1wb3J0RXZlbnRzKGpzb246IHN0cmluZyk6IGV2ZW50V2l0aFRpbWVbXSB7XHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCBldmVudHMgPSBKU09OLnBhcnNlKGpzb24pIGFzIGV2ZW50V2l0aFRpbWVbXTtcclxuICAgICAgdGhpcy5fZXZlbnRzLnNldChldmVudHMpO1xyXG4gICAgICByZXR1cm4gZXZlbnRzO1xyXG4gICAgfSBjYXRjaCB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgcnJ3ZWIgZXZlbnRzIEpTT04nKTtcclxuICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iXX0=