1 | /*
|
2 | Copyright 2013-2020 the original author or authors from the JHipster project.
|
3 |
|
4 | This file is part of the JHipster project, see https://www.jhipster.tech/
|
5 | for more information.
|
6 |
|
7 | Licensed under the Apache License, Version 2.0 (the "License");
|
8 | you may not use this file except in compliance with the License.
|
9 | You may obtain a copy of the License at
|
10 |
|
11 | http://www.apache.org/licenses/LICENSE-2.0
|
12 |
|
13 | Unless required by applicable law or agreed to in writing, software
|
14 | distributed under the License is distributed on an "AS IS" BASIS,
|
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16 | See the License for the specific language governing permissions and
|
17 | limitations under the License.
|
18 | */
|
19 | import { Injectable } from '@angular/core';
|
20 | import { Observable } from 'rxjs';
|
21 | import * as i0 from "@angular/core";
|
22 | /**
|
23 | * An utility service for data.
|
24 | */
|
25 | export class JhiDataUtils {
|
26 | constructor() { }
|
27 | /**
|
28 | * Method to abbreviate the text given
|
29 | */
|
30 | abbreviate(text, append = '...') {
|
31 | if (text.length < 30) {
|
32 | return text;
|
33 | }
|
34 | return text ? text.substring(0, 15) + append + text.slice(-10) : '';
|
35 | }
|
36 | /**
|
37 | * Method to find the byte size of the string provides
|
38 | */
|
39 | byteSize(base64String) {
|
40 | return this.formatAsBytes(this.size(base64String));
|
41 | }
|
42 | /**
|
43 | * Method to open file
|
44 | */
|
45 | openFile(contentType, data) {
|
46 | if (window.navigator && window.navigator.msSaveOrOpenBlob) {
|
47 | // To support IE and Edge
|
48 | const byteCharacters = atob(data);
|
49 | const byteNumbers = new Array(byteCharacters.length);
|
50 | for (let i = 0; i < byteCharacters.length; i++) {
|
51 | byteNumbers[i] = byteCharacters.charCodeAt(i);
|
52 | }
|
53 | const byteArray = new Uint8Array(byteNumbers);
|
54 | const blob = new Blob([byteArray], {
|
55 | type: contentType
|
56 | });
|
57 | window.navigator.msSaveOrOpenBlob(blob);
|
58 | }
|
59 | else {
|
60 | // Other browsers
|
61 | const fileURL = `data:${contentType};base64,${data}`;
|
62 | const win = window.open();
|
63 | win.document.write('<iframe src="' +
|
64 | fileURL +
|
65 | '" frameborder="0" style="border:0; top:0; left:0; bottom:0; right:0; width:100%; height:100%;" allowfullscreen></iframe>');
|
66 | }
|
67 | }
|
68 | /**
|
69 | * Method to convert the file to base64
|
70 | */
|
71 | toBase64(file, cb) {
|
72 | const fileReader = new FileReader();
|
73 | fileReader.onload = function (e) {
|
74 | const base64Data = e.target.result.substr(e.target.result.indexOf('base64,') + 'base64,'.length);
|
75 | cb(base64Data);
|
76 | };
|
77 | fileReader.readAsDataURL(file);
|
78 | }
|
79 | /**
|
80 | * Method to clear the input
|
81 | */
|
82 | clearInputImage(entity, elementRef, field, fieldContentType, idInput) {
|
83 | if (entity && field && fieldContentType) {
|
84 | if (Object.prototype.hasOwnProperty.call(entity, field)) {
|
85 | entity[field] = null;
|
86 | }
|
87 | if (Object.prototype.hasOwnProperty.call(entity, fieldContentType)) {
|
88 | entity[fieldContentType] = null;
|
89 | }
|
90 | if (elementRef && idInput && elementRef.nativeElement.querySelector('#' + idInput)) {
|
91 | elementRef.nativeElement.querySelector('#' + idInput).value = null;
|
92 | }
|
93 | }
|
94 | }
|
95 | /**
|
96 | * Sets the base 64 data & file type of the 1st file on the event (event.target.files[0]) in the passed entity object
|
97 | * and returns a promise.
|
98 | *
|
99 | * @param event the object containing the file (at event.target.files[0])
|
100 | * @param entity the object to set the file's 'base 64 data' and 'file type' on
|
101 | * @param field the field name to set the file's 'base 64 data' on
|
102 | * @param isImage boolean representing if the file represented by the event is an image
|
103 | * @returns a promise that resolves to the modified entity if operation is successful, otherwise rejects with an error message
|
104 | */
|
105 | setFileData(event, entity, field, isImage) {
|
106 | return new Promise((resolve, reject) => {
|
107 | if (event && event.target && event.target.files && event.target.files[0]) {
|
108 | const file = event.target.files[0];
|
109 | if (isImage && !file.type.startsWith('image/')) {
|
110 | reject(`File was expected to be an image but was found to be ${file.type}`);
|
111 | }
|
112 | else {
|
113 | this.toBase64(file, base64Data => {
|
114 | entity[field] = base64Data;
|
115 | entity[`${field}ContentType`] = file.type;
|
116 | resolve(entity);
|
117 | });
|
118 | }
|
119 | }
|
120 | else {
|
121 | reject(`Base64 data was not set as file could not be extracted from passed parameter: ${event}`);
|
122 | }
|
123 | });
|
124 | }
|
125 | /**
|
126 | * Sets the base 64 data & file type of the 1st file on the event (event.target.files[0]) in the passed entity object
|
127 | * and returns an observable.
|
128 | *
|
129 | * @param event the object containing the file (at event.target.files[0])
|
130 | * @param editForm the form group where the input field is located
|
131 | * @param field the field name to set the file's 'base 64 data' on
|
132 | * @param isImage boolean representing if the file represented by the event is an image
|
133 | * @returns an observable that loads file to form field and completes if sussessful
|
134 | * or returns error as JhiFileLoadError on failure
|
135 | */
|
136 | loadFileToForm(event, editForm, field, isImage) {
|
137 | return new Observable((observer) => {
|
138 | const eventTarget = event.target;
|
139 | if (eventTarget.files && eventTarget.files[0]) {
|
140 | const file = eventTarget.files[0];
|
141 | if (isImage && !file.type.startsWith('image/')) {
|
142 | const error = {
|
143 | message: `File was expected to be an image but was found to be '${file.type}'`,
|
144 | key: 'not.image',
|
145 | params: { fileType: file.type }
|
146 | };
|
147 | observer.error(error);
|
148 | }
|
149 | else {
|
150 | const fieldContentType = field + 'ContentType';
|
151 | this.toBase64(file, (base64Data) => {
|
152 | editForm.patchValue({
|
153 | [field]: base64Data,
|
154 | [fieldContentType]: file.type
|
155 | });
|
156 | observer.next();
|
157 | observer.complete();
|
158 | });
|
159 | }
|
160 | }
|
161 | else {
|
162 | const error = {
|
163 | message: 'Could not extract file',
|
164 | key: 'could.not.extract',
|
165 | params: { event }
|
166 | };
|
167 | observer.error(error);
|
168 | }
|
169 | });
|
170 | }
|
171 | /**
|
172 | * Method to download file
|
173 | */
|
174 | downloadFile(contentType, data, fileName) {
|
175 | const byteCharacters = atob(data);
|
176 | const byteNumbers = new Array(byteCharacters.length);
|
177 | for (let i = 0; i < byteCharacters.length; i++) {
|
178 | byteNumbers[i] = byteCharacters.charCodeAt(i);
|
179 | }
|
180 | const byteArray = new Uint8Array(byteNumbers);
|
181 | const blob = new Blob([byteArray], {
|
182 | type: contentType
|
183 | });
|
184 | const tempLink = document.createElement('a');
|
185 | tempLink.href = window.URL.createObjectURL(blob);
|
186 | tempLink.download = fileName;
|
187 | tempLink.target = '_blank';
|
188 | tempLink.click();
|
189 | }
|
190 | endsWith(suffix, str) {
|
191 | return str.includes(suffix, str.length - suffix.length);
|
192 | }
|
193 | paddingSize(value) {
|
194 | if (this.endsWith('==', value)) {
|
195 | return 2;
|
196 | }
|
197 | if (this.endsWith('=', value)) {
|
198 | return 1;
|
199 | }
|
200 | return 0;
|
201 | }
|
202 | size(value) {
|
203 | return (value.length / 4) * 3 - this.paddingSize(value);
|
204 | }
|
205 | formatAsBytes(size) {
|
206 | return size.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ') + ' bytes';
|
207 | }
|
208 | }
|
209 | JhiDataUtils.ɵprov = i0.ɵɵdefineInjectable({ factory: function JhiDataUtils_Factory() { return new JhiDataUtils(); }, token: JhiDataUtils, providedIn: "root" });
|
210 | JhiDataUtils.decorators = [
|
211 | { type: Injectable, args: [{
|
212 | providedIn: 'root'
|
213 | },] }
|
214 | ];
|
215 | JhiDataUtils.ctorParameters = () => [];
|
216 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS11dGlsLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZS9kYXRhLXV0aWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxPQUFPLEVBQWMsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZELE9BQU8sRUFBRSxVQUFVLEVBQVksTUFBTSxNQUFNLENBQUM7O0FBVzVDOztHQUVHO0FBSUgsTUFBTSxPQUFPLFlBQVk7SUFDckIsZ0JBQWUsQ0FBQztJQUVoQjs7T0FFRztJQUNILFVBQVUsQ0FBQyxJQUFZLEVBQUUsTUFBTSxHQUFHLEtBQUs7UUFDbkMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRTtZQUNsQixPQUFPLElBQUksQ0FBQztTQUNmO1FBQ0QsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUN4RSxDQUFDO0lBRUQ7O09BRUc7SUFDSCxRQUFRLENBQUMsWUFBb0I7UUFDekIsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxRQUFRLENBQUMsV0FBbUIsRUFBRSxJQUFZO1FBQ3RDLElBQUksTUFBTSxDQUFDLFNBQVMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLGdCQUFnQixFQUFFO1lBQ3ZELHlCQUF5QjtZQUN6QixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLE1BQU0s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QixPQUFPLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUMsdUJBQXVCLEVBQUUsR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDO0lBQzVFLENBQUM7Ozs7WUFsTUosVUFBVSxTQUFDO2dCQUNSLFVBQVUsRUFBRSxNQUFNO2FBQ3JCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiBDb3B5cmlnaHQgMjAxMy0yMDIwIHRoZSBvcmlnaW5hbCBhdXRob3Igb3IgYXV0aG9ycyBmcm9tIHRoZSBKSGlwc3RlciBwcm9qZWN0LlxuXG4gVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEpIaXBzdGVyIHByb2plY3QsIHNlZSBodHRwczovL3d3dy5qaGlwc3Rlci50ZWNoL1xuIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuXG4gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5pbXBvcnQgeyBFbGVtZW50UmVmLCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBPYnNlcnZlciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5leHBvcnQgdHlwZSBKaGlGaWxlTG9hZEVycm9yVHlwZSA9ICdub3QuaW1hZ2UnIHwgJ2NvdWxkLm5vdC5leHRyYWN0JztcblxuZXhwb3J0IGludGVyZmFjZSBKaGlGaWxlTG9hZEVycm9yIHtcbiAgICBtZXNzYWdlOiBzdHJpbmc7XG4gICAga2V5OiBKaGlGaWxlTG9hZEVycm9yVHlwZTtcbiAgICBwYXJhbXM/OiBhbnk7XG59XG5cbi8qKlxuICogQW4gdXRpbGl0eSBzZXJ2aWNlIGZvciBkYXRhLlxuICovXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEpoaURhdGFVdGlscyB7XG4gICAgY29uc3RydWN0b3IoKSB7fVxuXG4gICAgLyoqXG4gICAgICogTWV0aG9kIHRvIGFiYnJldmlhdGUgdGhlIHRleHQgZ2l2ZW5cbiAgICAgKi9cbiAgICBhYmJyZXZpYXRlKHRleHQ6IHN0cmluZywgYXBwZW5kID0gJy4uLicpOiBzdHJpbmcge1xuICAgICAgICBpZiAodGV4dC5sZW5ndGggPCAzMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRleHQgPyB0ZXh0LnN1YnN0cmluZygwLCAxNSkgKyBhcHBlbmQgKyB0ZXh0LnNsaWNlKC0xMCkgOiAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgdG8gZmluZCB0aGUgYnl0ZSBzaXplIG9mIHRoZSBzdHJpbmcgcHJvdmlkZXNcbiAgICAgKi9cbiAgICBieXRlU2l6ZShiYXNlNjRTdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEFzQnl0ZXModGhpcy5zaXplKGJhc2U2NFN0cmluZykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCB0byBvcGVuIGZpbGVcbiAgICAgKi9cbiAgICBvcGVuRmlsZShjb250ZW50VHlwZTogc3RyaW5nLCBkYXRhOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgaWYgKHdpbmRvdy5uYXZpZ2F0b3IgJiYgd2luZG93Lm5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iKSB7XG4gICAgICAgICAgICAvLyBUbyBzdXBwb3J0IElFIGFuZCBFZGdlXG4gICAgICAgICAgICBjb25zdCBieXRlQ2hhcmFjdGVycyA9IGF0b2IoZGF0YSk7XG4gICAgICAgICAgICBjb25zdCBieXRlTnVtYmVycyA9IG5ldyBBcnJheShieXRlQ2hhcmFjdGVycy5sZW5ndGgpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBieXRlQ2hhcmFjdGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGJ5dGVOdW1iZXJzW2ldID0gYnl0ZUNoYXJhY3RlcnMuY2hhckNvZGVBdChpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGJ5dGVBcnJheSA9IG5ldyBVaW50OEFycmF5KGJ5dGVOdW1iZXJzKTtcbiAgICAgICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbYnl0ZUFycmF5XSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IGNvbnRlbnRUeXBlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHdpbmRvdy5uYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYihibG9iKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIE90aGVyIGJyb3dzZXJzXG4gICAgICAgICAgICBjb25zdCBmaWxlVVJMID0gYGRhdGE6JHtjb250ZW50VHlwZX07YmFzZTY0LCR7ZGF0YX1gO1xuICAgICAgICAgICAgY29uc3Qgd2luID0gd2luZG93Lm9wZW4oKTtcbiAgICAgICAgICAgIHdpbi5kb2N1bWVudC53cml0ZShcbiAgICAgICAgICAgICAgICAnPGlmcmFtZSBzcmM9XCInICtcbiAgICAgICAgICAgICAgICAgICAgZmlsZVVSTCArXG4gICAgICAgICAgICAgICAgICAgICdcIiBmcmFtZWJvcmRlcj1cIjBcIiBzdHlsZT1cImJvcmRlcjowOyB0b3A6MDsgbGVmdDowOyBib3R0b206MDsgcmlnaHQ6MDsgd2lkdGg6MTAwJTsgaGVpZ2h0OjEwMCU7XCIgYWxsb3dmdWxsc2NyZWVuPjwvaWZyYW1lPidcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgdG8gY29udmVydCB0aGUgZmlsZSB0byBiYXNlNjRcbiAgICAgKi9cbiAgICB0b0Jhc2U2NChmaWxlOiBGaWxlLCBjYjogRnVuY3Rpb24pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZmlsZVJlYWRlcjogRmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24oZTogYW55KSB7XG4gICAgICAgICAgICBjb25zdCBiYXNlNjREYXRhOiBzdHJpbmcgPSBlLnRhcmdldC5yZXN1bHQuc3Vic3RyKGUudGFyZ2V0LnJlc3VsdC5pbmRleE9mKCdiYXNlNjQsJykgKyAnYmFzZTY0LCcubGVuZ3RoKTtcbiAgICAgICAgICAgIGNiKGJhc2U2NERhdGEpO1xuICAgICAgICB9O1xuICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWV0aG9kIHRvIGNsZWFyIHRoZSBpbnB1dFxuICAgICAqL1xuICAgIGNsZWFySW5wdXRJbWFnZShlbnRpdHk6IGFueSwgZWxlbWVudFJlZjogRWxlbWVudFJlZiwgZmllbGQ6IHN0cmluZywgZmllbGRDb250ZW50VHlwZTogc3RyaW5nLCBpZElucHV0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgaWYgKGVudGl0eSAmJiBmaWVsZCAmJiBmaWVsZENvbnRlbnRUeXBlKSB7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGVudGl0eSwgZmllbGQpKSB7XG4gICAgICAgICAgICAgICAgZW50aXR5W2ZpZWxkXSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGVudGl0eSwgZmllbGRDb250ZW50VHlwZSkpIHtcbiAgICAgICAgICAgICAgICBlbnRpdHlbZmllbGRDb250ZW50VHlwZV0gPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGVsZW1lbnRSZWYgJiYgaWRJbnB1dCAmJiBlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignIycgKyBpZElucHV0KSkge1xuICAgICAgICAgICAgICAgIGVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcjJyArIGlkSW5wdXQpLnZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGJhc2UgNjQgZGF0YSAmIGZpbGUgdHlwZSBvZiB0aGUgMXN0IGZpbGUgb24gdGhlIGV2ZW50IChldmVudC50YXJnZXQuZmlsZXNbMF0pIGluIHRoZSBwYXNzZWQgZW50aXR5IG9iamVjdFxuICAgICAqIGFuZCByZXR1cm5zIGEgcHJvbWlzZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBldmVudCB0aGUgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZpbGUgKGF0IGV2ZW50LnRhcmdldC5maWxlc1swXSlcbiAgICAgKiBAcGFyYW0gZW50aXR5IHRoZSBvYmplY3QgdG8gc2V0IHRoZSBmaWxlJ3MgJ2Jhc2UgNjQgZGF0YScgYW5kICdmaWxlIHR5cGUnIG9uXG4gICAgICogQHBhcmFtIGZpZWxkIHRoZSBmaWVsZCBuYW1lIHRvIHNldCB0aGUgZmlsZSdzICdiYXNlIDY0IGRhdGEnIG9uXG4gICAgICogQHBhcmFtIGlzSW1hZ2UgYm9vbGVhbiByZXByZXNlbnRpbmcgaWYgdGhlIGZpbGUgcmVwcmVzZW50ZWQgYnkgdGhlIGV2ZW50IGlzIGFuIGltYWdlXG4gICAgICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIG1vZGlmaWVkIGVudGl0eSBpZiBvcGVyYXRpb24gaXMgc3VjY2Vzc2Z1bCwgb3RoZXJ3aXNlIHJlamVjdHMgd2l0aCBhbiBlcnJvciBtZXNzYWdlXG4gICAgICovXG4gICAgc2V0RmlsZURhdGEoZXZlbnQsIGVudGl0eSwgZmllbGQ6IHN0cmluZywgaXNJbWFnZTogYm9vbGVhbik6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQgJiYgZXZlbnQudGFyZ2V0ICYmIGV2ZW50LnRhcmdldC5maWxlcyAmJiBldmVudC50YXJnZXQuZmlsZXNbMF0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlOiBGaWxlID0gZXZlbnQudGFyZ2V0LmZpbGVzWzBdO1xuICAgICAgICAgICAgICAgIGlmIChpc0ltYWdlICYmICFmaWxlLnR5cGUuc3RhcnRzV2l0aCgnaW1hZ2UvJykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGBGaWxlIHdhcyBleHBlY3RlZCB0byBiZSBhbiBpbWFnZSBidXQgd2FzIGZvdW5kIHRvIGJlICR7ZmlsZS50eXBlfWApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9CYXNlNjQoZmlsZSwgYmFzZTY0RGF0YSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbnRpdHlbZmllbGRdID0gYmFzZTY0RGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eVtgJHtmaWVsZH1Db250ZW50VHlwZWBdID0gZmlsZS50eXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShlbnRpdHkpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlamVjdChgQmFzZTY0IGRhdGEgd2FzIG5vdCBzZXQgYXMgZmlsZSBjb3VsZCBub3QgYmUgZXh0cmFjdGVkIGZyb20gcGFzc2VkIHBhcmFtZXRlcjogJHtldmVudH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYmFzZSA2NCBkYXRhICYgZmlsZSB0eXBlIG9mIHRoZSAxc3QgZmlsZSBvbiB0aGUgZXZlbnQgKGV2ZW50LnRhcmdldC5maWxlc1swXSkgaW4gdGhlIHBhc3NlZCBlbnRpdHkgb2JqZWN0XG4gICAgICogYW5kIHJldHVybnMgYW4gb2JzZXJ2YWJsZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBldmVudCB0aGUgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZpbGUgKGF0IGV2ZW50LnRhcmdldC5maWxlc1swXSlcbiAgICAgKiBAcGFyYW0gZWRpdEZvcm0gdGhlIGZvcm0gZ3JvdXAgd2hlcmUgdGhlIGlucHV0IGZpZWxkIGlzIGxvY2F0ZWRcbiAgICAgKiBAcGFyYW0gZmllbGQgdGhlIGZpZWxkIG5hbWUgdG8gc2V0IHRoZSBmaWxlJ3MgJ2Jhc2UgNjQgZGF0YScgb25cbiAgICAgKiBAcGFyYW0gaXNJbWFnZSBib29sZWFuIHJlcHJlc2VudGluZyBpZiB0aGUgZmlsZSByZXByZXNlbnRlZCBieSB0aGUgZXZlbnQgaXMgYW4gaW1hZ2VcbiAgICAgKiBAcmV0dXJucyBhbiBvYnNlcnZhYmxlIHRoYXQgbG9hZHMgZmlsZSB0byBmb3JtIGZpZWxkIGFuZCBjb21wbGV0ZXMgaWYgc3Vzc2Vzc2Z1bFxuICAgICAqICAgICAgICAgIG9yIHJldHVybnMgZXJyb3IgYXMgSmhpRmlsZUxvYWRFcnJvciBvbiBmYWlsdXJlXG4gICAgICovXG4gICAgbG9hZEZpbGVUb0Zvcm0oZXZlbnQ6IEV2ZW50LCBlZGl0Rm9ybTogRm9ybUdyb3VwLCBmaWVsZDogc3RyaW5nLCBpc0ltYWdlOiBib29sZWFuKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgob2JzZXJ2ZXI6IE9ic2VydmVyPHZvaWQ+KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBldmVudFRhcmdldDogSFRNTElucHV0RWxlbWVudCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgICAgICAgaWYgKGV2ZW50VGFyZ2V0LmZpbGVzICYmIGV2ZW50VGFyZ2V0LmZpbGVzWzBdKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZTogRmlsZSA9IGV2ZW50VGFyZ2V0LmZpbGVzWzBdO1xuICAgICAgICAgICAgICAgIGlmIChpc0ltYWdlICYmICFmaWxlLnR5cGUuc3RhcnRzV2l0aCgnaW1hZ2UvJykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3I6IEpoaUZpbGVMb2FkRXJyb3IgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgRmlsZSB3YXMgZXhwZWN0ZWQgdG8gYmUgYW4gaW1hZ2UgYnV0IHdhcyBmb3VuZCB0byBiZSAnJHtmaWxlLnR5cGV9J2AsXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXk6ICdub3QuaW1hZ2UnLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zOiB7IGZpbGVUeXBlOiBmaWxlLnR5cGUgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmllbGRDb250ZW50VHlwZTogc3RyaW5nID0gZmllbGQgKyAnQ29udGVudFR5cGUnO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvQmFzZTY0KGZpbGUsIChiYXNlNjREYXRhOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkaXRGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaWVsZF06IGJhc2U2NERhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ZpZWxkQ29udGVudFR5cGVdOiBmaWxlLnR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvcjogSmhpRmlsZUxvYWRFcnJvciA9IHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ0NvdWxkIG5vdCBleHRyYWN0IGZpbGUnLFxuICAgICAgICAgICAgICAgICAgICBrZXk6ICdjb3VsZC5ub3QuZXh0cmFjdCcsXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtczogeyBldmVudCB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCB0byBkb3dubG9hZCBmaWxlXG4gICAgICovXG4gICAgZG93bmxvYWRGaWxlKGNvbnRlbnRUeXBlOiBzdHJpbmcsIGRhdGE6IHN0cmluZywgZmlsZU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zdCBieXRlQ2hhcmFjdGVycyA9IGF0b2IoZGF0YSk7XG4gICAgICAgIGNvbnN0IGJ5dGVOdW1iZXJzID0gbmV3IEFycmF5KGJ5dGVDaGFyYWN0ZXJzLmxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZUNoYXJhY3RlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGJ5dGVOdW1iZXJzW2ldID0gYnl0ZUNoYXJhY3RlcnMuY2hhckNvZGVBdChpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBieXRlQXJyYXkgPSBuZXcgVWludDhBcnJheShieXRlTnVtYmVycyk7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbYnl0ZUFycmF5XSwge1xuICAgICAgICAgICAgdHlwZTogY29udGVudFR5cGVcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHRlbXBMaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgICAgICB0ZW1wTGluay5ocmVmID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgIHRlbXBMaW5rLmRvd25sb2FkID0gZmlsZU5hbWU7XG4gICAgICAgIHRlbXBMaW5rLnRhcmdldCA9ICdfYmxhbmsnO1xuICAgICAgICB0ZW1wTGluay5jbGljaygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZW5kc1dpdGgoc3VmZml4OiBzdHJpbmcsIHN0cjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBzdHIuaW5jbHVkZXMoc3VmZml4LCBzdHIubGVuZ3RoIC0gc3VmZml4Lmxlbmd0aCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwYWRkaW5nU2l6ZSh2YWx1ZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKHRoaXMuZW5kc1dpdGgoJz09JywgdmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gMjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5lbmRzV2l0aCgnPScsIHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzaXplKHZhbHVlOiBzdHJpbmcpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gKHZhbHVlLmxlbmd0aCAvIDQpICogMyAtIHRoaXMucGFkZGluZ1NpemUodmFsdWUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZm9ybWF0QXNCeXRlcyhzaXplOiBudW1iZXIpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gc2l6ZS50b1N0cmluZygpLnJlcGxhY2UoL1xcQig/PShcXGR7M30pKyg/IVxcZCkpL2csICcgJykgKyAnIGJ5dGVzJztcbiAgICB9XG59XG4iXX0= |
\ | No newline at end of file |