1 | ;
|
2 | /**
|
3 | * @license
|
4 | * Copyright Google LLC All Rights Reserved.
|
5 | *
|
6 | * Use of this source code is governed by an MIT-style license that can be
|
7 | * found in the LICENSE file at https://angular.io/license
|
8 | */
|
9 | Object.defineProperty(exports, "__esModule", { value: true });
|
10 | exports.SimpleMemoryHost = void 0;
|
11 | const rxjs_1 = require("rxjs");
|
12 | const exception_1 = require("../../exception");
|
13 | const path_1 = require("../path");
|
14 | class SimpleMemoryHost {
|
15 | _newDirStats() {
|
16 | return {
|
17 | inspect() {
|
18 | return '<Directory>';
|
19 | },
|
20 | isFile() {
|
21 | return false;
|
22 | },
|
23 | isDirectory() {
|
24 | return true;
|
25 | },
|
26 | size: 0,
|
27 | atime: new Date(),
|
28 | ctime: new Date(),
|
29 | mtime: new Date(),
|
30 | birthtime: new Date(),
|
31 | content: null,
|
32 | };
|
33 | }
|
34 | _newFileStats(content, oldStats) {
|
35 | return {
|
36 | inspect() {
|
37 | return `<File size(${content.byteLength})>`;
|
38 | },
|
39 | isFile() {
|
40 | return true;
|
41 | },
|
42 | isDirectory() {
|
43 | return false;
|
44 | },
|
45 | size: content.byteLength,
|
46 | atime: oldStats ? oldStats.atime : new Date(),
|
47 | ctime: new Date(),
|
48 | mtime: new Date(),
|
49 | birthtime: oldStats ? oldStats.birthtime : new Date(),
|
50 | content,
|
51 | };
|
52 | }
|
53 | constructor() {
|
54 | this._cache = new Map();
|
55 | this._watchers = new Map();
|
56 | this._cache.set((0, path_1.normalize)('/'), this._newDirStats());
|
57 | }
|
58 | _toAbsolute(path) {
|
59 | return (0, path_1.isAbsolute)(path) ? path : (0, path_1.normalize)('/' + path);
|
60 | }
|
61 | _updateWatchers(path, type) {
|
62 | const time = new Date();
|
63 | let currentPath = path;
|
64 | let parent = null;
|
65 | if (this._watchers.size == 0) {
|
66 | // Nothing to do if there's no watchers.
|
67 | return;
|
68 | }
|
69 | const maybeWatcher = this._watchers.get(currentPath);
|
70 | if (maybeWatcher) {
|
71 | maybeWatcher.forEach((watcher) => {
|
72 | const [options, subject] = watcher;
|
73 | subject.next({ path, time, type });
|
74 | if (!options.persistent && type == 2 /* HostWatchEventType.Deleted */) {
|
75 | subject.complete();
|
76 | this._watchers.delete(currentPath);
|
77 | }
|
78 | });
|
79 | }
|
80 | do {
|
81 | currentPath = parent !== null ? parent : currentPath;
|
82 | parent = (0, path_1.dirname)(currentPath);
|
83 | const maybeWatcher = this._watchers.get(currentPath);
|
84 | if (maybeWatcher) {
|
85 | maybeWatcher.forEach((watcher) => {
|
86 | const [options, subject] = watcher;
|
87 | if (!options.recursive) {
|
88 | return;
|
89 | }
|
90 | subject.next({ path, time, type });
|
91 | if (!options.persistent && type == 2 /* HostWatchEventType.Deleted */) {
|
92 | subject.complete();
|
93 | this._watchers.delete(currentPath);
|
94 | }
|
95 | });
|
96 | }
|
97 | } while (parent != currentPath);
|
98 | }
|
99 | get capabilities() {
|
100 | return { synchronous: true };
|
101 | }
|
102 | /**
|
103 | * List of protected methods that give direct access outside the observables to the cache
|
104 | * and internal states.
|
105 | */
|
106 | _write(path, content) {
|
107 | path = this._toAbsolute(path);
|
108 | const old = this._cache.get(path);
|
109 | if (old && old.isDirectory()) {
|
110 | throw new exception_1.PathIsDirectoryException(path);
|
111 | }
|
112 | // Update all directories. If we find a file we know it's an invalid write.
|
113 | const fragments = (0, path_1.split)(path);
|
114 | let curr = (0, path_1.normalize)('/');
|
115 | for (const fr of fragments) {
|
116 | curr = (0, path_1.join)(curr, fr);
|
117 | const maybeStats = this._cache.get(fr);
|
118 | if (maybeStats) {
|
119 | if (maybeStats.isFile()) {
|
120 | throw new exception_1.PathIsFileException(curr);
|
121 | }
|
122 | }
|
123 | else {
|
124 | this._cache.set(curr, this._newDirStats());
|
125 | }
|
126 | }
|
127 | // Create the stats.
|
128 | const stats = this._newFileStats(content, old);
|
129 | this._cache.set(path, stats);
|
130 | this._updateWatchers(path, old ? 0 /* HostWatchEventType.Changed */ : 1 /* HostWatchEventType.Created */);
|
131 | }
|
132 | _read(path) {
|
133 | path = this._toAbsolute(path);
|
134 | const maybeStats = this._cache.get(path);
|
135 | if (!maybeStats) {
|
136 | throw new exception_1.FileDoesNotExistException(path);
|
137 | }
|
138 | else if (maybeStats.isDirectory()) {
|
139 | throw new exception_1.PathIsDirectoryException(path);
|
140 | }
|
141 | else if (!maybeStats.content) {
|
142 | throw new exception_1.PathIsDirectoryException(path);
|
143 | }
|
144 | else {
|
145 | return maybeStats.content;
|
146 | }
|
147 | }
|
148 | _delete(path) {
|
149 | path = this._toAbsolute(path);
|
150 | if (this._isDirectory(path)) {
|
151 | for (const [cachePath] of this._cache.entries()) {
|
152 | if (cachePath.startsWith(path + path_1.NormalizedSep) || cachePath === path) {
|
153 | this._cache.delete(cachePath);
|
154 | }
|
155 | }
|
156 | }
|
157 | else {
|
158 | this._cache.delete(path);
|
159 | }
|
160 | this._updateWatchers(path, 2 /* HostWatchEventType.Deleted */);
|
161 | }
|
162 | _rename(from, to) {
|
163 | from = this._toAbsolute(from);
|
164 | to = this._toAbsolute(to);
|
165 | if (!this._cache.has(from)) {
|
166 | throw new exception_1.FileDoesNotExistException(from);
|
167 | }
|
168 | else if (this._cache.has(to)) {
|
169 | throw new exception_1.FileAlreadyExistException(to);
|
170 | }
|
171 | if (this._isDirectory(from)) {
|
172 | for (const path of this._cache.keys()) {
|
173 | if (path.startsWith(from + path_1.NormalizedSep)) {
|
174 | const content = this._cache.get(path);
|
175 | if (content) {
|
176 | // We don't need to clone or extract the content, since we're moving files.
|
177 | this._cache.set((0, path_1.join)(to, path_1.NormalizedSep, path.slice(from.length)), content);
|
178 | }
|
179 | }
|
180 | }
|
181 | }
|
182 | else {
|
183 | const content = this._cache.get(from);
|
184 | if (content) {
|
185 | const fragments = (0, path_1.split)(to);
|
186 | const newDirectories = [];
|
187 | let curr = (0, path_1.normalize)('/');
|
188 | for (const fr of fragments) {
|
189 | curr = (0, path_1.join)(curr, fr);
|
190 | const maybeStats = this._cache.get(fr);
|
191 | if (maybeStats) {
|
192 | if (maybeStats.isFile()) {
|
193 | throw new exception_1.PathIsFileException(curr);
|
194 | }
|
195 | }
|
196 | else {
|
197 | newDirectories.push(curr);
|
198 | }
|
199 | }
|
200 | for (const newDirectory of newDirectories) {
|
201 | this._cache.set(newDirectory, this._newDirStats());
|
202 | }
|
203 | this._cache.delete(from);
|
204 | this._cache.set(to, content);
|
205 | }
|
206 | }
|
207 | this._updateWatchers(from, 3 /* HostWatchEventType.Renamed */);
|
208 | }
|
209 | _list(path) {
|
210 | path = this._toAbsolute(path);
|
211 | if (this._isFile(path)) {
|
212 | throw new exception_1.PathIsFileException(path);
|
213 | }
|
214 | const fragments = (0, path_1.split)(path);
|
215 | const result = new Set();
|
216 | if (path !== path_1.NormalizedRoot) {
|
217 | for (const p of this._cache.keys()) {
|
218 | if (p.startsWith(path + path_1.NormalizedSep)) {
|
219 | result.add((0, path_1.split)(p)[fragments.length]);
|
220 | }
|
221 | }
|
222 | }
|
223 | else {
|
224 | for (const p of this._cache.keys()) {
|
225 | if (p.startsWith(path_1.NormalizedSep) && p !== path_1.NormalizedRoot) {
|
226 | result.add((0, path_1.split)(p)[1]);
|
227 | }
|
228 | }
|
229 | }
|
230 | return [...result];
|
231 | }
|
232 | _exists(path) {
|
233 | return !!this._cache.get(this._toAbsolute(path));
|
234 | }
|
235 | _isDirectory(path) {
|
236 | const maybeStats = this._cache.get(this._toAbsolute(path));
|
237 | return maybeStats ? maybeStats.isDirectory() : false;
|
238 | }
|
239 | _isFile(path) {
|
240 | const maybeStats = this._cache.get(this._toAbsolute(path));
|
241 | return maybeStats ? maybeStats.isFile() : false;
|
242 | }
|
243 | _stat(path) {
|
244 | const maybeStats = this._cache.get(this._toAbsolute(path));
|
245 | if (!maybeStats) {
|
246 | return null;
|
247 | }
|
248 | else {
|
249 | return maybeStats;
|
250 | }
|
251 | }
|
252 | _watch(path, options) {
|
253 | path = this._toAbsolute(path);
|
254 | const subject = new rxjs_1.Subject();
|
255 | let maybeWatcherArray = this._watchers.get(path);
|
256 | if (!maybeWatcherArray) {
|
257 | maybeWatcherArray = [];
|
258 | this._watchers.set(path, maybeWatcherArray);
|
259 | }
|
260 | maybeWatcherArray.push([options || {}, subject]);
|
261 | return subject.asObservable();
|
262 | }
|
263 | write(path, content) {
|
264 | return new rxjs_1.Observable((obs) => {
|
265 | this._write(path, content);
|
266 | obs.next();
|
267 | obs.complete();
|
268 | });
|
269 | }
|
270 | read(path) {
|
271 | return new rxjs_1.Observable((obs) => {
|
272 | const content = this._read(path);
|
273 | obs.next(content);
|
274 | obs.complete();
|
275 | });
|
276 | }
|
277 | delete(path) {
|
278 | return new rxjs_1.Observable((obs) => {
|
279 | this._delete(path);
|
280 | obs.next();
|
281 | obs.complete();
|
282 | });
|
283 | }
|
284 | rename(from, to) {
|
285 | return new rxjs_1.Observable((obs) => {
|
286 | this._rename(from, to);
|
287 | obs.next();
|
288 | obs.complete();
|
289 | });
|
290 | }
|
291 | list(path) {
|
292 | return new rxjs_1.Observable((obs) => {
|
293 | obs.next(this._list(path));
|
294 | obs.complete();
|
295 | });
|
296 | }
|
297 | exists(path) {
|
298 | return new rxjs_1.Observable((obs) => {
|
299 | obs.next(this._exists(path));
|
300 | obs.complete();
|
301 | });
|
302 | }
|
303 | isDirectory(path) {
|
304 | return new rxjs_1.Observable((obs) => {
|
305 | obs.next(this._isDirectory(path));
|
306 | obs.complete();
|
307 | });
|
308 | }
|
309 | isFile(path) {
|
310 | return new rxjs_1.Observable((obs) => {
|
311 | obs.next(this._isFile(path));
|
312 | obs.complete();
|
313 | });
|
314 | }
|
315 | // Some hosts may not support stat.
|
316 | stat(path) {
|
317 | return new rxjs_1.Observable((obs) => {
|
318 | obs.next(this._stat(path));
|
319 | obs.complete();
|
320 | });
|
321 | }
|
322 | watch(path, options) {
|
323 | return this._watch(path, options);
|
324 | }
|
325 | reset() {
|
326 | this._cache.clear();
|
327 | this._watchers.clear();
|
328 | }
|
329 | }
|
330 | exports.SimpleMemoryHost = SimpleMemoryHost;
|
331 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYW5ndWxhcl9kZXZraXQvY29yZS9zcmMvdmlydHVhbC1mcy9ob3N0L21lbW9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7OztHQU1HOzs7QUFFSCwrQkFBMkM7QUFDM0MsK0NBS3lCO0FBQ3pCLGtDQVVpQjtBQWVqQixNQUFhLGdCQUFnQjtJQUlqQixZQUFZO1FBQ3BCLE9BQU87WUFDTCxPQUFPO2dCQUNMLE9BQU8sYUFBYSxDQUFDO1lBQ3ZCLENBQUM7WUFFRCxNQUFNO2dCQUNKLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztZQUNELFdBQVc7Z0JBQ1QsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1lBQ0QsSUFBSSxFQUFFLENBQUM7WUFFUCxLQUFLLEVBQUUsSUFBSSxJQUFJLEVBQUU7WUFDakIsS0FBSyxFQUFFLElBQUksSUFBSSxFQUFFO1lBQ2pCLEtBQUssRUFBRSxJQUFJLElBQUksRUFBRTtZQUNqQixTQUFTLEVBQUUsSUFBSSxJQUFJLEVBQUU7WUFFckIsT0FBTyxFQUFFLElBQUk7U0FDZCxDQUFDO0lBQ0osQ0FBQztJQUNTLGFBQWEsQ0FBQyxPQUFtQixFQUFFLFFBQXVDO1FBQ2xGLE9BQU87WUFDTCxPQUFPO2dCQUNMLE9BQU8sY0FBYyxPQUFPLENBQUMsVUFBVSxJQUFJLENBQUM7WUFDOUMsQ0FBQztZQUVELE1BQU07Z0JBQ0osT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1lBQ0QsV0FBVztnQkFDVCxPQUFPLEtBQUssQ0FBQztZQUNmLENBQUM7WUFDRCxJQUFJLEVBQUUsT0FBTyxDQUFDLFVBQVU7WUFFeEIsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUU7WUFDN0MsS0FBSyxFQUFFLElBQUksSUFBSSxF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LElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDM0IsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2pCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFVLEVBQUUsT0FBMEI7UUFDMUMsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN6QixDQUFDO0NBQ0Y7QUE5VkQsNENBOFZDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIEZpbGVBbHJlYWR5RXhpc3RFeGNlcHRpb24sXG4gIEZpbGVEb2VzTm90RXhpc3RFeGNlcHRpb24sXG4gIFBhdGhJc0RpcmVjdG9yeUV4Y2VwdGlvbixcbiAgUGF0aElzRmlsZUV4Y2VwdGlvbixcbn0gZnJvbSAnLi4vLi4vZXhjZXB0aW9uJztcbmltcG9ydCB7XG4gIE5vcm1hbGl6ZWRSb290LFxuICBOb3JtYWxpemVkU2VwLFxuICBQYXRoLFxuICBQYXRoRnJhZ21lbnQsXG4gIGRpcm5hbWUsXG4gIGlzQWJzb2x1dGUsXG4gIGpvaW4sXG4gIG5vcm1hbGl6ZSxcbiAgc3BsaXQsXG59IGZyb20gJy4uL3BhdGgnO1xuaW1wb3J0IHtcbiAgRmlsZUJ1ZmZlcixcbiAgSG9zdCxcbiAgSG9zdENhcGFiaWxpdGllcyxcbiAgSG9zdFdhdGNoRXZlbnQsXG4gIEhvc3RXYXRjaEV2ZW50VHlwZSxcbiAgSG9zdFdhdGNoT3B0aW9ucyxcbiAgU3RhdHMsXG59IGZyb20gJy4vaW50ZXJmYWNlJztcblxuZXhwb3J0IGludGVyZmFjZSBTaW1wbGVNZW1vcnlIb3N0U3RhdHMge1xuICByZWFkb25seSBjb250ZW50OiBGaWxlQnVmZmVyIHwgbnVsbDtcbn1cblxuZXhwb3J0IGNsYXNzIFNpbXBsZU1lbW9yeUhvc3QgaW1wbGVtZW50cyBIb3N0PHt9PiB7XG4gIHByb3RlY3RlZCBfY2FjaGUgPSBuZXcgTWFwPFBhdGgsIFN0YXRzPFNpbXBsZU1lbW9yeUhvc3RTdGF0cz4+KCk7XG4gIHByaXZhdGUgX3dhdGNoZXJzID0gbmV3IE1hcDxQYXRoLCBbSG9zdFdhdGNoT3B0aW9ucywgU3ViamVjdDxIb3N0V2F0Y2hFdmVudD5dW10+KCk7XG5cbiAgcHJvdGVjdGVkIF9uZXdEaXJTdGF0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuICc8RGlyZWN0b3J5Pic7XG4gICAgICB9LFxuXG4gICAgICBpc0ZpbGUoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0sXG4gICAgICBpc0RpcmVjdG9yeSgpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9LFxuICAgICAgc2l6ZTogMCxcblxuICAgICAgYXRpbWU6IG5ldyBEYXRlKCksXG4gICAgICBjdGltZTogbmV3IERhdGUoKSxcbiAgICAgIG10aW1lOiBuZXcgRGF0ZSgpLFxuICAgICAgYmlydGh0aW1lOiBuZXcgRGF0ZSgpLFxuXG4gICAgICBjb250ZW50OiBudWxsLFxuICAgIH07XG4gIH1cbiAgcHJvdGVjdGVkIF9uZXdGaWxlU3RhdHMoY29udGVudDogRmlsZUJ1ZmZlciwgb2xkU3RhdHM/OiBTdGF0czxTaW1wbGVNZW1vcnlIb3N0U3RhdHM+KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGluc3BlY3QoKSB7XG4gICAgICAgIHJldHVybiBgPEZpbGUgc2l6ZSgke2NvbnRlbnQuYnl0ZUxlbmd0aH0pPmA7XG4gICAgICB9LFxuXG4gICAgICBpc0ZpbGUoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSxcbiAgICAgIGlzRGlyZWN0b3J5KCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9LFxuICAgICAgc2l6ZTogY29udGVudC5ieXRlTGVuZ3RoLFxuXG4gICAgICBhdGltZTogb2xkU3RhdHMgPyBvbGRTdGF0cy5hdGltZSA6IG5ldyBEYXRlKCksXG4gICAgICBjdGltZTogbmV3IERhdGUoKSxcbiAgICAgIG10aW1lOiBuZXcgRGF0ZSgpLFxuICAgICAgYmlydGh0aW1lOiBvbGRTdGF0cyA/IG9sZFN0YXRzLmJpcnRodGltZSA6IG5ldyBEYXRlKCksXG5cbiAgICAgIGNvbnRlbnQsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX2NhY2hlLnNldChub3JtYWxpemUoJy8nKSwgdGhpcy5fbmV3RGlyU3RhdHMoKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX3RvQWJzb2x1dGUocGF0aDogUGF0aCkge1xuICAgIHJldHVybiBpc0Fic29sdXRlKHBhdGgpID8gcGF0aCA6IG5vcm1hbGl6ZSgnLycgKyBwYXRoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfdXBkYXRlV2F0Y2hlcnMocGF0aDogUGF0aCwgdHlwZTogSG9zdFdhdGNoRXZlbnRUeXBlKSB7XG4gICAgY29uc3QgdGltZSA9IG5ldyBEYXRlKCk7XG4gICAgbGV0IGN1cnJlbnRQYXRoID0gcGF0aDtcbiAgICBsZXQgcGFyZW50OiBQYXRoIHwgbnVsbCA9IG51bGw7XG5cbiAgICBpZiAodGhpcy5fd2F0Y2hlcnMuc2l6ZSA9PSAwKSB7XG4gICAgICAvLyBOb3RoaW5nIHRvIGRvIGlmIHRoZXJlJ3Mgbm8gd2F0Y2hlcnMuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbWF5YmVXYXRjaGVyID0gdGhpcy5fd2F0Y2hlcnMuZ2V0KGN1cnJlbnRQYXRoKTtcbiAgICBpZiAobWF5YmVXYXRjaGVyKSB7XG4gICAgICBtYXliZVdhdGNoZXIuZm9yRWFjaCgod2F0Y2hlcikgPT4ge1xuICAgICAgICBjb25zdCBbb3B0aW9ucywgc3ViamVjdF0gPSB3YXRjaGVyO1xuICAgICAgICBzdWJqZWN0Lm5leHQoeyBwYXRoLCB0aW1lLCB0eXBlIH0pO1xuXG4gICAgICAgIGlmICghb3B0aW9ucy5wZXJzaXN0ZW50ICYmIHR5cGUgPT0gSG9zdFdhdGNoRXZlbnRUeXBlLkRlbGV0ZWQpIHtcbiAgICAgICAgICBzdWJqZWN0LmNvbXBsZXRlKCk7XG4gICAgICAgICAgdGhpcy5fd2F0Y2hlcnMuZGVsZXRlKGN1cnJlbnRQYXRoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZG8ge1xuICAgICAgY3VycmVudFBhdGggPSBwYXJlbnQgIT09IG51bGwgPyBwYXJlbnQgOiBjdXJyZW50UGF0aDtcbiAgICAgIHBhcmVudCA9IGRpcm5hbWUoY3VycmVudFBhdGgpO1xuXG4gICAgICBjb25zdCBtYXliZVdhdGNoZXIgPSB0aGlzLl93YXRjaGVycy5nZXQoY3VycmVudFBhdGgpO1xuICAgICAgaWYgKG1heWJlV2F0Y2hlcikge1xuICAgICAgICBtYXliZVdhdGNoZXIuZm9yRWFjaCgod2F0Y2hlcikgPT4ge1xuICAgICAgICAgIGNvbnN0IFtvcHRpb25zLCBzdWJqZWN0XSA9IHdhdGNoZXI7XG4gICAgICAgICAgaWYgKCFvcHRpb25zLnJlY3Vyc2l2ZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzdWJqZWN0Lm5leHQoeyBwYXRoLCB0aW1lLCB0eXBlIH0pO1xuXG4gICAgICAgICAgaWYgKCFvcHRpb25zLnBlcnNpc3RlbnQgJiYgdHlwZSA9PSBIb3N0V2F0Y2hFdmVudFR5cGUuRGVsZXRlZCkge1xuICAgICAgICAgICAgc3ViamVjdC5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgdGhpcy5fd2F0Y2hlcnMuZGVsZXRlKGN1cnJlbnRQYXRoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gd2hpbGUgKHBhcmVudCAhPSBjdXJyZW50UGF0aCk7XG4gIH1cblxuICBnZXQgY2FwYWJpbGl0aWVzKCk6IEhvc3RDYXBhYmlsaXRpZXMge1xuICAgIHJldHVybiB7IHN5bmNocm9ub3VzOiB0cnVlIH07XG4gIH1cblxuICAvKipcbiAgICogTGlzdCBvZiBwcm90ZWN0ZWQgbWV0aG9kcyB0aGF0IGdpdmUgZGlyZWN0IGFjY2VzcyBvdXRzaWRlIHRoZSBvYnNlcnZhYmxlcyB0byB0aGUgY2FjaGVcbiAgICogYW5kIGludGVybmFsIHN0YXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBfd3JpdGUocGF0aDogUGF0aCwgY29udGVudDogRmlsZUJ1ZmZlcik6IHZvaWQge1xuICAgIHBhdGggPSB0aGlzLl90b0Fic29sdXRlKHBhdGgpO1xuICAgIGNvbnN0IG9sZCA9IHRoaXMuX2NhY2hlLmdldChwYXRoKTtcbiAgICBpZiAob2xkICYmIG9sZC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICB0aHJvdyBuZXcgUGF0aElzRGlyZWN0b3J5RXhjZXB0aW9uKHBhdGgpO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSBhbGwgZGlyZWN0b3JpZXMuIElmIHdlIGZpbmQgYSBmaWxlIHdlIGtub3cgaXQncyBhbiBpbnZhbGlkIHdyaXRlLlxuICAgIGNvbnN0IGZyYWdtZW50cyA9IHNwbGl0KHBhdGgpO1xuICAgIGxldCBjdXJyOiBQYXRoID0gbm9ybWFsaXplKCcvJyk7XG4gICAgZm9yIChjb25zdCBmciBvZiBmcmFnbWVudHMpIHtcbiAgICAgIGN1cnIgPSBqb2luKGN1cnIsIGZyKTtcbiAgICAgIGNvbnN0IG1heWJlU3RhdHMgPSB0aGlzLl9jYWNoZS5nZXQoZnIpO1xuICAgICAgaWYgKG1heWJlU3RhdHMpIHtcbiAgICAgICAgaWYgKG1heWJlU3RhdHMuaXNGaWxlKCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGF0aElzRmlsZUV4Y2VwdGlvbihjdXJyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fY2FjaGUuc2V0KGN1cnIsIHRoaXMuX25ld0RpclN0YXRzKCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENyZWF0ZSB0aGUgc3RhdHMuXG4gICAgY29uc3Qgc3RhdHM6IFN0YXRzPFNpbXBsZU1lbW9yeUhvc3RTdGF0cz4gPSB0aGlzLl9uZXdGaWxlU3RhdHMoY29udGVudCwgb2xkKTtcbiAgICB0aGlzLl9jYWNoZS5zZXQocGF0aCwgc3RhdHMpO1xuICAgIHRoaXMuX3VwZGF0ZVdhdGNoZXJzKHBhdGgsIG9sZCA/IEhvc3RXYXRjaEV2ZW50VHlwZS5DaGFuZ2VkIDogSG9zdFdhdGNoRXZlbnRUeXBlLkNyZWF0ZWQpO1xuICB9XG4gIHByb3RlY3RlZCBfcmVhZChwYXRoOiBQYXRoKTogRmlsZUJ1ZmZlciB7XG4gICAgcGF0aCA9IHRoaXMuX3RvQWJzb2x1dGUocGF0aCk7XG4gICAgY29uc3QgbWF5YmVTdGF0cyA9IHRoaXMuX2NhY2hlLmdldChwYXRoKTtcbiAgICBpZiAoIW1heWJlU3RhdHMpIHtcbiAgICAgIHRocm93IG5ldyBGaWxlRG9lc05vdEV4aXN0RXhjZXB0aW9uKHBhdGgpO1xuICAgIH0gZWxzZSBpZiAobWF5YmVTdGF0cy5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICB0aHJvdyBuZXcgUGF0aElzRGlyZWN0b3J5RXhjZXB0aW9uKHBhdGgpO1xuICAgIH0gZWxzZSBpZiAoIW1heWJlU3RhdHMuY29udGVudCkge1xuICAgICAgdGhyb3cgbmV3IFBhdGhJc0RpcmVjdG9yeUV4Y2VwdGlvbihwYXRoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG1heWJlU3RhdHMuY29udGVudDtcbiAgICB9XG4gIH1cbiAgcHJvdGVjdGVkIF9kZWxldGUocGF0aDogUGF0aCk6IHZvaWQge1xuICAgIHBhdGggPSB0aGlzLl90b0Fic29sdXRlKHBhdGgpO1xuICAgIGlmICh0aGlzLl9pc0RpcmVjdG9yeShwYXRoKSkge1xuICAgICAgZm9yIChjb25zdCBbY2FjaGVQYXRoXSBvZiB0aGlzLl9jYWNoZS5lbnRyaWVzKCkpIHtcbiAgICAgICAgaWYgKGNhY2hlUGF0aC5zdGFydHNXaXRoKHBhdGggKyBOb3JtYWxpemVkU2VwKSB8fCBjYWNoZVBhdGggPT09IHBhdGgpIHtcbiAgICAgICAgICB0aGlzLl9jYWNoZS5kZWxldGUoY2FjaGVQYXRoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9jYWNoZS5kZWxldGUocGF0aCk7XG4gICAgfVxuICAgIHRoaXMuX3VwZGF0ZVdhdGNoZXJzKHBhdGgsIEhvc3RXYXRjaEV2ZW50VHlwZS5EZWxldGVkKTtcbiAgfVxuICBwcm90ZWN0ZWQgX3JlbmFtZShmcm9tOiBQYXRoLCB0bzogUGF0aCk6IHZvaWQge1xuICAgIGZyb20gPSB0aGlzLl90b0Fic29sdXRlKGZyb20pO1xuICAgIHRvID0gdGhpcy5fdG9BYnNvbHV0ZSh0byk7XG4gICAgaWYgKCF0aGlzLl9jYWNoZS5oYXMoZnJvbSkpIHtcbiAgICAgIHRocm93IG5ldyBGaWxlRG9lc05vdEV4aXN0RXhjZXB0aW9uKGZyb20pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5fY2FjaGUuaGFzKHRvKSkge1xuICAgICAgdGhyb3cgbmV3IEZpbGVBbHJlYWR5RXhpc3RFeGNlcHRpb24odG8pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9pc0RpcmVjdG9yeShmcm9tKSkge1xuICAgICAgZm9yIChjb25zdCBwYXRoIG9mIHRoaXMuX2NhY2hlLmtleXMoKSkge1xuICAgICAgICBpZiAocGF0aC5zdGFydHNXaXRoKGZyb20gKyBOb3JtYWxpemVkU2VwKSkge1xuICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLl9jYWNoZS5nZXQocGF0aCk7XG4gICAgICAgICAgaWYgKGNvbnRlbnQpIHtcbiAgICAgICAgICAgIC8vIFdlIGRvbid0IG5lZWQgdG8gY2xvbmUgb3IgZXh0cmFjdCB0aGUgY29udGVudCwgc2luY2Ugd2UncmUgbW92aW5nIGZpbGVzLlxuICAgICAgICAgICAgdGhpcy5fY2FjaGUuc2V0KGpvaW4odG8sIE5vcm1hbGl6ZWRTZXAsIHBhdGguc2xpY2UoZnJvbS5sZW5ndGgpKSwgY29udGVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLl9jYWNoZS5nZXQoZnJvbSk7XG4gICAgICBpZiAoY29udGVudCkge1xuICAgICAgICBjb25zdCBmcmFnbWVudHMgPSBzcGxpdCh0byk7XG4gICAgICAgIGNvbnN0IG5ld0RpcmVjdG9yaWVzOiBQYXRoW10gPSBbXTtcbiAgICAgICAgbGV0IGN1cnI6IFBhdGggPSBub3JtYWxpemUoJy8nKTtcbiAgICAgICAgZm9yIChjb25zdCBmciBvZiBmcmFnbWVudHMpIHtcbiAgICAgICAgICBjdXJyID0gam9pbihjdXJyLCBmcik7XG4gICAgICAgICAgY29uc3QgbWF5YmVTdGF0cyA9IHRoaXMuX2NhY2hlLmdldChmcik7XG4gICAgICAgICAgaWYgKG1heWJlU3RhdHMpIHtcbiAgICAgICAgICAgIGlmIChtYXliZVN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXRoSXNGaWxlRXhjZXB0aW9uKGN1cnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdEaXJlY3Rvcmllcy5wdXNoKGN1cnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IG5ld0RpcmVjdG9yeSBvZiBuZXdEaXJlY3Rvcmllcykge1xuICAgICAgICAgIHRoaXMuX2NhY2hlLnNldChuZXdEaXJlY3RvcnksIHRoaXMuX25ld0RpclN0YXRzKCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NhY2hlLmRlbGV0ZShmcm9tKTtcbiAgICAgICAgdGhpcy5fY2FjaGUuc2V0KHRvLCBjb250ZW50KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl91cGRhdGVXYXRjaGVycyhmcm9tLCBIb3N0V2F0Y2hFdmVudFR5cGUuUmVuYW1lZCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2xpc3QocGF0aDogUGF0aCk6IFBhdGhGcmFnbWVudFtdIHtcbiAgICBwYXRoID0gdGhpcy5fdG9BYnNvbHV0ZShwYXRoKTtcbiAgICBpZiAodGhpcy5faXNGaWxlKHBhdGgpKSB7XG4gICAgICB0aHJvdyBuZXcgUGF0aElzRmlsZUV4Y2VwdGlvbihwYXRoKTtcbiAgICB9XG5cbiAgICBjb25zdCBmcmFnbWVudHMgPSBzcGxpdChwYXRoKTtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgU2V0PFBhdGhGcmFnbWVudD4oKTtcbiAgICBpZiAocGF0aCAhPT0gTm9ybWFsaXplZFJvb3QpIHtcbiAgICAgIGZvciAoY29uc3QgcCBvZiB0aGlzLl9jYWNoZS5rZXlzKCkpIHtcbiAgICAgICAgaWYgKHAuc3RhcnRzV2l0aChwYXRoICsgTm9ybWFsaXplZFNlcCkpIHtcbiAgICAgICAgICByZXN1bHQuYWRkKHNwbGl0KHApW2ZyYWdtZW50cy5sZW5ndGhdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGNvbnN0IHAgb2YgdGhpcy5fY2FjaGUua2V5cygpKSB7XG4gICAgICAgIGlmIChwLnN0YXJ0c1dpdGgoTm9ybWFsaXplZFNlcCkgJiYgcCAhPT0gTm9ybWFsaXplZFJvb3QpIHtcbiAgICAgICAgICByZXN1bHQuYWRkKHNwbGl0KHApWzFdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbLi4ucmVzdWx0XTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfZXhpc3RzKHBhdGg6IFBhdGgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLl9jYWNoZS5nZXQodGhpcy5fdG9BYnNvbHV0ZShwYXRoKSk7XG4gIH1cbiAgcHJvdGVjdGVkIF9pc0RpcmVjdG9yeShwYXRoOiBQYXRoKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbWF5YmVTdGF0cyA9IHRoaXMuX2NhY2hlLmdldCh0aGlzLl90b0Fic29sdXRlKHBhdGgpKTtcblxuICAgIHJldHVybiBtYXliZVN0YXRzID8gbWF5YmVTdGF0cy5pc0RpcmVjdG9yeSgpIDogZmFsc2U7XG4gIH1cbiAgcHJvdGVjdGVkIF9pc0ZpbGUocGF0aDogUGF0aCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG1heWJlU3RhdHMgPSB0aGlzLl9jYWNoZS5nZXQodGhpcy5fdG9BYnNvbHV0ZShwYXRoKSk7XG5cbiAgICByZXR1cm4gbWF5YmVTdGF0cyA/IG1heWJlU3RhdHMuaXNGaWxlKCkgOiBmYWxzZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfc3RhdChwYXRoOiBQYXRoKTogU3RhdHM8U2ltcGxlTWVtb3J5SG9zdFN0YXRzPiB8IG51bGwge1xuICAgIGNvbnN0IG1heWJlU3RhdHMgPSB0aGlzLl9jYWNoZS5nZXQodGhpcy5fdG9BYnNvbHV0ZShwYXRoKSk7XG5cbiAgICBpZiAoIW1heWJlU3RhdHMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbWF5YmVTdGF0cztcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX3dhdGNoKHBhdGg6IFBhdGgsIG9wdGlvbnM/OiBIb3N0V2F0Y2hPcHRpb25zKTogT2JzZXJ2YWJsZTxIb3N0V2F0Y2hFdmVudD4ge1xuICAgIHBhdGggPSB0aGlzLl90b0Fic29sdXRlKHBhdGgpO1xuXG4gICAgY29uc3Qgc3ViamVjdCA9IG5ldyBTdWJqZWN0PEhvc3RXYXRjaEV2ZW50PigpO1xuICAgIGxldCBtYXliZVdhdGNoZXJBcnJheSA9IHRoaXMuX3dhdGNoZXJzLmdldChwYXRoKTtcbiAgICBpZiAoIW1heWJlV2F0Y2hlckFycmF5KSB7XG4gICAgICBtYXliZVdhdGNoZXJBcnJheSA9IFtdO1xuICAgICAgdGhpcy5fd2F0Y2hlcnMuc2V0KHBhdGgsIG1heWJlV2F0Y2hlckFycmF5KTtcbiAgICB9XG5cbiAgICBtYXliZVdhdGNoZXJBcnJheS5wdXNoKFtvcHRpb25zIHx8IHt9LCBzdWJqZWN0XSk7XG5cbiAgICByZXR1cm4gc3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIHdyaXRlKHBhdGg6IFBhdGgsIGNvbnRlbnQ6IEZpbGVCdWZmZXIpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8dm9pZD4oKG9icykgPT4ge1xuICAgICAgdGhpcy5fd3JpdGUocGF0aCwgY29udGVudCk7XG4gICAgICBvYnMubmV4dCgpO1xuICAgICAgb2JzLmNvbXBsZXRlKCk7XG4gICAgfSk7XG4gIH1cblxuICByZWFkKHBhdGg6IFBhdGgpOiBPYnNlcnZhYmxlPEZpbGVCdWZmZXI+IHtcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8RmlsZUJ1ZmZlcj4oKG9icykgPT4ge1xuICAgICAgY29uc3QgY29udGVudCA9IHRoaXMuX3JlYWQocGF0aCk7XG4gICAgICBvYnMubmV4dChjb250ZW50KTtcbiAgICAgIG9icy5jb21wbGV0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgZGVsZXRlKHBhdGg6IFBhdGgpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8dm9pZD4oKG9icykgPT4ge1xuICAgICAgdGhpcy5fZGVsZXRlKHBhdGgpO1xuICAgICAgb2JzLm5leHQoKTtcbiAgICAgIG9icy5jb21wbGV0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgcmVuYW1lKGZyb206IFBhdGgsIHRvOiBQYXRoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlPHZvaWQ+KChvYnMpID0+IHtcbiAgICAgIHRoaXMuX3JlbmFtZShmcm9tLCB0byk7XG4gICAgICBvYnMubmV4dCgpO1xuICAgICAgb2JzLmNvbXBsZXRlKCk7XG4gICAgfSk7XG4gIH1cblxuICBsaXN0KHBhdGg6IFBhdGgpOiBPYnNlcnZhYmxlPFBhdGhGcmFnbWVudFtdPiB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlPFBhdGhGcmFnbWVudFtdPigob2JzKSA9PiB7XG4gICAgICBvYnMubmV4dCh0aGlzLl9saXN0KHBhdGgpKTtcbiAgICAgIG9icy5jb21wbGV0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgZXhpc3RzKHBhdGg6IFBhdGgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8Ym9vbGVhbj4oKG9icykgPT4ge1xuICAgICAgb2JzLm5leHQodGhpcy5fZXhpc3RzKHBhdGgpKTtcbiAgICAgIG9icy5jb21wbGV0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgaXNEaXJlY3RvcnkocGF0aDogUGF0aCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZTxib29sZWFuPigob2JzKSA9PiB7XG4gICAgICBvYnMubmV4dCh0aGlzLl9pc0RpcmVjdG9yeShwYXRoKSk7XG4gICAgICBvYnMuY29tcGxldGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlzRmlsZShwYXRoOiBQYXRoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlPGJvb2xlYW4+KChvYnMpID0+IHtcbiAgICAgIG9icy5uZXh0KHRoaXMuX2lzRmlsZShwYXRoKSk7XG4gICAgICBvYnMuY29tcGxldGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFNvbWUgaG9zdHMgbWF5IG5vdCBzdXBwb3J0IHN0YXQuXG4gIHN0YXQocGF0aDogUGF0aCk6IE9ic2VydmFibGU8U3RhdHM8e30+IHwgbnVsbD4gfCBudWxsIHtcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8U3RhdHM8e30+IHwgbnVsbD4oKG9icykgPT4ge1xuICAgICAgb2JzLm5leHQodGhpcy5fc3RhdChwYXRoKSk7XG4gICAgICBvYnMuY29tcGxldGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHdhdGNoKHBhdGg6IFBhdGgsIG9wdGlvbnM/OiBIb3N0V2F0Y2hPcHRpb25zKTogT2JzZXJ2YWJsZTxIb3N0V2F0Y2hFdmVudD4gfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fd2F0Y2gocGF0aCwgb3B0aW9ucyk7XG4gIH1cblxuICByZXNldCgpOiB2b2lkIHtcbiAgICB0aGlzLl9jYWNoZS5jbGVhcigpO1xuICAgIHRoaXMuX3dhdGNoZXJzLmNsZWFyKCk7XG4gIH1cbn1cbiJdfQ== |
\ | No newline at end of file |