Blame view

esm2015/lib/_services/request.service.js 118 KB
75f29219   Anan Sangthongtum   first commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
 */
import * as tslib_1 from "tslib";
import { Injectable } from '@angular/core';
import { Http, Headers, URLSearchParams, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Router } from '@angular/router';
import * as _ from 'lodash';
import * as is from 'is_js';
import { ResultCode as RESULT_CODE } from '../model/result-code';
import { AppConfigService } from '../app-config/app-config.service';
import { Common } from './common.service';
import { B2bService } from './b2b.service';
import { HttpClient, HttpHeaders } from '@angular/common/http';
export class Request {
    /**
     * @param {?} appConfigService
     * @param {?} httpClient
     * @param {?} http
     * @param {?} router
     * @param {?} common
     * @param {?} b2bService
     */
    constructor(appConfigService, httpClient, http, router, common, b2bService) {
        this.appConfigService = appConfigService;
        this.httpClient = httpClient;
        this.http = http;
        this.router = router;
        this.common = common;
        this.b2bService = b2bService;
        this.config = appConfigService.getConfig();
        this.api = _.get(this.config, 'apiServers.tomcat.url');
        this.system_id = _.get(this.config, 'system_id');
        // this.api = 'https://d.gaizers.com/RestAPI';
    }
    /**
     * fn. get data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น
     * @param {?} customStoreOptions โยนค่าต่าง ๆ มาในนี้
     * @return {?}
     */
    getCustomStore(customStoreOptions) {
        /** @type {?} */
        const url = customStoreOptions.url || '';
        /** @type {?} */
        const data = customStoreOptions.filter || {};
        /** @type {?} */
        const loadMode = customStoreOptions.loadMode || 'processed';
        /** @type {?} */
        const params = new URLSearchParams();
        for (const key in data) {
            if (key === 'filter') {
                if (data[key] !== '{}') {
                    params.set(key, data[key]);
                }
            }
            else {
                params.set(key, data[key]);
            }
        }
        console.log('​Request -> getCustomStore -> params', params);
        /** @type {?} */
        let userData = this.b2bService.getVerifyToken();
        /** @type {?} */
        let headerData = {
            system_id: this.system_id,
            department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "",
            username: userData.username
        };
        /** @type {?} */
        const headers = new Headers();
        headers.append('x-Token', '1');
        headers.append('x-user-data', this.utoa(JSON.stringify(headerData)));
        /** @type {?} */
        const options = new RequestOptions({ headers: headers, withCredentials: true });
        options.search = params;
        return this.http.get(this.api + url, options)
            .map((res) => {
            /** @type {?} */
            const resData = res.json();
            console.log('​Request -> getCustomStore -> resData', resData);
            if (loadMode === 'processed') {
                return this.fnHandleResponseProcessedMode(resData);
            }
            else {
                return this.fnHandleResponseRawMode(resData);
            }
        })
            .toPromise()
            .catch((error) => {
            console.log('​Request -> getCustomStore -> error', error);
            if (loadMode === 'processed') {
                return this.fnHandleErrorProcessedMode(error);
            }
            else {
                return this.fnHandleErrorRawMode(error);
            }
        });
    }
    /**
     * fn. post data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น
     * @param {?} customStoreOptions โยนค่าต่าง ๆ มาในนี้
     * @return {?}
     */
    postCustomStore(customStoreOptions) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            /** @type {?} */
            const url = customStoreOptions.url || '';
            /** @type {?} */
            const data = JSON.parse(JSON.stringify(customStoreOptions.filter, this.common.replacer)) || {};
            /** @type {?} */
            const loadMode = customStoreOptions.loadMode || 'processed';
            /** @type {?} */
            let userData = this.b2bService.getVerifyToken();
            /** @type {?} */
            let headerData = {
                system_id: this.system_id,
                department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "",
                username: userData.username
            };
            /** @type {?} */
            const headers = new Headers();
            headers.append('x-Token', '1');
            headers.append('x-user-data', this.utoa(JSON.stringify(headerData)));
            /** @type {?} */
            const options = new RequestOptions({ headers: headers, withCredentials: true });
            return this.http.post(this.api + url, data, options)
                .map((res) => {
                /** @type {?} */
                const resData = res.json();
                console.log('​Request -> getCustomStore -> resData', resData);
                if (loadMode === 'processed') {
                    return this.fnHandleResponseProcessedMode(resData);
                }
                else {
                    return this.fnHandleResponseRawMode(resData);
                }
            })
                .toPromise()
                .catch((error) => {
                console.log('​Request -> getCustomStore -> error', error);
                if (loadMode === 'processed') {
                    return this.fnHandleErrorProcessedMode(error);
                }
                else {
                    return this.fnHandleErrorRawMode(error);
                }
            });
        });
    }
    /**
     * fn. post data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น
     * @param {?} customStoreOptions โยนค่าต่าง ๆ มาในนี้
     * @return {?}
     */
    postCustomStore31(customStoreOptions) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            /** @type {?} */
            const url = customStoreOptions.url || '';
            /** @type {?} */
            const data = JSON.parse(JSON.stringify(customStoreOptions.filter, this.common.replacer)) || {};
            /** @type {?} */
            const loadMode = customStoreOptions.loadMode || 'processed';
            /** @type {?} */
            let userData = this.b2bService.getVerifyToken();
            /** @type {?} */
            let headerData = {
                system_id: 31,
                department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "",
                username: userData.username
            };
            /** @type {?} */
            const headers = new Headers();
            headers.append('x-Token', '1');
            headers.append('x-user-data', this.utoa(JSON.stringify(headerData)));
            /** @type {?} */
            const options = new RequestOptions({ headers: headers, withCredentials: true });
            return this.http.post(this.api + url, data, options)
                .map((res) => {
                /** @type {?} */
                const resData = res.json();
                console.log('​Request -> getCustomStore -> resData', resData);
                if (loadMode === 'processed') {
                    return this.fnHandleResponseProcessedMode(resData);
                }
                else {
                    return this.fnHandleResponseRawMode(resData);
                }
            })
                .toPromise()
                .catch((error) => {
                console.log('​Request -> getCustomStore -> error', error);
                if (loadMode === 'processed') {
                    return this.fnHandleErrorProcessedMode(error);
                }
                else {
                    return this.fnHandleErrorRawMode(error);
                }
            });
        });
    }
    /**
     * ถ้า getCustomStore แล้ว error กรณี loadMode = 'processed'
     * @param {?} error
     * @return {?}
     */
    fnHandleErrorProcessedMode(error) {
        // alert('ERROR ' + error);
        console.error('ERROR ' + error);
        return {
            data: [],
            totalCount: 0
        };
    }
    /**
     * ถ้า getCustomStore แล้ว error กรณี loadMode = 'raw'
     * @param {?} error
     * @return {?}
     */
    fnHandleErrorRawMode(error) {
        // alert('ERROR ' + error);
        console.error('ERROR ' + error);
        return [];
    }
    /**
     * fn. get data สำหรับดึงข้อมูลทั่วไป
     * @param {?} url ex /test
     * @param {?=} data ค่าต่างที่ต้องการแนบไปกับ API
     * @return {?}
     */
    get(url, data) {
        /** @type {?} */
        const params = new URLSearchParams();
        for (const key in data) {
            if (key === 'filter') {
                if (data[key] !== '{}') {
                    params.set(key, data[key]);
                }
            }
            else {
                params.set(key, data[key]);
            }
        }
        console.log('​Request -> getCustomStore -> params', params);
        /** @type {?} */
        let userData = this.b2bService.getVerifyToken();
        /** @type {?} */
        let headerData = {
            system_id: this.system_id,
            department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "",
            username: userData.username
        };
        /** @type {?} */
        const headers = new Headers();
        headers.append('x-Token', '1');
        headers.append('x-user-data', this.utoa(JSON.stringify(headerData)));
        headers.append('Authorization', 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRlc3QiLCJzZXNzaW9uSWQiOiJjNzQwNDdiZi1jNGUwLTQxOTMtOTRiNy1jOGI4M2ViYjhlMGMiLCJpYXQiOjE1NDM5NDYyNDYsImV4cCI6MTU0NDU1MTA0Nn0.5y9f2ZYieRZHhGIMTryxuvsAjJYzvFnWnpcYLk1hSXw');
        /** @type {?} */
        const options = new RequestOptions({ headers: headers, withCredentials: true });
        options.search = params;
        return this.http.get(this.api + url, options)
            .map((res) => {
            /** @type {?} */
            const resData = res.json();
            return this.fnHandleResponse(resData);
        })
            .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
    }
    /**
     * fn. get data สำหรับดึงข้อมูลทั่วไป
     * @param {?} url ex /test
     * @param {?=} data ค่าต่างที่ต้องการแนบไปกับ API
     * @return {?}
     */
    get31(url, data) {
        /** @type {?} */
        const params = new URLSearchParams();
        for (const key in data) {
            if (key === 'filter') {
                if (data[key] !== '{}') {
                    params.set(key, data[key]);
                }
            }
            else {
                params.set(key, data[key]);
            }
        }
        console.log('​Request -> getCustomStore -> params', params);
        /** @type {?} */
        let userData = this.b2bService.getVerifyToken();
        /** @type {?} */
        let headerData = {
            system_id: 31,
            department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "",
            username: userData.username
        };
        /** @type {?} */
        const headers = new Headers();
        headers.append('x-Token', '1');
        headers.append('x-user-data', this.utoa(JSON.stringify(headerData)));
        headers.append('Authorization', 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRlc3QiLCJzZXNzaW9uSWQiOiJjNzQwNDdiZi1jNGUwLTQxOTMtOTRiNy1jOGI4M2ViYjhlMGMiLCJpYXQiOjE1NDM5NDYyNDYsImV4cCI6MTU0NDU1MTA0Nn0.5y9f2ZYieRZHhGIMTryxuvsAjJYzvFnWnpcYLk1hSXw');
        /** @type {?} */
        const options = new RequestOptions({ headers: headers, withCredentials: true });
        options.search = params;
        return this.http.get(this.api + url, options)
            .map((res) => {
            /** @type {?} */
            const resData = res.json();
            return this.fnHandleResponse(resData);
        })
            .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
    }
    /**
     * fn. get data สำหรับดึงข้อมูลทั่วไป
     * @param {?} url ex /test
     * @param {?=} headers
     * @return {?}
     */
    getCustom(url, headers) {
        if (!headers) {
            headers = new Headers();
        }
        /** @type {?} */
        const options = new RequestOptions({ headers: headers });
        return this.http.get(url, options)
            .map((res) => {
            /** @type {?} */
            const resData = res.json();
            return this.fnHandleResponse(resData);
        })
            .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
    }
    /**
     * fn. get data สำหรับดึงข้อมูลทั่วไป
     * @param {?} url ex /test
     * @param {?=} headers
     * @return {?}
     */
    getRawResponse(url, headers) {
        if (!headers) {
            headers = new Headers();
        }
        /** @type {?} */
        const options = new RequestOptions({ headers: headers });
        return this.http.get(url, options)
            .map((res) => {
            return res.json();
        })
            .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
    }
    /**
     * fn. delete data สำหรับลบข้อมูลทั่วไป
     * @param {?} url ex /test
     * @param {?=} data ค่าต่างที่ต้องการแนบไปกับ API
     * @return {?}
     */
    delete(url, data) {
        /** @type {?} */
        const params = new URLSearchParams();
        for (const key in data) {
            if (key === 'filter') {
                if (data[key] !== '{}') {
                    params.set(key, data[key]);
                }
            }
            else {
                params.set(key, data[key]);
            }
        }
        console.log('​Request -> getCustomStore -> params', params);
        /** @type {?} */
        let userData = this.b2bService.getVerifyToken();
        /** @type {?} */
        let headerData = {
            system_id: this.system_id,
            department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "",
            username: userData.username
        };
        /** @type {?} */
        const headers = new Headers();
        headers.append('x-Token', '1');
        headers.append('x-user-data', this.utoa(JSON.stringify(headerData)));
        /** @type {?} */
        const options = new RequestOptions({ headers: headers, withCredentials: true });
        options.search = params;
        return this.http.delete(this.api + url, options)
            .map((res) => {
            return res.json();
        })
            .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
    }
    /**
     * fn. post data สำหรับสร้างข้อมูลทั่วไป
     * @param {?} url ex /test
     * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API
     * @return {?}
     */
    post(url, data) {
        data = JSON.parse(JSON.stringify(data, this.common.replacer));
        console.log('​post -> data', data);
        console.log('​post -> data', typeof data);
        /** @type {?} */
        const params = new URLSearchParams();
        /** @type {?} */
        let userData = this.b2bService.getVerifyToken();
        /** @type {?} */
        let headerData = {
            system_id: this.system_id,
            department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "",
            username: userData.username
        };
        /** @type {?} */
        const headers = new Headers();
        headers.append('x-Token', '1');
        headers.append('x-user-data', this.utoa(JSON.stringify(headerData)));
        headers.append('Content-Type', 'application/json');
        /** @type {?} */
        const options = new RequestOptions({ headers: headers, withCredentials: true });
        return this.http.post(this.api + url, data, options)
            .map((res) => {
            return res.json();
        })
            .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
    }
    /**
     * fn. post data สำหรับสร้างข้อมูลทั่วไป
     * @param {?} url ex /test
     * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API
     * @return {?}
     */
    post31(url, data) {
        data = JSON.parse(JSON.stringify(data, this.common.replacer));
        console.log('​post -> data', data);
        console.log('​post -> data', typeof data);
        /** @type {?} */
        const params = new URLSearchParams();
        /** @type {?} */
        let userData = this.b2bService.getVerifyToken();
        /** @type {?} */
        let headerData = {
            system_id: 31,
            department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "",
            username: userData.username
        };
        /** @type {?} */
        const headers = new Headers();
        headers.append('x-Token', '1');
        headers.append('x-user-data', this.utoa(JSON.stringify(headerData)));
        headers.append('Content-Type', 'application/json');
        /** @type {?} */
        const options = new RequestOptions({ headers: headers, withCredentials: true });
        return this.http.post(this.api + url, data, options)
            .map((res) => {
            return res.json();
        })
            .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
    }
    /**
     * fn. post data สำหรับสร้างข้อมูลทั่วไป
     * @param {?} url ex /test
     * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API
     * @return {?}
     */
    post14(url, data) {
        data = JSON.parse(JSON.stringify(data, this.common.replacernotrim));
        console.log('​post -> data', data);
        console.log('​post -> data', typeof data);
        /** @type {?} */
        const params = new URLSearchParams();
        /** @type {?} */
        let userData = this.b2bService.getVerifyToken();
        /** @type {?} */
        let headerData = {
            system_id: this.system_id,
            department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "",
            username: userData.username
        };
        /** @type {?} */
        const headers = new Headers();
        headers.append('x-Token', '1');
        headers.append('x-user-data', this.utoa(JSON.stringify(headerData)));
        headers.append('Content-Type', 'application/json');
        /** @type {?} */
        const options = new RequestOptions({ headers: headers, withCredentials: true });
        return this.http.post(this.api + url, data, options)
            .map((res) => {
            return res.json();
        })
            .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
    }
    /**
     * fn. post data สำหรับสร้างข้อมูลทั่วไป
     * @param {?} url ex /test
     * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API
     * @param {?=} headers
     * @return {?}
     */
    postCustom(url, data, headers) {
        console.log('​post -> data', data);
        console.log('​post -> data', typeof data);
        if (!headers) {
            headers = new Headers();
            headers.append('Content-Type', 'application/json');
        }
        /** @type {?} */
        const options = new RequestOptions({ headers: headers, withCredentials: true });
        return this.http.post(url, data, options)
            .map((res) => {
            return res.json();
        })
            .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
    }
    /**
     * fn. put data สำหรับอัพเดตข้อมูลทั่วไป
     * @param {?} url ex /test
     * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API
     * @return {?}
     */
    put(url, data) {
        /** @type {?} */
        const params = new URLSearchParams();
        /** @type {?} */
        let userData = this.b2bService.getVerifyToken();
        /** @type {?} */
        let headerData = {
            system_id: this.system_id,
            department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "",
            username: userData.username
        };
        /** @type {?} */
        const headers = new Headers();
        headers.append('x-Token', '1');
        headers.append('x-user-data', this.utoa(JSON.stringify(headerData)));
        headers.append('Content-Type', 'application/json');
        /** @type {?} */
        const options = new RequestOptions({ headers: headers, withCredentials: true });
        return this.http.put(this.api + url, data, options)
            .map((res) => {
            return res.json();
        })
            .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
    }
    /**
     * ถ้า getCustomStore แล้ว success กรณี loadMode = 'processed'
     * @param {?} resData
     * @return {?}
     */
    fnHandleResponseProcessedMode(resData) {
        /** @type {?} */
        const customStoreData = {
            data: [],
            totalCount: 0
        };
        /** @type {?} */
        let code = '';
        /** @type {?} */
        let description = '';
        /** @type {?} */
        let data = [];
        /** @type {?} */
        let rowCount = 0;
        if (is.array(resData)) {
            data = resData;
            rowCount = _.size(data);
        }
        else {
            /** เปลี่ยนไปตามรูปแบบ response */
            code = resData.resultCode || '';
            description = resData.resultDescription || '';
            data = resData.resultData || [];
            rowCount = resData.rowCount || 0; // เปลี่ยนไปตาม Response
            /** */
        }
        if (code === RESULT_CODE.ERROR) {
            console.log('​fnHandleResponseProcessedMode -> RESULT_CODE.ERROR', RESULT_CODE.ERROR);
        }
        else if (code === RESULT_CODE.NOT_FOUND) {
            console.log('​fnHandleResponseProcessedMode -> RESULT_CODE.NOT_FOUND', RESULT_CODE.NOT_FOUND);
        }
        else {
            customStoreData.data = data;
            customStoreData.totalCount = rowCount;
        }
        return customStoreData;
    }
    /**
     * ถ้า getCustomStore แล้ว success กรณี loadMode = 'raw'
     * @param {?} resData
     * @return {?}
     */
    fnHandleResponseRawMode(resData) {
        /** @type {?} */
        let code = '';
        /** @type {?} */
        let description = '';
        /** @type {?} */
        let data = [];
        if (is.array(resData)) {
            data = resData;
        }
        else {
            /** เปลี่ยนไปตามรูปแบบ response */
            code = resData.resultCode || '';
            description = resData.resultDescription || '';
            data = resData.resultData || [];
            /** */
        }
        if (code === RESULT_CODE.ERROR) {
            alert('ERROR:' + RESULT_CODE.ERROR);
            return [];
        }
        else if (code === RESULT_CODE.NOT_FOUND) {
            alert('ERROR:' + RESULT_CODE.NOT_FOUND);
            return [];
        }
        else {
            return data;
        }
    }
    /**
     * @param {?} resData
     * @return {?}
     */
    fnHandleResponse(resData) {
        /** @type {?} */
        let code = '';
        /** @type {?} */
        let description = '';
        /** @type {?} */
        let data = [];
        if (is.array(resData)) {
            data = resData;
        }
        else if (resData.data && is.array(resData.data)) {
            data = resData.data;
        }
        else {
            /** เปลี่ยนไปตามรูปแบบ response */
            code = resData.resultCode || '';
            description = resData.resultDescription || '';
            data = resData.resultData || [];
            /** */
        }
        if (code === RESULT_CODE.ERROR) {
            console.log('​fnHandleResponse -> RESULT_CODE.ERROR', RESULT_CODE.ERROR);
            return [];
        }
        else if (code === RESULT_CODE.NOT_FOUND) {
            console.log('​fnHandleResponse -> RESULT_CODE.NOT_FOUND', RESULT_CODE.NOT_FOUND);
            return [];
        }
        else {
            return data;
        }
    }
    /**
     * fn ดึงข้อมูลเพื่อใช้ใน Dropdown List
     * @param {?} systemId เลขรหัสระบบที่ต้องการดึง
     * @param {?} dropDownType ประเภทข้อมูล dropdown ที่ต้องการดึง
     * @param {?=} code
     * @return {?}
     */
    getDropDown(systemId, dropDownType, code) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                const data = {
                    filter: {
                        system_id: systemId,
                        dropdown_type: dropDownType,
                        code: code
                    },
                    limit: 1000,
                    offset: 0,
                    order_by: ['id asc']
                };
                /** @type {?} */
                const urlDropdown = _.get(this.config, 'apiServers.tomcat.api.ct_dropdown_search');
                if (systemId === 31) {
                    /** @type {?} */
                    const resData = yield this.post31(urlDropdown, data);
                    return resData.resultData;
                }
                else {
                    /** @type {?} */
                    const resData = yield this.post(urlDropdown, data);
                    return resData.resultData;
                }
            }
            catch (error) {
                console.log('catch -> error', error);
                return [];
            }
        });
    }
    /**
     * @param {?=} parentId
     * @return {?}
     */
    getDepartment(parentId = 0) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                const data = {
                    filter: { ref_department_id: parentId },
                    limit: 1000,
                    offset: 0,
                    order_by: ['name asc']
                };
                /** @type {?} */
                const urlDropdown = _.get(this.config, 'apiServers.tomcat.api.ct_department_search');
                /** @type {?} */
                const resData = yield this.post(urlDropdown, data);
                return resData.resultData;
            }
            catch (error) {
                console.log('catch -> error', error);
                return [];
            }
        });
    }
    /**
     * @return {?}
     */
    getExtDepartment() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                const data = {
                    filter: {},
                    limit: 1000,
                    offset: 0,
                    order_by: ['name asc']
                };
                /** @type {?} */
                const urlDropdown = _.get(this.config, 'apiServers.tomcat.api.ct_ext_department_search');
                /** @type {?} */
                const resData = yield this.post(urlDropdown, data);
                return resData.resultData;
            }
            catch (error) {
                console.log('catch -> error', error);
                return [];
            }
        });
    }
    /**
     * @param {?} system_id
     * @return {?}
     */
    getCategory(system_id) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                const urlStep = _.get(this.config, 'apiServers.tomcat.api.ct_category');
                /** @type {?} */
                const params = `?_where=(system_id,eq,${system_id})&_sort=seq_no`;
                /** @type {?} */
                const resData = yield this.get(urlStep + params);
                return resData;
            }
            catch (error) {
                console.log('catch -> error', error);
                return [];
            }
        });
    }
    /**
     * @param {?} category_id
     * @return {?}
     */
    getStepName(category_id) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                const urlStep = _.get(this.config, 'apiServers.tomcat.api.ct_step');
                /** @type {?} */
                const params = `?_where=(category_id,eq,${category_id})&_sort=seq_no`;
                /** @type {?} */
                const resData = yield this.get(urlStep + params);
                return resData;
            }
            catch (error) {
                console.log('catch -> error', error);
                return [];
            }
        });
    }
    /**
     * @param {?} url
     * @return {?}
     */
    getAttachment(url) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                const headers = new Headers();
                headers.append('Authorization', 'Basic ' + btoa('APPSOC:123456'));
                /** @type {?} */
                const resData = yield this.getCustom(url, headers);
                return resData;
            }
            catch (error) {
                console.log('catch -> error', error);
                return error;
            }
        });
    }
    /**
     * @param {?} url
     * @param {?} data
     * @return {?}
     */
    postAttachment(url, data) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                const headers = new Headers();
                headers.append('Authorization', 'Basic ' + btoa('APPSOC:123456'));
                headers.append('test', 'test');
                /** @type {?} */
                const resData = yield this.postCustom(url, data, headers);
                return resData;
            }
            catch (error) {
                console.log('catch -> error', error);
                return error;
            }
        });
    }
    /**
     * @return {?}
     */
    getUserLevel() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                const data = {
                    filter: {},
                    limit: 1000,
                    offset: 0,
                    order_by: ['level asc']
                };
                /** @type {?} */
                const urlDropdown = _.get(this.config, 'apiServers.tomcat.api.ct_user_level_search');
                /** @type {?} */
                const resData = yield this.post(urlDropdown, data);
                return resData;
            }
            catch (error) {
                console.log('catch -> error', error);
                return [];
            }
        });
    }
    /**
     * @param {?} table
     * @param {?} idList
     * @return {?}
     */
    multipleDeleteMain(table, idList) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                let url = "/" + table.split("_")[0] + "/main";
                /** @type {?} */
                let deleteObj = {};
                deleteObj[table] = [];
                for (let id of idList) {
                    /** @type {?} */
                    let tmp = {
                        id: id,
                        action: "delete"
                    };
                    deleteObj[table].push(tmp);
                }
                /** @type {?} */
                const resData = yield this.post(url, [deleteObj]);
                if (resData.resultCode === 20000) {
                    idList = [];
                }
                return resData;
            }
            catch (error) {
                console.log('catch -> error', error);
                return [];
            }
        });
    }
    /**
     * @param {?} url
     * @return {?}
     */
    getAttachmentLinkToken(url) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            return url + '?downloadToken=' + this.b2bService.getAttachmentToken() + '&inline=true';
        });
    }
    /**
     * @param {?} data
     * @param {?} fieldList
     * @param {?} modal
     * @return {?}
     */
    checkSpell(data, fieldList, modal) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            /** @type {?} */
            let url = "/spellCheck";
            /** @type {?} */
            let body = {};
            for (let field of fieldList) {
                if (data[field.field]) {
                    body[field.field] = {
                        value: data[field.field],
                        display: field.display
                    };
                }
            }
            /** @type {?} */
            let resData = yield this.post(url, body);
            /** @type {?} */
            let spellCheck = JSON.parse(resData.resultData);
            if (_.size(spellCheck) === 0) {
                return true;
            }
            else {
                modal.open(spellCheck);
                return false;
            }
        });
    }
    /**
     * @param {?} url
     * @param {?=} headers
     * @return {?}
     */
    getQualification(url, headers) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!headers) {
                headers = new Headers();
            }
            /** @type {?} */
            const options = new RequestOptions({ headers: headers, withCredentials: true });
            return this.http.get(url, options)
                .map((res) => {
                return res.json();
            })
                .catch((error) => Observable.throw(error.json().error || 'Server error')).toPromise();
        });
    }
    /**
     * @return {?}
     */
    verifyUserName() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            /** @type {?} */
            let verifyToken = yield this.b2bService.verify();
            if (+verifyToken.resultCode === 20000) {
                /** @type {?} */
                let data = verifyToken.resultData;
                /** @type {?} */
                let phoneBookData = data.phoneBookData && data.phoneBookData.length > 0 ? data.phoneBookData[0] : {};
                return phoneBookData.name;
            }
        });
    }
    /**
     * @param {?} str
     * @return {?}
     */
    utoa(str) {
        return window.btoa(unescape(encodeURIComponent(str)));
    }
    /**
     * @param {?} api
     * @return {?}
     */
    downloadImgToBase64(api) {
        return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                let httpOptions = {
                    headers: new HttpHeaders({ "Authorization": "Basic " + btoa('APPSOC:123456') })
                };
                /** @type {?} */
                let blob = yield this.httpClient.get(api, { headers: httpOptions.headers, responseType: "blob" }).toPromise();
                /** @type {?} */
                let reader = new FileReader();
                reader.readAsDataURL(blob);
                reader.onloadend = function () {
                    /** @type {?} */
                    var base64data = reader.result;
                    resolve(base64data);
                };
            }
            catch (err) {
                console.log(err);
                resolve(false);
            }
        }));
    }
    /**
     * @param {?} api
     * @return {?}
     */
    downloadView(api) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                let httpOptions = {
                    headers: new HttpHeaders({ "Authorization": "Basic " + btoa('APPSOC:123456') })
                };
                /** @type {?} */
                let blob = yield this.httpClient.get(api, { headers: httpOptions.headers, responseType: "blob" }).toPromise();
                /** @type {?} */
                let url = window.URL.createObjectURL(blob, { oneTimeOnly: true });
                window.open(url, '_blank');
            }
            catch (err) {
                console.log(err);
            }
        });
    }
    /**
     * @param {?} api
     * @return {?}
     */
    download(api) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                /** @type {?} */
                let w = window.open();
                w.document.writeln("");
                /** @type {?} */
                let httpOptions = {
                    headers: new HttpHeaders({ "Authorization": "Basic " + btoa('APPSOC:123456') })
                };
                /** @type {?} */
                let blob = yield this.httpClient.get(api, { headers: httpOptions.headers, responseType: "blob" }).toPromise();
                /** @type {?} */
                let url = window.URL.createObjectURL(blob);
                w.location.href = url;
            }
            catch (err) {
                console.log(err);
            }
        });
    }
}
Request.decorators = [
    { type: Injectable }
];
/** @nocollapse */
Request.ctorParameters = () => [
    { type: AppConfigService },
    { type: HttpClient },
    { type: Http },
    { type: Router },
    { type: Common },
    { type: B2bService }
];
if (false) {
    /** @type {?} */
    Request.prototype.config;
    /** @type {?} */
    Request.prototype.api;
    /** @type {?} */
    Request.prototype.system_id;
    /** @type {?} */
    Request.prototype.appConfigService;
    /** @type {?} */
    Request.prototype.httpClient;
    /** @type {?} */
    Request.prototype.http;
    /** @type {?} */
    Request.prototype.router;
    /** @type {?} */
    Request.prototype.common;
    /** @type {?} */
    Request.prototype.b2bService;
}

//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vc29jLWFwcC1saWJyYXJ5LyIsInNvdXJjZXMiOlsibGliL19zZXJ2aWNlcy9yZXF1ZXN0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFZLGVBQWUsRUFBRSxjQUFjLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDdkYsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUdoQyxPQUFPLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sS0FBSyxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBRzVCLE9BQU8sRUFBQyxVQUFVLElBQUksV0FBVyxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDL0QsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFDbEUsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQ3hDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFekMsT0FBTyxFQUFDLFVBQVUsRUFBNEIsV0FBVyxFQUE0QixNQUFNLHNCQUFzQixDQUFDO0FBRWxILE1BQU07Ozs7Ozs7OztJQUtGLFlBQW9CLGdCQUFrQyxFQUFTLFVBQXNCLEVBQVMsSUFBVSxFQUFVLE1BQWMsRUFBVSxNQUFjLEVBQVUsVUFBc0I7UUFBcEsscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUFTLGVBQVUsR0FBVixVQUFVLENBQVk7UUFBUyxTQUFJLEdBQUosSUFBSSxDQUFNO1FBQVUsV0FBTSxHQUFOLE1BQU0sQ0FBUTtR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YmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7SHR0cCwgSGVhZGVycywgUmVzcG9uc2UsIFVSTFNlYXJjaFBhcmFtcywgUmVxdWVzdE9wdGlvbnN9IGZyb20gJ0Bhbmd1bGFyL2h0dHAnO1xuaW1wb3J0IHtPYnNlcnZhYmxlfSBmcm9tICdyeGpzJztcbi8vIGltcG9ydCB7IGVudmlyb25tZW50IH0gZnJvbSAnLi4vLi4vLi4vZW52aXJvbm1lbnRzL2Vudmlyb25tZW50Jztcbi8vIEltcG9ydCBSeEpzIHJlcXVpcmVkIG1ldGhvZHNcbmltcG9ydCAncnhqcy9hZGQvb3BlcmF0b3IvbWFwJztcbmltcG9ydCAncnhqcy9hZGQvb3BlcmF0b3IvY2F0Y2gnO1xuaW1wb3J0IHtSb3V0ZXJ9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgKiBhcyBpcyBmcm9tICdpc19qcyc7XG5pbXBvcnQge0N1c3RvbVN0b3JlRGF0YX0gZnJvbSAnLi4vbW9kZWwvY3VzdG9tLXN0b3JlLWRhdGEnO1xuaW1wb3J0IHtDdXN0b21TdG9yZU9wdGlvbnN9IGZyb20gJy4uL21vZGVsL2N1c3RvbS1zdG9yZS1vcHRpb25zJztcbmltcG9ydCB7UmVzdWx0Q29kZSBhcyBSRVNVTFRfQ09ERX0gZnJvbSAnLi4vbW9kZWwvcmVzdWx0LWNvZGUnO1xuaW1wb3J0IHtBcHBDb25maWdTZXJ2aWNlfSBmcm9tICcuLi9hcHAtY29uZmlnL2FwcC1jb25maWcuc2VydmljZSc7XG5pbXBvcnQge0NvbW1vbn0gZnJvbSAnLi9jb21tb24uc2VydmljZSc7XG5pbXBvcnQge0IyYlNlcnZpY2V9IGZyb20gJy4vYjJiLnNlcnZpY2UnO1xuaW1wb3J0IHtNb2RhbFNwZWxsQ2hlY2tDb21wb25lbnR9IGZyb20gJy4uL21vZGFsLXNwZWxsLWNoZWNrL21vZGFsLXNwZWxsLWNoZWNrLmNvbXBvbmVudCc7XG5pbXBvcnQge0h0dHBDbGllbnQsIEh0dHBFdmVudCwgSHR0cEV2ZW50VHlwZSwgSHR0cEhlYWRlcnMsIEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2V9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBSZXF1ZXN0IHtcbiAgICBjb25maWc6IGFueTtcbiAgICBhcGk6IGFueTtcbiAgICBzeXN0ZW1faWQ6IGFueTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgYXBwQ29uZmlnU2VydmljZTogQXBwQ29uZmlnU2VydmljZSwgcHVibGljIGh0dHBDbGllbnQ6IEh0dHBDbGllbnQsIHB1YmxpYyBodHRwOiBIdHRwLCBwcml2YXRlIHJvdXRlcjogUm91dGVyLCBwcml2YXRlIGNvbW1vbjogQ29tbW9uLCBwcml2YXRlIGIyYlNlcnZpY2U6IEIyYlNlcnZpY2UpIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBhcHBDb25maWdTZXJ2aWNlLmdldENvbmZpZygpO1xuICAgICAgICB0aGlzLmFwaSA9IF8uZ2V0KHRoaXMuY29uZmlnLCAnYXBpU2VydmVycy50b21jYXQudXJsJyk7XG4gICAgICAgIHRoaXMuc3lzdGVtX2lkID0gXy5nZXQodGhpcy5jb25maWcsICdzeXN0ZW1faWQnKTtcbiAgICAgICAgLy8gdGhpcy5hcGkgPSAnaHR0cHM6Ly9kLmdhaXplcnMuY29tL1Jlc3RBUEknO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGZuLiBnZXQgZGF0YSDguKrguLPguKvguKPguLHguJrguJTguLbguIfguILguYnguK3guKHguLnguKXguKrguLPguKvguKPguLHguJogRGF0YWdyaWQg4LmA4LiX4LmI4Liy4LiZ4Lix4LmJ4LiZXG4gICAgICogQHBhcmFtIGN1c3RvbVN0b3JlT3B0aW9ucyDguYLguKLguJnguITguYjguLLguJXguYjguLLguIcg4LmGIOC4oeC4suC5g+C4meC4meC4teC5iVxuICAgICAqL1xuICAgIGdldEN1c3RvbVN0b3JlKGN1c3RvbVN0b3JlT3B0aW9uczogQ3VzdG9tU3RvcmVPcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IGN1c3RvbVN0b3JlT3B0aW9ucy51cmwgfHwgJyc7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBjdXN0b21TdG9yZU9wdGlvbnMuZmlsdGVyIHx8IHt9O1xuICAgICAgICBjb25zdCBsb2FkTW9kZSA9IGN1c3RvbVN0b3JlT3B0aW9ucy5sb2FkTW9kZSB8fCAncHJvY2Vzc2VkJztcbiAgICAgICAgY29uc3QgcGFyYW1zOiBVUkxTZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGRhdGEpIHtcbiAgICAgICAgICAgIGlmIChrZXkgPT09ICdmaWx0ZXInKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGFba2V5XSAhPT0gJ3t9Jykge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXMuc2V0KGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmFtcy5zZXQoa2V5LCBkYXRhW2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKCfigItSZXF1ZXN0IC0+IGdldEN1c3RvbVN0b3JlIC0+IHBhcmFtcycsIHBhcmFtcyk7XG4gICAgICAgIGxldCB1c2VyRGF0YSA9IHRoaXMuYjJiU2VydmljZS5nZXRWZXJpZnlUb2tlbigpO1xuICAgICAgICBsZXQgaGVhZGVyRGF0YSA6IGFueSA9IHtcbiAgICAgICAgICAgIHN5c3RlbV9pZDogdGhpcy5zeXN0ZW1faWQsXG4gICAgICAgICAgICBkZXBhcnRtZW50OiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhICYmIHVzZXJEYXRhLnBob25lQm9va0RhdGEubGVuZ3RoID4gMCA/IHVzZXJEYXRhLnBob25lQm9va0RhdGFbMF0uZGVwdCA6IFwiXCIsXG4gICAgICAgICAgICB1c2VybmFtZTogdXNlckRhdGEudXNlcm5hbWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtVG9rZW4nLCAnMScpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgneC11c2VyLWRhdGEnLCB0aGlzLnV0b2EoSlNPTi5zdHJpbmdpZnkoaGVhZGVyRGF0YSkpKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVycywgd2l0aENyZWRlbnRpYWxzOiB0cnVlfSk7XG4gICAgICAgIG9wdGlvbnMuc2VhcmNoID0gcGFyYW1zO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldCh0aGlzLmFwaSArIHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNEYXRhID0gcmVzLmpzb24oKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygn4oCLUmVxdWVzdCAtPiBnZXRDdXN0b21TdG9yZSAtPiByZXNEYXRhJywgcmVzRGF0YSk7XG4gICAgICAgICAgICAgICAgaWYgKGxvYWRNb2RlID09PSAncHJvY2Vzc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZVJlc3BvbnNlUHJvY2Vzc2VkTW9kZShyZXNEYXRhKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZVJlc3BvbnNlUmF3TW9kZShyZXNEYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRvUHJvbWlzZSgpXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygn4oCLUmVxdWVzdCAtPiBnZXRDdXN0b21TdG9yZSAtPiBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICAgICAgICBpZiAobG9hZE1vZGUgPT09ICdwcm9jZXNzZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZuSGFuZGxlRXJyb3JQcm9jZXNzZWRNb2RlKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZUVycm9yUmF3TW9kZShlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBmbi4gcG9zdCBkYXRhIOC4quC4s+C4q+C4o+C4seC4muC4lOC4tuC4h+C4guC5ieC4reC4oeC4ueC4peC4quC4s+C4q+C4o+C4seC4miBEYXRhZ3JpZCDguYDguJfguYjguLLguJnguLHguYnguJlcbiAgICAgKiBAcGFyYW0gY3VzdG9tU3RvcmVPcHRpb25zIOC5guC4ouC4meC4hOC5iOC4suC4leC5iOC4suC4hyDguYYg4Lih4Liy4LmD4LiZ4LiZ4Li14LmJXG4gICAgICovXG4gICAgYXN5bmMgcG9zdEN1c3RvbVN0b3JlKGN1c3RvbVN0b3JlT3B0aW9uczogQ3VzdG9tU3RvcmVPcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IGN1c3RvbVN0b3JlT3B0aW9ucy51cmwgfHwgJyc7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGN1c3RvbVN0b3JlT3B0aW9ucy5maWx0ZXIsIHRoaXMuY29tbW9uLnJlcGxhY2VyKSkgfHwge307XG4gICAgICAgIGNvbnN0IGxvYWRNb2RlID0gY3VzdG9tU3RvcmVPcHRpb25zLmxvYWRNb2RlIHx8ICdwcm9jZXNzZWQnO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IHRoaXMuc3lzdGVtX2lkLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBuZXcgUmVxdWVzdE9wdGlvbnMoe2hlYWRlcnM6IGhlYWRlcnMsIHdpdGhDcmVkZW50aWFsczogdHJ1ZX0pO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QodGhpcy5hcGkgKyB1cmwsIGRhdGEsIG9wdGlvbnMpXG4gICAgICAgICAgICAubWFwKChyZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzRGF0YSA9IHJlcy5qc29uKCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi1JlcXVlc3QgLT4gZ2V0Q3VzdG9tU3RvcmUgLT4gcmVzRGF0YScsIHJlc0RhdGEpO1xuICAgICAgICAgICAgICAgIGlmIChsb2FkTW9kZSA9PT0gJ3Byb2Nlc3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVSZXNwb25zZVByb2Nlc3NlZE1vZGUocmVzRGF0YSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVSZXNwb25zZVJhd01vZGUocmVzRGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50b1Byb21pc2UoKVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi1JlcXVlc3QgLT4gZ2V0Q3VzdG9tU3RvcmUgLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgaWYgKGxvYWRNb2RlID09PSAncHJvY2Vzc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZUVycm9yUHJvY2Vzc2VkTW9kZShlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVFcnJvclJhd01vZGUoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZm4uIHBvc3QgZGF0YSDguKrguLPguKvguKPguLHguJrguJTguLbguIfguILguYnguK3guKHguLnguKXguKrguLPguKvguKPguLHguJogRGF0YWdyaWQg4LmA4LiX4LmI4Liy4LiZ4Lix4LmJ4LiZXG4gICAgICogQHBhcmFtIGN1c3RvbVN0b3JlT3B0aW9ucyDguYLguKLguJnguITguYjguLLguJXguYjguLLguIcg4LmGIOC4oeC4suC5g+C4meC4meC4teC5iVxuICAgICAqL1xuICAgIGFzeW5jIHBvc3RDdXN0b21TdG9yZTMxKGN1c3RvbVN0b3JlT3B0aW9uczogQ3VzdG9tU3RvcmVPcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IGN1c3RvbVN0b3JlT3B0aW9ucy51cmwgfHwgJyc7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGN1c3RvbVN0b3JlT3B0aW9ucy5maWx0ZXIsIHRoaXMuY29tbW9uLnJlcGxhY2VyKSkgfHwge307XG4gICAgICAgIGNvbnN0IGxvYWRNb2RlID0gY3VzdG9tU3RvcmVPcHRpb25zLmxvYWRNb2RlIHx8ICdwcm9jZXNzZWQnO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IDMxLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBuZXcgUmVxdWVzdE9wdGlvbnMoe2hlYWRlcnM6IGhlYWRlcnMsIHdpdGhDcmVkZW50aWFsczogdHJ1ZX0pO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QodGhpcy5hcGkgKyB1cmwsIGRhdGEsIG9wdGlvbnMpXG4gICAgICAgICAgICAubWFwKChyZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzRGF0YSA9IHJlcy5qc29uKCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi1JlcXVlc3QgLT4gZ2V0Q3VzdG9tU3RvcmUgLT4gcmVzRGF0YScsIHJlc0RhdGEpO1xuICAgICAgICAgICAgICAgIGlmIChsb2FkTW9kZSA9PT0gJ3Byb2Nlc3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVSZXNwb25zZVByb2Nlc3NlZE1vZGUocmVzRGF0YSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVSZXNwb25zZVJhd01vZGUocmVzRGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50b1Byb21pc2UoKVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi1JlcXVlc3QgLT4gZ2V0Q3VzdG9tU3RvcmUgLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgaWYgKGxvYWRNb2RlID09PSAncHJvY2Vzc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZUVycm9yUHJvY2Vzc2VkTW9kZShlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVFcnJvclJhd01vZGUoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog4LiW4LmJ4LiyIGdldEN1c3RvbVN0b3JlIOC5geC4peC5ieC4pyBlcnJvciDguIHguKPguJPguLUgbG9hZE1vZGUgPSAncHJvY2Vzc2VkJ1xuICAgICAqIEBwYXJhbSBlcnJvclxuICAgICAqL1xuICAgIGZuSGFuZGxlRXJyb3JQcm9jZXNzZWRNb2RlKGVycm9yKSB7XG4gICAgICAgIC8vIGFsZXJ0KCdFUlJPUiAnICsgZXJyb3IpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFUlJPUiAnICsgZXJyb3IpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICB0b3RhbENvdW50OiAwXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog4LiW4LmJ4LiyIGdldEN1c3RvbVN0b3JlIOC5geC4peC5ieC4pyBlcnJvciDguIHguKPguJPguLUgbG9hZE1vZGUgPSAncmF3J1xuICAgICAqIEBwYXJhbSBlcnJvclxuICAgICAqL1xuICAgIGZuSGFuZGxlRXJyb3JSYXdNb2RlKGVycm9yKSB7XG4gICAgICAgIC8vIGFsZXJ0KCdFUlJPUiAnICsgZXJyb3IpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFUlJPUiAnICsgZXJyb3IpO1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZm4uIGdldCBkYXRhIOC4quC4s+C4q+C4o+C4seC4muC4lOC4tuC4h+C4guC5ieC4reC4oeC4ueC4peC4l+C4seC5iOC4p+C5hOC4m1xuICAgICAqIEBwYXJhbSB1cmwgZXggL3Rlc3RcbiAgICAgKiBAcGFyYW0gZGF0YSDguITguYjguLLguJXguYjguLLguIfguJfguLXguYjguJXguYnguK3guIfguIHguLLguKPguYHguJnguJrguYTguJvguIHguLHguJogQVBJXG4gICAgICovXG4gICAgZ2V0KHVybCwgZGF0YT8pIHtcbiAgICAgICAgY29uc3QgcGFyYW1zOiBVUkxTZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGRhdGEpIHtcbiAgICAgICAgICAgIGlmIChrZXkgPT09ICdmaWx0ZXInKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGFba2V5XSAhPT0gJ3t9Jykge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXMuc2V0KGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmFtcy5zZXQoa2V5LCBkYXRhW2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKCfigItSZXF1ZXN0IC0+IGdldEN1c3RvbVN0b3JlIC0+IHBhcmFtcycsIHBhcmFtcyk7XG4gICAgICAgIGxldCB1c2VyRGF0YSA9IHRoaXMuYjJiU2VydmljZS5nZXRWZXJpZnlUb2tlbigpO1xuICAgICAgICBsZXQgaGVhZGVyRGF0YSA6IGFueSA9IHtcbiAgICAgICAgICAgIHN5c3RlbV9pZDogdGhpcy5zeXN0ZW1faWQsXG4gICAgICAgICAgICBkZXBhcnRtZW50OiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhICYmIHVzZXJEYXRhLnBob25lQm9va0RhdGEubGVuZ3RoID4gMCA/IHVzZXJEYXRhLnBob25lQm9va0RhdGFbMF0uZGVwdCA6IFwiXCIsXG4gICAgICAgICAgICB1c2VybmFtZTogdXNlckRhdGEudXNlcm5hbWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtVG9rZW4nLCAnMScpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgneC11c2VyLWRhdGEnLCB0aGlzLnV0b2EoSlNPTi5zdHJpbmdpZnkoaGVhZGVyRGF0YSkpKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyIGV5SmhiR2NpT2lKSVV6STFOaUlzSW5SNWNDSTZJa3BYVkNKOS5leUoxYzJWeWJtRnRaU0k2SWxSbGMzUWlMQ0p6WlhOemFXOXVTV1FpT2lKak56UXdORGRpWmkxak5HVXdMVFF4T1RNdE9UUmlOeTFqT0dJNE0yVmlZamhsTUdNaUxDSnBZWFFpT2pFMU5ETTVORFl5TkRZc0ltVjRjQ0k2TVRVME5EVTFNVEEwTm4wLjV5OWYyWllpZVJaSGhHSU1Ucnl4dXZzQWpKWXp2Rm5XbnBjWUxrMWhTWHcnKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVycywgd2l0aENyZWRlbnRpYWxzOiB0cnVlfSk7XG4gICAgICAgIG9wdGlvbnMuc2VhcmNoID0gcGFyYW1zO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldCh0aGlzLmFwaSArIHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNEYXRhID0gcmVzLmpzb24oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZVJlc3BvbnNlKHJlc0RhdGEpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IGFueSkgPT4gT2JzZXJ2YWJsZS50aHJvdyhlcnJvci5qc29uKCkuZXJyb3IgfHwgJ1NlcnZlciBlcnJvcicpKS50b1Byb21pc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBmbi4gZ2V0IGRhdGEg4Liq4Liz4Lir4Lij4Lix4Lia4LiU4Li24LiH4LiC4LmJ4Lit4Lih4Li54Lil4LiX4Lix4LmI4Lin4LmE4LibXG4gICAgICogQHBhcmFtIHVybCBleCAvdGVzdFxuICAgICAqIEBwYXJhbSBkYXRhIOC4hOC5iOC4suC4leC5iOC4suC4h+C4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C5geC4meC4muC5hOC4m+C4geC4seC4miBBUElcbiAgICAgKi9cbiAgICBnZXQzMSh1cmwsIGRhdGE/KSB7XG4gICAgICAgIGNvbnN0IHBhcmFtczogVVJMU2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSAnZmlsdGVyJykge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhW2tleV0gIT09ICd7fScpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLnNldChrZXksIGRhdGFba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMuc2V0KGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZygn4oCLUmVxdWVzdCAtPiBnZXRDdXN0b21TdG9yZSAtPiBwYXJhbXMnLCBwYXJhbXMpO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IDMxLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciBleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKMWMyVnlibUZ0WlNJNklsUmxjM1FpTENKelpYTnphVzl1U1dRaU9pSmpOelF3TkRkaVppMWpOR1V3TFRReE9UTXRPVFJpTnkxak9HSTRNMlZpWWpobE1HTWlMQ0pwWVhRaU9qRTFORE01TkRZeU5EWXNJbVY0Y0NJNk1UVTBORFUxTVRBME5uMC41eTlmMlpZaWVSWkhoR0lNVHJ5eHV2c0FqSll6dkZuV25wY1lMazFoU1h3Jyk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBuZXcgUmVxdWVzdE9wdGlvbnMoe2hlYWRlcnM6IGhlYWRlcnMsIHdpdGhDcmVkZW50aWFsczogdHJ1ZX0pO1xuICAgICAgICBvcHRpb25zLnNlYXJjaCA9IHBhcmFtcztcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQodGhpcy5hcGkgKyB1cmwsIG9wdGlvbnMpXG4gICAgICAgICAgICAubWFwKChyZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzRGF0YSA9IHJlcy5qc29uKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVSZXNwb25zZShyZXNEYXRhKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IE9ic2VydmFibGUudGhyb3coZXJyb3IuanNvbigpLmVycm9yIHx8ICdTZXJ2ZXIgZXJyb3InKSkudG9Qcm9taXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZm4uIGdldCBkYXRhIOC4quC4s+C4q+C4o+C4seC4muC4lOC4tuC4h+C4guC5ieC4reC4oeC4ueC4peC4l+C4seC5iOC4p+C5hOC4m1xuICAgICAqIEBwYXJhbSB1cmwgZXggL3Rlc3RcbiAgICAgKiBAcGFyYW0gZGF0YSDguITguYjguLLguJXguYjguLLguIfguJfguLXguYjguJXguYnguK3guIfguIHguLLguKPguYHguJnguJrguYTguJvguIHguLHguJogQVBJXG4gICAgICovXG4gICAgZ2V0Q3VzdG9tKHVybCwgaGVhZGVycz8pIHtcbiAgICAgICAgaWYgKCFoZWFkZXJzKSB7XG4gICAgICAgICAgICBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0gbmV3IFJlcXVlc3RPcHRpb25zKHtoZWFkZXJzOiBoZWFkZXJzfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0KHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNEYXRhID0gcmVzLmpzb24oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZVJlc3BvbnNlKHJlc0RhdGEpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IGFueSkgPT4gT2JzZXJ2YWJsZS50aHJvdyhlcnJvci5qc29uKCkuZXJyb3IgfHwgJ1NlcnZlciBlcnJvcicpKS50b1Byb21pc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBmbi4gZ2V0IGRhdGEg4Liq4Liz4Lir4Lij4Lix4Lia4LiU4Li24LiH4LiC4LmJ4Lit4Lih4Li54Lil4LiX4Lix4LmI4Lin4LmE4LibXG4gICAgICogQHBhcmFtIHVybCBleCAvdGVzdFxuICAgICAqIEBwYXJhbSBkYXRhIOC4hOC5iOC4suC4leC5iOC4suC4h+C4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C5geC4meC4muC5hOC4m+C4geC4seC4miBBUElcbiAgICAgKi9cbiAgICBnZXRSYXdSZXNwb25zZSh1cmwsIGhlYWRlcnM/KSB7XG4gICAgICAgIGlmICghaGVhZGVycykge1xuICAgICAgICAgICAgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVyc30pO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldCh1cmwsIG9wdGlvbnMpXG4gICAgICAgICAgICAubWFwKChyZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcjogYW55KSA9PiBPYnNlcnZhYmxlLnRocm93KGVycm9yLmpzb24oKS5lcnJvciB8fCAnU2VydmVyIGVycm9yJykpLnRvUHJvbWlzZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGZuLiBkZWxldGUgZGF0YSDguKrguLPguKvguKPguLHguJrguKXguJrguILguYnguK3guKHguLnguKXguJfguLHguYjguKfguYTguJtcbiAgICAgKiBAcGFyYW0gdXJsIGV4IC90ZXN0XG4gICAgICogQHBhcmFtIGRhdGEg4LiE4LmI4Liy4LiV4LmI4Liy4LiH4LiX4Li14LmI4LiV4LmJ4Lit4LiH4LiB4Liy4Lij4LmB4LiZ4Lia4LmE4Lib4LiB4Lix4LiaIEFQSVxuICAgICAqL1xuICAgIGRlbGV0ZSh1cmwsIGRhdGE/KSB7XG4gICAgICAgIGNvbnN0IHBhcmFtczogVVJMU2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSAnZmlsdGVyJykge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhW2tleV0gIT09ICd7fScpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLnNldChrZXksIGRhdGFba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMuc2V0KGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZygn4oCLUmVxdWVzdCAtPiBnZXRDdXN0b21TdG9yZSAtPiBwYXJhbXMnLCBwYXJhbXMpO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IHRoaXMuc3lzdGVtX2lkLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBuZXcgUmVxdWVzdE9wdGlvbnMoe2hlYWRlcnM6IGhlYWRlcnMsIHdpdGhDcmVkZW50aWFsczogdHJ1ZX0pO1xuICAgICAgICBvcHRpb25zLnNlYXJjaCA9IHBhcmFtcztcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5kZWxldGUodGhpcy5hcGkgKyB1cmwsIG9wdGlvbnMpXG4gICAgICAgICAgICAubWFwKChyZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcjogYW55KSA9PiBPYnNlcnZhYmxlLnRocm93KGVycm9yLmpzb24oKS5lcnJvciB8fCAnU2VydmVyIGVycm9yJykpLnRvUHJvbWlzZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGZuLiBwb3N0IGRhdGEg4Liq4Liz4Lir4Lij4Lix4Lia4Liq4Lij4LmJ4Liy4LiH4LiC4LmJ4Lit4Lih4Li54Lil4LiX4Lix4LmI4Lin4LmE4LibXG4gICAgICogQHBhcmFtIHVybCBleCAvdGVzdFxuICAgICAqIEBwYXJhbSBkYXRhIOC4hOC5iOC4suC4leC5iOC4suC4h+C4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C5geC4meC4muC5hOC4m+C4geC4seC4miBBUElcbiAgICAgKi9cbiAgICBwb3N0KHVybCwgZGF0YSkge1xuICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkYXRhLCB0aGlzLmNvbW1vbi5yZXBsYWNlcikpO1xuICAgICAgICBjb25zb2xlLmxvZygn4oCLcG9zdCAtPiBkYXRhJywgZGF0YSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCfigItwb3N0IC0+IGRhdGEnLCB0eXBlb2YgZGF0YSk7XG4gICAgICAgIGNvbnN0IHBhcmFtczogVVJMU2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IHRoaXMuc3lzdGVtX2lkLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gbmV3IFJlcXVlc3RPcHRpb25zKHtoZWFkZXJzOiBoZWFkZXJzLCB3aXRoQ3JlZGVudGlhbHM6IHRydWV9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHRoaXMuYXBpICsgdXJsLCBkYXRhLCBvcHRpb25zKVxuICAgICAgICAgICAgLm1hcCgocmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IGFueSkgPT4gT2JzZXJ2YWJsZS50aHJvdyhlcnJvci5qc29uKCkuZXJyb3IgfHwgJ1NlcnZlciBlcnJvcicpKS50b1Byb21pc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBmbi4gcG9zdCBkYXRhIOC4quC4s+C4q+C4o+C4seC4muC4quC4o+C5ieC4suC4h+C4guC5ieC4reC4oeC4ueC4peC4l+C4seC5iOC4p+C5hOC4m1xuICAgICAqIEBwYXJhbSB1cmwgZXggL3Rlc3RcbiAgICAgKiBAcGFyYW0gZGF0YSDguITguYjguLLguJXguYjguLLguIfguJfguLXguYjguJXguYnguK3guIfguIHguLLguKPguYHguJnguJrguYTguJvguIHguLHguJogQVBJXG4gICAgICovXG4gICAgcG9zdDMxKHVybCwgZGF0YSkge1xuICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkYXRhLCB0aGlzLmNvbW1vbi5yZXBsYWNlcikpO1xuICAgICAgICBjb25zb2xlLmxvZygn4oCLcG9zdCAtPiBkYXRhJywgZGF0YSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCfigItwb3N0IC0+IGRhdGEnLCB0eXBlb2YgZGF0YSk7XG4gICAgICAgIGNvbnN0IHBhcmFtczogVVJMU2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IDMxLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gbmV3IFJlcXVlc3RPcHRpb25zKHtoZWFkZXJzOiBoZWFkZXJzLCB3aXRoQ3JlZGVudGlhbHM6IHRydWV9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHRoaXMuYXBpICsgdXJsLCBkYXRhLCBvcHRpb25zKVxuICAgICAgICAgICAgLm1hcCgocmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IGFueSkgPT4gT2JzZXJ2YWJsZS50aHJvdyhlcnJvci5qc29uKCkuZXJyb3IgfHwgJ1NlcnZlciBlcnJvcicpKS50b1Byb21pc2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogZm4uIHBvc3QgZGF0YSDguKrguLPguKvguKPguLHguJrguKrguKPguYnguLLguIfguILguYnguK3guKHguLnguKXguJfguLHguYjguKfguYTguJtcbiAgICAgKiBAcGFyYW0gdXJsIGV4IC90ZXN0XG4gICAgICogQHBhcmFtIGRhdGEg4LiE4LmI4Liy4LiV4LmI4Liy4LiH4LiX4Li14LmI4LiV4LmJ4Lit4LiH4LiB4Liy4Lij4LmB4LiZ4Lia4LmE4Lib4LiB4Lix4LiaIEFQSVxuICAgICAqL1xuICAgIHBvc3QxNCh1cmwsIGRhdGEpIHtcbiAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGF0YSwgdGhpcy5jb21tb24ucmVwbGFjZXJub3RyaW0pKTtcbiAgICAgICAgY29uc29sZS5sb2coJ+KAi3Bvc3QgLT4gZGF0YScsIGRhdGEpO1xuICAgICAgICBjb25zb2xlLmxvZygn4oCLcG9zdCAtPiBkYXRhJywgdHlwZW9mIGRhdGEpO1xuICAgICAgICBjb25zdCBwYXJhbXM6IFVSTFNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcbiAgICAgICAgbGV0IHVzZXJEYXRhID0gdGhpcy5iMmJTZXJ2aWNlLmdldFZlcmlmeVRva2VuKCk7XG4gICAgICAgIGxldCBoZWFkZXJEYXRhIDogYW55ID0ge1xuICAgICAgICAgICAgc3lzdGVtX2lkOiB0aGlzLnN5c3RlbV9pZCxcbiAgICAgICAgICAgIGRlcGFydG1lbnQ6IHVzZXJEYXRhLnBob25lQm9va0RhdGEgJiYgdXNlckRhdGEucGhvbmVCb29rRGF0YS5sZW5ndGggPiAwID8gdXNlckRhdGEucGhvbmVCb29rRGF0YVswXS5kZXB0IDogXCJcIixcbiAgICAgICAgICAgIHVzZXJuYW1lOiB1c2VyRGF0YS51c2VybmFtZVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgneC1Ub2tlbicsICcxJyk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LXVzZXItZGF0YScsIHRoaXMudXRvYShKU09OLnN0cmluZ2lmeShoZWFkZXJEYXRhKSkpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVycywgd2l0aENyZWRlbnRpYWxzOiB0cnVlfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAucG9zdCh0aGlzLmFwaSArIHVybCwgZGF0YSwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IE9ic2VydmFibGUudGhyb3coZXJyb3IuanNvbigpLmVycm9yIHx8ICdTZXJ2ZXIgZXJyb3InKSkudG9Qcm9taXNlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGZuLiBwb3N0IGRhdGEg4Liq4Liz4Lir4Lij4Lix4Lia4Liq4Lij4LmJ4Liy4LiH4LiC4LmJ4Lit4Lih4Li54Lil4LiX4Lix4LmI4Lin4LmE4LibXG4gICAgICogQHBhcmFtIHVybCBleCAvdGVzdFxuICAgICAqIEBwYXJhbSBkYXRhIOC4hOC5iOC4suC4leC5iOC4suC4h+C4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C5geC4meC4muC5hOC4m+C4geC4seC4miBBUElcbiAgICAgKi9cbiAgICBwb3N0Q3VzdG9tKHVybCwgZGF0YSwgaGVhZGVycz8pIHtcbiAgICAgICAgY29uc29sZS5sb2coJ+KAi3Bvc3QgLT4gZGF0YScsIGRhdGEpO1xuICAgICAgICBjb25zb2xlLmxvZygn4oCLcG9zdCAtPiBkYXRhJywgdHlwZW9mIGRhdGEpXG4gICAgICAgIGlmICghaGVhZGVycykge1xuICAgICAgICAgICAgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgICAgICBoZWFkZXJzLmFwcGVuZCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0gbmV3IFJlcXVlc3RPcHRpb25zKHtoZWFkZXJzOiBoZWFkZXJzLCB3aXRoQ3JlZGVudGlhbHM6IHRydWV9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHVybCwgZGF0YSwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IE9ic2VydmFibGUudGhyb3coZXJyb3IuanNvbigpLmVycm9yIHx8ICdTZXJ2ZXIgZXJyb3InKSkudG9Qcm9taXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZm4uIHB1dCBkYXRhIOC4quC4s+C4q+C4o+C4seC4muC4reC4seC4nuC5gOC4lOC4leC4guC5ieC4reC4oeC4ueC4peC4l+C4seC5iOC4p+C5hOC4m1xuICAgICAqIEBwYXJhbSB1cmwgZXggL3Rlc3RcbiAgICAgKiBAcGFyYW0gZGF0YSDguITguYjguLLguJXguYjguLLguIfguJfguLXguYjguJXguYnguK3guIfguIHguLLguKPguYHguJnguJrguYTguJvguIHguLHguJogQVBJXG4gICAgICovXG4gICAgcHV0KHVybCwgZGF0YSkge1xuICAgICAgICBjb25zdCBwYXJhbXM6IFVSTFNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcbiAgICAgICAgbGV0IHVzZXJEYXRhID0gdGhpcy5iMmJTZXJ2aWNlLmdldFZlcmlmeVRva2VuKCk7XG4gICAgICAgIGxldCBoZWFkZXJEYXRhIDogYW55ID0ge1xuICAgICAgICAgICAgc3lzdGVtX2lkOiB0aGlzLnN5c3RlbV9pZCxcbiAgICAgICAgICAgIGRlcGFydG1lbnQ6IHVzZXJEYXRhLnBob25lQm9va0RhdGEgJiYgdXNlckRhdGEucGhvbmVCb29rRGF0YS5sZW5ndGggPiAwID8gdXNlckRhdGEucGhvbmVCb29rRGF0YVswXS5kZXB0IDogXCJcIixcbiAgICAgICAgICAgIHVzZXJuYW1lOiB1c2VyRGF0YS51c2VybmFtZVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgneC1Ub2tlbicsICcxJyk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LXVzZXItZGF0YScsIHRoaXMudXRvYShKU09OLnN0cmluZ2lmeShoZWFkZXJEYXRhKSkpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVycywgd2l0aENyZWRlbnRpYWxzOiB0cnVlfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAucHV0KHRoaXMuYXBpICsgdXJsLCBkYXRhLCBvcHRpb25zKVxuICAgICAgICAgICAgLm1hcCgocmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IGFueSkgPT4gT2JzZXJ2YWJsZS50aHJvdyhlcnJvci5qc29uKCkuZXJyb3IgfHwgJ1NlcnZlciBlcnJvcicpKS50b1Byb21pc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDguJbguYnguLIgZ2V0Q3VzdG9tU3RvcmUg4LmB4Lil4LmJ4LinIHN1Y2Nlc3Mg4LiB4Lij4LiT4Li1IGxvYWRNb2RlID0gJ3Byb2Nlc3NlZCdcbiAgICAgKiBAcGFyYW0gcmVzRGF0YVxuICAgICAqL1xuICAgIGZuSGFuZGxlUmVzcG9uc2VQcm9jZXNzZWRNb2RlKHJlc0RhdGEpIHtcbiAgICAgICAgY29uc3QgY3VzdG9tU3RvcmVEYXRhID0ge1xuICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICB0b3RhbENvdW50OiAwXG4gICAgICAgIH07XG4gICAgICAgIGxldCBjb2RlID0gJyc7XG4gICAgICAgIGxldCBkZXNjcmlwdGlvbiA9ICcnO1xuICAgICAgICBsZXQgZGF0YSA9IFtdO1xuICAgICAgICBsZXQgcm93Q291bnQgPSAwO1xuICAgICAgICBpZiAoaXMuYXJyYXkocmVzRGF0YSkpIHtcbiAgICAgICAgICAgIGRhdGEgPSByZXNEYXRhO1xuICAgICAgICAgICAgcm93Q291bnQgPSBfLnNpemUoZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvKiog4LmA4Lib4Lil4Li14LmI4Lii4LiZ4LmE4Lib4LiV4Liy4Lih4Lij4Li54Lib4LmB4Lia4LiaIHJlc3BvbnNlICovXG4gICAgICAgICAgICBjb2RlID0gcmVzRGF0YS5yZXN1bHRDb2RlIHx8ICcnO1xuICAgICAgICAgICAgZGVzY3JpcHRpb24gPSByZXNEYXRhLnJlc3VsdERlc2NyaXB0aW9uIHx8ICcnO1xuICAgICAgICAgICAgZGF0YSA9IHJlc0RhdGEucmVzdWx0RGF0YSB8fCBbXTtcbiAgICAgICAgICAgIHJvd0NvdW50ID0gcmVzRGF0YS5yb3dDb3VudCB8fCAwOyAvLyDguYDguJvguKXguLXguYjguKLguJnguYTguJvguJXguLLguKEgUmVzcG9uc2VcbiAgICAgICAgICAgIC8qKiAqL1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb2RlID09PSBSRVNVTFRfQ09ERS5FUlJPUikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi2ZuSGFuZGxlUmVzcG9uc2VQcm9jZXNzZWRNb2RlIC0+IFJFU1VMVF9DT0RFLkVSUk9SJywgUkVTVUxUX0NPREUuRVJST1IpO1xuICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPT09IFJFU1VMVF9DT0RFLk5PVF9GT1VORCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi2ZuSGFuZGxlUmVzcG9uc2VQcm9jZXNzZWRNb2RlIC0+IFJFU1VMVF9DT0RFLk5PVF9GT1VORCcsIFJFU1VMVF9DT0RFLk5PVF9GT1VORCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjdXN0b21TdG9yZURhdGEuZGF0YSA9IGRhdGE7XG4gICAgICAgICAgICBjdXN0b21TdG9yZURhdGEudG90YWxDb3VudCA9IHJvd0NvdW50O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjdXN0b21TdG9yZURhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog4LiW4LmJ4LiyIGdldEN1c3RvbVN0b3JlIOC5geC4peC5ieC4pyBzdWNjZXNzIOC4geC4o+C4k+C4tSBsb2FkTW9kZSA9ICdyYXcnXG4gICAgICogQHBhcmFtIHJlc0RhdGFcbiAgICAgKi9cbiAgICBmbkhhbmRsZVJlc3BvbnNlUmF3TW9kZShyZXNEYXRhKSB7XG4gICAgICAgIGxldCBjb2RlID0gJyc7XG4gICAgICAgIGxldCBkZXNjcmlwdGlvbiA9ICcnO1xuICAgICAgICBsZXQgZGF0YSA9IFtdO1xuICAgICAgICBpZiAoaXMuYXJyYXkocmVzRGF0YSkpIHtcbiAgICAgICAgICAgIGRhdGEgPSByZXNEYXRhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLyoqIOC5gOC4m+C4peC4teC5iOC4ouC4meC5hOC4m+C4leC4suC4oeC4o+C4ueC4m+C5geC4muC4miByZXNwb25zZSAqL1xuICAgICAgICAgICAgY29kZSA9IHJlc0RhdGEucmVzdWx0Q29kZSB8fCAnJztcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gcmVzRGF0YS5yZXN1bHREZXNjcmlwdGlvbiB8fCAnJztcbiAgICAgICAgICAgIGRhdGEgPSByZXNEYXRhLnJlc3VsdERhdGEgfHwgW107XG4gICAgICAgICAgICAvKiogKi9cbiAgICAgICAgfVxuICAgICAgICBpZiAoY29kZSA9PT0gUkVTVUxUX0NPREUuRVJST1IpIHtcbiAgICAgICAgICAgIGFsZXJ0KCdFUlJPUjonICsgUkVTVUxUX0NPREUuRVJST1IpO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPT09IFJFU1VMVF9DT0RFLk5PVF9GT1VORCkge1xuICAgICAgICAgICAgYWxlcnQoJ0VSUk9SOicgKyBSRVNVTFRfQ09ERS5OT1RfRk9VTkQpO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmbkhhbmRsZVJlc3BvbnNlKHJlc0RhdGEpIHtcbiAgICAgICAgbGV0IGNvZGUgPSAnJztcbiAgICAgICAgbGV0IGRlc2NyaXB0aW9uID0gJyc7XG4gICAgICAgIGxldCBkYXRhID0gW107XG4gICAgICAgIGlmIChpcy5hcnJheShyZXNEYXRhKSkge1xuICAgICAgICAgICAgZGF0YSA9IHJlc0RhdGE7XG4gICAgICAgIH1lbHNlIGlmKHJlc0RhdGEuZGF0YSAmJiBpcy5hcnJheShyZXNEYXRhLmRhdGEpKXtcbiAgICAgICAgICAgIGRhdGEgPSByZXNEYXRhLmRhdGE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvKiog4LmA4Lib4Lil4Li14LmI4Lii4LiZ4LmE4Lib4LiV4Liy4Lih4Lij4Li54Lib4LmB4Lia4LiaIHJlc3BvbnNlICovXG4gICAgICAgICAgICBjb2RlID0gcmVzRGF0YS5yZXN1bHRDb2RlIHx8ICcnO1xuICAgICAgICAgICAgZGVzY3JpcHRpb24gPSByZXNEYXRhLnJlc3VsdERlc2NyaXB0aW9uIHx8ICcnO1xuICAgICAgICAgICAgZGF0YSA9IHJlc0RhdGEucmVzdWx0RGF0YSB8fCBbXTtcbiAgICAgICAgICAgIC8qKiAqL1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvZGUgPT09IFJFU1VMVF9DT0RFLkVSUk9SKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygn4oCLZm5IYW5kbGVSZXNwb25zZSAtPiBSRVNVTFRfQ09ERS5FUlJPUicsIFJFU1VMVF9DT0RFLkVSUk9SKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2RlID09PSBSRVNVTFRfQ09ERS5OT1RfRk9VTkQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCfigItmbkhhbmRsZVJlc3BvbnNlIC0+IFJFU1VMVF9DT0RFLk5PVF9GT1VORCcsIFJFU1VMVF9DT0RFLk5PVF9GT1VORCk7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGZuIOC4lOC4tuC4h+C4guC5ieC4reC4oeC4ueC4peC5gOC4nuC4t+C5iOC4reC5g+C4iuC5ieC5g+C4mSBEcm9wZG93biBMaXN0XG4gICAgICogQHBhcmFtIHN5c3RlbUlkIOC5gOC4peC4guC4o+C4q+C4seC4quC4o+C4sOC4muC4muC4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C4lOC4tuC4h1xuICAgICAqIEBwYXJhbSBkcm9wRG93blR5cGUg4Lib4Lij4Liw4LmA4Lig4LiX4LiC4LmJ4Lit4Lih4Li54LilIGRyb3Bkb3duIOC4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C4lOC4tuC4h1xuICAgICAqL1xuICAgIGFzeW5jIGdldERyb3BEb3duKHN5c3RlbUlkOiBudW1iZXIsIGRyb3BEb3duVHlwZTogU3RyaW5nLCBjb2RlPzogU3RyaW5nKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAgICAgICAgIGZpbHRlcjoge1xuICAgICAgICAgICAgICAgICAgICBzeXN0ZW1faWQ6IHN5c3RlbUlkLFxuICAgICAgICAgICAgICAgICAgICBkcm9wZG93bl90eXBlOiBkcm9wRG93blR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGNvZGU6IGNvZGVcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpbWl0OiAxMDAwLFxuICAgICAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgICAgICBvcmRlcl9ieTogWydpZCBhc2MnXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHVybERyb3Bkb3duID0gXy5nZXQodGhpcy5jb25maWcsICdhcGlTZXJ2ZXJzLnRvbWNhdC5hcGkuY3RfZHJvcGRvd25fc2VhcmNoJyk7XG4gICAgICAgICAgICBpZihzeXN0ZW1JZCA9PT0gMzEpe1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3QzMSh1cmxEcm9wZG93biwgZGF0YSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc0RhdGEucmVzdWx0RGF0YTtcbiAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3QodXJsRHJvcGRvd24sIGRhdGEpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNEYXRhLnJlc3VsdERhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnY2F0Y2ggLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBnZXREZXBhcnRtZW50KHBhcmVudElkOiBudW1iZXIgPSAwKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAgICAgICAgIGZpbHRlcjoge3JlZl9kZXBhcnRtZW50X2lkOiBwYXJlbnRJZH0sXG4gICAgICAgICAgICAgICAgbGltaXQ6IDEwMDAsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiAwLFxuICAgICAgICAgICAgICAgIG9yZGVyX2J5OiBbJ25hbWUgYXNjJ11cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCB1cmxEcm9wZG93biA9IF8uZ2V0KHRoaXMuY29uZmlnLCAnYXBpU2VydmVycy50b21jYXQuYXBpLmN0X2RlcGFydG1lbnRfc2VhcmNoJyk7XG4gICAgICAgICAgICBjb25zdCByZXNEYXRhID0gYXdhaXQgdGhpcy5wb3N0KHVybERyb3Bkb3duLCBkYXRhKTtcbiAgICAgICAgICAgIHJldHVybiByZXNEYXRhLnJlc3VsdERhdGE7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnY2F0Y2ggLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBnZXRFeHREZXBhcnRtZW50KCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICBmaWx0ZXI6IHt9LFxuICAgICAgICAgICAgICAgIGxpbWl0OiAxMDAwLFxuICAgICAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgICAgICBvcmRlcl9ieTogWyduYW1lIGFzYyddXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgdXJsRHJvcGRvd24gPSBfLmdldCh0aGlzLmNvbmZpZywgJ2FwaVNlcnZlcnMudG9tY2F0LmFwaS5jdF9leHRfZGVwYXJ0bWVudF9zZWFyY2gnKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3QodXJsRHJvcGRvd24sIGRhdGEpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc0RhdGEucmVzdWx0RGF0YTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdjYXRjaCAtPiBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGdldENhdGVnb3J5KHN5c3RlbV9pZCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgdXJsU3RlcCA9IF8uZ2V0KHRoaXMuY29uZmlnLCAnYXBpU2VydmVycy50b21jYXQuYXBpLmN0X2NhdGVnb3J5Jyk7XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSBgP193aGVyZT0oc3lzdGVtX2lkLGVxLCR7c3lzdGVtX2lkfSkmX3NvcnQ9c2VxX25vYDtcbiAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLmdldCh1cmxTdGVwICsgcGFyYW1zKTtcbiAgICAgICAgICAgIHJldHVybiByZXNEYXRhO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ2NhdGNoIC0+IGVycm9yJywgZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0U3RlcE5hbWUoY2F0ZWdvcnlfaWQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHVybFN0ZXAgPSBfLmdldCh0aGlzLmNvbmZpZywgJ2FwaVNlcnZlcnMudG9tY2F0LmFwaS5jdF9zdGVwJyk7XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSBgP193aGVyZT0oY2F0ZWdvcnlfaWQsZXEsJHtjYXRlZ29yeV9pZH0pJl9zb3J0PXNlcV9ub2A7XG4gICAgICAgICAgICBjb25zdCByZXNEYXRhID0gYXdhaXQgdGhpcy5nZXQodXJsU3RlcCArIHBhcmFtcyk7XG4gICAgICAgICAgICByZXR1cm4gcmVzRGF0YTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdjYXRjaCAtPiBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGdldEF0dGFjaG1lbnQodXJsKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgICAgIGhlYWRlcnMuYXBwZW5kKCdBdXRob3JpemF0aW9uJywgJ0Jhc2ljICcgKyBidG9hKCdBUFBTT0M6MTIzNDU2JykpO1xuICAgICAgICAgICAgY29uc3QgcmVzRGF0YSA9IGF3YWl0IHRoaXMuZ2V0Q3VzdG9tKHVybCwgaGVhZGVycyk7XG4gICAgICAgICAgICByZXR1cm4gcmVzRGF0YTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdjYXRjaCAtPiBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHBvc3RBdHRhY2htZW50KHVybCwgZGF0YSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgICAgICBoZWFkZXJzLmFwcGVuZCgnQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgYnRvYSgnQVBQU09DOjEyMzQ1NicpKTtcbiAgICAgICAgICAgIGhlYWRlcnMuYXBwZW5kKCd0ZXN0JywgJ3Rlc3QnKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3RDdXN0b20odXJsLCBkYXRhLCBoZWFkZXJzKTtcbiAgICAgICAgICAgIHJldHVybiByZXNEYXRhO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ2NhdGNoIC0+IGVycm9yJywgZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0VXNlckxldmVsKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICBmaWx0ZXI6IHt9LFxuICAgICAgICAgICAgICAgIGxpbWl0OiAxMDAwLFxuICAgICAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgICAgICBvcmRlcl9ieTogWydsZXZlbCBhc2MnXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHVybERyb3Bkb3duID0gXy5nZXQodGhpcy5jb25maWcsICdhcGlTZXJ2ZXJzLnRvbWNhdC5hcGkuY3RfdXNlcl9sZXZlbF9zZWFyY2gnKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3QodXJsRHJvcGRvd24sIGRhdGEpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc0RhdGE7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnY2F0Y2ggLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBtdWx0aXBsZURlbGV0ZU1haW4odGFibGUsIGlkTGlzdCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IHVybCA9IFwiL1wiICsgdGFibGUuc3BsaXQoXCJfXCIpWzBdICsgXCIvbWFpblwiO1xuICAgICAgICAgICAgbGV0IGRlbGV0ZU9iajogYW55ID0ge307XG4gICAgICAgICAgICBkZWxldGVPYmpbdGFibGVdID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBpZCBvZiBpZExpc3QpIHtcbiAgICAgICAgICAgICAgICBsZXQgdG1wID0ge1xuICAgICAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbjogXCJkZWxldGVcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGVPYmpbdGFibGVdLnB1c2godG1wKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3QodXJsLCBbZGVsZXRlT2JqXSk7XG4gICAgICAgICAgICBpZiAocmVzRGF0YS5yZXN1bHRDb2RlID09PSAyMDAwMCkge1xuICAgICAgICAgICAgICAgIGlkTGlzdCA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc0RhdGE7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnY2F0Y2ggLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBnZXRBdHRhY2htZW50TGlua1Rva2VuKHVybCkge1xuICAgICAgICByZXR1cm4gdXJsICsgJz9kb3dubG9hZFRva2VuPScgKyB0aGlzLmIyYlNlcnZpY2UuZ2V0QXR0YWNobWVudFRva2VuKCkgKycmaW5saW5lPXRydWUnO1xuICAgIH1cblxuICAgIGFzeW5jIGNoZWNrU3BlbGwoZGF0YSwgZmllbGRMaXN0LCBtb2RhbDogTW9kYWxTcGVsbENoZWNrQ29tcG9uZW50KSB7XG4gICAgICAgIGxldCB1cmwgPSBcIi9zcGVsbENoZWNrXCI7XG4gICAgICAgIGxldCBib2R5OiBhbnkgPSB7fTtcbiAgICAgICAgZm9yIChsZXQgZmllbGQgb2YgZmllbGRMaXN0KSB7XG4gICAgICAgICAgICBpZiAoZGF0YVtmaWVsZC5maWVsZF0pIHtcbiAgICAgICAgICAgICAgICBib2R5W2ZpZWxkLmZpZWxkXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGRhdGFbZmllbGQuZmllbGRdLFxuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5OiBmaWVsZC5kaXNwbGF5XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzRGF0YSA9IGF3YWl0IHRoaXMucG9zdCh1cmwsIGJvZHkpO1xuICAgICAgICBsZXQgc3BlbGxDaGVjayA9IEpTT04ucGFyc2UocmVzRGF0YS5yZXN1bHREYXRhKTtcbiAgICAgICAgaWYgKF8uc2l6ZShzcGVsbENoZWNrKSA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtb2RhbC5vcGVuKHNwZWxsQ2hlY2spO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0UXVhbGlmaWNhdGlvbih1cmwsIGhlYWRlcnM/KSB7XG4gICAgICAgIGlmICghaGVhZGVycykge1xuICAgICAgICAgICAgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVycywgd2l0aENyZWRlbnRpYWxzOiB0cnVlfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0KHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IE9ic2VydmFibGUudGhyb3coZXJyb3IuanNvbigpLmVycm9yIHx8ICdTZXJ2ZXIgZXJyb3InKSkudG9Qcm9taXNlKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgdmVyaWZ5VXNlck5hbWUoKSB7XG4gICAgICAgIGxldCB2ZXJpZnlUb2tlbjogYW55ID0gYXdhaXQgdGhpcy5iMmJTZXJ2aWNlLnZlcmlmeSgpO1xuICAgICAgICBpZiAoK3ZlcmlmeVRva2VuLnJlc3VsdENvZGUgPT09IDIwMDAwKSB7XG4gICAgICAgICAgICBsZXQgZGF0YSA9IHZlcmlmeVRva2VuLnJlc3VsdERhdGE7XG4gICAgICAgICAgICBsZXQgcGhvbmVCb29rRGF0YSA9IGRhdGEucGhvbmVCb29rRGF0YSAmJiBkYXRhLnBob25lQm9va0RhdGEubGVuZ3RoID4gMCA/IGRhdGEucGhvbmVCb29rRGF0YVswXSA6IHt9O1xuICAgICAgICAgICAgcmV0dXJuIHBob25lQm9va0RhdGEubmFtZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHV0b2Eoc3RyKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuYnRvYSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSkpO1xuICAgIH1cblxuICAgIGRvd25sb2FkSW1nVG9CYXNlNjQoYXBpKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4gIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBodHRwT3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiBuZXcgSHR0cEhlYWRlcnMoeyBcIkF1dGhvcml6YXRpb25cIjogXCJCYXNpYyBcIitidG9hKCdBUFBTT0M6MTIzNDU2JykgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgbGV0IGJsb2IgPSBhd2FpdCB0aGlzLmh0dHBDbGllbnQuZ2V0KGFwaSwgeyBoZWFkZXJzOiBodHRwT3B0aW9ucy5oZWFkZXJzLCByZXNwb25zZVR5cGU6IFwiYmxvYlwiIH0pLnRvUHJvbWlzZSgpXG4gICAgICAgICAgIGxldCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwoYmxvYik7XG4gICAgICAgICAgICByZWFkZXIub25sb2FkZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJhc2U2NGRhdGEgPSByZWFkZXIucmVzdWx0O1xuICAgICAgICAgICAgICAgIHJlc29sdmUoYmFzZTY0ZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAgICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBkb3dubG9hZFZpZXcoYXBpOmFueSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IGh0dHBPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIGhlYWRlcnM6IG5ldyBIdHRwSGVhZGVycyh7IFwiQXV0aG9yaXphdGlvblwiOiBcIkJhc2ljIFwiK2J0b2EoJ0FQUFNPQzoxMjM0NTYnKSB9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGJsb2IgPSBhd2FpdCB0aGlzLmh0dHBDbGllbnQuZ2V0KGFwaSwgeyBoZWFkZXJzOiBodHRwT3B0aW9ucy5oZWFkZXJzLCByZXNwb25zZVR5cGU6IFwiYmxvYlwiIH0pLnRvUHJvbWlzZSgpXG4gICAgICAgICAgICBsZXQgdXJsID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYiwgeyBvbmVUaW1lT25seTogdHJ1ZSB9KVxuICAgICAgICAgICAgIHdpbmRvdy5vcGVuKHVybCwnX2JsYW5rJyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYXN5bmMgZG93bmxvYWQoYXBpOmFueSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGxldCB3ID0gd2luZG93Lm9wZW4oKVxuICAgICAgICAgICAgICB3LmRvY3VtZW50LndyaXRlbG4oXCJcIilcbiAgICAgICAgICAgICAgbGV0IGh0dHBPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogbmV3IEh0dHBIZWFkZXJzKHsgXCJBdXRob3JpemF0aW9uXCI6IFwiQmFzaWMgXCIrYnRvYSgnQVBQU09DOjEyMzQ1NicpIH0pXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGV0IGJsb2IgPSBhd2FpdCB0aGlzLmh0dHBDbGllbnQuZ2V0KGFwaSwgeyBoZWFkZXJzOiBodHRwT3B0aW9ucy5oZWFkZXJzLCByZXNwb25zZVR5cGU6IFwiYmxvYlwiIH0pLnRvUHJvbWlzZSgpXG4gICAgICAgICAgICAgIGxldCB1cmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKVxuICAgICAgICAgICAgICB3LmxvY2F0aW9uLmhyZWYgPSB1cmxcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbn1cbiJdfQ==