UNPKG

fiscalapi

Version:

SDK de Node.js para FiscalAPI

302 lines 40.1 kB
/** * Cliente HTTP para FiscalAPI */ export class FiscalapiHttpClient { /** * Crea una nueva instancia del cliente HTTP para FiscalAPI * @param {AxiosInstance} httpClient - Instancia de Axios configurada * @param {FiscalapiSettings} settings - Configuración para el cliente FiscalAPI */ constructor(httpClient, settings) { this.httpClient = httpClient; this.settings = settings; // Configurar interceptores para el logging en modo debug if (this.settings.debug) { this.setupDebugInterceptors(); } } /** * Configura los interceptores para logear las peticiones y respuestas en modo debug * @private */ setupDebugInterceptors() { // Interceptor para peticiones this.httpClient.interceptors.request.use((config) => { this.logRequest(config); return config; }); // Interceptor para respuestas this.httpClient.interceptors.response.use((response) => { this.logResponse(response); return response; }, (error) => { if (error.response) { this.logResponse(error.response); } return Promise.reject(error); }); } /** * Logea los detalles de una petición HTTP cuando el modo debug está activado * @param {InternalAxiosRequestConfig} config - Configuración de la petición * @private */ logRequest(config) { var _a; if (this.settings.debug) { console.log(''); console.log('********************** Raw Request **************************'); console.log('Method: ', (_a = config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()); console.log('BaseURL: ', config.baseURL); console.log('PathURL: ', config.url); const resource = `${config.baseURL || ''}/${config.url || ''}`; console.log('FullURL: ', resource); if (config.data) { console.log('Body:', typeof config.data === 'string' ? config.data : JSON.stringify(config.data, null, 2)); } console.log(''); if (config.params) { console.log('Params:', config.params); } console.log(''); } } /** * Logea los detalles de una respuesta HTTP cuando el modo debug está activado * @param {AxiosResponse} response - Respuesta de la petición * @private */ logResponse(response) { if (this.settings.debug) { console.log(''); console.log('********************** Raw Response **************************'); console.log(''); console.log('Status:', response.status, response.statusText); //console.log('Headers:', response.headers); console.log('Data:', JSON.stringify(response.data, null, 2)); console.log(''); console.log('*************************************************************'); console.log(''); } } /** * Ejecuta una petición HTTP genérica con control completo sobre los parámetros * @param {HttpMethod} method - Método HTTP a utilizar * @param {string} endpoint - Punto final de la API * @param {RequestOptions<TData>} options - Opciones de la petición * @returns {Promise<ApiResponse<TResult>>} Respuesta de la API * @template TResult - Tipo de datos esperado en la respuesta * @template TData - Tipo de datos a enviar en la petición (opcional) */ async executeRequest(method, endpoint, options = {}) { try { // Extraer opciones const { data, queryParams, config = {}, responseTransformer } = options; // Construir configuración de la petición const requestConfig = { ...config, method, url: endpoint }; // Añadir parámetros de consulta si existen if (queryParams && Object.keys(queryParams).length > 0) { requestConfig.params = { ...(requestConfig.params || {}), ...queryParams }; } // Ejecutar la petición según el método let response; // Los métodos que no aceptan cuerpo en la petición if (method === 'GET' || method === 'HEAD' || method === 'OPTIONS' || method === 'DELETE') { // Para DELETE podríamos querer enviar datos en el cuerpo si es necesario if (method === 'DELETE' && data) { // Aunque no es estándar, algunas APIs aceptan body en DELETE requestConfig.data = data; } response = await this.httpClient.request(requestConfig); } else { // Métodos que aceptan cuerpo (POST, PUT, PATCH) requestConfig.data = data; response = await this.httpClient.request(requestConfig); } // Procesar la respuesta let processedResponse = await this.processResponse(response); // Aplicar transformador personalizado si se proporciona if (responseTransformer && processedResponse.succeeded) { try { const transformedData = responseTransformer(processedResponse.data); processedResponse = { ...processedResponse, data: transformedData }; } catch (transformError) { return { data: {}, succeeded: false, message: `Error al transformar la respuesta: ${transformError instanceof Error ? transformError.message : 'Error desconocido'}`, details: transformError instanceof Error ? transformError.stack || '' : '', httpStatusCode: processedResponse.httpStatusCode }; } } return processedResponse; } catch (error) { return this.handleRequestError(error); } } /** * Procesa la respuesta HTTP y la convierte en ApiResponse * @param {AxiosResponse} response - Respuesta HTTP original * @returns {ApiResponse<T>} Respuesta procesada * @template T - Tipo de datos esperado * @private */ async processResponse(response) { // Si la respuesta ya es un ApiResponse, lo retornamos con el tipo correcto if (response.data && typeof response.data === 'object' && 'succeeded' in response.data && 'data' in response.data) { // La respuesta es un ApiResponse<T> const apiResponse = response.data; // Aseguramos que el httpStatusCode refleje el status de la respuesta HTTP return { ...apiResponse, httpStatusCode: response.status }; } // La respuesta no es un ApiResponse, la encapsulamos return { data: response.data, succeeded: true, message: '', details: '', httpStatusCode: response.status }; } /** * Maneja los errores de las peticiones HTTP * @param {unknown} error - Error capturado * @returns {ApiResponse<T>} Respuesta de error estandarizada * @template T - Tipo de datos esperado * @private */ handleRequestError(error) { var _a, _b, _c, _d; const axiosError = error; // Extraer datos de respuesta const responseData = (_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.data; // Revisar si es un ProblemDetails según RFC 9457 if (responseData && typeof responseData === 'object' && 'type' in responseData && 'title' in responseData && 'status' in responseData) { const problemDetails = responseData; return { data: {}, succeeded: false, message: problemDetails.title, details: problemDetails.detail || JSON.stringify(problemDetails), httpStatusCode: ((_b = axiosError.response) === null || _b === void 0 ? void 0 : _b.status) || 500 }; } // Revisar si es un ApiResponse<ValidationFailure[]> para errores 400 if (((_c = axiosError.response) === null || _c === void 0 ? void 0 : _c.status) === 400 && responseData && typeof responseData === 'object' && 'data' in responseData && Array.isArray(responseData.data)) { const apiResponse = responseData; // Si hay errores de validación, extraer el primer mensaje if (apiResponse.data && apiResponse.data.length > 0) { const firstFailure = apiResponse.data[0]; return { data: {}, succeeded: false, message: firstFailure.errorMessage, details: JSON.stringify(apiResponse.data), httpStatusCode: 400 }; } } // Respuesta de error genérica return { data: {}, succeeded: false, message: axiosError.message || 'Ocurrió un error en la comunicación con el servidor', details: JSON.stringify(responseData || {}), httpStatusCode: ((_d = axiosError.response) === null || _d === void 0 ? void 0 : _d.status) || 500 }; } /** * Realiza una petición GET a la API * @param {string} endpoint - Punto final de la API * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<T>>} Respuesta de la API * @template T - Tipo de datos esperado en la respuesta */ async getAsync(endpoint, config) { return this.executeRequest('GET', endpoint, { config }); } /** * Realiza una petición GET por ID a la API * @param {string} endpoint - Punto final de la API con ID * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<T>>} Respuesta de la API * @template T - Tipo de datos esperado en la respuesta */ async getByIdAsync(endpoint, config) { return this.executeRequest('GET', endpoint, { config }); } /** * Realiza una petición POST a la API * @param {string} endpoint - Punto final de la API * @param {TData} data - Datos a enviar en la petición * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<T>>} Respuesta de la API * @template T - Tipo de datos esperado en la respuesta * @template TData - Tipo de datos a enviar en la petición */ async postAsync(endpoint, data, config) { return this.executeRequest('POST', endpoint, { data, config }); } /** * Realiza una petición PUT a la API * @param {string} endpoint - Punto final de la API * @param {TData} data - Datos a enviar en la petición * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<T>>} Respuesta de la API * @template T - Tipo de datos esperado en la respuesta * @template TData - Tipo de datos a enviar en la petición */ async putAsync(endpoint, data, config) { return this.executeRequest('PUT', endpoint, { data, config }); } /** * Realiza una petición DELETE a la API * @param {string} endpoint - Punto final de la API * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<boolean>>} Respuesta de la API */ async deleteAsync(endpoint, config) { return this.executeRequest('DELETE', endpoint, { config }); } /** * Realiza una petición PATCH a la API * @param {string} endpoint - Punto final de la API * @param {TData} data - Datos a enviar en la petición * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<T>>} Respuesta de la API * @template T - Tipo de datos esperado en la respuesta * @template TData - Tipo de datos a enviar en la petición */ async patchAsync(endpoint, data, config) { return this.executeRequest('PATCH', endpoint, { data, config }); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlzY2FsYXBpLWh0dHAtY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2h0dHAvZmlzY2FsYXBpLWh0dHAtY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVdBOztHQUVHO0FBQ0gsTUFBTSxPQUFPLG1CQUFtQjtJQUk5Qjs7OztPQUlHO0lBQ0gsWUFBWSxVQUF5QixFQUFFLFFBQTJCO1FBQ2hFLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBRXpCLHlEQUF5RDtRQUN6RCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDaEMsQ0FBQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSyxzQkFBc0I7UUFDNUIsOEJBQThCO1FBQzlCLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFrQyxFQUFFLEVBQUU7WUFDOUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN4QixPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDLENBQUMsQ0FBQztRQUVILDhCQUE4QjtRQUM5QixJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUN2QyxDQUFDLFFBQXVCLEVBQUUsRUFBRTtZQUMxQixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sUUFBUSxDQUFDO1FBQ2xCLENBQUMsRUFDRCxDQUFDLEtBQWlCLEVBQUUsRUFBRTtZQUNwQixJQUFJLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDbkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbkMsQ0FBQztZQUNELE9BQU8sT0FB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RUFBRSxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLFNBQVMsQ0FDYixRQUFnQixFQUNoQixJQUFXLEVBQ1gsTUFBMkI7UUFFM0IsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFXLE1BQU0sRUFBRSxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxLQUFLLENBQUMsUUFBUSxDQUNaLFFBQWdCLEVBQ2hCLElBQVcsRUFDWCxNQUEyQjtRQUUzQixPQUFPLElBQUksQ0FBQyxjQUFjLENBQVcsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxXQUFXLENBQ2YsUUFBZ0IsRUFDaEIsTUFBMkI7UUFFM0IsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFVLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILEtBQUssQ0FBQyxVQUFVLENBQ2QsUUFBZ0IsRUFDaEIsSUFBVyxFQUNYLE1BQTJCO1FBRTNCLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBVyxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDNUUsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgXG4gIEF4aW9zSW5zdGFuY2UsIFxuICBBeGlvc0Vycm9yLCBcbiAgQXhpb3NSZXNwb25zZSwgXG4gIEF4aW9zUmVxdWVzdENvbmZpZyxcbiAgSW50ZXJuYWxBeGlvc1JlcXVlc3RDb25maWdcbn0gZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHsgRmlzY2FsYXBpU2V0dGluZ3MgfSBmcm9tICcuLy4uL2NvbW1vbi9maXNjYWxhcGktc2V0dGluZ3MnO1xuaW1wb3J0IHsgSUZpc2NhbGFwaUh0dHBDbGllbnQsIEh0dHBNZXRob2QsIFJlcXVlc3RPcHRpb25zIH0gZnJvbSAnLi9maXNjYWxhcGktaHR0cC1jbGllbnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IEFwaVJlc3BvbnNlLCBQcm9ibGVtRGV0YWlscywgVmFsaWRhdGlvbkZhaWx1cmUgfSBmcm9tICcuLi9jb21tb24vYXBpLXJlc3BvbnNlJztcblxuLyoqXG4gKiBDbGllbnRlIEhUVFAgcGFyYSBGaXNjYWxBUElcbiAqL1xuZXhwb3J0IGNsYXNzIEZpc2NhbGFwaUh0dHBDbGllbnQgaW1wbGVtZW50cyBJRmlzY2FsYXBpSHR0cENsaWVudCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgaHR0cENsaWVudDogQXhpb3NJbnN0YW5jZTtcbiAgcHJpdmF0ZSByZWFkb25seSBzZXR0aW5nczogRmlzY2FsYXBpU2V0dGluZ3M7XG5cbiAgLyoqXG4gICAqIENyZWEgdW5hIG51ZXZhIGluc3RhbmNpYSBkZWwgY2xpZW50ZSBIVFRQIHBhcmEgRmlzY2FsQVBJXG4gICAqIEBwYXJhbSB7QXhpb3NJbnN0YW5jZX0gaHR0cENsaWVudCAtIEluc3RhbmNpYSBkZSBBeGlvcyBjb25maWd1cmFkYVxuICAgKiBAcGFyYW0ge0Zpc2NhbGFwaVNldHRpbmdzfSBzZXR0aW5ncyAtIENvbmZpZ3VyYWNpw7NuIHBhcmEgZWwgY2xpZW50ZSBGaXNjYWxBUElcbiAgICovXG4gIGNvbnN0cnVjdG9yKGh0dHBDbGllbnQ6IEF4aW9zSW5zdGFuY2UsIHNldHRpbmdzOiBGaXNjYWxhcGlTZXR0aW5ncykge1xuICAgIHRoaXMuaHR0cENsaWVudCA9IGh0dHBDbGllbnQ7XG4gICAgdGhpcy5zZXR0aW5ncyA9IHNldHRpbmdzO1xuXG4gICAgLy8gQ29uZmlndXJhciBpbnRlcmNlcHRvcmVzIHBhcmEgZWwgbG9nZ2luZyBlbiBtb2RvIGRlYnVnXG4gICAgaWYgKHRoaXMuc2V0dGluZ3MuZGVidWcpIHtcbiAgICAgIHRoaXMuc2V0dXBEZWJ1Z0ludGVyY2VwdG9ycygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmEgbG9zIGludGVyY2VwdG9yZXMgcGFyYSBsb2dlYXIgbGFzIHBldGljaW9uZXMgeSByZXNwdWVzdGFzIGVuIG1vZG8gZGVidWdcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgc2V0dXBEZWJ1Z0ludGVyY2VwdG9ycygpOiB2b2lkIHtcbiAgICAvLyBJbnRlcmNlcHRvciBwYXJhIHBldGljaW9uZXNcbiAgICB0aGlzLmh0dHBDbGllbnQuaW50ZXJjZXB0b3JzLnJlcXVlc3QudXNlKChjb25maWc6IEludGVybmFsQXhpb3NSZXF1ZXN0Q29uZmlnKSA9PiB7XG4gICAgICB0aGlzLmxvZ1JlcXVlc3QoY29uZmlnKTtcbiAgICAgIHJldHVybiBjb25maWc7XG4gICAgfSk7XG5cbiAgICAvLyBJbnRlcmNlcHRvciBwYXJhIHJlc3B1ZXN0YXNcbiAgICB0aGlzLmh0dHBDbGllbnQuaW50ZXJjZXB0b3JzLnJlc3BvbnNlLnVzZShcbiAgICAgIChyZXNwb25zZTogQXhpb3NSZXNwb25zZSkgPT4ge1xuICAgICAgICB0aGlzLmxvZ1Jlc3BvbnNlKHJlc3BvbnNlKTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgfSxcbiAgICAgIChlcnJvcjogQXhpb3NFcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IucmVzcG9uc2UpIHtcbiAgICAgICAgICB0aGlzLmxvZ1Jlc3BvbnNlKGVycm9yLnJlc3BvbnNlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogTG9nZWEgbG9zIGRldGFsbGVzIGRlIHVuYSBwZXRpY2nDs24gSFRUUCBjdWFuZG8gZWwgbW9kbyBkZWJ1ZyBlc3TDoSBhY3RpdmFkb1xuICAgKiBAcGFyYW0ge0ludGVybmFsQXhpb3NSZXF1ZXN0Q29uZmlnfSBjb25maWcgLSBDb25maWd1cmFjacOzbiBkZSBsYSBwZXRpY2nDs25cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgbG9nUmVxdWVzdChjb25maWc6IEludGVybmFsQXhpb3NSZXF1ZXN0Q29uZmlnKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2V0dGluZ3MuZGVidWcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgIGNvbnNvbGUubG9nKCcqKioqKioqKioqKioqKioqKioqKioqIFJhdyBSZXF1ZXN0ICoqKioqKioqKioqKioqKioqKioqKioqKioqJyk7XG4gICAgICBcbiAgICAgIGNvbnNvbGUubG9nKCdNZXRob2Q6ICcsICBjb25maWcubWV0aG9kPy50b1VwcGVyQ2FzZSgpKTtcbiAgICAgIGNvbnNvbGUubG9nKCdCYXNlVVJMOiAnLCBjb25maWcuYmFzZVVSTCk7XG4gICAgICBjb25zb2xlLmxvZygnUGF0aFVSTDogJywgY29uZmlnLnVybCk7XG4gICAgICBjb25zdCByZXNvdXJjZSA9IGAke2NvbmZpZy5iYXNlVVJMIHx8ICcnfS8ke2NvbmZpZy51cmwgfHwgJyd9YDtcbiAgICAgIGNvbnNvbGUubG9nKCdGdWxsVVJMOiAnLCByZXNvdXJjZSk7XG4gICAgICBcbiAgICAgIGlmIChjb25maWcuZGF0YSkge1xuICAgICAgICBjb25zb2xlLmxvZygnQm9keTonLCB0eXBlb2YgY29uZmlnLmRhdGEgPT09ICdzdHJpbmcnID8gY29uZmlnLmRhdGEgOiBKU09OLnN0cmluZ2lmeShjb25maWcuZGF0YSwgbnVsbCwgMikpO1xuICAgICAgfVxuICAgICAgXG4gICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICBcbiAgICAgIGlmIChjb25maWcucGFyYW1zKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdQYXJhbXM6JywgY29uZmlnLnBhcmFtcyk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTG9nZWEgbG9zIGRldGFsbGVzIGRlIHVuYSByZXNwdWVzdGEgSFRUUCBjdWFuZG8gZWwgbW9kbyBkZWJ1ZyBlc3TDoSBhY3RpdmFkb1xuICAgKiBAcGFyYW0ge0F4aW9zUmVzcG9uc2V9IHJlc3BvbnNlIC0gUmVzcHVlc3RhIGRlIGxhIHBldGljacOzblxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBsb2dSZXNwb25zZShyZXNwb25zZTogQXhpb3NSZXNwb25zZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNldHRpbmdzLmRlYnVnKSB7XG4gICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICBjb25zb2xlLmxvZygnKioqKioqKioqKioqKioqKioqKioqKiBSYXcgUmVzcG9uc2UgKioqKioqKioqKioqKioqKioqKioqKioqKionKTtcbiAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgIGNvbnNvbGUubG9nKCdTdGF0dXM6JywgcmVzcG9uc2Uuc3RhdHVzLCByZXNwb25zZS5zdGF0dXNUZXh0KTtcbiAgICAgIC8vY29uc29sZS5sb2coJ0hlYWRlcnM6JywgcmVzcG9uc2UuaGVhZGVycyk7XG4gICAgICBjb25zb2xlLmxvZygnRGF0YTonLCBKU09OLnN0cmluZ2lmeShyZXNwb25zZS5kYXRhLCBudWxsLCAyKSk7XG5cbiAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgIGNvbnNvbGUubG9nKCcqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqJyk7XG4gICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVqZWN1dGEgdW5hIHBldGljacOzbiBIVFRQIGdlbsOpcmljYSBjb24gY29udHJvbCBjb21wbGV0byBzb2JyZSBsb3MgcGFyw6FtZXRyb3NcbiAgICogQHBhcmFtIHtIdHRwTWV0aG9kfSBtZXRob2QgLSBNw6l0b2RvIEhUVFAgYSB1dGlsaXphclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZW5kcG9pbnQgLSBQdW50byBmaW5hbCBkZSBsYSBBUElcbiAgICogQHBhcmFtIHtSZXF1ZXN0T3B0aW9uczxURGF0YT59IG9wdGlvbnMgLSBPcGNpb25lcyBkZSBsYSBwZXRpY2nDs25cbiAgICogQHJldHVybnMge1Byb21pc2U8QXBpUmVzcG9uc2U8VFJlc3VsdD4+fSBSZXNwdWVzdGEgZGUgbGEgQVBJXG4gICAqIEB0ZW1wbGF0ZSBUUmVzdWx0IC0gVGlwbyBkZSBkYXRvcyBlc3BlcmFkbyBlbiBsYSByZXNwdWVzdGFcbiAgICogQHRlbXBsYXRlIFREYXRhIC0gVGlwbyBkZSBkYXRvcyBhIGVudmlhciBlbiBsYSBwZXRpY2nDs24gKG9wY2lvbmFsKVxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZVJlcXVlc3Q8VFJlc3VsdCwgVERhdGEgPSBhbnk+KFxuICAgIG1ldGhvZDogSHR0cE1ldGhvZCxcbiAgICBlbmRwb2ludDogc3RyaW5nLFxuICAgIG9wdGlvbnM6IFJlcXVlc3RPcHRpb25zPFREYXRhPiA9IHt9XG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VFJlc3VsdD4+IHtcbiAgICB0cnkge1xuICAgICAgLy8gRXh0cmFlciBvcGNpb25lc1xuICAgICAgY29uc3QgeyBkYXRhLCBxdWVyeVBhcmFtcywgY29uZmlnID0ge30sIHJlc3BvbnNlVHJhbnNmb3JtZXIgfSA9IG9wdGlvbnM7XG4gICAgICBcbiAgICAgIC8vIENvbnN0cnVpciBjb25maWd1cmFjacOzbiBkZSBsYSBwZXRpY2nDs25cbiAgICAgIGNvbnN0IHJlcXVlc3RDb25maWc6IEF4aW9zUmVxdWVzdENvbmZpZyA9IHtcbiAgICAgICAgLi4uY29uZmlnLFxuICAgICAgICBtZXRob2QsXG4gICAgICAgIHVybDogZW5kcG9pbnRcbiAgICAgIH07XG4gICAgICBcbiAgICAgIC8vIEHDsWFkaXIgcGFyw6FtZXRyb3MgZGUgY29uc3VsdGEgc2kgZXhpc3RlblxuICAgICAgaWYgKHF1ZXJ5UGFyYW1zICYmIE9iamVjdC5rZXlzKHF1ZXJ5UGFyYW1zKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJlcXVlc3RDb25maWcucGFyYW1zID0ge1xuICAgICAgICAgIC4uLihyZXF1ZXN0Q29uZmlnLnBhcmFtcyB8fCB7fSksXG4gICAgICAgICAgLi4ucXVlcnlQYXJhbXNcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gRWplY3V0YXIgbGEgcGV0aWNpw7NuIHNlZ8O6biBlbCBtw6l0b2RvXG4gICAgICBsZXQgcmVzcG9uc2U6IEF4aW9zUmVzcG9uc2U7XG4gICAgICBcbiAgICAgIC8vIExvcyBtw6l0b2RvcyBxdWUgbm8gYWNlcHRhbiBjdWVycG8gZW4gbGEgcGV0aWNpw7NuXG4gICAgICBpZiAobWV0aG9kID09PSAnR0VUJyB8fCBtZXRob2QgPT09ICdIRUFEJyB8fCBtZXRob2QgPT09ICdPUFRJT05TJyB8fCBtZXRob2QgPT09ICdERUxFVEUnKSB7XG4gICAgICAgIC8vIFBhcmEgREVMRVRFIHBvZHLDrWFtb3MgcXVlcmVyIGVudmlhciBkYXRvcyBlbiBlbCBjdWVycG8gc2kgZXMgbmVjZXNhcmlvXG4gICAgICAgIGlmIChtZXRob2QgPT09ICdERUxFVEUnICYmIGRhdGEpIHtcbiAgICAgICAgICAvLyBBdW5xdWUgbm8gZXMgZXN0w6FuZGFyLCBhbGd1bmFzIEFQSXMgYWNlcHRhbiBib2R5IGVuIERFTEVURVxuICAgICAgICAgIHJlcXVlc3RDb25maWcuZGF0YSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmh0dHBDbGllbnQucmVxdWVzdChyZXF1ZXN0Q29uZmlnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE3DqXRvZG9zIHF1ZSBhY2VwdGFuIGN1ZXJwbyAoUE9TVCwgUFVULCBQQVRDSClcbiAgICAgICAgcmVxdWVzdENvbmZpZy5kYXRhID0gZGF0YTtcbiAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmh0dHBDbGllbnQucmVxdWVzdChyZXF1ZXN0Q29uZmlnKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gUHJvY2VzYXIgbGEgcmVzcHVlc3RhXG4gICAgICBsZXQgcHJvY2Vzc2VkUmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb2Nlc3NSZXNwb25zZTxUUmVzdWx0PihyZXNwb25zZSk7XG4gICAgICBcbiAgICAgIC8vIEFwbGljYXIgdHJhbnNmb3JtYWRvciBwZXJzb25hbGl6YWRvIHNpIHNlIHByb3BvcmNpb25hXG4gICAgICBpZiAocmVzcG9uc2VUcmFuc2Zvcm1lciAmJiBwcm9jZXNzZWRSZXNwb25zZS5zdWNjZWVkZWQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZERhdGEgPSByZXNwb25zZVRyYW5zZm9ybWVyKHByb2Nlc3NlZFJlc3BvbnNlLmRhdGEpO1xuICAgICAgICAgIHByb2Nlc3NlZFJlc3BvbnNlID0ge1xuICAgICAgICAgICAgLi4ucHJvY2Vzc2VkUmVzcG9uc2UsXG4gICAgICAgICAgICBkYXRhOiB0cmFuc2Zvcm1lZERhdGEgYXMgVFJlc3VsdFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKHRyYW5zZm9ybUVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRhdGE6IHt9IGFzIFRSZXN1bHQsXG4gICAgICAgICAgICBzdWNjZWVkZWQ6IGZhbHNlLFxuICAgICAgICAgICAgbWVzc2FnZTogYEVycm9yIGFsIHRyYW5zZm9ybWFyIGxhIHJlc3B1ZXN0YTogJHt0cmFuc2Zvcm1FcnJvciBpbnN0YW5jZW9mIEVycm9yID8gdHJhbnNmb3JtRXJyb3IubWVzc2FnZSA6ICdFcnJvciBkZXNjb25vY2lkbyd9YCxcbiAgICAgICAgICAgIGRldGFpbHM6IHRyYW5zZm9ybUVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyB0cmFuc2Zvcm1FcnJvci5zdGFjayB8fCAnJyA6ICcnLFxuICAgICAgICAgICAgaHR0cFN0YXR1c0NvZGU6IHByb2Nlc3NlZFJlc3BvbnNlLmh0dHBTdGF0dXNDb2RlXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgXG4gICAgICByZXR1cm4gcHJvY2Vzc2VkUmVzcG9uc2U7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlcXVlc3RFcnJvcjxUUmVzdWx0PihlcnJvcik7XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogUHJvY2VzYSBsYSByZXNwdWVzdGEgSFRUUCB5IGxhIGNvbnZpZXJ0ZSBlbiBBcGlSZXNwb25zZVxuICAgKiBAcGFyYW0ge0F4aW9zUmVzcG9uc2V9IHJlc3BvbnNlIC0gUmVzcHVlc3RhIEhUVFAgb3JpZ2luYWxcbiAgICogQHJldHVybnMge0FwaVJlc3BvbnNlPFQ+fSBSZXNwdWVzdGEgcHJvY2VzYWRhXG4gICAqIEB0ZW1wbGF0ZSBUIC0gVGlwbyBkZSBkYXRvcyBlc3BlcmFkb1xuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzUmVzcG9uc2U8VD4ocmVzcG9uc2U6IEF4aW9zUmVzcG9uc2UpOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQ+PiB7XG4gICAgLy8gU2kgbGEgcmVzcHVlc3RhIHlhIGVzIHVuIEFwaVJlc3BvbnNlLCBsbyByZXRvcm5hbW9zIGNvbiBlbCB0aXBvIGNvcnJlY3RvXG4gICAgaWYgKFxuICAgICAgcmVzcG9uc2UuZGF0YSAmJiBcbiAgICAgIHR5cGVvZiByZXNwb25zZS5kYXRhID09PSAnb2JqZWN0JyAmJiBcbiAgICAgICdzdWNjZWVkZWQnIGluIHJlc3BvbnNlLmRhdGEgJiYgXG4gICAgICAnZGF0YScgaW4gcmVzcG9uc2UuZGF0YVxuICAgICkge1xuICAgICAgLy8gTGEgcmVzcHVlc3RhIGVzIHVuIEFwaVJlc3BvbnNlPFQ+XG4gICAgICBjb25zdCBhcGlSZXNwb25zZSA9IHJlc3BvbnNlLmRhdGEgYXMgdW5rbm93biBhcyBBcGlSZXNwb25zZTxUPjtcbiAgICAgIFxuICAgICAgLy8gQXNlZ3VyYW1vcyBxdWUgZWwgaHR0cFN0YXR1c0NvZGUgcmVmbGVqZSBlbCBzdGF0dXMgZGUgbGEgcmVzcHVlc3RhIEhUVFBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmFwaVJlc3BvbnNlLFxuICAgICAgICBodHRwU3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzXG4gICAgICB9O1xuICAgIH1cbiAgICBcbiAgICAvLyBMYSByZXNwdWVzdGEgbm8gZXMgdW4gQXBpUmVzcG9uc2UsIGxhIGVuY2Fwc3VsYW1vc1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiByZXNwb25zZS5kYXRhIGFzIHVua25vd24gYXMgVCxcbiAgICAgIHN1Y2NlZWRlZDogdHJ1ZSxcbiAgICAgIG1lc3NhZ2U6ICcnLFxuICAgICAgZGV0YWlsczogJycsXG4gICAgICBodHRwU3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzXG4gICAgfTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIE1hbmVqYSBsb3MgZXJyb3JlcyBkZSBsYXMgcGV0aWNpb25lcyBIVFRQXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gZXJyb3IgLSBFcnJvciBjYXB0dXJhZG9cbiAgICogQHJldHVybnMge0FwaVJlc3BvbnNlPFQ+fSBSZXNwdWVzdGEgZGUgZXJyb3IgZXN0YW5kYXJpemFkYVxuICAgKiBAdGVtcGxhdGUgVCAtIFRpcG8gZGUgZGF0b3MgZXNwZXJhZG9cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgaGFuZGxlUmVxdWVzdEVycm9yPFQ+KGVycm9yOiB1bmtub3duKTogQXBpUmVzcG9uc2U8VD4ge1xuICAgIGNvbnN0IGF4aW9zRXJyb3IgPSBlcnJvciBhcyBBeGlvc0Vycm9yO1xuICAgIFxuICAgIC8vIEV4dHJhZXIgZGF0b3MgZGUgcmVzcHVlc3RhXG4gICAgY29uc3QgcmVzcG9uc2VEYXRhID0gYXhpb3NFcnJvci5yZXNwb25zZT8uZGF0YTtcbiAgICBcbiAgICAvLyBSZXZpc2FyIHNpIGVzIHVuIFByb2JsZW1EZXRhaWxzIHNlZ8O6biBSRkMgOTQ1N1xuICAgIGlmIChcbiAgICAgIHJlc3BvbnNlRGF0YSAmJiBcbiAgICAgIHR5cGVvZiByZXNwb25zZURhdGEgPT09ICdvYmplY3QnICYmIFxuICAgICAgJ3R5cGUnIGluIHJlc3BvbnNlRGF0YSAmJiBcbiAgICAgICd0aXRsZScgaW4gcmVzcG9uc2VEYXRhICYmXG4gICAgICAnc3RhdHVzJyBpbiByZXNwb25zZURhdGFcbiAgICApIHtcbiAgICAgIGNvbnN0IHByb2JsZW1EZXRhaWxzID0gcmVzcG9uc2VEYXRhIGFzIFByb2JsZW1EZXRhaWxzO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkYXRhOiB7fSBhcyBULFxuICAgICAgICBzdWNjZWVkZWQ6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiBwcm9ibGVtRGV0YWlscy50aXRsZSxcbiAgICAgICAgZGV0YWlsczogcHJvYmxlbURldGFpbHMuZGV0YWlsIHx8IEpTT04uc3RyaW5naWZ5KHByb2JsZW1EZXRhaWxzKSxcbiAgICAgICAgaHR0cFN0YXR1c0NvZGU6IGF4aW9zRXJyb3IucmVzcG9uc2U/LnN0YXR1cyB8fCA1MDBcbiAgICAgIH07XG4gICAgfVxuICAgIFxuICAgIC8vIFJldmlzYXIgc2kgZXMgdW4gQXBpUmVzcG9uc2U8VmFsaWRhdGlvbkZhaWx1cmVbXT4gcGFyYSBlcnJvcmVzIDQwMFxuICAgIGlmIChcbiAgICAgIGF4aW9zRXJyb3IucmVzcG9uc2U/LnN0YXR1cyA9PT0gNDAwICYmXG4gICAgICByZXNwb25zZURhdGEgJiZcbiAgICAgIHR5cGVvZiByZXNwb25zZURhdGEgPT09ICdvYmplY3QnICYmXG4gICAgICAnZGF0YScgaW4gcmVzcG9uc2VEYXRhICYmXG4gICAgICBBcnJheS5pc0FycmF5KHJlc3BvbnNlRGF0YS5kYXRhKVxuICAgICkge1xuICAgICAgY29uc3QgYXBpUmVzcG9uc2UgPSByZXNwb25zZURhdGEgYXMgQXBpUmVzcG9uc2U8VmFsaWRhdGlvbkZhaWx1cmVbXT47XG4gICAgICBcbiAgICAgIC8vIFNpIGhheSBlcnJvcmVzIGRlIHZhbGlkYWNpw7NuLCBleHRyYWVyIGVsIHByaW1lciBtZW5zYWplXG4gICAgICBpZiAoYXBpUmVzcG9uc2UuZGF0YSAmJiBhcGlSZXNwb25zZS5kYXRhLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgZmlyc3RGYWlsdXJlID0gYXBpUmVzcG9uc2UuZGF0YVswXTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBkYXRhOiB7fSBhcyBULFxuICAgICAgICAgIHN1Y2NlZWRlZDogZmFsc2UsXG4gICAgICAgICAgbWVzc2FnZTogZmlyc3RGYWlsdXJlLmVycm9yTWVzc2FnZSxcbiAgICAgICAgICBkZXRhaWxzOiBKU09OLnN0cmluZ2lmeShhcGlSZXNwb25zZS5kYXRhKSxcbiAgICAgICAgICBodHRwU3RhdHVzQ29kZTogNDAwXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIC8vIFJlc3B1ZXN0YSBkZSBlcnJvciBnZW7DqXJpY2FcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YToge30gYXMgVCxcbiAgICAgIHN1Y2NlZWRlZDogZmFsc2UsXG4gICAgICBtZXNzYWdlOiBheGlvc0Vycm9yLm1lc3NhZ2UgfHwgJ09jdXJyacOzIHVuIGVycm9yIGVuIGxhIGNvbXVuaWNhY2nDs24gY29uIGVsIHNlcnZpZG9yJyxcbiAgICAgIGRldGFpbHM6IEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlRGF0YSB8fCB7fSksXG4gICAgICBodHRwU3RhdHVzQ29kZTogYXhpb3NFcnJvci5yZXNwb25zZT8uc3RhdHVzIHx8IDUwMFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVhbGl6YSB1bmEgcGV0aWNpw7NuIEdFVCBhIGxhIEFQSVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZW5kcG9pbnQgLSBQdW50byBmaW5hbCBkZSBsYSBBUElcbiAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddIC0gQ29uZmlndXJhY2nDs24gYWRpY2lvbmFsIHBhcmEgbGEgcGV0aWNpw7NuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFwaVJlc3BvbnNlPFQ+Pn0gUmVzcHVlc3RhIGRlIGxhIEFQSVxuICAgKiBAdGVtcGxhdGUgVCAtIFRpcG8gZGUgZGF0b3MgZXNwZXJhZG8gZW4gbGEgcmVzcHVlc3RhXG4gICAqL1xuICBhc3luYyBnZXRBc3luYzxUPihlbmRwb2ludDogc3RyaW5nLCBjb25maWc/OiBBeGlvc1JlcXVlc3RDb25maWcpOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQ+PiB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZVJlcXVlc3Q8VD4oJ0dFVCcsIGVuZHBvaW50LCB7IGNvbmZpZyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFsaXphIHVuYSBwZXRpY2nDs24gR0VUIHBvciBJRCBhIGxhIEFQSVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZW5kcG9pbnQgLSBQdW50byBmaW5hbCBkZSBsYSBBUEkgY29uIElEXG4gICAqIEBwYXJhbSB7QXhpb3NSZXF1ZXN0Q29uZmlnfSBbY29uZmlnXSAtIENvbmZpZ3VyYWNpw7NuIGFkaWNpb25hbCBwYXJhIGxhIHBldGljacOzblxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBcGlSZXNwb25zZTxUPj59IFJlc3B1ZXN0YSBkZSBsYSBBUElcbiAgICogQHRlbXBsYXRlIFQgLSBUaXBvIGRlIGRhdG9zIGVzcGVyYWRvIGVuIGxhIHJlc3B1ZXN0YVxuICAgKi9cbiAgYXN5bmMgZ2V0QnlJZEFzeW5jPFQ+KGVuZHBvaW50OiBzdHJpbmcsIGNvbmZpZz86IEF4aW9zUmVxdWVzdENvbmZpZyk6IFByb21pc2U8QXBpUmVzcG9uc2U8VD4+IHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlUmVxdWVzdDxUPignR0VUJywgZW5kcG9pbnQsIHsgY29uZmlnIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWxpemEgdW5hIHBldGljacOzbiBQT1NUIGEgbGEgQVBJXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBlbmRwb2ludCAtIFB1bnRvIGZpbmFsIGRlIGxhIEFQSVxuICAgKiBAcGFyYW0ge1REYXRhfSBkYXRhIC0gRGF0b3MgYSBlbnZpYXIgZW4gbGEgcGV0aWNpw7NuXG4gICAqIEBwYXJhbSB7QXhpb3NSZXF1ZXN0Q29uZmlnfSBbY29uZmlnXSAtIENvbmZpZ3VyYWNpw7NuIGFkaWNpb25hbCBwYXJhIGxhIHBldGljacOzblxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBcGlSZXNwb25zZTxUPj59IFJlc3B1ZXN0YSBkZSBsYSBBUElcbiAgICogQHRlbXBsYXRlIFQgLSBUaXBvIGRlIGRhdG9zIGVzcGVyYWRvIGVuIGxhIHJlc3B1ZXN0YVxuICAgKiBAdGVtcGxhdGUgVERhdGEgLSBUaXBvIGRlIGRhdG9zIGEgZW52aWFyIGVuIGxhIHBldGljacOzblxuICAgKi9cbiAgYXN5bmMgcG9zdEFzeW5jPFQsIFREYXRhID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxuICAgIGVuZHBvaW50OiBzdHJpbmcsIFxuICAgIGRhdGE6IFREYXRhLCBcbiAgICBjb25maWc/OiBBeGlvc1JlcXVlc3RDb25maWdcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxUPj4ge1xuICAgIHJldHVybiB0aGlzLmV4ZWN1dGVSZXF1ZXN0PFQsIFREYXRhPignUE9TVCcsIGVuZHBvaW50LCB7IGRhdGEsIGNvbmZpZyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFsaXphIHVuYSBwZXRpY2nDs24gUFVUIGEgbGEgQVBJXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBlbmRwb2ludCAtIFB1bnRvIGZpbmFsIGRlIGxhIEFQSVxuICAgKiBAcGFyYW0ge1REYXRhfSBkYXRhIC0gRGF0b3MgYSBlbnZpYXIgZW4gbGEgcGV0aWNpw7NuXG4gICAqIEBwYXJhbSB7QXhpb3NSZXF1ZXN0Q29uZmlnfSBbY29uZmlnXSAtIENvbmZpZ3VyYWNpw7NuIGFkaWNpb25hbCBwYXJhIGxhIHBldGljacOzblxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBcGlSZXNwb25zZTxUPj59IFJlc3B1ZXN0YSBkZSBsYSBBUElcbiAgICogQHRlbXBsYXRlIFQgLSBUaXBvIGRlIGRhdG9zIGVzcGVyYWRvIGVuIGxhIHJlc3B1ZXN0YVxuICAgKiBAdGVtcGxhdGUgVERhdGEgLSBUaXBvIGRlIGRhdG9zIGEgZW52aWFyIGVuIGxhIHBldGljacOzblxuICAgKi9cbiAgYXN5bmMgcHV0QXN5bmM8VCwgVERhdGEgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gICAgZW5kcG9pbnQ6IHN0cmluZywgXG4gICAgZGF0YTogVERhdGEsIFxuICAgIGNvbmZpZz86IEF4aW9zUmVxdWVzdENvbmZpZ1xuICApOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQ+PiB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZVJlcXVlc3Q8VCwgVERhdGE+KCdQVVQnLCBlbmRwb2ludCwgeyBkYXRhLCBjb25maWcgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVhbGl6YSB1bmEgcGV0aWNpw7NuIERFTEVURSBhIGxhIEFQSVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZW5kcG9pbnQgLSBQdW50byBmaW5hbCBkZSBsYSBBUElcbiAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddIC0gQ29uZmlndXJhY2nDs24gYWRpY2lvbmFsIHBhcmEgbGEgcGV0aWNpw7NuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFwaVJlc3BvbnNlPGJvb2xlYW4+Pn0gUmVzcHVlc3RhIGRlIGxhIEFQSVxuICAgKi9cbiAgYXN5bmMgZGVsZXRlQXN5bmMoXG4gICAgZW5kcG9pbnQ6IHN0cmluZywgXG4gICAgY29uZmlnPzogQXhpb3NSZXF1ZXN0Q29uZmlnXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8Ym9vbGVhbj4+IHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlUmVxdWVzdDxib29sZWFuPignREVMRVRFJywgZW5kcG9pbnQsIHsgY29uZmlnIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWxpemEgdW5hIHBldGljacOzbiBQQVRDSCBhIGxhIEFQSVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZW5kcG9pbnQgLSBQdW50byBmaW5hbCBkZSBsYSBBUElcbiAgICogQHBhcmFtIHtURGF0YX0gZGF0YSAtIERhdG9zIGEgZW52aWFyIGVuIGxhIHBldGljacOzblxuICAgKiBAcGFyYW0ge0F4aW9zUmVxdWVzdENvbmZpZ30gW2NvbmZpZ10gLSBDb25maWd1cmFjacOzbiBhZGljaW9uYWwgcGFyYSBsYSBwZXRpY2nDs25cbiAgICogQHJldHVybnMge1Byb21pc2U8QXBpUmVzcG9uc2U8VD4+fSBSZXNwdWVzdGEgZGUgbGEgQVBJXG4gICAqIEB0ZW1wbGF0ZSBUIC0gVGlwbyBkZSBkYXRvcyBlc3BlcmFkbyBlbiBsYSByZXNwdWVzdGFcbiAgICogQHRlbXBsYXRlIFREYXRhIC0gVGlwbyBkZSBkYXRvcyBhIGVudmlhciBlbiBsYSBwZXRpY2nDs25cbiAgICovXG4gIGFzeW5jIHBhdGNoQXN5bmM8VCwgVERhdGEgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gICAgZW5kcG9pbnQ6IHN0cmluZywgXG4gICAgZGF0YTogVERhdGEsIFxuICAgIGNvbmZpZz86IEF4aW9zUmVxdWVzdENvbmZpZ1xuICApOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQ+PiB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZVJlcXVlc3Q8VCwgVERhdGE+KCdQQVRDSCcsIGVuZHBvaW50LCB7IGRhdGEsIGNvbmZpZyB9KTtcbiAgfVxufSJdfQ==