UNPKG

15.9 kBJavaScriptView Raw
1"use strict";
2var seq = require("./task.sequence");
3var task_runner_1 = require("./task.runner");
4var Rx = require("rx");
5var reporter_resolve_1 = require("./reporter.resolve");
6var command_watch_1 = require("./command.watch");
7var immutable_1 = require("immutable");
8var debug = require("debug")("cb:watch.runner");
9/**
10 * Create a stream that is the combination of all watchers
11 */
12function createObservablesForWatchers(watchers, trigger) {
13 /**
14 * Wrap every chokidar watcher in an observable
15 * @type {Rx.Observable<WatchEvent>[]}
16 */
17 var watchersAsObservables = watchers.map(function (watcher) {
18 return createObservableForWatcher(watcher, trigger);
19 });
20 var blockable$ = new Rx.BehaviorSubject([]);
21 /**
22 * Now map file-change events to task running
23 */
24 return (_a = Rx.Observable).merge.apply(_a, watchersAsObservables).map(function (watchEvent) {
25 var watcher = watchers.filter(function (x) { return x.watcherUID === watchEvent.watcherUID; })[0];
26 return { watchEvent: watchEvent, watcher: watcher };
27 })
28 .filter(function (x) {
29 if (x.watcher.options.block) {
30 var blocked = !~blockable$.getValue().indexOf(x.watchEvent.watcherUID);
31 debug("BLOCKED - " + x.watchEvent.watcherUID + " " + x.watchEvent.path + " " + x.watchEvent.event);
32 return blocked;
33 }
34 return true;
35 })
36 .do(function (x) {
37 if (x.watcher.options.block) {
38 blockable$.onNext(blockable$.getValue().concat(x.watchEvent.watcherUID));
39 }
40 })
41 .timestamp(trigger.config.scheduler)
42 .flatMap(function (incoming, i) {
43 return runTasks(incoming, i);
44 });
45 function runTasks(incoming, i) {
46 /**
47 * @type {WatchEvent}
48 */
49 var _a = incoming.value, watchEvent = _a.watchEvent, watcher = _a.watcher;
50 return Rx.Observable.create(function (obs) {
51 /**
52 * Report start of task run
53 */
54 trigger.reporter({
55 type: reporter_resolve_1.ReportTypes.WatcherTriggeredTasks,
56 data: {
57 index: i,
58 taskCollection: watcher.tasks
59 }
60 });
61 /**
62 * todo: Is there a way to handle this without subscribing manually?
63 */
64 watcher._runner.series(immutable_1.fromJS({
65 watchEvent: watchEvent,
66 watcher: {
67 patterns: watcher.patterns,
68 tasks: watcher.tasks,
69 options: watcher.options,
70 watcherUID: watcher.watcherUID
71 }
72 }))
73 .do(function (taskReport) { return obs.onNext({
74 type: command_watch_1.WatchCommandEventTypes.WatchTaskReport,
75 data: {
76 taskReport: taskReport,
77 watchEvent: watchEvent,
78 count: i
79 }
80 }); })
81 .toArray()
82 .timestamp(trigger.config.scheduler)
83 .subscribe(function (x) {
84 var reports = x.value;
85 var sequence = seq.decorateSequenceWithReports(watcher._sequence, reports);
86 var errors = reports.filter(function (x) { return x.type === task_runner_1.TaskReportType.error; });
87 obs.onNext({
88 type: command_watch_1.WatchCommandEventTypes.WatchRunnerComplete,
89 data: {
90 sequence: sequence,
91 reports: reports,
92 errors: errors,
93 watchEvent: watchEvent,
94 runtime: x.timestamp - incoming.timestamp
95 }
96 });
97 if (errors.length > 0) {
98 trigger.reporter({
99 type: reporter_resolve_1.ReportTypes.WatcherSummary,
100 data: {
101 sequence: sequence,
102 cli: trigger.cli,
103 title: watcher.tasks.join(", "),
104 config: trigger.config,
105 runtime: x.timestamp - incoming.timestamp,
106 watcher: watcher,
107 watchEvent: watchEvent
108 }
109 });
110 }
111 else {
112 trigger.reporter({
113 type: reporter_resolve_1.ReportTypes.WatcherTriggeredTasksCompleted,
114 data: {
115 index: i,
116 taskCollection: watcher.tasks,
117 time: x.timestamp - incoming.timestamp
118 }
119 });
120 }
121 var withoutThis = blockable$.getValue().filter(function (x) { return x !== watchEvent.watcherUID; });
122 blockable$.onNext(withoutThis);
123 obs.onCompleted();
124 });
125 });
126 }
127 var _a;
128}
129exports.createObservablesForWatchers = createObservablesForWatchers;
130/**
131 * Create a file-system watcher that will emit <WatchEvent>
132 */
133function createObservableForWatcher(watcher, trigger) {
134 var reporter = trigger.reporter;
135 var scheduler = trigger.config.scheduler;
136 /**
137 * First create a stream of file-watcher events for this Watcher
138 */
139 var output$ = trigger.config.fileChangeObserver || getFileChangeStream(watcher, reporter);
140 /**
141 * Specify a mapping from option name -> Rx.Observable operator name
142 */
143 var additionalOperators = [
144 {
145 option: "debounce",
146 fnName: "debounce"
147 },
148 {
149 option: "throttle",
150 fnName: "throttle"
151 },
152 {
153 option: "delay",
154 fnName: "delay"
155 }
156 ];
157 return applyOperators(output$, additionalOperators, watcher.options, scheduler);
158}
159exports.createObservableForWatcher = createObservableForWatcher;
160function getFileChangeStream(watcher, reporter) {
161 /** DEBUG **/
162 debug("[id:" + watcher.watcherUID + "] options: " + JSON.stringify(watcher.options, null, 2));
163 /** DEBUG END **/
164 return Rx.Observable.create(function (observer) {
165 /** DEBUG **/
166 debug("+ [id:" + watcher.watcherUID + "] " + watcher.patterns.length + " patterns (" + watcher.patterns + ")");
167 debug("\u2514\u2500 " + watcher.tasks.length + " tasks (" + watcher.tasks + ")");
168 /** DEBUG END **/
169 var chokidarWatcher = require("chokidar").watch(watcher.patterns, watcher.options)
170 .on("all", function (event, path) {
171 debug("\u2514\u2500 CHOKIDAR EVENT " + event + " - " + path);
172 observer.onNext({
173 event: event,
174 path: path,
175 watcherUID: watcher.watcherUID
176 });
177 });
178 chokidarWatcher.on("ready", function () {
179 /** DEBUG **/
180 debug("\u221A [id:" + watcher.watcherUID + "] watcher ready (" + watcher.patterns + ")");
181 /** DEBUG END **/
182 if (Object.keys(chokidarWatcher.getWatched()).length === 0) {
183 reporter({ type: reporter_resolve_1.ReportTypes.NoFilesMatched, data: { watcher: watcher } });
184 }
185 });
186 return function () {
187 debug("- for " + watcher.patterns);
188 chokidarWatcher.close();
189 };
190 });
191}
192exports.getFileChangeStream = getFileChangeStream;
193/**
194 *
195 */
196function applyOperators(source, items, options, scheduler) {
197 return items.reduce(function (stream$, item) {
198 var value = options[item.option];
199 if (value !== undefined && value > 0) {
200 return stream$[item.fnName].call(stream$, value, scheduler);
201 }
202 return stream$;
203 }, source);
204}
205//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F0Y2guZmlsZS13YXRjaGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dhdGNoLmZpbGUtd2F0Y2hlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EscUNBQXVDO0FBRXZDLDZDQUF5RDtBQUN6RCx1QkFBMEI7QUFFMUIsdURBQTRFO0FBRTVFLGlEQUF1RDtBQUN2RCx1Q0FBaUM7QUFFakMsSUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUEyQmxEOztHQUVHO0FBQ0gsc0NBQTZDLFFBQW1CLEVBQUUsT0FBdUI7SUFHckY7OztPQUdHO0lBQ0gsSUFBTSxxQkFBcUIsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLFVBQUMsT0FBTztRQUMvQyxNQUFNLENBQUMsMEJBQTBCLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3hELENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBTSxVQUFVLEdBQUcsSUFBSSxFQUFFLENBQUMsZUFBZSxDQUFXLEVBQUUsQ0FBQyxDQUFDO0lBRXhEOztPQUVHO0lBQ0gsTUFBTSxDQUFDLENBQUEsS0FBQSxFQUFFLENBQUMsVUFBVSxDQUFBLENBSWYsS0FBSyxXQUFJLHFCQUFxQixFQU05QixHQUFHLENBQXdCLFVBQUMsVUFBc0I7UUFDL0MsSUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFBLENBQUMsSUFBSSxPQUFBLENBQUMsQ0FBQyxVQUFVLEtBQUssVUFBVSxDQUFDLFVBQVUsRUFBdEMsQ0FBc0MsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hGLE1BQU0sQ0FBQyxFQUFDLFVBQVUsWUFBQSxFQUFFLE9BQU8sU0FBQSxFQUFDLENBQUM7SUFDakMsQ0FBQyxDQUFDO1NBS0QsTUFBTSxDQUFDLFVBQUMsQ0FBd0I7UUFDN0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUMxQixJQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3pFLEtBQUssQ0FBQyxlQUFhLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxTQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxTQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBTyxDQUFDLENBQUM7WUFDekYsTUFBTSxDQUFDLE9BQU8sQ0FBQztRQUNuQixDQUFDO1FBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNoQixDQUFDLENBQUM7U0FDRCxFQUFFLENBQUMsVUFBQyxDQUF3QjtRQUN6QixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQzFCLFVBQVUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDN0UsQ0FBQztJQUNMLENBQUMsQ0FBQztTQUNELFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztTQUNuQyxPQUFPLENBQUMsVUFBQyxRQUEyRCxFQUFFLENBQVM7UUFDNUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDakMsQ0FBQyxDQUFDLENBQUM7SUFFUCxrQkFBbUIsUUFBUSxFQUFFLENBQVM7UUFDbEM7O1dBRUc7UUFDRyxJQUFBLG1CQUFzQyxFQUFyQywwQkFBVSxFQUFFLG9CQUFPLENBQW1CO1FBRTdDLE1BQU0sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBNEUsVUFBVSxHQUFHO1lBRWhIOztlQUVHO1lBQ0gsT0FBTyxDQUFDLFFBQVEsQ0FBQztnQkFDYixJQUFJLEVBQUUsOEJBQVcsQ0FBQyxxQkFBcUI7Z0JBQ3ZDLElBQUksRUFBRTtvQkFDRixLQUFLLEVBQUUsQ0FBQztvQkFDUixjQUFjLEVBQUUsT0FBTyxDQUFDLEtBQUs7aUJBQ0Q7YUFDbkMsQ0FBQyxDQUFDO1lBRUg7O2VBRUc7WUFDSCxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxrQkFBTSxDQUFDO2dCQUMxQixVQUFVLFlBQUE7Z0JBQ1YsT0FBTyxFQUFFO29CQUNMLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUTtvQkFDMUIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO29CQUNwQixPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87b0JBQ3hCLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtpQkFDakM7YUFDSixDQUFDLENBQUM7aUJBQ0UsRUFBRSxDQUFDLFVBQUEsVUFBVSxJQUFJLE9BQUEsR0FBRyxDQUFDLE1BQU0sQ0FBQztnQkFDekIsSUFBSSxFQUFFLHNDQUFzQixDQUFDLGVBQWU7Z0JBQzVDLElBQUksRUFBRTtvQkFDRixVQUFVLFlBQUE7b0JBQ1YsVUFBVSxZQUFBO29CQUNWLEtBQUssRUFBRSxDQUFDO2lCQUNRO2FBQ3ZCLENBQUMsRUFQZ0IsQ0FPaEIsQ0FBQztpQkFDRixPQUFPLEVBQUU7aUJBQ1QsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDO2lCQUNuQyxTQUFTLENBQUMsVUFBVSxDQUEyQztnQkFFNUQsSUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQztnQkFDeEIsSUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLDJCQUEyQixDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQzdFLElBQU0sTUFBTSxHQUFLLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBQSxDQUFDLElBQUksT0FBQSxDQUFDLENBQUMsSUFBSSxLQUFLLDRCQUFjLENBQUMsS0FBSyxFQUEvQixDQUErQixDQUFDLENBQUM7Z0JBRXRFLEdBQUcsQ0FBQyxNQUFNLENBQUM7b0JBQ1AsSUFBSSxFQUFFLHNDQUFzQixDQUFDLG1CQUFtQjtvQkFDaEQsSUFBSSxFQUFFO3dCQUNGLFFBQVEsVUFBQTt3QkFDUixPQUFPLFNBQUE7d0JBQ1AsTUFBTSxRQUFBO3dCQUNOLFVBQVUsWUFBQTt3QkFDVixPQUFPLEVBQUUsQ0FBQyxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUztxQkFDckI7aUJBQzNCLENBQUMsQ0FBQztnQkFFSCxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3BCLE9BQU8sQ0FBQyxRQUFRLENBQUM7d0JBQ2IsSUFBSSxFQUFFLDhCQUFXLENBQUMsY0FBYzt3QkFDaEMsSUFBSSxFQUFFOzRCQUNGLFFBQVEsRUFBRSxRQUFROzRCQUNsQixHQUFHLEVBQU8sT0FBTyxDQUFDLEdBQUc7NEJBQ3JCLEtBQUssRUFBSyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7NEJBQ2xDLE1BQU0sRUFBSSxPQUFPLENBQUMsTUFBTTs0QkFDeEIsT0FBTyxFQUFHLENBQUMsQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVM7NEJBQzFDLE9BQU8sU0FBQTs0QkFDUCxVQUFVLFlBQUE7eUJBQ2I7cUJBQ0osQ0FBQyxDQUFDO2dCQUNQLENBQUM7Z0JBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ0osT0FBTyxDQUFDLFFBQVEsQ0FBQzt3QkFDYixJQUFJLEVBQUUsOEJBQVcsQ0FBQyw4QkFBOEI7d0JBQ2hELElBQUksRUFBRTs0QkFDRixLQUFLLEVBQUUsQ0FBQzs0QkFDUixjQUFjLEVBQUUsT0FBTyxDQUFDLEtBQUs7NEJBQzdCLElBQUksRUFBRSxDQUFDLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxTQUFTO3lCQUN6QztxQkFDSixDQUFDLENBQUM7Z0JBQ1AsQ0FBQztnQkFFRCxJQUFNLFdBQVcsR0FBRyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsQ0FBQyxLQUFLLFVBQVUsQ0FBQyxVQUFVLEVBQTNCLENBQTJCLENBQUMsQ0FBQztnQkFFbkYsVUFBVSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFFL0IsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDO1FBQ1gsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDOztBQUNMLENBQUM7QUE5SUQsb0VBOElDO0FBRUQ7O0dBRUc7QUFDSCxvQ0FBMkMsT0FBZ0IsRUFBRSxPQUF1QjtJQUV6RSxJQUFBLDJCQUFRLENBQWE7SUFDckIsSUFBQSxvQ0FBUyxDQUFtQjtJQUVuQzs7T0FFRztJQUNILElBQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsa0JBQWtCLElBQUksbUJBQW1CLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBRTVGOztPQUVHO0lBQ0gsSUFBTSxtQkFBbUIsR0FBRztRQUN4QjtZQUNJLE1BQU0sRUFBRSxVQUFVO1lBQ2xCLE1BQU0sRUFBRSxVQUFVO1NBQ3JCO1FBQ0Q7WUFDSSxNQUFNLEVBQUUsVUFBVTtZQUNsQixNQUFNLEVBQUUsVUFBVTtTQUNyQjtRQUNEO1lBQ0ksTUFBTSxFQUFFLE9BQU87WUFDZixNQUFNLEVBQUUsT0FBTztTQUNsQjtLQUNKLENBQUM7SUFFRixNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxPQUFPLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ3BGLENBQUM7QUE3QkQsZ0VBNkJDO0FBRUQsNkJBQW9DLE9BQWdCLEVBQUUsUUFBMEI7SUFFNUUsYUFBYTtJQUNiLEtBQUssQ0FBQyxTQUFPLE9BQU8sQ0FBQyxVQUFVLG1CQUFjLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFHLENBQUMsQ0FBQztJQUN6RixpQkFBaUI7SUFFakIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLFVBQUMsUUFBaUM7UUFFMUQsYUFBYTtRQUNiLEtBQUssQ0FBQyxXQUFTLE9BQU8sQ0FBQyxVQUFVLFVBQUssT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLG1CQUFjLE9BQU8sQ0FBQyxRQUFRLE1BQUcsQ0FBQyxDQUFDO1FBQ2hHLEtBQUssQ0FBQyxrQkFBTSxPQUFPLENBQUMsS0FBSyxDQUFDLE1BQU0sZ0JBQVcsT0FBTyxDQUFDLEtBQUssTUFBRyxDQUFDLENBQUM7UUFDN0QsaUJBQWlCO1FBRWpCLElBQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDO2FBRS9FLEVBQUUsQ0FBQyxLQUFLLEVBQUUsVUFBVSxLQUFLLEVBQUUsSUFBSTtZQUM1QixLQUFLLENBQUMsaUNBQXFCLEtBQUssV0FBTSxJQUFNLENBQUMsQ0FBQztZQUM5QyxRQUFRLENBQUMsTUFBTSxDQUFDO2dCQUNaLEtBQUssRUFBRSxLQUFLO2dCQUNaLElBQUksRUFBRSxJQUFJO2dCQUNWLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTthQUNqQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQztRQUVQLGVBQWUsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFO1lBRXhCLGFBQWE7WUFDYixLQUFLLENBQUMsZ0JBQVMsT0FBTyxDQUFDLFVBQVUseUJBQW9CLE9BQU8sQ0FBQyxRQUFRLE1BQUcsQ0FBQyxDQUFDO1lBQzFFLGlCQUFpQjtZQUVqQixFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN6RCxRQUFRLENBQUMsRUFBQyxJQUFJLEVBQUUsOEJBQVcsQ0FBQyxjQUFjLEVBQUUsSUFBSSxFQUFFLEVBQUMsT0FBTyxTQUFBLEVBQUMsRUFBQyxDQUFDLENBQUM7WUFDbEUsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDO1lBQ0gsS0FBSyxDQUFDLFdBQVMsT0FBTyxDQUFDLFFBQVUsQ0FBQyxDQUFDO1lBQ25DLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM1QixDQUFDLENBQUM7SUFDTixDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUF4Q0Qsa0RBd0NDO0FBRUQ7O0dBRUc7QUFDSCx3QkFBd0IsTUFBMEIsRUFBRSxLQUF5QyxFQUFFLE9BQXVCLEVBQUUsU0FBVTtJQUM5SCxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFDLE9BQU8sRUFBRSxJQUFJO1FBQzlCLElBQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbkMsRUFBRSxDQUFDLENBQUMsS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNoRSxDQUFDO1FBQ0QsTUFBTSxDQUFDLE9BQU8sQ0FBQztJQUNuQixDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDZixDQUFDIn0=
\No newline at end of file