@textbus/collaborate 2.0.0-beta.4 → 2.0.0-beta.42

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,33 +1,44 @@
1
1
  import { SelectionBridge } from '@textbus/browser';
2
- import { Selection, SelectionPaths } from '@textbus/core';
2
+ import { Selection, SelectionPaths, Range as TBRange } from '@textbus/core';
3
3
  export interface RemoteSelection {
4
4
  color: string;
5
5
  username: string;
6
6
  paths: SelectionPaths;
7
7
  }
8
- export interface SelectionRect {
9
- color: string;
10
- username: string;
8
+ export interface Rect {
11
9
  x: number;
12
10
  y: number;
13
11
  width: number;
14
12
  height: number;
15
13
  }
14
+ export interface SelectionRect extends Rect {
15
+ color: string;
16
+ username: string;
17
+ }
16
18
  export interface RemoteSelectionCursor {
17
19
  cursor: HTMLElement;
18
20
  anchor: HTMLElement;
19
21
  userTip: HTMLElement;
20
22
  }
23
+ export declare abstract class CollaborateCursorAwarenessDelegate {
24
+ abstract getRects(range: TBRange, nativeRange: Range): false | Rect[];
25
+ }
21
26
  export declare class CollaborateCursor {
22
27
  private container;
23
- private document;
28
+ private awarenessDelegate;
24
29
  private nativeSelection;
25
30
  private selection;
31
+ private host;
32
+ private canvasContainer;
26
33
  private canvas;
27
34
  private context;
28
35
  private tooltips;
29
36
  private onRectsChange;
30
- constructor(container: HTMLElement, document: Document, nativeSelection: SelectionBridge, selection: Selection);
37
+ private subscription;
38
+ private currentSelection;
39
+ constructor(container: HTMLElement, awarenessDelegate: CollaborateCursorAwarenessDelegate, nativeSelection: SelectionBridge, selection: Selection);
40
+ refresh(): void;
41
+ destroy(): void;
31
42
  draw(paths: RemoteSelection[]): void;
32
43
  private drawUserCursor;
33
44
  private getUserCursor;
@@ -0,0 +1,267 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Inject, Injectable, Optional } from '@tanbo/di';
14
+ import { createElement, VIEW_CONTAINER, getLayoutRectByRange, SelectionBridge } from '@textbus/browser';
15
+ import { Selection } from '@textbus/core';
16
+ import { fromEvent, Subject, Subscription } from '@tanbo/stream';
17
+ export class CollaborateCursorAwarenessDelegate {
18
+ }
19
+ let CollaborateCursor = class CollaborateCursor {
20
+ constructor(container, awarenessDelegate, nativeSelection, selection) {
21
+ this.container = container;
22
+ this.awarenessDelegate = awarenessDelegate;
23
+ this.nativeSelection = nativeSelection;
24
+ this.selection = selection;
25
+ this.host = createElement('div', {
26
+ styles: {
27
+ position: 'absolute',
28
+ left: 0,
29
+ top: 0,
30
+ width: '100%',
31
+ height: '100%',
32
+ pointerEvents: 'none',
33
+ zIndex: 1
34
+ }
35
+ });
36
+ this.canvasContainer = createElement('div', {
37
+ styles: {
38
+ position: 'absolute',
39
+ left: 0,
40
+ top: 0,
41
+ width: '100%',
42
+ height: '100%',
43
+ overflow: 'hidden'
44
+ }
45
+ });
46
+ this.canvas = createElement('canvas', {
47
+ styles: {
48
+ position: 'absolute',
49
+ opacity: 0.5,
50
+ left: 0,
51
+ top: 0,
52
+ width: '100%',
53
+ height: document.documentElement.clientHeight + 'px',
54
+ pointerEvents: 'none',
55
+ }
56
+ });
57
+ this.context = this.canvas.getContext('2d');
58
+ this.tooltips = createElement('div', {
59
+ styles: {
60
+ position: 'absolute',
61
+ left: 0,
62
+ top: 0,
63
+ width: '100%',
64
+ height: '100%',
65
+ pointerEvents: 'none',
66
+ fontSize: '12px',
67
+ zIndex: 10
68
+ }
69
+ });
70
+ this.onRectsChange = new Subject();
71
+ this.subscription = new Subscription();
72
+ this.currentSelection = [];
73
+ this.canvasContainer.append(this.canvas);
74
+ this.host.append(this.canvasContainer, this.tooltips);
75
+ container.prepend(this.host);
76
+ this.subscription.add(this.onRectsChange.subscribe(rects => {
77
+ for (const rect of rects) {
78
+ this.context.fillStyle = rect.color;
79
+ this.context.beginPath();
80
+ this.context.rect(rect.x, rect.y, rect.width, rect.height);
81
+ this.context.fill();
82
+ this.context.closePath();
83
+ }
84
+ }), fromEvent(window, 'resize').subscribe(() => {
85
+ this.canvas.style.height = document.documentElement.clientHeight + 'px';
86
+ this.refresh();
87
+ }));
88
+ }
89
+ refresh() {
90
+ this.draw(this.currentSelection);
91
+ }
92
+ destroy() {
93
+ this.subscription.unsubscribe();
94
+ }
95
+ draw(paths) {
96
+ this.currentSelection = paths;
97
+ const containerRect = this.container.getBoundingClientRect();
98
+ this.canvas.style.top = containerRect.y * -1 + 'px';
99
+ this.canvas.width = this.canvas.offsetWidth;
100
+ this.canvas.height = this.canvas.offsetHeight;
101
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
102
+ const users = [];
103
+ paths.filter(i => {
104
+ return i.paths.anchor.length && i.paths.focus.length;
105
+ }).forEach(item => {
106
+ const anchorPaths = [...item.paths.anchor];
107
+ const focusPaths = [...item.paths.focus];
108
+ const anchorOffset = anchorPaths.pop();
109
+ const anchorSlot = this.selection.findSlotByPaths(anchorPaths);
110
+ const focusOffset = focusPaths.pop();
111
+ const focusSlot = this.selection.findSlotByPaths(focusPaths);
112
+ if (!anchorSlot || !focusSlot) {
113
+ return;
114
+ }
115
+ const { focus, anchor } = this.nativeSelection.getPositionByRange({
116
+ focusOffset,
117
+ anchorOffset,
118
+ focusSlot,
119
+ anchorSlot
120
+ });
121
+ if (!focus || !anchor) {
122
+ return;
123
+ }
124
+ const nativeRange = document.createRange();
125
+ nativeRange.setStart(anchor.node, anchor.offset);
126
+ nativeRange.setEnd(focus.node, focus.offset);
127
+ if ((anchor.node !== focus.node || anchor.offset !== focus.offset) && nativeRange.collapsed) {
128
+ nativeRange.setStart(focus.node, focus.offset);
129
+ nativeRange.setEnd(anchor.node, anchor.offset);
130
+ }
131
+ let rects = false;
132
+ if (this.awarenessDelegate) {
133
+ rects = this.awarenessDelegate.getRects({
134
+ focusOffset,
135
+ anchorOffset,
136
+ focusSlot,
137
+ anchorSlot
138
+ }, nativeRange);
139
+ }
140
+ if (!rects) {
141
+ rects = nativeRange.getClientRects();
142
+ }
143
+ const selectionRects = [];
144
+ for (let i = rects.length - 1; i >= 0; i--) {
145
+ const rect = rects[i];
146
+ selectionRects.push({
147
+ color: item.color,
148
+ username: item.username,
149
+ x: rect.x - containerRect.x,
150
+ y: rect.y,
151
+ width: rect.width,
152
+ height: rect.height,
153
+ });
154
+ }
155
+ this.onRectsChange.next(selectionRects);
156
+ const cursorRange = nativeRange.cloneRange();
157
+ cursorRange.setStart(focus.node, focus.offset);
158
+ cursorRange.collapse(true);
159
+ const cursorRect = getLayoutRectByRange(cursorRange);
160
+ const rect = {
161
+ username: item.username,
162
+ color: item.color,
163
+ x: cursorRect.x - containerRect.x,
164
+ y: cursorRect.y - containerRect.y,
165
+ width: 2,
166
+ height: cursorRect.height
167
+ };
168
+ if (rect.x < 0 || rect.y < 0 || rect.x > containerRect.width) {
169
+ return;
170
+ }
171
+ users.push(rect);
172
+ });
173
+ this.drawUserCursor(users);
174
+ }
175
+ drawUserCursor(rects) {
176
+ for (let i = 0; i < rects.length; i++) {
177
+ const rect = rects[i];
178
+ const { cursor, userTip, anchor } = this.getUserCursor(i);
179
+ Object.assign(cursor.style, {
180
+ left: rect.x + 'px',
181
+ top: rect.y + 'px',
182
+ width: rect.width + 'px',
183
+ height: rect.height + 'px',
184
+ background: rect.color,
185
+ display: 'block'
186
+ });
187
+ anchor.style.background = rect.color;
188
+ userTip.innerText = rect.username;
189
+ userTip.style.background = rect.color;
190
+ }
191
+ for (let i = rects.length; i < this.tooltips.children.length; i++) {
192
+ this.tooltips.removeChild(this.tooltips.children[i]);
193
+ }
194
+ }
195
+ getUserCursor(index) {
196
+ let child = this.tooltips.children[index];
197
+ if (child) {
198
+ const anchor = child.children[0];
199
+ return {
200
+ cursor: child,
201
+ anchor,
202
+ userTip: anchor.children[0]
203
+ };
204
+ }
205
+ const userTip = createElement('span', {
206
+ styles: {
207
+ position: 'absolute',
208
+ display: 'none',
209
+ left: '50%',
210
+ transform: 'translateX(-50%)',
211
+ marginBottom: '2px',
212
+ bottom: '100%',
213
+ whiteSpace: 'nowrap',
214
+ color: '#fff',
215
+ boxShadow: '0 1px 2px rgba(0,0,0,.1)',
216
+ borderRadius: '3px',
217
+ padding: '3px 5px',
218
+ pointerEvents: 'none',
219
+ }
220
+ });
221
+ const anchor = createElement('span', {
222
+ styles: {
223
+ position: 'absolute',
224
+ top: '-2px',
225
+ left: '-2px',
226
+ width: '6px',
227
+ height: '6px',
228
+ pointerEvents: 'auto',
229
+ pointer: 'cursor',
230
+ },
231
+ children: [userTip],
232
+ on: {
233
+ mouseenter() {
234
+ userTip.style.display = 'block';
235
+ },
236
+ mouseleave() {
237
+ userTip.style.display = 'none';
238
+ }
239
+ }
240
+ });
241
+ child = createElement('span', {
242
+ styles: {
243
+ position: 'absolute',
244
+ },
245
+ children: [
246
+ anchor
247
+ ]
248
+ });
249
+ this.tooltips.append(child);
250
+ return {
251
+ cursor: child,
252
+ anchor,
253
+ userTip
254
+ };
255
+ }
256
+ };
257
+ CollaborateCursor = __decorate([
258
+ Injectable(),
259
+ __param(0, Inject(VIEW_CONTAINER)),
260
+ __param(1, Optional()),
261
+ __metadata("design:paramtypes", [HTMLElement,
262
+ CollaborateCursorAwarenessDelegate,
263
+ SelectionBridge,
264
+ Selection])
265
+ ], CollaborateCursor);
266
+ export { CollaborateCursor };
267
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGFib3JhdGUtY3Vyc29yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbGxhYm9yYXRlLWN1cnNvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDeEQsT0FBTyxFQUNMLGFBQWEsRUFDYixjQUFjLEVBQ2Qsb0JBQW9CLEVBQ3BCLGVBQWUsRUFDaEIsTUFBTSxrQkFBa0IsQ0FBQTtBQUN6QixPQUFPLEVBQUUsU0FBUyxFQUFvQyxNQUFNLGVBQWUsQ0FBQTtBQUMzRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUE7QUEwQmhFLE1BQU0sT0FBZ0Isa0NBQWtDO0NBRXZEO0FBR0QsSUFBYSxpQkFBaUIsR0FBOUIsTUFBYSxpQkFBaUI7SUFvRDVCLFlBQTRDLFNBQXNCLEVBQ2xDLGlCQUFxRCxFQUNqRSxlQUFnQyxFQUNoQyxTQUFvQjtRQUhJLGNBQVMsR0FBVCxTQUFTLENBQWE7UUFDbEMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFvQztRQUNqRSxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDaEMsY0FBUyxHQUFULFNBQVMsQ0FBVztRQXREaEMsU0FBSSxHQUFHLGFBQWEsQ0FBQyxLQUFLLEVBQUU7WUFDbEMsTUFBTSxFQUFFO2dCQUNOLFFBQVEsRUFBRSxVQUFVO2dCQUNwQixJQUFJLEVBQUUsQ0FBQztnQkFDUCxHQUFHLEVBQUUsQ0FBQztnQkFDTixLQUFLLEVBQUUsTUFBTTtnQkFDYixNQUFNLEVBQUUsTUFBTTtnQkFDZCxhQUFhLEVBQUUsTUFBTTtnQkFDckIsTUFBTSxFQUFFLENBQUM7YUFDVjtTQUNGLENBQUMsQ0FBQTtRQUNNLG9CQUFlLEdBQUcsYUFBYSxDQUFDLEtBQUssRUFBRTtZQUM3QyxNQUFNLEVBQUU7Z0JBQ04sUUFBUSxFQUFFLFVBQVU7Z0JBQ3BCLElBQUksRUFBRSxDQUFDO2dCQUNQLEdBQUcsRUFBRSxDQUFDO2dCQUNOLEtBQUssRUFBRSxNQUFNO2dCQUNiLE1BQU0sRUFBRSxNQUFNO2dCQUNkLFFBQVEsRUFBRSxRQUFRO2FBQ25CO1NBQ0YsQ0FBQyxDQUFBO1FBQ00sV0FBTSxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUU7WUFDdkMsTUFBTSxFQUFFO2dCQUNOLFFBQVEsRUFBRSxVQUFVO2dCQUNwQixPQUFPLEVBQUUsR0FBRztnQkFDWixJQUFJLEVBQUUsQ0FBQztnQkFDUCxHQUFHLEVBQUUsQ0FBQztnQkFDTixLQUFLLEVBQUUsTUFBTTtnQkFDYixNQUFNLEVBQUUsUUFBUSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEdBQUcsSUFBSTtnQkFDcEQsYUFBYSxFQUFFLE1BQU07YUFDdEI7U0FDRixDQUFzQixDQUFBO1FBQ2YsWUFBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBRSxDQUFBO1FBQ3ZDLGFBQVEsR0FBRyxhQUFhLENBQUMsS0FBSyxFQUFFO1lBQ3RDLE1BQU0sRUFBRTtnQkFDTixRQUFRLEVBQUUsVUFBVTtnQkFDcEIsSUFBSSxFQUFFLENBQUM7Z0JBQ1AsR0FBRyxFQUFFLENBQUM7Z0JBQ04sS0FBSyxFQUFFLE1BQU07Z0JBQ2IsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsYUFBYSxFQUFFLE1BQU07Z0JBQ3JCLFFBQVEsRUFBRSxNQUFNO2dCQUNoQixNQUFNLEVBQUUsRUFBRTthQUNYO1NBQ0YsQ0FBQyxDQUFBO1FBRU0sa0JBQWEsR0FBRyxJQUFJLE9BQU8sRUFBbUIsQ0FBQTtRQUU5QyxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUE7UUFDakMscUJBQWdCLEdBQXNCLEVBQUUsQ0FBQTtRQU05QyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDeEMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDckQsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDNUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDekQsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7Z0JBQ3hCLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUE7Z0JBQ25DLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUE7Z0JBQ3hCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtnQkFDMUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQTtnQkFDbkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQTthQUN6QjtRQUNILENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUM3QyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFBO1lBQ3ZFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtRQUNoQixDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ0wsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO0lBQ2xDLENBQUM7SUFFRCxPQUFPO1FBQ0wsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUNqQyxDQUFDO0lBRUQsSUFBSSxDQUFDLEtBQXdCO1FBQzNCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUE7UUFDN0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxxQkFBcUIsRUFBRSxDQUFBO1FBQzVELElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxhQUFhLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQTtRQUNuRCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQTtRQUMzQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQTtRQUM3QyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7UUFFbkUsTUFBTSxLQUFLLEdBQW9CLEVBQUUsQ0FBQTtRQUVqQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ2YsT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFBO1FBQ3RELENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNoQixNQUFNLFdBQVcsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQTtZQUMxQyxNQUFNLFVBQVUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUN4QyxNQUFNLFlBQVksR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFHLENBQUE7WUFDdkMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUE7WUFDOUQsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRyxDQUFBO1lBQ3JDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQzVELElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQzdCLE9BQU07YUFDUDtZQUVELE1BQU0sRUFBQyxLQUFLLEVBQUUsTUFBTSxFQUFDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxrQkFBa0IsQ0FBQztnQkFDOUQsV0FBVztnQkFDWCxZQUFZO2dCQUNaLFNBQVM7Z0JBQ1QsVUFBVTthQUNYLENBQUMsQ0FBQTtZQUNGLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ3JCLE9BQU07YUFDUDtZQUNELE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtZQUMxQyxXQUFXLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1lBQ2hELFdBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUE7WUFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssS0FBSyxDQUFDLElBQUksSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxXQUFXLENBQUMsU0FBUyxFQUFFO2dCQUMzRixXQUFXLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFBO2dCQUM5QyxXQUFXLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO2FBQy9DO1lBRUQsSUFBSSxLQUFLLEdBQWlDLEtBQUssQ0FBQTtZQUMvQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDMUIsS0FBSyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUM7b0JBQ3RDLFdBQVc7b0JBQ1gsWUFBWTtvQkFDWixTQUFTO29CQUNULFVBQVU7aUJBQ1gsRUFBRSxXQUFXLENBQUMsQ0FBQTthQUNoQjtZQUNELElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ1YsS0FBSyxHQUFHLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQTthQUNyQztZQUNELE1BQU0sY0FBYyxHQUFvQixFQUFFLENBQUE7WUFDMUMsS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUMxQyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7Z0JBQ3JCLGNBQWMsQ0FBQyxJQUFJLENBQUM7b0JBQ2xCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztvQkFDakIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO29CQUN2QixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsQ0FBQztvQkFDM0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO29CQUNULEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztvQkFDakIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO2lCQUNwQixDQUFDLENBQUE7YUFDSDtZQUNELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFBO1lBRXZDLE1BQU0sV0FBVyxHQUFHLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQTtZQUM1QyxXQUFXLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1lBQzlDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7WUFFMUIsTUFBTSxVQUFVLEdBQUcsb0JBQW9CLENBQUMsV0FBVyxDQUFDLENBQUE7WUFFcEQsTUFBTSxJQUFJLEdBQWtCO2dCQUMxQixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7Z0JBQ3ZCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztnQkFDakIsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUM7Z0JBQ2pDLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDO2dCQUNqQyxLQUFLLEVBQUUsQ0FBQztnQkFDUixNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU07YUFDMUIsQ0FBQTtZQUNELElBQUksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsS0FBSyxFQUFFO2dCQUM1RCxPQUFNO2FBQ1A7WUFDRCxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUM1QixDQUFDO0lBRU8sY0FBYyxDQUFDLEtBQXNCO1FBQzNDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3JDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUNyQixNQUFNLEVBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQ3ZELE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRTtnQkFDMUIsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSTtnQkFDbkIsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSTtnQkFDbEIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSTtnQkFDeEIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSTtnQkFDMUIsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLO2dCQUN0QixPQUFPLEVBQUUsT0FBTzthQUNqQixDQUFDLENBQUE7WUFDRixNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFBO1lBQ3BDLE9BQU8sQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQTtZQUNqQyxPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFBO1NBQ3RDO1FBRUQsS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDakUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtTQUNyRDtJQUNILENBQUM7SUFFTyxhQUFhLENBQUMsS0FBYTtRQUNqQyxJQUFJLEtBQUssR0FBZ0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFnQixDQUFBO1FBQ3JFLElBQUksS0FBSyxFQUFFO1lBQ1QsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQWdCLENBQUE7WUFDL0MsT0FBTztnQkFDTCxNQUFNLEVBQUUsS0FBSztnQkFDYixNQUFNO2dCQUNOLE9BQU8sRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBZ0I7YUFDM0MsQ0FBQTtTQUNGO1FBQ0QsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRTtZQUNwQyxNQUFNLEVBQUU7Z0JBQ04sUUFBUSxFQUFFLFVBQVU7Z0JBQ3BCLE9BQU8sRUFBRSxNQUFNO2dCQUNmLElBQUksRUFBRSxLQUFLO2dCQUNYLFNBQVMsRUFBRSxrQkFBa0I7Z0JBQzdCLFlBQVksRUFBRSxLQUFLO2dCQUNuQixNQUFNLEVBQUUsTUFBTTtnQkFDZCxVQUFVLEVBQUUsUUFBUTtnQkFDcEIsS0FBSyxFQUFFLE1BQU07Z0JBQ2IsU0FBUyxFQUFFLDBCQUEwQjtnQkFDckMsWUFBWSxFQUFFLEtBQUs7Z0JBQ25CLE9BQU8sRUFBRSxTQUFTO2dCQUNsQixhQUFhLEVBQUUsTUFBTTthQUN0QjtTQUNGLENBQUMsQ0FBQTtRQUVGLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxNQUFNLEVBQUU7WUFDbkMsTUFBTSxFQUFFO2dCQUNOLFFBQVEsRUFBRSxVQUFVO2dCQUNwQixHQUFHLEVBQUUsTUFBTTtnQkFDWCxJQUFJLEVBQUUsTUFBTTtnQkFDWixLQUFLLEVBQUUsS0FBSztnQkFDWixNQUFNLEVBQUUsS0FBSztnQkFDYixhQUFhLEVBQUUsTUFBTTtnQkFDckIsT0FBTyxFQUFFLFFBQVE7YUFDbEI7WUFDRCxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUM7WUFDbkIsRUFBRSxFQUFFO2dCQUNGLFVBQVU7b0JBQ1IsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO2dCQUNqQyxDQUFDO2dCQUNELFVBQVU7b0JBQ1IsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFBO2dCQUNoQyxDQUFDO2FBQ0Y7U0FDRixDQUFDLENBQUE7UUFDRixLQUFLLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRTtZQUM1QixNQUFNLEVBQUU7Z0JBQ04sUUFBUSxFQUFFLFVBQVU7YUFDckI7WUFDRCxRQUFRLEVBQUU7Z0JBQ1IsTUFBTTthQUNQO1NBQ0YsQ0FBQyxDQUFBO1FBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDM0IsT0FBTztZQUNMLE1BQU0sRUFBRSxLQUFLO1lBQ2IsTUFBTTtZQUNOLE9BQU87U0FDUixDQUFBO0lBQ0gsQ0FBQztDQUNGLENBQUE7QUE3UFksaUJBQWlCO0lBRDdCLFVBQVUsRUFBRTtJQXFERSxXQUFBLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUN0QixXQUFBLFFBQVEsRUFBRSxDQUFBO3FDQURnQyxXQUFXO1FBQ2Ysa0NBQWtDO1FBQ2hELGVBQWU7UUFDckIsU0FBUztHQXZEN0IsaUJBQWlCLENBNlA3QjtTQTdQWSxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIE9wdGlvbmFsIH0gZnJvbSAnQHRhbmJvL2RpJ1xuaW1wb3J0IHtcbiAgY3JlYXRlRWxlbWVudCxcbiAgVklFV19DT05UQUlORVIsXG4gIGdldExheW91dFJlY3RCeVJhbmdlLFxuICBTZWxlY3Rpb25CcmlkZ2Vcbn0gZnJvbSAnQHRleHRidXMvYnJvd3NlcidcbmltcG9ydCB7IFNlbGVjdGlvbiwgU2VsZWN0aW9uUGF0aHMsIFJhbmdlIGFzIFRCUmFuZ2UgfSBmcm9tICdAdGV4dGJ1cy9jb3JlJ1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdAdGFuYm8vc3RyZWFtJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlbW90ZVNlbGVjdGlvbiB7XG4gIGNvbG9yOiBzdHJpbmdcbiAgdXNlcm5hbWU6IHN0cmluZ1xuICBwYXRoczogU2VsZWN0aW9uUGF0aHNcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWN0IHtcbiAgeDogbnVtYmVyXG4gIHk6IG51bWJlclxuICB3aWR0aDogbnVtYmVyXG4gIGhlaWdodDogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VsZWN0aW9uUmVjdCBleHRlbmRzIFJlY3Qge1xuICBjb2xvcjogc3RyaW5nXG4gIHVzZXJuYW1lOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZW1vdGVTZWxlY3Rpb25DdXJzb3Ige1xuICBjdXJzb3I6IEhUTUxFbGVtZW50XG4gIGFuY2hvcjogSFRNTEVsZW1lbnRcbiAgdXNlclRpcDogSFRNTEVsZW1lbnRcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIENvbGxhYm9yYXRlQ3Vyc29yQXdhcmVuZXNzRGVsZWdhdGUge1xuICBhYnN0cmFjdCBnZXRSZWN0cyhyYW5nZTogVEJSYW5nZSwgbmF0aXZlUmFuZ2U6IFJhbmdlKTogZmFsc2UgfCBSZWN0W11cbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENvbGxhYm9yYXRlQ3Vyc29yIHtcbiAgcHJpdmF0ZSBob3N0ID0gY3JlYXRlRWxlbWVudCgnZGl2Jywge1xuICAgIHN0eWxlczoge1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICBsZWZ0OiAwLFxuICAgICAgdG9wOiAwLFxuICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnLFxuICAgICAgekluZGV4OiAxXG4gICAgfVxuICB9KVxuICBwcml2YXRlIGNhbnZhc0NvbnRhaW5lciA9IGNyZWF0ZUVsZW1lbnQoJ2RpdicsIHtcbiAgICBzdHlsZXM6IHtcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgbGVmdDogMCxcbiAgICAgIHRvcDogMCxcbiAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgIG92ZXJmbG93OiAnaGlkZGVuJ1xuICAgIH1cbiAgfSlcbiAgcHJpdmF0ZSBjYW52YXMgPSBjcmVhdGVFbGVtZW50KCdjYW52YXMnLCB7XG4gICAgc3R5bGVzOiB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIG9wYWNpdHk6IDAuNSxcbiAgICAgIGxlZnQ6IDAsXG4gICAgICB0b3A6IDAsXG4gICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgaGVpZ2h0OiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0ICsgJ3B4JyxcbiAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJyxcbiAgICB9XG4gIH0pIGFzIEhUTUxDYW52YXNFbGVtZW50XG4gIHByaXZhdGUgY29udGV4dCA9IHRoaXMuY2FudmFzLmdldENvbnRleHQoJzJkJykhXG4gIHByaXZhdGUgdG9vbHRpcHMgPSBjcmVhdGVFbGVtZW50KCdkaXYnLCB7XG4gICAgc3R5bGVzOiB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIGxlZnQ6IDAsXG4gICAgICB0b3A6IDAsXG4gICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICBwb2ludGVyRXZlbnRzOiAnbm9uZScsXG4gICAgICBmb250U2l6ZTogJzEycHgnLFxuICAgICAgekluZGV4OiAxMFxuICAgIH1cbiAgfSlcblxuICBwcml2YXRlIG9uUmVjdHNDaGFuZ2UgPSBuZXcgU3ViamVjdDxTZWxlY3Rpb25SZWN0W10+KClcblxuICBwcml2YXRlIHN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKVxuICBwcml2YXRlIGN1cnJlbnRTZWxlY3Rpb246IFJlbW90ZVNlbGVjdGlvbltdID0gW11cblxuICBjb25zdHJ1Y3RvcihASW5qZWN0KFZJRVdfQ09OVEFJTkVSKSBwcml2YXRlIGNvbnRhaW5lcjogSFRNTEVsZW1lbnQsXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIHByaXZhdGUgYXdhcmVuZXNzRGVsZWdhdGU6IENvbGxhYm9yYXRlQ3Vyc29yQXdhcmVuZXNzRGVsZWdhdGUsXG4gICAgICAgICAgICAgIHByaXZhdGUgbmF0aXZlU2VsZWN0aW9uOiBTZWxlY3Rpb25CcmlkZ2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgc2VsZWN0aW9uOiBTZWxlY3Rpb24pIHtcbiAgICB0aGlzLmNhbnZhc0NvbnRhaW5lci5hcHBlbmQodGhpcy5jYW52YXMpXG4gICAgdGhpcy5ob3N0LmFwcGVuZCh0aGlzLmNhbnZhc0NvbnRhaW5lciwgdGhpcy50b29sdGlwcylcbiAgICBjb250YWluZXIucHJlcGVuZCh0aGlzLmhvc3QpXG4gICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKHRoaXMub25SZWN0c0NoYW5nZS5zdWJzY3JpYmUocmVjdHMgPT4ge1xuICAgICAgZm9yIChjb25zdCByZWN0IG9mIHJlY3RzKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5maWxsU3R5bGUgPSByZWN0LmNvbG9yXG4gICAgICAgIHRoaXMuY29udGV4dC5iZWdpblBhdGgoKVxuICAgICAgICB0aGlzLmNvbnRleHQucmVjdChyZWN0LngsIHJlY3QueSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpXG4gICAgICAgIHRoaXMuY29udGV4dC5maWxsKClcbiAgICAgICAgdGhpcy5jb250ZXh0LmNsb3NlUGF0aCgpXG4gICAgICB9XG4gICAgfSksIGZyb21FdmVudCh3aW5kb3csICdyZXNpemUnKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5jYW52YXMuc3R5bGUuaGVpZ2h0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCArICdweCdcbiAgICAgIHRoaXMucmVmcmVzaCgpXG4gICAgfSkpXG4gIH1cblxuICByZWZyZXNoKCkge1xuICAgIHRoaXMuZHJhdyh0aGlzLmN1cnJlbnRTZWxlY3Rpb24pXG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKClcbiAgfVxuXG4gIGRyYXcocGF0aHM6IFJlbW90ZVNlbGVjdGlvbltdKSB7XG4gICAgdGhpcy5jdXJyZW50U2VsZWN0aW9uID0gcGF0aHNcbiAgICBjb25zdCBjb250YWluZXJSZWN0ID0gdGhpcy5jb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICB0aGlzLmNhbnZhcy5zdHlsZS50b3AgPSBjb250YWluZXJSZWN0LnkgKiAtMSArICdweCdcbiAgICB0aGlzLmNhbnZhcy53aWR0aCA9IHRoaXMuY2FudmFzLm9mZnNldFdpZHRoXG4gICAgdGhpcy5jYW52YXMuaGVpZ2h0ID0gdGhpcy5jYW52YXMub2Zmc2V0SGVpZ2h0XG4gICAgdGhpcy5jb250ZXh0LmNsZWFyUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy53aWR0aCwgdGhpcy5jYW52YXMuaGVpZ2h0KVxuXG4gICAgY29uc3QgdXNlcnM6IFNlbGVjdGlvblJlY3RbXSA9IFtdXG5cbiAgICBwYXRocy5maWx0ZXIoaSA9PiB7XG4gICAgICByZXR1cm4gaS5wYXRocy5hbmNob3IubGVuZ3RoICYmIGkucGF0aHMuZm9jdXMubGVuZ3RoXG4gICAgfSkuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGNvbnN0IGFuY2hvclBhdGhzID0gWy4uLml0ZW0ucGF0aHMuYW5jaG9yXVxuICAgICAgY29uc3QgZm9jdXNQYXRocyA9IFsuLi5pdGVtLnBhdGhzLmZvY3VzXVxuICAgICAgY29uc3QgYW5jaG9yT2Zmc2V0ID0gYW5jaG9yUGF0aHMucG9wKCkhXG4gICAgICBjb25zdCBhbmNob3JTbG90ID0gdGhpcy5zZWxlY3Rpb24uZmluZFNsb3RCeVBhdGhzKGFuY2hvclBhdGhzKVxuICAgICAgY29uc3QgZm9jdXNPZmZzZXQgPSBmb2N1c1BhdGhzLnBvcCgpIVxuICAgICAgY29uc3QgZm9jdXNTbG90ID0gdGhpcy5zZWxlY3Rpb24uZmluZFNsb3RCeVBhdGhzKGZvY3VzUGF0aHMpXG4gICAgICBpZiAoIWFuY2hvclNsb3QgfHwgIWZvY3VzU2xvdCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgY29uc3Qge2ZvY3VzLCBhbmNob3J9ID0gdGhpcy5uYXRpdmVTZWxlY3Rpb24uZ2V0UG9zaXRpb25CeVJhbmdlKHtcbiAgICAgICAgZm9jdXNPZmZzZXQsXG4gICAgICAgIGFuY2hvck9mZnNldCxcbiAgICAgICAgZm9jdXNTbG90LFxuICAgICAgICBhbmNob3JTbG90XG4gICAgICB9KVxuICAgICAgaWYgKCFmb2N1cyB8fCAhYW5jaG9yKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgY29uc3QgbmF0aXZlUmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpXG4gICAgICBuYXRpdmVSYW5nZS5zZXRTdGFydChhbmNob3Iubm9kZSwgYW5jaG9yLm9mZnNldClcbiAgICAgIG5hdGl2ZVJhbmdlLnNldEVuZChmb2N1cy5ub2RlLCBmb2N1cy5vZmZzZXQpXG4gICAgICBpZiAoKGFuY2hvci5ub2RlICE9PSBmb2N1cy5ub2RlIHx8IGFuY2hvci5vZmZzZXQgIT09IGZvY3VzLm9mZnNldCkgJiYgbmF0aXZlUmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgICAgIG5hdGl2ZVJhbmdlLnNldFN0YXJ0KGZvY3VzLm5vZGUsIGZvY3VzLm9mZnNldClcbiAgICAgICAgbmF0aXZlUmFuZ2Uuc2V0RW5kKGFuY2hvci5ub2RlLCBhbmNob3Iub2Zmc2V0KVxuICAgICAgfVxuXG4gICAgICBsZXQgcmVjdHM6IFJlY3RbXSB8IERPTVJlY3RMaXN0IHwgZmFsc2UgPSBmYWxzZVxuICAgICAgaWYgKHRoaXMuYXdhcmVuZXNzRGVsZWdhdGUpIHtcbiAgICAgICAgcmVjdHMgPSB0aGlzLmF3YXJlbmVzc0RlbGVnYXRlLmdldFJlY3RzKHtcbiAgICAgICAgICBmb2N1c09mZnNldCxcbiAgICAgICAgICBhbmNob3JPZmZzZXQsXG4gICAgICAgICAgZm9jdXNTbG90LFxuICAgICAgICAgIGFuY2hvclNsb3RcbiAgICAgICAgfSwgbmF0aXZlUmFuZ2UpXG4gICAgICB9XG4gICAgICBpZiAoIXJlY3RzKSB7XG4gICAgICAgIHJlY3RzID0gbmF0aXZlUmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKVxuICAgICAgfVxuICAgICAgY29uc3Qgc2VsZWN0aW9uUmVjdHM6IFNlbGVjdGlvblJlY3RbXSA9IFtdXG4gICAgICBmb3IgKGxldCBpID0gcmVjdHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgY29uc3QgcmVjdCA9IHJlY3RzW2ldXG4gICAgICAgIHNlbGVjdGlvblJlY3RzLnB1c2goe1xuICAgICAgICAgIGNvbG9yOiBpdGVtLmNvbG9yLFxuICAgICAgICAgIHVzZXJuYW1lOiBpdGVtLnVzZXJuYW1lLFxuICAgICAgICAgIHg6IHJlY3QueCAtIGNvbnRhaW5lclJlY3QueCxcbiAgICAgICAgICB5OiByZWN0LnksXG4gICAgICAgICAgd2lkdGg6IHJlY3Qud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiByZWN0LmhlaWdodCxcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIHRoaXMub25SZWN0c0NoYW5nZS5uZXh0KHNlbGVjdGlvblJlY3RzKVxuXG4gICAgICBjb25zdCBjdXJzb3JSYW5nZSA9IG5hdGl2ZVJhbmdlLmNsb25lUmFuZ2UoKVxuICAgICAgY3Vyc29yUmFuZ2Uuc2V0U3RhcnQoZm9jdXMubm9kZSwgZm9jdXMub2Zmc2V0KVxuICAgICAgY3Vyc29yUmFuZ2UuY29sbGFwc2UodHJ1ZSlcblxuICAgICAgY29uc3QgY3Vyc29yUmVjdCA9IGdldExheW91dFJlY3RCeVJhbmdlKGN1cnNvclJhbmdlKVxuXG4gICAgICBjb25zdCByZWN0OiBTZWxlY3Rpb25SZWN0ID0ge1xuICAgICAgICB1c2VybmFtZTogaXRlbS51c2VybmFtZSxcbiAgICAgICAgY29sb3I6IGl0ZW0uY29sb3IsXG4gICAgICAgIHg6IGN1cnNvclJlY3QueCAtIGNvbnRhaW5lclJlY3QueCxcbiAgICAgICAgeTogY3Vyc29yUmVjdC55IC0gY29udGFpbmVyUmVjdC55LFxuICAgICAgICB3aWR0aDogMixcbiAgICAgICAgaGVpZ2h0OiBjdXJzb3JSZWN0LmhlaWdodFxuICAgICAgfVxuICAgICAgaWYgKHJlY3QueCA8IDAgfHwgcmVjdC55IDwgMCB8fCByZWN0LnggPiBjb250YWluZXJSZWN0LndpZHRoKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgdXNlcnMucHVzaChyZWN0KVxuICAgIH0pXG4gICAgdGhpcy5kcmF3VXNlckN1cnNvcih1c2VycylcbiAgfVxuXG4gIHByaXZhdGUgZHJhd1VzZXJDdXJzb3IocmVjdHM6IFNlbGVjdGlvblJlY3RbXSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHJlY3QgPSByZWN0c1tpXVxuICAgICAgY29uc3Qge2N1cnNvciwgdXNlclRpcCwgYW5jaG9yfSA9IHRoaXMuZ2V0VXNlckN1cnNvcihpKVxuICAgICAgT2JqZWN0LmFzc2lnbihjdXJzb3Iuc3R5bGUsIHtcbiAgICAgICAgbGVmdDogcmVjdC54ICsgJ3B4JyxcbiAgICAgICAgdG9wOiByZWN0LnkgKyAncHgnLFxuICAgICAgICB3aWR0aDogcmVjdC53aWR0aCArICdweCcsXG4gICAgICAgIGhlaWdodDogcmVjdC5oZWlnaHQgKyAncHgnLFxuICAgICAgICBiYWNrZ3JvdW5kOiByZWN0LmNvbG9yLFxuICAgICAgICBkaXNwbGF5OiAnYmxvY2snXG4gICAgICB9KVxuICAgICAgYW5jaG9yLnN0eWxlLmJhY2tncm91bmQgPSByZWN0LmNvbG9yXG4gICAgICB1c2VyVGlwLmlubmVyVGV4dCA9IHJlY3QudXNlcm5hbWVcbiAgICAgIHVzZXJUaXAuc3R5bGUuYmFja2dyb3VuZCA9IHJlY3QuY29sb3JcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gcmVjdHMubGVuZ3RoOyBpIDwgdGhpcy50b29sdGlwcy5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy50b29sdGlwcy5yZW1vdmVDaGlsZCh0aGlzLnRvb2x0aXBzLmNoaWxkcmVuW2ldKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0VXNlckN1cnNvcihpbmRleDogbnVtYmVyKTogUmVtb3RlU2VsZWN0aW9uQ3Vyc29yIHtcbiAgICBsZXQgY2hpbGQ6IEhUTUxFbGVtZW50ID0gdGhpcy50b29sdGlwcy5jaGlsZHJlbltpbmRleF0gYXMgSFRNTEVsZW1lbnRcbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIGNvbnN0IGFuY2hvciA9IGNoaWxkLmNoaWxkcmVuWzBdIGFzIEhUTUxFbGVtZW50XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjdXJzb3I6IGNoaWxkLFxuICAgICAgICBhbmNob3IsXG4gICAgICAgIHVzZXJUaXA6IGFuY2hvci5jaGlsZHJlblswXSBhcyBIVE1MRWxlbWVudFxuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCB1c2VyVGlwID0gY3JlYXRlRWxlbWVudCgnc3BhbicsIHtcbiAgICAgIHN0eWxlczoge1xuICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgZGlzcGxheTogJ25vbmUnLFxuICAgICAgICBsZWZ0OiAnNTAlJyxcbiAgICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgtNTAlKScsXG4gICAgICAgIG1hcmdpbkJvdHRvbTogJzJweCcsXG4gICAgICAgIGJvdHRvbTogJzEwMCUnLFxuICAgICAgICB3aGl0ZVNwYWNlOiAnbm93cmFwJyxcbiAgICAgICAgY29sb3I6ICcjZmZmJyxcbiAgICAgICAgYm94U2hhZG93OiAnMCAxcHggMnB4IHJnYmEoMCwwLDAsLjEpJyxcbiAgICAgICAgYm9yZGVyUmFkaXVzOiAnM3B4JyxcbiAgICAgICAgcGFkZGluZzogJzNweCA1cHgnLFxuICAgICAgICBwb2ludGVyRXZlbnRzOiAnbm9uZScsXG4gICAgICB9XG4gICAgfSlcblxuICAgIGNvbnN0IGFuY2hvciA9IGNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7XG4gICAgICBzdHlsZXM6IHtcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgIHRvcDogJy0ycHgnLFxuICAgICAgICBsZWZ0OiAnLTJweCcsXG4gICAgICAgIHdpZHRoOiAnNnB4JyxcbiAgICAgICAgaGVpZ2h0OiAnNnB4JyxcbiAgICAgICAgcG9pbnRlckV2ZW50czogJ2F1dG8nLFxuICAgICAgICBwb2ludGVyOiAnY3Vyc29yJyxcbiAgICAgIH0sXG4gICAgICBjaGlsZHJlbjogW3VzZXJUaXBdLFxuICAgICAgb246IHtcbiAgICAgICAgbW91c2VlbnRlcigpIHtcbiAgICAgICAgICB1c2VyVGlwLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snXG4gICAgICAgIH0sXG4gICAgICAgIG1vdXNlbGVhdmUoKSB7XG4gICAgICAgICAgdXNlclRpcC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICAgIGNoaWxkID0gY3JlYXRlRWxlbWVudCgnc3BhbicsIHtcbiAgICAgIHN0eWxlczoge1xuICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIH0sXG4gICAgICBjaGlsZHJlbjogW1xuICAgICAgICBhbmNob3JcbiAgICAgIF1cbiAgICB9KVxuICAgIHRoaXMudG9vbHRpcHMuYXBwZW5kKGNoaWxkKVxuICAgIHJldHVybiB7XG4gICAgICBjdXJzb3I6IGNoaWxkLFxuICAgICAgYW5jaG9yLFxuICAgICAgdXNlclRpcFxuICAgIH1cbiAgfVxufVxuIl19
@@ -1,12 +1,14 @@
1
1
  import { Observable } from '@tanbo/stream';
2
- import { RootComponentRef, Starter, Translator, Registry, Selection, SelectionPaths, History, Renderer } from '@textbus/core';
2
+ import { Controller, History, Registry, RootComponentRef, Scheduler, Selection, SelectionPaths, Starter, Translator } from '@textbus/core';
3
3
  import { Doc as YDoc } from 'yjs';
4
- import { CollaborateCursor, RemoteSelection } from './collab/_api';
4
+ import { CollaborateCursor, RemoteSelection } from './collaborate-cursor';
5
5
  export declare class Collaborate implements History {
6
+ private stackSize;
6
7
  private rootComponentRef;
7
8
  private collaborateCursor;
9
+ private controller;
10
+ private scheduler;
8
11
  private translator;
9
- private renderer;
10
12
  private registry;
11
13
  private selection;
12
14
  private starter;
@@ -30,15 +32,19 @@ export declare class Collaborate implements History {
30
32
  private slotsSyncCaches;
31
33
  private componentStateSyncCaches;
32
34
  private selectionChangeEvent;
35
+ private contentMap;
33
36
  private updateRemoteActions;
34
- constructor(rootComponentRef: RootComponentRef, collaborateCursor: CollaborateCursor, translator: Translator, renderer: Renderer, registry: Registry, selection: Selection, starter: Starter);
37
+ constructor(stackSize: number, rootComponentRef: RootComponentRef, collaborateCursor: CollaborateCursor, controller: Controller, scheduler: Scheduler, translator: Translator, registry: Registry, selection: Selection, starter: Starter);
35
38
  setup(): void;
36
39
  updateRemoteSelection(paths: RemoteSelection[]): void;
37
40
  listen(): void;
38
41
  back(): void;
39
42
  forward(): void;
43
+ clear(): void;
40
44
  destroy(): void;
41
- private listen2;
45
+ private syncRootComponent;
46
+ private restoreCursorLocation;
47
+ private getRelativeCursorLocation;
42
48
  private syncContent;
43
49
  private syncSlot;
44
50
  private syncSlots;