@hurbis/comum
Version:
Biblioteca contendo rotinas e utilitários para desenvolvimento em Angular.
489 lines (476 loc) • 38.9 kB
JavaScript
import { Injectable, NgModule, Injector, defineInjectable, inject } from '@angular/core';
import { TranslateService, TranslatePipe, TranslateModule } from '@ngx-translate/core';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class CNPJ {
/**
* @param {?} numeros
* @return {?}
*/
static retornarDigito(numeros) {
/** @type {?} */
let invertido = numeros.split("").reduce((buffer, number) => {
return [parseInt(number, 10)].concat(buffer);
}, []);
/** @type {?} */
let indice = 2;
/** @type {?} */
let soma = invertido.reduce((buffer, numero) => {
buffer += numero * indice;
indice = (indice === 9 ? 2 : indice + 1);
return buffer;
}, 0);
/** @type {?} */
let mod = soma % 11;
return (mod < 2 ? 0 : 11 - mod);
}
/**
* @param {?} numero
* @return {?}
*/
static formatar(numero) {
/** @type {?} */
let regex = new RegExp("^(\\d{2})(\\d{3})(\\d{3})(\\d{4})(\\d{2})$");
return this.limpar(numero).replace(regex, "$1.$2.$3/$4-$5");
}
/**
* @param {?} numero
* @param {?=} strict
* @return {?}
*/
static limpar(numero, strict) {
/** @type {?} */
let regex = strict ? this.STRICT_STRIP_REGEX : this.LOOSE_STRIP_REGEX;
return (numero || "").toString().replace(regex, "");
}
/**
* @param {?} numeroSemDV
* @return {?}
*/
static atualizarComDV(numeroSemDV) {
numeroSemDV += this.retornarDigito(numeroSemDV); // 13
numeroSemDV += this.retornarDigito(numeroSemDV); // 14
return numeroSemDV;
}
/**
* @param {?} numero
* @param {?=} strict
* @return {?}
*/
static validar(numero, strict) {
/** @type {?} */
let numeroLimpo = this.limpar(numero, strict);
if (!numeroLimpo) {
return false;
}
if (numeroLimpo.length !== 14) {
return false;
}
if (this.LISTA_IGNORADA.indexOf(numeroLimpo) >= 0) {
return false;
}
/** @type {?} */
let numeroComDV = this.atualizarComDV(numeroLimpo.substr(0, 12));
return numeroComDV.substr(-2) === numeroLimpo.substr(-2);
}
/**
* @param {?} formatado
* @return {?}
*/
static gerar(formatado) {
/** @type {?} */
let numeroSemDV = "";
for (let i = 0; i < 12; i++) {
numeroSemDV += Math.floor(Math.random() * 9);
}
/** @type {?} */
let numeroComDV = this.atualizarComDV(numeroSemDV);
return (formatado ? this.formatar(numeroComDV) : numeroComDV);
}
}
CNPJ.LISTA_IGNORADA = [
"00000000000000",
"11111111111111",
"22222222222222",
"33333333333333",
"44444444444444",
"55555555555555",
"66666666666666",
"77777777777777",
"88888888888888",
"99999999999999"
];
CNPJ.STRICT_STRIP_REGEX = new RegExp("[-\/.]/g");
CNPJ.LOOSE_STRIP_REGEX = new RegExp("[^\\d]/g");
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class CPF {
/**
* @param {?} numeros
* @return {?}
*/
static retornarDigito(numeros) {
/** @type {?} */
let listaNumero = numeros
.split("")
.map((numero) => { return parseInt(numero, 10); });
/** @type {?} */
var modulo = listaNumero.length + 1;
/** @type {?} */
var multiplificador = listaNumero.map((numero, indice) => {
return numero * (modulo - indice);
});
/** @type {?} */
var resto = multiplificador.reduce((buffer, numero) => {
return buffer + numero;
}) % 11;
return (resto < 2 ? 0 : 11 - resto);
}
/**
* @param {?} numero
* @return {?}
*/
static formatar(numero) {
/** @type {?} */
let regex = new RegExp("^(\\d{3})(\\d{3})(\\d{3})(\\d{2})$");
return this.limpar(numero).replace(regex, "$1.$2.$3-$4");
}
/**
* @param {?} numero
* @param {?=} strict
* @return {?}
*/
static limpar(numero, strict) {
/** @type {?} */
let regex = strict ? this.STRICT_STRIP_REGEX : this.LOOSE_STRIP_REGEX;
return (numero || "").toString().replace(regex, "");
}
/**
* @param {?} numeroSemDV
* @return {?}
*/
static atualizarComDV(numeroSemDV) {
numeroSemDV += this.retornarDigito(numeroSemDV); // 10
numeroSemDV += this.retornarDigito(numeroSemDV); // 11
return numeroSemDV;
}
/**
* @param {?} numero
* @param {?=} strict
* @return {?}
*/
static validar(numero, strict) {
/** @type {?} */
let numeroLimpo = this.limpar(numero, strict);
if (!numeroLimpo) {
return false;
}
if (numeroLimpo.length !== 11) {
return false;
}
if (this.LISTA_IGNORADA.indexOf(numeroLimpo) >= 0) {
return false;
}
/** @type {?} */
let numeroComDV = this.atualizarComDV(numeroLimpo.substr(0, 9));
return numeroComDV.substr(-2) === numeroLimpo.substr(-2);
}
/**
* @param {?} formatado
* @return {?}
*/
static gerar(formatado) {
/** @type {?} */
let numeroSemDV = "";
for (let i = 0; i < 9; i++) {
numeroSemDV += Math.floor(Math.random() * 9);
}
/** @type {?} */
let numeroComDV = this.atualizarComDV(numeroSemDV);
return (formatado ? this.formatar(numeroComDV) : numeroComDV);
}
}
CPF.LISTA_IGNORADA = [
"00000000000",
"11111111111",
"22222222222",
"33333333333",
"44444444444",
"55555555555",
"66666666666",
"77777777777",
"88888888888",
"99999999999",
"12345678909"
];
CPF.STRICT_STRIP_REGEX = new RegExp("[.-]/g");
CPF.LOOSE_STRIP_REGEX = new RegExp("[^\d]/g");
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class Arquivo {
/**
* @param {?} conteudo
* @param {?=} sliceSize
* @return {?}
*/
static fromBase64ToByteArray(conteudo, sliceSize = 512) {
/** @type {?} */
let byteString = window.atob(conteudo);
/** @type {?} */
let byteArrays = [];
for (let offset = 0; offset < byteString.length; offset += sliceSize) {
/** @type {?} */
const slice = byteString.slice(offset, offset + sliceSize);
/** @type {?} */
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
/** @type {?} */
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return byteArrays;
}
/**
* @param {?} conteudo
* @param {?} tipo
* @return {?}
*/
static fromByteArrayToBlob(conteudo, tipo) {
return new Blob(conteudo, { type: tipo });
}
/**
* @param {?} conteudo
* @param {?=} tipo
* @param {?=} sliceSize
* @return {?}
*/
static fromBase64ToBlob(conteudo, tipo = "", sliceSize = 512) {
/** @type {?} */
var bytes = Arquivo.fromBase64ToByteArray(conteudo);
return Arquivo.fromByteArrayToBlob(bytes, tipo);
}
/**
* @param {?} arquivo
* @return {?}
*/
static toBlob(arquivo) {
return Arquivo.fromBase64ToBlob(arquivo.conteudo, arquivo.tipo);
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class Gerador {
/**
* Gera um código aleatório.
* @param {?} tamanho Tamanho do código desejado.
* @return {?}
*/
static gerarCodigoAleatorio(tamanho) {
/** @type {?} */
let texto = "";
/** @type {?} */
let possibilidades = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < tamanho; i++)
texto += possibilidades.charAt(Math.floor(Math.random() * possibilidades.length));
return texto;
}
/**
* Gera código utilizando lógica e formato GUID.
* @return {?}
*/
static gerarGUID() {
/** @type {?} */
var s4 = () => {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
};
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class LocalizacaoService {
/**
* @param {?} translate
* @param {?} translatePipe
*/
constructor(translate, translatePipe) {
this.translate = translate;
this.translatePipe = translatePipe;
}
/**
* @param {?} linguagem
* @return {?}
*/
definirLinguagemPadrao(linguagem) {
this.translate.setDefaultLang(linguagem);
}
/**
* @param {...?} traducoes
* @return {?}
*/
carregar(...traducoes) {
/** @type {?} */
const traducoesAux = [...traducoes];
traducoesAux.forEach((localizacao) => {
this.translate.setTranslation(localizacao.idioma, localizacao.traducao, true);
});
}
/**
* @param {?} linguagens
* @return {?}
*/
adicionar(linguagens) {
this.translate.addLangs(linguagens);
}
/**
* @param {?=} linguagem
* @return {?}
*/
traduzir(linguagem) {
this.translate.use((linguagem) ? linguagem : this.sugerida()).subscribe();
}
/**
* @param {?} chave
* @return {?}
*/
traducaoSimples(chave) {
return this.translatePipe.transform(chave);
}
/**
* @param {?} chaves
* @return {?}
*/
traducao(chaves) {
return this.translate.get(chaves);
}
/**
* @return {?}
*/
selecionada() {
return this.translate.currentLang;
}
/**
* @return {?}
*/
sugerida() {
return this.translate.getBrowserLang() || this.translate.getDefaultLang();
}
}
LocalizacaoService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
/** @nocollapse */
LocalizacaoService.ctorParameters = () => [
{ type: TranslateService },
{ type: TranslatePipe }
];
/** @nocollapse */ LocalizacaoService.ngInjectableDef = defineInjectable({ factory: function LocalizacaoService_Factory() { return new LocalizacaoService(inject(TranslateService), inject(TranslatePipe)); }, token: LocalizacaoService, providedIn: "root" });
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class ComumModule {
/**
* @param {?} injector
*/
constructor(injector) {
ComumModule._injector = injector;
}
/**
* @return {?}
*/
static getInjector() {
return ComumModule._injector;
}
}
ComumModule._injector = null;
ComumModule.decorators = [
{ type: NgModule, args: [{
imports: [
TranslateModule.forRoot()
],
providers: [
LocalizacaoService
]
},] }
];
/** @nocollapse */
ComumModule.ctorParameters = () => [
{ type: Injector }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class Objeto {
/**
* @template T
* @param {?} origem
* @return {?}
*/
static copiar(origem) {
return Object.assign({}, origem);
}
/**
* @param {?} destino
* @param {...?} fontes
* @return {?}
*/
static estender(destino, ...fontes) {
Object.assign(destino, fontes);
}
/**
* Recupera a instância de uma classe registrada.
* @template T
* @param {?} tipoInstancia Tipo do serviço a ser recuperado.
* @return {?}
*/
static recuperarInstancia(tipoInstancia) {
if (ComumModule.getInjector() == null) {
this.excecaoObjetoNaoCarregado("injector");
return;
}
return ComumModule.getInjector().get(tipoInstancia);
}
/**
* @param {?} objeto
* @return {?}
*/
static excecaoObjetoNaoCarregado(objeto) {
throw objeto + " não carregado.";
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
export { CNPJ, CPF, Arquivo, Gerador, Objeto, LocalizacaoService, ComumModule };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHVyYmlzLWNvbXVtLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9AaHVyYmlzL2NvbXVtL2xpYi91dGlsL3ZhbGlkYWRvci9jbnBqLnRzIiwibmc6Ly9AaHVyYmlzL2NvbXVtL2xpYi91dGlsL3ZhbGlkYWRvci9jcGYudHMiLCJuZzovL0BodXJiaXMvY29tdW0vbGliL3V0aWwvYXJxdWl2by50cyIsIm5nOi8vQGh1cmJpcy9jb211bS9saWIvdXRpbC9nZXJhZG9yLnRzIiwibmc6Ly9AaHVyYmlzL2NvbXVtL2xpYi91dGlsL2xvY2FsaXphY2FvLnNlcnZpY2UudHMiLCJuZzovL0BodXJiaXMvY29tdW0vbGliL2NvbXVtLm1vZHVsZS50cyIsIm5nOi8vQGh1cmJpcy9jb211bS9saWIvdXRpbC9vYmpldG8udHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIENOUEoge1xyXG4gIHByaXZhdGUgc3RhdGljIExJU1RBX0lHTk9SQURBOiBzdHJpbmdbXSA9IFtcclxuICAgIFwiMDAwMDAwMDAwMDAwMDBcIixcclxuICAgIFwiMTExMTExMTExMTExMTFcIixcclxuICAgIFwiMjIyMjIyMjIyMjIyMjJcIixcclxuICAgIFwiMzMzMzMzMzMzMzMzMzNcIixcclxuICAgIFwiNDQ0NDQ0NDQ0NDQ0NDRcIixcclxuICAgIFwiNTU1NTU1NTU1NTU1NTVcIixcclxuICAgIFwiNjY2NjY2NjY2NjY2NjZcIixcclxuICAgIFwiNzc3Nzc3Nzc3Nzc3NzdcIixcclxuICAgIFwiODg4ODg4ODg4ODg4ODhcIixcclxuICAgIFwiOTk5OTk5OTk5OTk5OTlcIlxyXG4gIF07XHJcblxyXG4gIHByaXZhdGUgc3RhdGljIFNUUklDVF9TVFJJUF9SRUdFWDogUmVnRXhwID0gbmV3IFJlZ0V4cChcIlstXFwvLl0vZ1wiKTtcclxuICBwcml2YXRlIHN0YXRpYyBMT09TRV9TVFJJUF9SRUdFWDogUmVnRXhwID0gbmV3IFJlZ0V4cChcIlteXFxcXGRdL2dcIik7XHJcblxyXG4gIHByaXZhdGUgc3RhdGljIHJldG9ybmFyRGlnaXRvKG51bWVyb3M6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICBsZXQgaW52ZXJ0aWRvOiBudW1iZXJbXSA9IG51bWVyb3Muc3BsaXQoXCJcIikucmVkdWNlPG51bWJlcltdPihcclxuICAgICAgKGJ1ZmZlcjogbnVtYmVyW10sIG51bWJlcjogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIFtwYXJzZUludChudW1iZXIsIDEwKV0uY29uY2F0KGJ1ZmZlcik7XHJcbiAgICAgIH0sIFtdKTtcclxuXHJcbiAgICBsZXQgaW5kaWNlOiBudW1iZXIgPSAyO1xyXG4gICAgbGV0IHNvbWE6IG51bWJlciA9IGludmVydGlkby5yZWR1Y2UoXHJcbiAgICAgIChidWZmZXI6IG51bWJlciwgbnVtZXJvOiBudW1iZXIpID0+IHtcclxuICAgICAgICBidWZmZXIgKz0gbnVtZXJvICogaW5kaWNlO1xyXG4gICAgICAgIGluZGljZSA9IChpbmRpY2UgPT09IDkgPyAyIDogaW5kaWNlICsgMSk7XHJcbiAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcclxuICAgICAgfSwgMCk7XHJcblxyXG4gICAgbGV0IG1vZDogbnVtYmVyID0gc29tYSAlIDExO1xyXG4gICAgcmV0dXJuIChtb2QgPCAyID8gMCA6IDExIC0gbW9kKTtcclxuICB9XHJcblxyXG4gIHN0YXRpYyBmb3JtYXRhcihudW1lcm86IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBsZXQgcmVnZXg6IFJlZ0V4cCA9IG5ldyBSZWdFeHAoXCJeKFxcXFxkezJ9KShcXFxcZHszfSkoXFxcXGR7M30pKFxcXFxkezR9KShcXFxcZHsyfSkkXCIpO1xyXG4gICAgcmV0dXJuIHRoaXMubGltcGFyKG51bWVybykucmVwbGFjZShyZWdleCwgXCIkMS4kMi4kMy8kNC0kNVwiKTtcclxuICB9XHJcblxyXG4gIHN0YXRpYyBsaW1wYXIobnVtZXJvOiBzdHJpbmcsIHN0cmljdD86IGJvb2xlYW4pOiBzdHJpbmcge1xyXG4gICAgbGV0IHJlZ2V4OiBSZWdFeHAgPSBzdHJpY3QgPyB0aGlzLlNUUklDVF9TVFJJUF9SRUdFWCA6IHRoaXMuTE9PU0VfU1RSSVBfUkVHRVg7XHJcbiAgICByZXR1cm4gKG51bWVybyB8fCBcIlwiKS50b1N0cmluZygpLnJlcGxhY2UocmVnZXgsIFwiXCIpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzdGF0aWMgYXR1YWxpemFyQ29tRFYobnVtZXJvU2VtRFY6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBudW1lcm9TZW1EViArPSB0aGlzLnJldG9ybmFyRGlnaXRvKG51bWVyb1NlbURWKTsgLy8gMTNcclxuICAgIG51bWVyb1NlbURWICs9IHRoaXMucmV0b3JuYXJEaWdpdG8obnVtZXJvU2VtRFYpOyAvLyAxNFxyXG4gICAgcmV0dXJuIG51bWVyb1NlbURWO1xyXG4gIH1cclxuXHJcbiAgc3RhdGljIHZhbGlkYXIobnVtZXJvOiBzdHJpbmcsIHN0cmljdD86IGJvb2xlYW4pOiBib29sZWFuIHtcclxuICAgIGxldCBudW1lcm9MaW1wbzogc3RyaW5nID0gdGhpcy5saW1wYXIobnVtZXJvLCBzdHJpY3QpO1xyXG5cclxuICAgIGlmICghbnVtZXJvTGltcG8pIHsgcmV0dXJuIGZhbHNlOyB9XHJcblxyXG4gICAgaWYgKG51bWVyb0xpbXBvLmxlbmd0aCAhPT0gMTQpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblxyXG4gICAgaWYgKHRoaXMuTElTVEFfSUdOT1JBREEuaW5kZXhPZihudW1lcm9MaW1wbykgPj0gMCkgeyByZXR1cm4gZmFsc2U7IH1cclxuXHJcbiAgICBsZXQgbnVtZXJvQ29tRFY6IHN0cmluZyA9IHRoaXMuYXR1YWxpemFyQ29tRFYobnVtZXJvTGltcG8uc3Vic3RyKDAsIDEyKSk7XHJcblxyXG4gICAgcmV0dXJuIG51bWVyb0NvbURWLnN1YnN0cigtMikgPT09IG51bWVyb0xpbXBvLnN1YnN0cigtMik7XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgZ2VyYXIoZm9ybWF0YWRvOiBib29sZWFuKTogc3RyaW5nIHtcclxuICAgIGxldCBudW1lcm9TZW1EVjogc3RyaW5nID0gXCJcIjtcclxuXHJcbiAgICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgMTI7IGkrKykge1xyXG4gICAgICBudW1lcm9TZW1EViArPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiA5KTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgbnVtZXJvQ29tRFY6IHN0cmluZyA9IHRoaXMuYXR1YWxpemFyQ29tRFYobnVtZXJvU2VtRFYpO1xyXG5cclxuICAgIHJldHVybiAoZm9ybWF0YWRvID8gdGhpcy5mb3JtYXRhcihudW1lcm9Db21EVikgOiBudW1lcm9Db21EVik7XHJcbiAgfVxyXG59XHJcbiIsImV4cG9ydCBjbGFzcyBDUEYge1xyXG4gIHByaXZhdGUgc3RhdGljIExJU1RBX0lHTk9SQURBOiBzdHJpbmdbXSA9IFtcclxuICAgIFwiMDAwMDAwMDAwMDBcIixcclxuICAgIFwiMTExMTExMTExMTFcIixcclxuICAgIFwiMjIyMjIyMjIyMjJcIixcclxuICAgIFwiMzMzMzMzMzMzMzNcIixcclxuICAgIFwiNDQ0NDQ0NDQ0NDRcIixcclxuICAgIFwiNTU1NTU1NTU1NTVcIixcclxuICAgIFwiNjY2NjY2NjY2NjZcIixcclxuICAgIFwiNzc3Nzc3Nzc3NzdcIixcclxuICAgIFwiODg4ODg4ODg4ODhcIixcclxuICAgIFwiOTk5OTk5OTk5OTlcIixcclxuICAgIFwiMTIzNDU2Nzg5MDlcIlxyXG4gIF07XHJcblxyXG4gIHByaXZhdGUgc3RhdGljIFNUUklDVF9TVFJJUF9SRUdFWDogUmVnRXhwID0gbmV3IFJlZ0V4cChcIlsuLV0vZ1wiKTtcclxuICBwcml2YXRlIHN0YXRpYyBMT09TRV9TVFJJUF9SRUdFWDogUmVnRXhwID0gbmV3IFJlZ0V4cChcIlteXFxkXS9nXCIpO1xyXG5cclxuICBwcml2YXRlIHN0YXRpYyByZXRvcm5hckRpZ2l0byhudW1lcm9zOiBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgbGV0IGxpc3RhTnVtZXJvOiBudW1iZXJbXSA9IG51bWVyb3NcclxuICAgICAgLnNwbGl0KFwiXCIpXHJcbiAgICAgIC5tYXAoKG51bWVybzogc3RyaW5nKSA9PiB7IHJldHVybiBwYXJzZUludChudW1lcm8sIDEwKTsgfSk7XHJcblxyXG4gICAgdmFyIG1vZHVsbzogbnVtYmVyID0gbGlzdGFOdW1lcm8ubGVuZ3RoICsgMTtcclxuXHJcbiAgICB2YXIgbXVsdGlwbGlmaWNhZG9yOiBudW1iZXJbXSA9IGxpc3RhTnVtZXJvLm1hcChcclxuICAgICAgKG51bWVybzogbnVtYmVyLCBpbmRpY2U6IG51bWJlcikgPT4ge1xyXG4gICAgICAgIHJldHVybiBudW1lcm8gKiAobW9kdWxvIC0gaW5kaWNlKTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgdmFyIHJlc3RvOiBudW1iZXIgPSBtdWx0aXBsaWZpY2Fkb3IucmVkdWNlKFxyXG4gICAgICAoYnVmZmVyOiBudW1iZXIsIG51bWVybzogbnVtYmVyKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIGJ1ZmZlciArIG51bWVybztcclxuICAgICAgfSkgJSAxMTtcclxuXHJcbiAgICByZXR1cm4gKHJlc3RvIDwgMiA/IDAgOiAxMSAtIHJlc3RvKTtcclxuICB9XHJcblxyXG4gIHN0YXRpYyBmb3JtYXRhcihudW1lcm86IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBsZXQgcmVnZXg6IFJlZ0V4cCA9IG5ldyBSZWdFeHAoXCJeKFxcXFxkezN9KShcXFxcZHszfSkoXFxcXGR7M30pKFxcXFxkezJ9KSRcIik7XHJcbiAgICByZXR1cm4gdGhpcy5saW1wYXIobnVtZXJvKS5yZXBsYWNlKHJlZ2V4LCBcIiQxLiQyLiQzLSQ0XCIpO1xyXG4gIH1cclxuXHJcbiAgc3RhdGljIGxpbXBhcihudW1lcm86IHN0cmluZywgc3RyaWN0PzogYm9vbGVhbik6IHN0cmluZyB7XHJcbiAgICBsZXQgcmVnZXg6IFJlZ0V4cCA9IHN0cmljdCA/IHRoaXMuU1RSSUNUX1NUUklQX1JFR0VYIDogdGhpcy5MT09TRV9TVFJJUF9SRUdFWDtcclxuICAgIHJldHVybiAobnVtZXJvIHx8IFwiXCIpLnRvU3RyaW5nKCkucmVwbGFjZShyZWdleCwgXCJcIik7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN0YXRpYyBhdHVhbGl6YXJDb21EVihudW1lcm9TZW1EVjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIG51bWVyb1NlbURWICs9IHRoaXMucmV0b3JuYXJEaWdpdG8obnVtZXJvU2VtRFYpOyAvLyAxMFxyXG4gICAgbnVtZXJvU2VtRFYgKz0gdGhpcy5yZXRvcm5hckRpZ2l0byhudW1lcm9TZW1EVik7IC8vIDExXHJcbiAgICByZXR1cm4gbnVtZXJvU2VtRFY7XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgdmFsaWRhcihudW1lcm86IHN0cmluZywgc3RyaWN0PzogYm9vbGVhbik6IGJvb2xlYW4ge1xyXG4gICAgbGV0IG51bWVyb0xpbXBvOiBzdHJpbmcgPSB0aGlzLmxpbXBhcihudW1lcm8sIHN0cmljdCk7XHJcblxyXG4gICAgaWYgKCFudW1lcm9MaW1wbykgeyByZXR1cm4gZmFsc2U7IH1cclxuXHJcbiAgICBpZiAobnVtZXJvTGltcG8ubGVuZ3RoICE9PSAxMSkgeyByZXR1cm4gZmFsc2U7IH1cclxuXHJcbiAgICBpZiAodGhpcy5MSVNUQV9JR05PUkFEQS5pbmRleE9mKG51bWVyb0xpbXBvKSA+PSAwKSB7IHJldHVybiBmYWxzZTsgfVxyXG5cclxuICAgIGxldCBudW1lcm9Db21EVjogc3RyaW5nID0gdGhpcy5hdHVhbGl6YXJDb21EVihudW1lcm9MaW1wby5zdWJzdHIoMCwgOSkpO1xyXG5cclxuICAgIHJldHVybiBudW1lcm9Db21EVi5zdWJzdHIoLTIpID09PSBudW1lcm9MaW1wby5zdWJzdHIoLTIpO1xyXG4gIH1cclxuXHJcbiAgc3RhdGljIGdlcmFyKGZvcm1hdGFkbzogYm9vbGVhbik6IHN0cmluZyB7XHJcbiAgICBsZXQgbnVtZXJvU2VtRFY6IHN0cmluZyA9IFwiXCI7XHJcblxyXG4gICAgZm9yIChsZXQgaTogbnVtYmVyID0gMDsgaSA8IDk7IGkrKykge1xyXG4gICAgICBudW1lcm9TZW1EViArPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiA5KTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgbnVtZXJvQ29tRFY6IHN0cmluZyA9IHRoaXMuYXR1YWxpemFyQ29tRFYobnVtZXJvU2VtRFYpO1xyXG5cclxuICAgIHJldHVybiAoZm9ybWF0YWRvID8gdGhpcy5mb3JtYXRhcihudW1lcm9Db21EVikgOiBudW1lcm9Db21EVik7XHJcbiAgfVxyXG59XHJcbiIsImV4cG9ydCBpbnRlcmZhY2UgSUFycXVpdm8ge1xyXG4gICAgbm9tZTogc3RyaW5nO1xyXG4gICAgdGlwbzogc3RyaW5nO1xyXG4gICAgY29udGV1ZG86IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIEFycXVpdm8ge1xyXG4gICAgc3RhdGljIGZyb21CYXNlNjRUb0J5dGVBcnJheShjb250ZXVkbzogc3RyaW5nLCBzbGljZVNpemU6IG51bWJlciA9IDUxMik6IFVpbnQ4QXJyYXlbXSB7XHJcbiAgICAgICAgbGV0IGJ5dGVTdHJpbmcgPSB3aW5kb3cuYXRvYihjb250ZXVkbyk7XHJcbiAgICAgICAgbGV0IGJ5dGVBcnJheXM6IFVpbnQ4QXJyYXlbXSA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBieXRlU3RyaW5nLmxlbmd0aDsgb2Zmc2V0ICs9IHNsaWNlU2l6ZSkge1xyXG4gICAgICAgICAgICBjb25zdCBzbGljZSA9IGJ5dGVTdHJpbmcuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBzbGljZVNpemUpO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgYnl0ZU51bWJlcnMgPSBuZXcgQXJyYXkoc2xpY2UubGVuZ3RoKTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGljZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgYnl0ZU51bWJlcnNbaV0gPSBzbGljZS5jaGFyQ29kZUF0KGkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBieXRlQXJyYXkgPSBuZXcgVWludDhBcnJheShieXRlTnVtYmVycyk7XHJcblxyXG4gICAgICAgICAgICBieXRlQXJyYXlzLnB1c2goYnl0ZUFycmF5KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBieXRlQXJyYXlzO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBmcm9tQnl0ZUFycmF5VG9CbG9iKGNvbnRldWRvOiBVaW50OEFycmF5W10sIHRpcG86IHN0cmluZyk6IEJsb2Ige1xyXG4gICAgICAgIHJldHVybiBuZXcgQmxvYihjb250ZXVkbywgeyB0eXBlOiB0aXBvIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBmcm9tQmFzZTY0VG9CbG9iKGNvbnRldWRvOiBzdHJpbmcsIHRpcG86IHN0cmluZyA9IFwiXCIsIHNsaWNlU2l6ZSA9IDUxMik6IEJsb2Ige1xyXG4gICAgICAgIHZhciBieXRlczogVWludDhBcnJheVtdID0gQXJxdWl2by5mcm9tQmFzZTY0VG9CeXRlQXJyYXkoY29udGV1ZG8pO1xyXG5cclxuICAgICAgICByZXR1cm4gQXJxdWl2by5mcm9tQnl0ZUFycmF5VG9CbG9iKGJ5dGVzLCB0aXBvKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgdG9CbG9iKGFycXVpdm86IElBcnF1aXZvKTogQmxvYiB7XHJcbiAgICAgICAgcmV0dXJuIEFycXVpdm8uZnJvbUJhc2U2NFRvQmxvYihhcnF1aXZvLmNvbnRldWRvLCBhcnF1aXZvLnRpcG8pO1xyXG4gICAgfVxyXG5cclxufSIsImV4cG9ydCBjbGFzcyBHZXJhZG9yIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlcmEgdW0gY8ODwrNkaWdvIGFsZWF0w4PCs3Jpby5cclxuICAgICAqIEBwYXJhbSB0YW1hbmhvIFRhbWFuaG8gZG8gY8ODwrNkaWdvIGRlc2VqYWRvLlxyXG4gICAgICovXHJcbiAgICBzdGF0aWMgZ2VyYXJDb2RpZ29BbGVhdG9yaW8odGFtYW5obzogbnVtYmVyKTogc3RyaW5nIHtcclxuICAgICAgICBsZXQgdGV4dG8gPSBcIlwiO1xyXG4gICAgICAgIGxldCBwb3NzaWJpbGlkYWRlcyA9IFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODlcIjtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YW1hbmhvOyBpKyspXHJcbiAgICAgICAgICAgIHRleHRvICs9IHBvc3NpYmlsaWRhZGVzLmNoYXJBdChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBwb3NzaWJpbGlkYWRlcy5sZW5ndGgpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRleHRvO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBHZXJhIGPDg8KzZGlnbyB1dGlsaXphbmRvIGzDg8KzZ2ljYSBlIGZvcm1hdG8gR1VJRC4gKi9cclxuICAgIHN0YXRpYyBnZXJhckdVSUQoKTogc3RyaW5nIHtcclxuICAgICAgICB2YXIgczQgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKCgxICsgTWF0aC5yYW5kb20oKSkgKiAweDEwMDAwKVxyXG4gICAgICAgICAgICAgICAgLnRvU3RyaW5nKDE2KVxyXG4gICAgICAgICAgICAgICAgLnN1YnN0cmluZygxKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gczQoKSArIHM0KCkgKyAnLScgKyBzNCgpICsgJy0nICsgczQoKSArICctJyArIHM0KCkgKyAnLScgKyBzNCgpICsgczQoKSArIHM0KCk7XHJcbiAgICB9XHJcblxyXG59IiwiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UsIFRyYW5zbGF0ZVBpcGUgfSBmcm9tIFwiQG5neC10cmFuc2xhdGUvY29yZVwiO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSBcInJ4anNcIjtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTG9jYWxpemFjYW8ge1xyXG4gIGlkaW9tYTogc3RyaW5nO1xyXG4gIHRyYWR1Y2FvOiBPYmplY3Q7XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxyXG5leHBvcnQgY2xhc3MgTG9jYWxpemFjYW9TZXJ2aWNlIHtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsIHByaXZhdGUgdHJhbnNsYXRlUGlwZTogVHJhbnNsYXRlUGlwZSkge1xyXG4gIH1cclxuXHJcbiAgZGVmaW5pckxpbmd1YWdlbVBhZHJhbyhsaW5ndWFnZW06IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy50cmFuc2xhdGUuc2V0RGVmYXVsdExhbmcobGluZ3VhZ2VtKTtcclxuICB9XHJcblxyXG4gIGNhcnJlZ2FyKC4uLnRyYWR1Y29lczogTG9jYWxpemFjYW9bXSk6IHZvaWQge1xyXG4gICAgY29uc3QgdHJhZHVjb2VzQXV4ID0gWy4uLnRyYWR1Y29lc107XHJcblxyXG4gICAgdHJhZHVjb2VzQXV4LmZvckVhY2goKGxvY2FsaXphY2FvKSA9PiB7XHJcbiAgICAgIHRoaXMudHJhbnNsYXRlLnNldFRyYW5zbGF0aW9uKGxvY2FsaXphY2FvLmlkaW9tYSwgbG9jYWxpemFjYW8udHJhZHVjYW8sIHRydWUpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBhZGljaW9uYXIobGluZ3VhZ2Vuczogc3RyaW5nW10pOiB2b2lkIHtcclxuICAgIHRoaXMudHJhbnNsYXRlLmFkZExhbmdzKGxpbmd1YWdlbnMpO1xyXG4gIH1cclxuXHJcbiAgdHJhZHV6aXIobGluZ3VhZ2VtPzogc3RyaW5nKTogdm9pZCB7XHJcbiAgICB0aGlzLnRyYW5zbGF0ZS51c2UoKGxpbmd1YWdlbSkgPyBsaW5ndWFnZW0gOiB0aGlzLnN1Z2VyaWRhKCkpLnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgdHJhZHVjYW9TaW1wbGVzKGNoYXZlOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlUGlwZS50cmFuc2Zvcm0oY2hhdmUpO1xyXG4gIH1cclxuXHJcbiAgdHJhZHVjYW8oY2hhdmVzOiBzdHJpbmdbXSk6IE9ic2VydmFibGU8c3RyaW5nPiB7XHJcbiAgICByZXR1cm4gdGhpcy50cmFuc2xhdGUuZ2V0KGNoYXZlcyk7XHJcbiAgfVxyXG5cclxuICBzZWxlY2lvbmFkYSgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlLmN1cnJlbnRMYW5nO1xyXG4gIH1cclxuXHJcbiAgc3VnZXJpZGEoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLnRyYW5zbGF0ZS5nZXRCcm93c2VyTGFuZygpIHx8IHRoaXMudHJhbnNsYXRlLmdldERlZmF1bHRMYW5nKCk7XHJcbiAgfVxyXG5cclxufVxyXG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVHJhbnNsYXRlTW9kdWxlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XHJcbmltcG9ydCB7IExvY2FsaXphY2FvU2VydmljZSB9IGZyb20gJy4vdXRpbC9sb2NhbGl6YWNhby5zZXJ2aWNlJztcclxuaW1wb3J0IHsgSW5qZWN0b3IgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbkBOZ01vZHVsZSh7XHJcbiAgaW1wb3J0czogW1xyXG4gICAgVHJhbnNsYXRlTW9kdWxlLmZvclJvb3QoKVxyXG4gIF0sXHJcbiAgcHJvdmlkZXJzOiBbXHJcbiAgICBMb2NhbGl6YWNhb1NlcnZpY2VcclxuICBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDb211bU1vZHVsZSB7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgX2luamVjdG9yOiBJbmplY3RvciA9IG51bGw7XHJcblxyXG4gIHN0YXRpYyBnZXRJbmplY3RvcigpOiBJbmplY3RvciB7XHJcbiAgICByZXR1cm4gQ29tdW1Nb2R1bGUuX2luamVjdG9yO1xyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IoaW5qZWN0b3I6IEluamVjdG9yKSB7ICAgIC8vIENyaWFuZG8gaW5qZWN0b3IgZ2xvYmFsLlxyXG4gICAgQ29tdW1Nb2R1bGUuX2luamVjdG9yID0gaW5qZWN0b3I7XHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCB7IFR5cGUsIEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbXVtTW9kdWxlIH0gZnJvbSAnLi4vY29tdW0ubW9kdWxlJztcclxuXHJcbmV4cG9ydCBjbGFzcyBPYmpldG8ge1xyXG5cclxuICBzdGF0aWMgY29waWFyPFQ+KG9yaWdlbTogVCk6IFQge1xyXG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIG9yaWdlbSk7XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgZXN0ZW5kZXIoZGVzdGlubzogYW55LCAuLi5mb250ZXM6IGFueVtdKTogdm9pZCB7XHJcbiAgICBPYmplY3QuYXNzaWduKGRlc3Rpbm8sIGZvbnRlcyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWN1cGVyYSBhIGluc3TDg8KibmNpYSBkZSB1bWEgY2xhc3NlIHJlZ2lzdHJhZGEuXHJcbiAgICogQHBhcmFtIHRpcG9JbnN0YW5jaWEgVGlwbyBkbyBzZXJ2acODwqdvIGEgc2VyIHJlY3VwZXJhZG8uXHJcbiAgICovXHJcbiAgc3RhdGljIHJlY3VwZXJhckluc3RhbmNpYTxUPih0aXBvSW5zdGFuY2lhOiBUeXBlPFQ+IHwgSW5qZWN0aW9uVG9rZW48VD4pOiBUIHtcclxuICAgIGlmIChDb211bU1vZHVsZS5nZXRJbmplY3RvcigpID09IG51bGwpIHtcclxuICAgICAgdGhpcy5leGNlY2FvT2JqZXRvTmFvQ2FycmVnYWRvKFwiaW5qZWN0b3JcIik7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHJldHVybiBDb211bU1vZHVsZS5nZXRJbmplY3RvcigpLmdldCh0aXBvSW5zdGFuY2lhKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc3RhdGljIGV4Y2VjYW9PYmpldG9OYW9DYXJyZWdhZG8ob2JqZXRvOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRocm93IG9iamV0byArIFwiIG7Dg8KjbyBjYXJyZWdhZG8uXCI7XHJcbiAgfVxyXG5cclxufVxyXG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLE1BQWEsSUFBSTs7Ozs7SUFpQlAsT0FBTyxjQUFjLENBQUMsT0FBZTs7WUFDdkMsU0FBUyxHQUFhLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUNoRCxDQUFDLE1BQWdCLEVBQUUsTUFBYztZQUMvQixPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUM5QyxFQUFFLEVBQUUsQ0FBQzs7WUFFSixNQUFNLEdBQVcsQ0FBQzs7WUFDbEIsSUFBSSxHQUFXLFNBQVMsQ0FBQyxNQUFNLENBQ2pDLENBQUMsTUFBYyxFQUFFLE1BQWM7WUFDN0IsTUFBTSxJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUM7WUFDMUIsTUFBTSxJQUFJLE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN6QyxPQUFPLE1BQU0sQ0FBQztTQUNmLEVBQUUsQ0FBQyxDQUFDOztZQUVILEdBQUcsR0FBVyxJQUFJLEdBQUcsRUFBRTtRQUMzQixRQUFRLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLEVBQUU7S0FDakM7Ozs7O0lBRUQsT0FBTyxRQUFRLENBQUMsTUFBYzs7WUFDeEIsS0FBSyxHQUFXLElBQUksTUFBTSxDQUFDLDRDQUE0QyxDQUFDO1FBQzVFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxF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