@notectl/angular 0.0.2

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.
package/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # @notectl/angular
2
+
3
+ Angular adapter for NotectlEditor - a framework-agnostic rich text editor built on Web Components.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @notectl/angular @notectl/core
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Import Module
14
+
15
+ ```typescript
16
+ import { NgModule } from '@angular/core';
17
+ import { BrowserModule } from '@angular/platform-browser';
18
+ import { NotectlEditorModule } from '@notectl/angular';
19
+ import { AppComponent } from './app.component';
20
+
21
+ @NgModule({
22
+ declarations: [AppComponent],
23
+ imports: [
24
+ BrowserModule,
25
+ NotectlEditorModule
26
+ ],
27
+ providers: [],
28
+ bootstrap: [AppComponent]
29
+ })
30
+ export class AppModule { }
31
+ ```
32
+
33
+ ### Component Usage
34
+
35
+ ```typescript
36
+ import { Component } from '@angular/core';
37
+ import type { EditorAPI } from '@notectl/core';
38
+
39
+ @Component({
40
+ selector: 'app-root',
41
+ template: `
42
+ <notectl-editor
43
+ [content]="content"
44
+ [placeholder]="'Start writing...'"
45
+ [readOnly]="false"
46
+ (contentChange)="onContentChange($event)"
47
+ (ready)="onReady($event)"
48
+ ></notectl-editor>
49
+ `
50
+ })
51
+ export class AppComponent {
52
+ content = { type: 'doc', content: [] };
53
+
54
+ onContentChange(content: unknown): void {
55
+ console.log('Content changed:', content);
56
+ }
57
+
58
+ onReady(editor: EditorAPI): void {
59
+ console.log('Editor ready:', editor);
60
+ }
61
+ }
62
+ ```
63
+
64
+ ### Reactive Forms Integration
65
+
66
+ ```typescript
67
+ import { Component } from '@angular/core';
68
+ import { FormControl, FormGroup } from '@angular/forms';
69
+
70
+ @Component({
71
+ selector: 'app-editor-form',
72
+ template: `
73
+ <form [formGroup]="form">
74
+ <notectl-editor formControlName="content"></notectl-editor>
75
+ </form>
76
+ `
77
+ })
78
+ export class EditorFormComponent {
79
+ form = new FormGroup({
80
+ content: new FormControl(null)
81
+ });
82
+ }
83
+ ```
84
+
85
+ ### Directive Usage
86
+
87
+ ```typescript
88
+ import { Component } from '@angular/core';
89
+
90
+ @Component({
91
+ selector: 'app-editor',
92
+ template: `
93
+ <div
94
+ notectl-editor
95
+ [content]="content"
96
+ (contentChange)="onContentChange($event)"
97
+ ></div>
98
+ `
99
+ })
100
+ export class EditorComponent {
101
+ content = { type: 'doc', content: [] };
102
+
103
+ onContentChange(content: unknown): void {
104
+ console.log('Content changed:', content);
105
+ }
106
+ }
107
+ ```
108
+
109
+ ## API
110
+
111
+ ### Component Props
112
+
113
+ - `debug?: boolean` - Enable debug mode
114
+ - `content?: string | object` - Initial editor content
115
+ - `placeholder?: string` - Placeholder text
116
+ - `readOnly?: boolean` - Read-only mode
117
+ - `accessibility?: object` - Accessibility configuration
118
+ - `i18n?: object` - Internationalization settings
119
+ - `theme?: object` - Theme configuration
120
+
121
+ ### Component Events
122
+
123
+ - `contentChange: EventEmitter<unknown>` - Emitted when content changes
124
+ - `selectionChange: EventEmitter<unknown>` - Emitted when selection changes
125
+ - `editorFocus: EventEmitter<void>` - Emitted when editor gains focus
126
+ - `editorBlur: EventEmitter<void>` - Emitted when editor loses focus
127
+ - `ready: EventEmitter<EditorAPI>` - Emitted when editor is ready
128
+ - `error: EventEmitter<Error>` - Emitted when an error occurs
129
+
130
+ ### Component Methods
131
+
132
+ - `getContent(): unknown` - Get current content
133
+ - `setContent(content: unknown): void` - Set content
134
+ - `getState(): unknown` - Get editor state
135
+ - `executeCommand(command: string, ...args: unknown[]): void` - Execute command
136
+ - `registerPlugin(plugin: unknown): void` - Register a plugin
137
+ - `unregisterPlugin(pluginId: string): void` - Unregister a plugin
138
+
139
+ ## License
140
+
141
+ MIT
package/dist/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # @notectl/angular
2
+
3
+ Angular adapter for NotectlEditor - a framework-agnostic rich text editor built on Web Components.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @notectl/angular @notectl/core
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Import Module
14
+
15
+ ```typescript
16
+ import { NgModule } from '@angular/core';
17
+ import { BrowserModule } from '@angular/platform-browser';
18
+ import { NotectlEditorModule } from '@notectl/angular';
19
+ import { AppComponent } from './app.component';
20
+
21
+ @NgModule({
22
+ declarations: [AppComponent],
23
+ imports: [
24
+ BrowserModule,
25
+ NotectlEditorModule
26
+ ],
27
+ providers: [],
28
+ bootstrap: [AppComponent]
29
+ })
30
+ export class AppModule { }
31
+ ```
32
+
33
+ ### Component Usage
34
+
35
+ ```typescript
36
+ import { Component } from '@angular/core';
37
+ import type { EditorAPI } from '@notectl/core';
38
+
39
+ @Component({
40
+ selector: 'app-root',
41
+ template: `
42
+ <notectl-editor
43
+ [content]="content"
44
+ [placeholder]="'Start writing...'"
45
+ [readOnly]="false"
46
+ (contentChange)="onContentChange($event)"
47
+ (ready)="onReady($event)"
48
+ ></notectl-editor>
49
+ `
50
+ })
51
+ export class AppComponent {
52
+ content = { type: 'doc', content: [] };
53
+
54
+ onContentChange(content: unknown): void {
55
+ console.log('Content changed:', content);
56
+ }
57
+
58
+ onReady(editor: EditorAPI): void {
59
+ console.log('Editor ready:', editor);
60
+ }
61
+ }
62
+ ```
63
+
64
+ ### Reactive Forms Integration
65
+
66
+ ```typescript
67
+ import { Component } from '@angular/core';
68
+ import { FormControl, FormGroup } from '@angular/forms';
69
+
70
+ @Component({
71
+ selector: 'app-editor-form',
72
+ template: `
73
+ <form [formGroup]="form">
74
+ <notectl-editor formControlName="content"></notectl-editor>
75
+ </form>
76
+ `
77
+ })
78
+ export class EditorFormComponent {
79
+ form = new FormGroup({
80
+ content: new FormControl(null)
81
+ });
82
+ }
83
+ ```
84
+
85
+ ### Directive Usage
86
+
87
+ ```typescript
88
+ import { Component } from '@angular/core';
89
+
90
+ @Component({
91
+ selector: 'app-editor',
92
+ template: `
93
+ <div
94
+ notectl-editor
95
+ [content]="content"
96
+ (contentChange)="onContentChange($event)"
97
+ ></div>
98
+ `
99
+ })
100
+ export class EditorComponent {
101
+ content = { type: 'doc', content: [] };
102
+
103
+ onContentChange(content: unknown): void {
104
+ console.log('Content changed:', content);
105
+ }
106
+ }
107
+ ```
108
+
109
+ ## API
110
+
111
+ ### Component Props
112
+
113
+ - `debug?: boolean` - Enable debug mode
114
+ - `content?: string | object` - Initial editor content
115
+ - `placeholder?: string` - Placeholder text
116
+ - `readOnly?: boolean` - Read-only mode
117
+ - `accessibility?: object` - Accessibility configuration
118
+ - `i18n?: object` - Internationalization settings
119
+ - `theme?: object` - Theme configuration
120
+
121
+ ### Component Events
122
+
123
+ - `contentChange: EventEmitter<unknown>` - Emitted when content changes
124
+ - `selectionChange: EventEmitter<unknown>` - Emitted when selection changes
125
+ - `editorFocus: EventEmitter<void>` - Emitted when editor gains focus
126
+ - `editorBlur: EventEmitter<void>` - Emitted when editor loses focus
127
+ - `ready: EventEmitter<EditorAPI>` - Emitted when editor is ready
128
+ - `error: EventEmitter<Error>` - Emitted when an error occurs
129
+
130
+ ### Component Methods
131
+
132
+ - `getContent(): unknown` - Get current content
133
+ - `setContent(content: unknown): void` - Set content
134
+ - `getState(): unknown` - Get editor state
135
+ - `executeCommand(command: string, ...args: unknown[]): void` - Execute command
136
+ - `registerPlugin(plugin: unknown): void` - Register a plugin
137
+ - `unregisterPlugin(pluginId: string): void` - Unregister a plugin
138
+
139
+ ## License
140
+
141
+ MIT
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @notectl/angular - Angular adapter for NotectlEditor
3
+ * @packageDocumentation
4
+ */
5
+ export * from './public-api';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBub3RlY3RsL2FuZ3VsYXIgLSBBbmd1bGFyIGFkYXB0ZXIgZm9yIE5vdGVjdGxFZGl0b3JcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG4iXX0=
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Angular component wrapper for NotectlEditor
3
+ */
4
+ import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, forwardRef, } from '@angular/core';
5
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
6
+ import * as i0 from "@angular/core";
7
+ /**
8
+ * NotectlEditor Angular component
9
+ */
10
+ export class NotectlEditorComponent {
11
+ containerRef;
12
+ /** Debug mode */
13
+ debug;
14
+ /** Initial content */
15
+ content;
16
+ /** Placeholder text */
17
+ placeholder;
18
+ /** Read-only mode */
19
+ readOnly;
20
+ /** Accessibility configuration */
21
+ accessibility;
22
+ /** Internationalization configuration */
23
+ i18n;
24
+ /** Theme configuration */
25
+ theme;
26
+ /** Custom class name */
27
+ className;
28
+ /** Emitted when content changes */
29
+ contentChange = new EventEmitter();
30
+ /** Emitted when selection changes */
31
+ selectionChange = new EventEmitter();
32
+ /** Emitted when editor gains focus */
33
+ editorFocus = new EventEmitter();
34
+ /** Emitted when editor loses focus */
35
+ editorBlur = new EventEmitter();
36
+ /** Emitted when editor is ready */
37
+ ready = new EventEmitter();
38
+ /** Emitted when an error occurs */
39
+ error = new EventEmitter();
40
+ editor = null;
41
+ onChange = () => { };
42
+ onTouched = () => { };
43
+ ngOnInit() {
44
+ this.initEditor();
45
+ }
46
+ ngOnDestroy() {
47
+ this.destroyEditor();
48
+ }
49
+ /**
50
+ * Initialize the editor instance
51
+ */
52
+ initEditor() {
53
+ if (!this.containerRef?.nativeElement) {
54
+ console.error('NotectlEditor: Container element not found');
55
+ return;
56
+ }
57
+ // Create editor instance
58
+ this.editor = document.createElement('notectl-editor');
59
+ // Configure editor
60
+ const config = {
61
+ debug: this.debug,
62
+ content: this.content,
63
+ placeholder: this.placeholder,
64
+ readOnly: this.readOnly,
65
+ accessibility: this.accessibility,
66
+ i18n: this.i18n,
67
+ theme: this.theme,
68
+ };
69
+ this.editor.configure(config);
70
+ // Attach event listeners
71
+ this.editor.on('content-change', (data) => {
72
+ const eventData = data;
73
+ const content = eventData.content;
74
+ this.contentChange.emit(content);
75
+ this.onChange(content);
76
+ });
77
+ this.editor.on('selection-change', (data) => {
78
+ const eventData = data;
79
+ this.selectionChange.emit(eventData.selection);
80
+ });
81
+ this.editor.on('focus', () => {
82
+ this.editorFocus.emit();
83
+ this.onTouched();
84
+ });
85
+ this.editor.on('blur', () => {
86
+ this.editorBlur.emit();
87
+ });
88
+ this.editor.on('ready', () => {
89
+ this.ready.emit(this.getEditorAPI());
90
+ });
91
+ this.editor.on('error', (data) => {
92
+ const eventData = data;
93
+ if (eventData.error) {
94
+ this.error.emit(eventData.error);
95
+ }
96
+ });
97
+ // Mount editor
98
+ this.containerRef.nativeElement.appendChild(this.editor);
99
+ }
100
+ /**
101
+ * Destroy the editor instance
102
+ */
103
+ destroyEditor() {
104
+ if (this.editor) {
105
+ this.editor.destroy();
106
+ if (this.containerRef?.nativeElement?.contains(this.editor)) {
107
+ this.containerRef.nativeElement.removeChild(this.editor);
108
+ }
109
+ this.editor = null;
110
+ }
111
+ }
112
+ /**
113
+ * Update editor configuration
114
+ */
115
+ updateConfig() {
116
+ if (!this.editor)
117
+ return;
118
+ const config = {
119
+ debug: this.debug,
120
+ content: this.content,
121
+ placeholder: this.placeholder,
122
+ readOnly: this.readOnly,
123
+ accessibility: this.accessibility,
124
+ i18n: this.i18n,
125
+ theme: this.theme,
126
+ };
127
+ this.editor.configure(config);
128
+ }
129
+ /**
130
+ * Get editor API
131
+ */
132
+ getEditorAPI() {
133
+ if (!this.editor) {
134
+ throw new Error('Editor not initialized');
135
+ }
136
+ return this.editor;
137
+ }
138
+ // ControlValueAccessor implementation
139
+ writeValue(value) {
140
+ if (this.editor && typeof value === 'string') {
141
+ this.editor.setContent(value);
142
+ }
143
+ }
144
+ registerOnChange(fn) {
145
+ this.onChange = fn;
146
+ }
147
+ registerOnTouched(fn) {
148
+ this.onTouched = fn;
149
+ }
150
+ setDisabledState(isDisabled) {
151
+ if (this.editor) {
152
+ this.editor.configure({ readOnly: isDisabled });
153
+ }
154
+ }
155
+ // Public API methods
156
+ /**
157
+ * Get current editor content
158
+ */
159
+ getContent() {
160
+ return this.editor?.getContent();
161
+ }
162
+ /**
163
+ * Set editor content
164
+ */
165
+ setContent(content) {
166
+ if (this.editor && typeof content === 'string') {
167
+ this.editor.setContent(content);
168
+ }
169
+ }
170
+ /**
171
+ * Get current editor state
172
+ */
173
+ getState() {
174
+ return this.editor?.getState();
175
+ }
176
+ /**
177
+ * Execute an editor command
178
+ */
179
+ executeCommand(command, ...args) {
180
+ this.editor?.executeCommand(command, ...args);
181
+ }
182
+ /**
183
+ * Register a plugin
184
+ */
185
+ registerPlugin(plugin) {
186
+ this.editor?.registerPlugin(plugin);
187
+ }
188
+ /**
189
+ * Unregister a plugin
190
+ */
191
+ unregisterPlugin(pluginId) {
192
+ this.editor?.unregisterPlugin(pluginId);
193
+ }
194
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NotectlEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
195
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: NotectlEditorComponent, selector: "notectl-editor", inputs: { debug: "debug", content: "content", placeholder: "placeholder", readOnly: "readOnly", accessibility: "accessibility", i18n: "i18n", theme: "theme", className: "className" }, outputs: { contentChange: "contentChange", selectionChange: "selectionChange", editorFocus: "editorFocus", editorBlur: "editorBlur", ready: "ready", error: "error" }, providers: [
196
+ {
197
+ provide: NG_VALUE_ACCESSOR,
198
+ useExisting: forwardRef(() => NotectlEditorComponent),
199
+ multi: true,
200
+ },
201
+ ], viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }], ngImport: i0, template: '<div #container [attr.data-notectl-angular-wrapper]="true"></div>', isInline: true, styles: [":host{display:block}\n"], encapsulation: i0.ViewEncapsulation.None });
202
+ }
203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NotectlEditorComponent, decorators: [{
204
+ type: Component,
205
+ args: [{ selector: 'notectl-editor', template: '<div #container [attr.data-notectl-angular-wrapper]="true"></div>', encapsulation: ViewEncapsulation.None, providers: [
206
+ {
207
+ provide: NG_VALUE_ACCESSOR,
208
+ useExisting: forwardRef(() => NotectlEditorComponent),
209
+ multi: true,
210
+ },
211
+ ], styles: [":host{display:block}\n"] }]
212
+ }], propDecorators: { containerRef: [{
213
+ type: ViewChild,
214
+ args: ['container', { static: true }]
215
+ }], debug: [{
216
+ type: Input
217
+ }], content: [{
218
+ type: Input
219
+ }], placeholder: [{
220
+ type: Input
221
+ }], readOnly: [{
222
+ type: Input
223
+ }], accessibility: [{
224
+ type: Input
225
+ }], i18n: [{
226
+ type: Input
227
+ }], theme: [{
228
+ type: Input
229
+ }], className: [{
230
+ type: Input
231
+ }], contentChange: [{
232
+ type: Output
233
+ }], selectionChange: [{
234
+ type: Output
235
+ }], editorFocus: [{
236
+ type: Output
237
+ }], editorBlur: [{
238
+ type: Output
239
+ }], ready: [{
240
+ type: Output
241
+ }], error: [{
242
+ type: Output
243
+ }] } });
244
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90ZWN0bC1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9ub3RlY3RsLWVkaXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxPQUFPLEVBQ0wsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsRUFDVCxpQkFBaUIsRUFDakIsVUFBVSxHQUNYLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7QUFJekU7O0dBRUc7QUFjSCxNQUFNLE9BQU8sc0JBQXNCO0lBQ1MsWUFBWSxDQUE4QjtJQUVwRixpQkFBaUI7SUFDUixLQUFLLENBQVc7SUFFekIsc0JBQXNCO0lBQ2IsT0FBTyxDQUFtQjtJQUVuQyx1QkFBdUI7SUFDZCxXQUFXLENBQVU7SUFFOUIscUJBQXFCO0lBQ1osUUFBUSxDQUFXO0lBRTVCLGtDQUFrQztJQUN6QixhQUFhLENBQWlDO0lBRXZELHlDQUF5QztJQUNoQyxJQUFJLENBQXdCO0lBRXJDLDBCQUEwQjtJQUNqQixLQUFLLENBQXlCO0lBRXZDLHdCQUF3QjtJQUNmLFNBQVMsQ0FBVTtJQUU1QixtQ0FBbUM7SUFDekIsYUFBYSxHQUFHLElBQUksWUFBWSxFQUFXLENBQUM7SUFFdEQscUNBQXFDO0lBQzNCLGVBQWUsR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFDO0lBRXhELHNDQUFzQztJQUM1QixXQUFXLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztJQUVqRCxzQ0FBc0M7SUFDNUIsVUFBVSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7SUFFaEQsbUNBQW1DO0lBQ3pCLEtBQUssR0FBRyxJQUFJLFlBQVksRUFBYSxDQUFDO0lBRWhELG1DQUFtQztJQUN6QixLQUFLLEdBQUcsSUFBSSxZQUFZLEVBQVMsQ0FBQztJQUVwQyxNQUFNLEdBQTZC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QVc7c0JBQXBCLE1BQU07Z0JBR0csVUFBVTtzQkFBbkIsTUFBTTtnQkFHRyxLQUFLO3NCQUFkLE1BQU07Z0JBR0csS0FBSztzQkFBZCxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBbmd1bGFyIGNvbXBvbmVudCB3cmFwcGVyIGZvciBOb3RlY3RsRWRpdG9yXG4gKi9cblxuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBmb3J3YXJkUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE5vdGVjdGxFZGl0b3IgYXMgTm90ZWN0bEVkaXRvckNvcmUgfSBmcm9tICdAbm90ZWN0bC9jb3JlJztcbmltcG9ydCB0eXBlIHsgRWRpdG9yQ29uZmlnLCBFZGl0b3JBUEkgfSBmcm9tICdAbm90ZWN0bC9jb3JlJztcblxuLyoqXG4gKiBOb3RlY3RsRWRpdG9yIEFuZ3VsYXIgY29tcG9uZW50XG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25vdGVjdGwtZWRpdG9yJyxcbiAgdGVtcGxhdGU6ICc8ZGl2ICNjb250YWluZXIgW2F0dHIuZGF0YS1ub3RlY3RsLWFuZ3VsYXItd3JhcHBlcl09XCJ0cnVlXCI+PC9kaXY+JyxcbiAgc3R5bGVzOiBbJzpob3N0IHsgZGlzcGxheTogYmxvY2s7IH0nXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBOb3RlY3RsRWRpdG9yQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH0sXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIE5vdGVjdGxFZGl0b3JDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuICBAVmlld0NoaWxkKCdjb250YWluZXInLCB7IHN0YXRpYzogdHJ1ZSB9KSBjb250YWluZXJSZWYhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcblxuICAvKiogRGVidWcgbW9kZSAqL1xuICBASW5wdXQoKSBkZWJ1Zz86IGJvb2xlYW47XG5cbiAgLyoqIEluaXRpYWwgY29udGVudCAqL1xuICBASW5wdXQoKSBjb250ZW50Pzogc3RyaW5nIHwgb2JqZWN0O1xuXG4gIC8qKiBQbGFjZWhvbGRlciB0ZXh0ICovXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyPzogc3RyaW5nO1xuXG4gIC8qKiBSZWFkLW9ubHkgbW9kZSAqL1xuICBASW5wdXQoKSByZWFkT25seT86IGJvb2xlYW47XG5cbiAgLyoqIEFjY2Vzc2liaWxpdHkgY29uZmlndXJhdGlvbiAqL1xuICBASW5wdXQoKSBhY2Nlc3NpYmlsaXR5PzogRWRpdG9yQ29uZmlnWydhY2Nlc3NpYmlsaXR5J107XG5cbiAgLyoqIEludGVybmF0aW9uYWxpemF0aW9uIGNvbmZpZ3VyYXRpb24gKi9cbiAgQElucHV0KCkgaTE4bj86IEVkaXRvckNvbmZpZ1snaTE4biddO1xuXG4gIC8qKiBUaGVtZSBjb25maWd1cmF0aW9uICovXG4gIEBJbnB1dCgpIHRoZW1lPzogRWRpdG9yQ29uZmlnWyd0aGVtZSddO1xuXG4gIC8qKiBDdXN0b20gY2xhc3MgbmFtZSAqL1xuICBASW5wdXQoKSBjbGFzc05hbWU/OiBzdHJpbmc7XG5cbiAgLyoqIEVtaXR0ZWQgd2hlbiBjb250ZW50IGNoYW5nZXMgKi9cbiAgQE91dHB1dCgpIGNvbnRlbnRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHVua25vd24+KCk7XG5cbiAgLyoqIEVtaXR0ZWQgd2hlbiBzZWxlY3Rpb24gY2hhbmdlcyAqL1xuICBAT3V0cHV0KCkgc2VsZWN0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjx1bmtub3duPigpO1xuXG4gIC8qKiBFbWl0dGVkIHdoZW4gZWRpdG9yIGdhaW5zIGZvY3VzICovXG4gIEBPdXRwdXQoKSBlZGl0b3JGb2N1cyA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAvKiogRW1pdHRlZCB3aGVuIGVkaXRvciBsb3NlcyBmb2N1cyAqL1xuICBAT3V0cHV0KCkgZWRpdG9yQmx1ciA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAvKiogRW1pdHRlZCB3aGVuIGVkaXRvciBpcyByZWFkeSAqL1xuICBAT3V0cHV0KCkgcmVhZHkgPSBuZXcgRXZlbnRFbWl0dGVyPEVkaXRvckFQST4oKTtcblxuICAvKiogRW1pdHRlZCB3aGVuIGFuIGVycm9yIG9jY3VycyAqL1xuICBAT3V0cHV0KCkgZXJyb3IgPSBuZXcgRXZlbnRFbWl0dGVyPEVycm9yPigpO1xuXG4gIHByaXZhdGUgZWRpdG9yOiBOb3RlY3RsRWRpdG9yQ29yZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIG9uQ2hhbmdlOiAodmFsdWU6IHVua25vd24pID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgcHJpdmF0ZSBvblRvdWNoZWQ6ICgpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmluaXRFZGl0b3IoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveUVkaXRvcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIGVkaXRvciBpbnN0YW5jZVxuICAgKi9cbiAgcHJpdmF0ZSBpbml0RWRpdG9yKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb250YWluZXJSZWY/Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ05vdGVjdGxFZGl0b3I6IENvbnRhaW5lciBlbGVtZW50IG5vdCBmb3VuZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBlZGl0b3IgaW5zdGFuY2VcbiAgICB0aGlzLmVkaXRvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ25vdGVjdGwtZWRpdG9yJykgYXMgTm90ZWN0bEVkaXRvckNvcmU7XG5cbiAgICAvLyBDb25maWd1cmUgZWRpdG9yXG4gICAgY29uc3QgY29uZmlnOiBFZGl0b3JDb25maWcgPSB7XG4gICAgICBkZWJ1ZzogdGhpcy5kZWJ1ZyxcbiAgICAgIGNvbnRlbnQ6IHRoaXMuY29udGVudCxcbiAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLnBsYWNlaG9sZGVyLFxuICAgICAgcmVhZE9ubHk6IHRoaXMucmVhZE9ubHksXG4gICAgICBhY2Nlc3NpYmlsaXR5OiB0aGlzLmFjY2Vzc2liaWxpdHksXG4gICAgICBpMThuOiB0aGlzLmkxOG4sXG4gICAgICB0aGVtZTogdGhpcy50aGVtZSxcbiAgICB9O1xuICAgIHRoaXMuZWRpdG9yLmNvbmZpZ3VyZShjb25maWcpO1xuXG4gICAgLy8gQXR0YWNoIGV2ZW50IGxpc3RlbmVyc1xuICAgIHRoaXMuZWRpdG9yLm9uKCdjb250ZW50LWNoYW5nZScsIChkYXRhKSA9PiB7XG4gICAgICBjb25zdCBldmVudERhdGEgPSBkYXRhIGFzIHsgY29udGVudD86IHVua25vd24gfTtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBldmVudERhdGEuY29udGVudDtcbiAgICAgIHRoaXMuY29udGVudENoYW5nZS5lbWl0KGNvbnRlbnQpO1xuICAgICAgdGhpcy5vbkNoYW5nZShjb250ZW50KTtcbiAgICB9KTtcblxuICAgIHRoaXMuZWRpdG9yLm9uKCdzZWxlY3Rpb24tY2hhbmdlJywgKGRhdGEpID0+IHtcbiAgICAgIGNvbnN0IGV2ZW50RGF0YSA9IGRhdGEgYXMgeyBzZWxlY3Rpb24/OiB1bmtub3duIH07XG4gICAgICB0aGlzLnNlbGVjdGlvbkNoYW5nZS5lbWl0KGV2ZW50RGF0YS5zZWxlY3Rpb24pO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lZGl0b3Iub24oJ2ZvY3VzJywgKCkgPT4ge1xuICAgICAgdGhpcy5lZGl0b3JGb2N1cy5lbWl0KCk7XG4gICAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lZGl0b3Iub24oJ2JsdXInLCAoKSA9PiB7XG4gICAgICB0aGlzLmVkaXRvckJsdXIuZW1pdCgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lZGl0b3Iub24oJ3JlYWR5JywgKCkgPT4ge1xuICAgICAgdGhpcy5yZWFkeS5lbWl0KHRoaXMuZ2V0RWRpdG9yQVBJKCkpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5lZGl0b3Iub24oJ2Vycm9yJywgKGRhdGEpID0+IHtcbiAgICAgIGNvbnN0IGV2ZW50RGF0YSA9IGRhdGEgYXMgeyBlcnJvcj86IEVycm9yIH07XG4gICAgICBpZiAoZXZlbnREYXRhLmVycm9yKSB7XG4gICAgICAgIHRoaXMuZXJyb3IuZW1pdChldmVudERhdGEuZXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gTW91bnQgZWRpdG9yXG4gICAgdGhpcy5jb250YWluZXJSZWYubmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmVkaXRvcik7XG4gIH1cblxuICAvKipcbiAgICogRGVzdHJveSB0aGUgZWRpdG9yIGluc3RhbmNlXG4gICAqL1xuICBwcml2YXRlIGRlc3Ryb3lFZGl0b3IoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWRpdG9yKSB7XG4gICAgICB0aGlzLmVkaXRvci5kZXN0cm95KCk7XG4gICAgICBpZiAodGhpcy5jb250YWluZXJSZWY/Lm5hdGl2ZUVsZW1lbnQ/LmNvbnRhaW5zKHRoaXMuZWRpdG9yKSkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lclJlZi5uYXRpdmVFbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMuZWRpdG9yKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZWRpdG9yID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGVkaXRvciBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZUNvbmZpZygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZWRpdG9yKSByZXR1cm47XG5cbiAgICBjb25zdCBjb25maWc6IEVkaXRvckNvbmZpZyA9IHtcbiAgICAgIGRlYnVnOiB0aGlzLmRlYnVnLFxuICAgICAgY29udGVudDogdGhpcy5jb250ZW50LFxuICAgICAgcGxhY2Vob2xkZXI6IHRoaXMucGxhY2Vob2xkZXIsXG4gICAgICByZWFkT25seTogdGhpcy5yZWFkT25seSxcbiAgICAgIGFjY2Vzc2liaWxpdHk6IHRoaXMuYWNjZXNzaWJpbGl0eSxcbiAgICAgIGkxOG46IHRoaXMuaTE4bixcbiAgICAgIHRoZW1lOiB0aGlzLnRoZW1lLFxuICAgIH07XG4gICAgdGhpcy5lZGl0b3IuY29uZmlndXJlKGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGVkaXRvciBBUElcbiAgICovXG4gIHByaXZhdGUgZ2V0RWRpdG9yQVBJKCk6IEVkaXRvckFQSSB7XG4gICAgaWYgKCF0aGlzLmVkaXRvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFZGl0b3Igbm90IGluaXRpYWxpemVkJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmVkaXRvciBhcyBFZGl0b3JBUEk7XG4gIH1cblxuICAvLyBDb250cm9sVmFsdWVBY2Nlc3NvciBpbXBsZW1lbnRhdGlvblxuICB3cml0ZVZhbHVlKHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWRpdG9yICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRoaXMuZWRpdG9yLnNldENvbnRlbnQodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogdW5rbm93bikgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh0aGlzLmVkaXRvcikge1xuICAgICAgdGhpcy5lZGl0b3IuY29uZmlndXJlKHsgcmVhZE9ubHk6IGlzRGlzYWJsZWQgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gUHVibGljIEFQSSBtZXRob2RzXG4gIC8qKlxuICAgKiBHZXQgY3VycmVudCBlZGl0b3IgY29udGVudFxuICAgKi9cbiAgcHVibGljIGdldENvbnRlbnQoKTogdW5rbm93biB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yPy5nZXRDb250ZW50KCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGVkaXRvciBjb250ZW50XG4gICAqL1xuICBwdWJsaWMgc2V0Q29udGVudChjb250ZW50OiB1bmtub3duKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWRpdG9yICYmIHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5lZGl0b3Iuc2V0Q29udGVudChjb250ZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGN1cnJlbnQgZWRpdG9yIHN0YXRlXG4gICAqL1xuICBwdWJsaWMgZ2V0U3RhdGUoKTogdW5rbm93biB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yPy5nZXRTdGF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgYW4gZWRpdG9yIGNvbW1hbmRcbiAgICovXG4gIHB1YmxpYyBleGVjdXRlQ29tbWFuZChjb21tYW5kOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQge1xuICAgIHRoaXMuZWRpdG9yPy5leGVjdXRlQ29tbWFuZChjb21tYW5kLCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhIHBsdWdpblxuICAgKi9cbiAgcHVibGljIHJlZ2lzdGVyUGx1Z2luKHBsdWdpbjogdW5rbm93bik6IHZvaWQge1xuICAgIHRoaXMuZWRpdG9yPy5yZWdpc3RlclBsdWdpbihwbHVnaW4gYXMgYW55KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVyIGEgcGx1Z2luXG4gICAqL1xuICBwdWJsaWMgdW5yZWdpc3RlclBsdWdpbihwbHVnaW5JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0b3I/LnVucmVnaXN0ZXJQbHVnaW4ocGx1Z2luSWQpO1xuICB9XG59XG4iXX0=