import { r as registerInstance, e as createEvent, h, f as Host, g as getElement } from './index-e9c7ceaa.js';
import { DateUtils, StringUtils, ObjectUtils, WaitingChangeException, SilentException, WarningException, ErrorException, ElementIDUtils, SearchUtils, ArrayUtils, KeyboardManager, OnboardingUtils, DependencyType, DataType, ApplicationContext, ErrorTracking, UserAgentUtils, LockManager, LockManagerOperation } from '@sankhyalabs/core';
import { ApplicationUtils } from '@sankhyalabs/ezui/dist/collection/utils';
import { C as ConfigStorage } from './ConfigStorage-4eee53da.js';
import { d as dist, D as DataFetcher, U as UrlUtils, S as SnkMessageBuilder } from './DataFetcher-955ee53e.js';
import { A as AutorizationType, a as AuthFetcher } from './auth-fetcher-46872d79.js';
import { P as PreloadManager, D as DataUnitFetcher } from './dataunit-fetcher-6cacb959.js';
import { P as PesquisaFetcher } from './ISave-c8bf12c4.js';
import { T as TEMPLATES_SKELETON } from './constants-7b422de0.js';
import './index-b40568ff.js';
import './filter-item-type.enum-d45e026f.js';
import { F as FormConfigFetcher } from './form-config-fetcher-baa89098.js';
import './PrintUtils-3e4ff0f5.js';
import '@sankhyalabs/core/dist/dataunit/metadata/UnitMetadata';
import '@sankhyalabs/ezui/dist/collection/utils/constants';
import '@sankhyalabs/ezui/dist/collection/components/ez-grid/utils';
import '@sankhyalabs/core/dist/utils/SortingUtils';
import './ResourceIDUtils-a114189a.js';

class AppletCaller {
  static webConnectionCaller(port, methodName, params) {
    var _a;
    (_a = window["AppletCaller"]) === null || _a === void 0 ? void 0 : _a.webConnectionCaller(port, methodName, params);
  }
}

const _0x5b7870=_0x2202;(function(_0x42e134,_0x5d9727){const _0x185c97=_0x2202,_0x5854c7=_0x42e134();while(!![]){try{const _0x129d35=parseInt(_0x185c97(0x18f))/0x1*(-parseInt(_0x185c97(0x183))/0x2)+-parseInt(_0x185c97(0x191))/0x3+parseInt(_0x185c97(0x17d))/0x4*(-parseInt(_0x185c97(0x185))/0x5)+parseInt(_0x185c97(0x184))/0x6*(-parseInt(_0x185c97(0x182))/0x7)+parseInt(_0x185c97(0x17b))/0x8+parseInt(_0x185c97(0x18c))/0x9+parseInt(_0x185c97(0x17f))/0xa;if(_0x129d35===_0x5d9727)break;else _0x5854c7['push'](_0x5854c7['shift']());}catch(_0x4becb4){_0x5854c7['push'](_0x5854c7['shift']());}}}(_0xdfb1,0x44ac7));function _0x2202(_0x2eac1f,_0x170d27){const _0xdfb1b4=_0xdfb1();return _0x2202=function(_0x2202d7,_0x224df5){_0x2202d7=_0x2202d7-0x17a;let _0x4d54a9=_0xdfb1b4[_0x2202d7];return _0x4d54a9;},_0x2202(_0x2eac1f,_0x170d27);}function _0xdfb1(){const _0x2b9dc4=['true','863GKWjmo','parse','56355fjjjAm','isSup','putAccess','4324480sjuCdS','hasOwnProperty','239748okvJLB','name','6055770tXeRaU','actions','forEach','7RPRvzn','1042CHxkUw','2988126NIwRMm','20MTNzmH','authorizationSf','item','string','hasAccess','isArray','Objeto\x20não\x20pode\x20ser\x20indefinido.','3071943fWslZp','parseFromJSON'];_0xdfb1=function(){return _0x2b9dc4;};return _0xdfb1();}class MGEAuthorization{[_0x5b7870(0x18d)](_0x37e96b){const _0x580407=_0x5b7870;_0x37e96b=utxt(_0x37e96b[_0x580407(0x186)]);typeof _0x37e96b==_0x580407(0x188)&&(_0x37e96b=JSON[_0x580407(0x190)](_0x37e96b));if(_0x37e96b==undefined)throw Error(_0x580407(0x18b));const _0x291d34=new MGEAuthorizationData(_0x37e96b[_0x580407(0x192)]==='S'||_0x37e96b[_0x580407(0x192)]===!![]);return Array[_0x580407(0x18a)](_0x37e96b[_0x580407(0x187)])&&_0x37e96b[_0x580407(0x187)][_0x580407(0x181)](_0x58a748=>_0x291d34['putAccess'](_0x58a748[_0x580407(0x17e)],String(_0x58a748['status'])==_0x580407(0x18e))),_0x291d34;}}class MGEAuthorizationData{constructor(_0x51ec5d){const _0x2c8472=_0x5b7870;this['isSup']=_0x51ec5d,this[_0x2c8472(0x180)]={};}[_0x5b7870(0x17a)](_0x5bd0f2,_0x2ef465){const _0x40d701=_0x5b7870;this[_0x40d701(0x180)][_0x5bd0f2]=_0x2ef465;}[_0x5b7870(0x189)](_0x4fd772){const _0x3707c1=_0x5b7870;if(this[_0x3707c1(0x192)])return !![];let _0x25e60a=!![];return this[_0x3707c1(0x180)][_0x3707c1(0x17c)](_0x4fd772)&&(_0x25e60a=this['actions'][_0x4fd772]),_0x25e60a;}['isUserSup'](){return this['isSup'];}}

class ParametersFetcher {
  constructor() {
    this._embeddedParams = new Map();
    this._cachedParams = new Map();
    this.templateByQuery = new Map();
    try {
      if (window["MGE_PARAMS"] != undefined) {
        const source = atob(window['MGE_PARAMS']);
        const params = source.split('__;__');
        params.forEach(param => {
          const [key, value] = param.split("__=__");
          this._embeddedParams.set(key, value);
        });
      }
    }
    catch (error) {
      console.error("Problemas ao obter parâmetros embarcados");
      console.error(error);
    }
    this.buldTemplates();
  }
  buldTemplates() {
    this.templateByQuery.set("fetchParam", dist.gql `query($name: String!) {
            $queryAlias$: fetchResource(name: $name){
              name
              resource
            }
        }`);
  }
  async getParam(name) {
    if (this._embeddedParams.has(name)) {
      return Promise.resolve(this._embeddedParams.get(name));
    }
    if (this._cachedParams.has(name)) {
      return this._cachedParams.get(name);
    }
    const completPath = `param://application?params=${name}`;
    const param = await DataFetcher.get().callGraphQL({
      values: { name: completPath },
      query: this.templateByQuery.get("fetchParam"),
    });
    this._cachedParams.set(name, param);
    return param;
  }
  async asString(name) {
    const paramArr = await this.getParam(name);
    return this.getValue(paramArr);
  }
  async asInteger(name) {
    const paramArr = await this.getParam(name);
    return parseInt(this.getValue(paramArr));
  }
  async asFloat(name) {
    const paramArr = await this.getParam(name);
    return parseFloat(this.getValue(paramArr));
  }
  async asBoolean(name) {
    const paramArr = await this.getParam(name);
    return (this.getValue(paramArr) === "S");
  }
  async asDate(name) {
    const paramArr = await this.getParam(name);
    return DateUtils.strToDate(this.getValue(paramArr));
  }
  async getBatchParams(names) {
    const paramArr = await this.getParam(names.join(","));
    //TODO: try to typed params val?
    const response = {};
    paramArr.forEach((param) => (response[param.name] = param.resource));
    return response;
  }
  getValue(obj = {}) {
    if (Array.isArray(obj) && obj.length > 0) {
      obj = obj[0];
    }
    if (typeof obj === "string") {
      return obj;
    }
    if (StringUtils.isEmpty(obj.resource))
      return "";
    try {
      const parameter = ObjectUtils.stringToObject(obj.resource);
      const [key] = Object.keys(parameter);
      return parameter[key];
    }
    catch (error) {
      console.warn("Erro ao converter string JSON.");
    }
  }
}

class TotalsFetcher {
  constructor() {
    this.templateByQuery = new Map();
    this.cancel = [];
    this.buildTemplates();
  }
  buildTemplates() {
    this.templateByQuery.set("fetchTotals", dist.gql `query($filters: [InputFilter!] $name: String!) {
                $queryAlias$: fetchTotals(name: $name, filters: $filters ){
                name
                value
                }
            }`);
  }
  fetchTotals(name, resourceID, filters = []) {
    const cancelKey = `${name}_${resourceID}`;
    const anotherPromiseIndex = this.cancel.findIndex(promiseExecuting => promiseExecuting[cancelKey]);
    if (anotherPromiseIndex >= 0) {
      this.cancel[anotherPromiseIndex][cancelKey]();
      this.cancel.splice(anotherPromiseIndex, 1);
    }
    return Promise
      .race([
      new Promise(resolve => this.cancel.push({ [cancelKey]: resolve })),
      this.getTotals(name, resourceID, filters)
    ])
      .then((results) => {
      let dataResult = new Map();
      if (results) {
        dataResult = results;
        const myPromiseIndex = this.cancel.findIndex(promiseExecuting => promiseExecuting[cancelKey]);
        if (myPromiseIndex >= 0) {
          this.cancel.splice(myPromiseIndex, 1);
        }
      }
      return dataResult;
    });
  }
  getTotals(name, resourceID, filters = []) {
    return new Promise((accept, reject) => {
      DataFetcher
        .get()
        .callGraphQL({
        query: this.templateByQuery.get("fetchTotals"),
        values: {
          name: `totals://${name}/${resourceID}`,
          filters: filters
        },
      })
        .then(result => {
        if (result.length > 0) {
          const totalsData = new Map();
          result.forEach(total => totalsData.set(total.name, parseFloat(total.value)));
          return accept(totalsData);
        }
        return reject("Não foi possível recuperar os totalizadores");
      })
        .catch(reject);
    });
  }
}

var _a;
class Workspace {
  static openAppActivity(resourceId, pkObject) {
    var _a;
    (_a = window["workspace"]) === null || _a === void 0 ? void 0 : _a.openAppActivity(resourceId, pkObject);
  }
  static getAppLabel(resourceID) {
    if ((window === null || window === void 0 ? void 0 : window["workspace"]) == undefined) {
      return;
    }
    if (window["workspace"].getAppLabel == undefined) {
      window["workspace"].getAppLabel = (id) => {
        return (id || "").split(".").pop();
      };
    }
    return window["workspace"].getAppLabel(resourceID);
  }
  static setScreenToUseV3Layout() {
    var _a;
    (_a = window["workspace"]) === null || _a === void 0 ? void 0 : _a.setScreenToUseV3Layout();
  }
  static setScreenToUseOldLayout() {
    var _a;
    (_a = window["workspace"]) === null || _a === void 0 ? void 0 : _a.setScreenToUseOldLayout();
  }
  static showDesktop() {
    var _a, _b;
    (_b = (_a = window["workspace"]) === null || _a === void 0 ? void 0 : _a.showDesktop) === null || _b === void 0 ? void 0 : _b.call(_a);
  }
  static searchApp() {
    var _a, _b;
    (_b = (_a = window["workspace"]) === null || _a === void 0 ? void 0 : _a.searchApp) === null || _b === void 0 ? void 0 : _b.call(_a);
  }
  static openHelp() {
    var _a, _b;
    (_b = (_a = window["workspace"]) === null || _a === void 0 ? void 0 : _a.openHelp) === null || _b === void 0 ? void 0 : _b.call(_a);
  }
  static applicationClick() {
    var _a, _b;
    if (!((_a = window["workspace"]) === null || _a === void 0 ? void 0 : _a.applicationClick)) {
      return;
    }
    (_b = window["workspace"]) === null || _b === void 0 ? void 0 : _b.applicationClick();
  }
}
Workspace.resourceID = (_a = window["workspace"]) === null || _a === void 0 ? void 0 : _a.resourceID;

class SnkErrorHandler {
  constructor(app) {
    this._app = app;
    window.addEventListener("error", evt => this.errorHandler(evt));
    window.addEventListener("unhandledrejection", evt => this.rejectionHandler(evt));
  }
  getMessage(key, params) {
    return this._app.messagesBuilder.getMessage(key, params);
  }
  rejectionHandler(evt) {
    const reason = evt.reason;
    //Promisse rejeitada com WaitingChangeException, não precisam
    //ser notificadas pelo usuário.
    if (!(reason instanceof WaitingChangeException)) {
      if (reason) {
        this.processException(reason);
      }
      else {
        this._app.isDebugMode().then((isDebug) => {
          if (isDebug) {
            this._app.error(this.getMessage("snkErrorHandler.title.promiseRejected"), this.getMessage("snkErrorHandler.message.undeterminedPromiseRejection"));
          }
        });
      }
    }
  }
  errorHandler(evt) {
    this.processException(evt.error);
  }
  buildErrorCodeHTML(errorCode) {
    const cannotOpenHelpMessage = this.getMessage("snkErrorHandler.message.cannotOpenHelp");
    const errorCodeLabel = this.getMessage("snkErrorHandler.errorCode.label");
    const onclick = `try{window.workspace.openHelp('_tbcode:${errorCode}')} catch(e){alert('${cannotOpenHelpMessage}');}`;
    return `<br><a href="#" onclick="${onclick}">${errorCodeLabel}${errorCode}</a>`;
  }
  processException(exception) {
    if (exception.errorCode) {
      exception.message += this.buildErrorCodeHTML(exception.errorCode);
    }
    if (exception instanceof SilentException) {
      console.warn(this.getMessage("snkErrorHandler.message.silentExceptionIgnored"), exception);
    }
    else if (exception instanceof WaitingChangeException) {
      this._app.alert(exception.title, exception.message);
    }
    else if (exception instanceof WarningException) {
      this._app.alert(exception.title, exception.message);
    }
    else if (exception instanceof ErrorException) {
      this._app.error(exception.title, exception.message);
    }
    else {
      console.warn("Erro não tratado", exception);
      this._app.isDebugMode().then(isDebug => {
        if (isDebug) {
          if (exception instanceof Error) {
            this._app.error(exception.name, exception.message);
          }
          else {
            const title = (exception === null || exception === void 0 ? void 0 : exception.title) || this.getMessage("snkErrorHandler.title.errorDetected", undefined);
            const message = (typeof exception === "string") ? exception :
              exception.message || `${this.getMessage("snkErrorHandler.error.internal")} "${ObjectUtils.objectToString(exception)}"`;
            this._app.error(title, message);
          }
        }
      });
    }
  }
}

class DebouncedRequestListener {
  constructor() {
    this._debounceTime = 1500;
    this.requests = new Map();
    this.requestsLoadingBar = [];
  }
  onRequestStart(param) {
    if (param.url.includes("quietMode=true")) {
      return;
    }
    this.requestsLoadingBar.push(param.requestId);
    const timeout = setTimeout(() => {
      this.ezLoadingBar.show();
    }, this._debounceTime);
    this.requests.set(param.requestId, timeout);
  }
  ;
  onRequestEnd(param) {
    var _a, _b, _c;
    const timeoutId = this.requests.get(param.requestId);
    clearTimeout(timeoutId);
    if ((_a = this.requestsLoadingBar) === null || _a === void 0 ? void 0 : _a.includes(param.requestId)) {
      this.requestsLoadingBar = (_b = this.requestsLoadingBar) === null || _b === void 0 ? void 0 : _b.filter(id => id !== param.requestId);
      !this.requestsLoadingBar.length && ((_c = this.ezLoadingBar) === null || _c === void 0 ? void 0 : _c.hide());
    }
  }
  ;
}

class RequestListenerLoadingBar {
  constructor() {
    this._debounceTime = 1000;
    this._ignoredNameTypes = ["totals"];
    this._countRequest = 0;
  }
  onRequestStart(param) {
    if (this.isIgnoreLoadingOnRequest(param)) {
      return;
    }
    this._countRequest++;
    this.ezLoadingBar.show();
    if (this._timerLoading) {
      clearTimeout(this._timerLoading);
    }
  }
  ;
  onRequestEnd(param) {
    if (this.isIgnoreLoadingOnRequest(param)) {
      return;
    }
    this._countRequest--;
    this._timerLoading = setTimeout(() => {
      if (this._countRequest <= 0) {
        this.ezLoadingBar.hide();
      }
    }, this._debounceTime);
  }
  ;
  isIgnoreLoadingOnRequest(param) {
    if (param == undefined) {
      return false;
    }
    if (param.url.includes("quietMode=true")) {
      return true;
    }
    if (param.requestBody == undefined) {
      return false;
    }
    if (param.requestBody.length == 1) {
      const { name } = param.requestBody[0].variables;
      if (name) {
        const nameParts = name.split(":");
        const nameType = nameParts[0];
        return this._ignoredNameTypes.indexOf(nameType) >= 0;
      }
    }
    return false;
  }
  ;
}

class RequestListenerFactory {
  static create({ strategy }) {
    switch (strategy) {
      case 'request_name':
        return new RequestListenerLoadingBar();
      case 'request_time':
        return new DebouncedRequestListener();
      default:
        throw new Error('Strategy not found');
    }
  }
}

const QTD_DETAIL_FIELDS_PREDICTIVE_SEARCH = 6;
const INVALID_CONTENT_PATTERNS = ['<img', '<svg'];
const executePreparedSearchPlus = async (mode, argument, options, app, pesquisaFetcher) => {
  var _a;
  const mdByName = {};
  const { entity, entityDescription, criteria, searchOptions, isHierarchyEntity, allowsNonAnalytic } = options;
  if (mode === "ADVANCED") {
    return new Promise((accept, reject) => {
      const pesquisaContent = document.createElement("snk-pesquisa");
      pesquisaContent[ElementIDUtils.DATA_ELEMENT_ID_ATTRIBUTE_NAME] = `entity_${entity}`;
      pesquisaContent.entityName = entity;
      pesquisaContent.argument = argument;
      pesquisaContent.searchLoader = (text) => pesquisaFetcher.loadAdvancedSearch(entity, text, criteria, searchOptions);
      pesquisaContent.isHierarchyEntity = isHierarchyEntity;
      if (isHierarchyEntity) {
        pesquisaContent.treeLoader = (text) => pesquisaFetcher.loadTree(entity, text, criteria, searchOptions);
        pesquisaContent.allowsNonAnalytic = allowsNonAnalytic;
      }
      pesquisaContent.selectItem = (option) => {
        accept(option);
        app.clearPopUpTitle();
        app.closePopUp();
      };
      app.setPopUpTitle(entityDescription);
      app.showPopUp(pesquisaContent, undefined, undefined, reject);
    });
  }
  else if (mode === "LOAD_DESCRIPTION") {
    let result = await pesquisaFetcher.loadByCode(entity, argument, criteria, searchOptions);
    result = ObjectUtils.stringToObject(result.json.$);
    let descriptionField = result.descriptionField;
    const option = (_a = result.data) === null || _a === void 0 ? void 0 : _a[0];
    if (!option) {
      return {
        value: argument,
        label: ""
      };
    }
    return {
      value: argument,
      label: option[descriptionField]
    };
  }
  else {
    let codeValue;
    let result = await pesquisaFetcher.loadAdvancedSearch(entity, argument, criteria, searchOptions, codeValue);
    result = ObjectUtils.stringToObject(result.json.$);
    let descriptionField = result.descriptionField;
    let pkField = result.pkField;
    const list = result.data.map((item) => {
      let fieldsMetadata = filterInvalidFields(result, item, mdByName);
      let fields = filterMathFields(item['__matchFields'], fieldsMetadata, QTD_DETAIL_FIELDS_PREDICTIVE_SEARCH, mdByName);
      return buildOptionItem(argument, item, fields, descriptionField, pkField);
    });
    return list;
  }
};
const buildOptionItem = (argument, item, fields, descriptionField, pkField) => {
  var _a;
  const matchFields = item['__matchFields'];
  const descriptionValue = (_a = item[descriptionField]) !== null && _a !== void 0 ? _a : "";
  const pkValue = item[pkField];
  let searchOption = {
    value: pkValue,
    label: descriptionValue,
    presentationValue: StringUtils.highlightValue(argument, matchFields, pkValue, fields, true),
    presentationLabel: descriptionField ? StringUtils.highlightValue(argument, matchFields, descriptionValue, fields, true) : "",
    details: SearchUtils.buildDetails(argument, fields, item)
  };
  return searchOption;
};
const filterInvalidFields = (resp, item, mdByName) => {
  let fieldsMetadata = resp.fieldsMetadata.filter((field) => {
    let accept = !StringUtils.isEmpty(item[field.fieldName]) &&
      field.visible !== false &&
      field.type !== 'B' &&
      resp.pkField !== field.fieldName &&
      resp.descriptionField !== field.fieldName &&
      (field.isPrimaryKey || !field.isLinkField) &&
      !(field.type === 'S' && field.presentationType === 'H');
    if (accept) {
      mdByName[field.fieldName] = field;
    }
    //Condição que trata o problema de trazer imagem no entityCard na pesquisa de registros
    if (typeof item[field.fieldName] === 'string' && INVALID_CONTENT_PATTERNS.some(pattern => item[field.fieldName].includes(pattern))) {
      return false;
    }
    return accept;
  });
  return fieldsMetadata;
};
const filterMathFields = (matchFields, fields, qtyFields, mdByName) => {
  if (matchFields && Array.isArray(matchFields)) {
    matchFields.forEach((matchField) => {
      let fieldMD = ArrayUtils.removeReference(fields, mdByName[matchField]);
      if (fieldMD) {
        fields.unshift(fieldMD);
      }
    });
  }
  fields = fields.slice(0, qtyFields);
  return fields;
};

class LayoutFormConfig {
  constructor() {
    this._config = null;
    this.listeners = [];
  }
  static getInstance() {
    if (!LayoutFormConfig.instance) {
      LayoutFormConfig.instance = new LayoutFormConfig();
    }
    return LayoutFormConfig.instance;
  }
  get config() {
    return this._config;
  }
  setConfig(newConfig) {
    this._config = newConfig;
    this.notifyListeners();
  }
  onConfigChange(listener) {
    this.listeners.push(listener);
  }
  notifyListeners() {
    this.listeners.forEach(listener => listener(this._config));
  }
}

const snkApplicationCss = ".sc-snk-application-h{--scrim-z-index:var(--elevation--100, 100);display:flex;flex-direction:column;height:100%}.sc-snk-application-h>.loading-hidden.sc-snk-application{display:none;pointer-events:none}.skeleton-content-left.sc-snk-application{width:300px;padding-right:5px}.skeleton-content.sc-snk-application{height:calc(100vh - 310px)}.spinner.sc-snk-application{height:100vh;gap:10px}.spinner.sc-snk-application>.spin.sc-snk-application{animation-name:spin;animation-duration:5000ms;animation-iteration-count:infinite;animation-timing-function:linear}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}";

const SnkApplication = class {
  constructor(hostRef) {
    registerInstance(this, hostRef);
    this.applicationLoaded = createEvent(this, "applicationLoaded", 7);
    this.applicationLoading = createEvent(this, "applicationLoading", 7);
    this.NEW_VERSION_POPUP_LOCKER = "NEW_VERSION_POPUP_LOCKER";
    this.FEATURE_FLAG_CACHE_DURATION = 3600000; // 1 hora em milissegundos
    this._authPromises = [];
    this._keyboardManager = new KeyboardManager();
    this._waitingAppReady = new Array();
    this._duCache = new Map();
    this._duPromises = new Map();
    this._requestListener = RequestListenerFactory.create({ strategy: 'request_time' });
    this._maxTimerAppLoading = 10000;
    this._featureFlagsCache = new Map();
    this._isBrowserTypeElectron = false;
    this._pendingActions = new Map;
    this._loadPkParameter = null;
    this._isLoadedByPk = false;
    this._formConfigFetcher = new FormConfigFetcher();
    this._LayoutFormConfigSingleton = LayoutFormConfig.getInstance();
    this._applicationReady = false;
    this._templateSkeleton = TEMPLATES_SKELETON.GRID;
    this._activeScrimWindow = false;
    this.enableLockManagerLoadingApp = undefined;
    this.messagesBuilder = undefined;
    this.configName = undefined;
    this.gridLegacyConfigName = undefined;
    this.formLegacyConfigName = undefined;
    this.loadByPK = undefined;
  }
  async processPendingActions(actionsLocker) {
    const pendingActionsFromContext = this._pendingActions.get(actionsLocker);
    if (pendingActionsFromContext && pendingActionsFromContext.length) {
      pendingActionsFromContext.forEach(action => action());
      this._pendingActions.set(actionsLocker, []);
    }
  }
  get parameters() {
    if (!this._parameters) {
      this._parameters = new ParametersFetcher();
    }
    return this._parameters;
  }
  async getAuth(resourceID) {
    if (resourceID == undefined) {
      return this.getApplicationAuth();
    }
    else {
      return new Promise((resolve, reject) => {
        this.authFetcher.getData(resourceID).then((authList) => {
          resolve(authList);
        }).catch(error => {
          reject(error);
        });
      });
    }
  }
  async getApplicationAuth() {
    if (this._auth) {
      return Promise.resolve(this._auth);
    }
    else {
      return new Promise((resolve, reject) => {
        const waitingAuth = this._authPromises.length > 0;
        this._authPromises.push(new PendingPromise(resolve, reject));
        if (!waitingAuth) {
          this.authFetcher.getData(this.applicationResourceID).then((authList) => {
            this._auth = authList;
            while (this._authPromises.length > 0) {
              this._authPromises.pop().resolve(this._auth);
            }
          }).catch(error => {
            while (this._authPromises.length > 0) {
              this._authPromises.pop().reject(error);
            }
          });
        }
      });
    }
  }
  watchPropHandler(newValue, _) {
    if (newValue && this._loadPkParameter) {
      this.loadByPK(this._loadPkParameter.pk, this._loadPkParameter.redirect);
      this._loadPkParameter = null;
    }
  }
  /**
   * Obtém o controlador de teclado.
   * @returns {Promise<KeyboardManager>} O gerenciador de teclado.
   * @async
   */
  async getKeyboardManager() {
    return Promise.resolve(this._keyboardManager);
  }
  /**
   * Obtém o notificador de Layout de formulário.
   * @returns {Promise<LayoutFormConfig>} O configurador de Layout do Formulário.
   * @async
   */
  async getLayoutFormConfig() {
    return Promise.resolve(this._LayoutFormConfigSingleton);
  }
  /**
   * Obtém `true` caso o usuário logado seja o SUP.
   * @returns {Promise<boolean>} `true` se o usuário for SUP, `false` caso contrário.
   * @async
   */
  async isUserSup() {
    return new Promise((resolve, reject) => {
      this.getAuth().then((authorization) => {
        this.getAuthList(authorization).then((auths) => {
          resolve(auths.isSup);
        }).catch(error => reject(error));
      });
    });
  }
  /**
   * Adiciona uma ação pendente que deve ser executada por um determinado locker.
   * @param {string} actionsLocker - Nome do locker da ação que será adicionada.
   * @param {Function} action - Ação que será executada.
   * @returns {Promise<void>}
   * @async
   */
  async addPendingAction(actionsLocker, action) {
    var _a;
    const actionsFromContext = (_a = this._pendingActions.get(actionsLocker)) !== null && _a !== void 0 ? _a : [];
    this._pendingActions.set(actionsLocker, [...actionsFromContext, action]);
  }
  /**
   * Realiza a chamada ao Service Broker conforme o nome do serviço.
   * @param {string} serviceName - Nome do serviço.
   * @param {string | Object} payload - Dados que serão processados na ação.
   * @param {Options} [options] - Parâmetros de URL.
   * @returns {Promise<any>} A resposta do Service Broker.
   * @async
   */
  async callServiceBroker(serviceName, payload, options) {
    return DataFetcher.get().callServiceBroker(serviceName, payload, options);
  }
  /**
   * Inicializa o onboarding para uma chave específica.
   * @param {string} onboardingKey - A chave do onboarding a ser iniciado.
   * @returns {Promise<void>}
   * @async
   */
  async initOnboarding(onboardingKey) {
    if (this.hasToShowNewVersionPopup()) {
      await this.addPendingAction(this.NEW_VERSION_POPUP_LOCKER, () => this.doInitOnboarding(onboardingKey));
      return;
    }
    this.doInitOnboarding(onboardingKey);
  }
  doInitOnboarding(onboardingKey) {
    OnboardingUtils.getInstance().init(onboardingKey, window.envContext);
  }
  /**
   * Obtém `true` caso o usuário logado tenha permissão para determinada ação.
   * @param {AutorizationType} access - O tipo de acesso a ser verificado.
   * @param {string} [resourceID] - O ID do recurso para verificar a permissão. Se não fornecido, verifica a permissão da aplicação.
   * @returns {Promise<boolean>} `true` se o usuário tiver acesso, `false` caso contrário.
   * @async
   */
  async hasAccess(access, resourceID) {
    return new Promise((resolve, reject) => {
      this.getAuth(resourceID).then((authorization) => {
        this.getAuthList(authorization).then((auths) => {
          resolve(auths.isSup || auths.actions[access]);
        }).catch(error => reject(error));
      });
    });
  }
  /**
   * Obtém todos os acessos do usuário logado para um recurso específico ou para a aplicação.
   * @param {string} [resourceID] - O ID do recurso. Se não fornecido, obtém os acessos da aplicação.
   * @returns {Promise<any>} Um objeto contendo todos os tipos de acesso e se o usuário os possui.
   * @async
   */
  async getAllAccess(resourceID) {
    return new Promise((resolve, reject) => {
      this.getAuth(resourceID).then((authorization) => {
        this.getAuthList(authorization).then((auths) => {
          const allAccess = {};
          allAccess['isSup'] = auths.isSup;
          Object.entries(AutorizationType).forEach((data) => {
            if (data[1] === AutorizationType.CLONE) {
              const insertPermission = auths.actions[AutorizationType.INSERT] || false;
              const clonePermission = auths.actions[AutorizationType.CLONE] || false;
              allAccess[data[0]] = insertPermission && clonePermission;
            }
            else {
              allAccess[data[0]] = auths.actions[data[1]] || false;
            }
          });
          resolve(allAccess);
        }).catch(error => reject(error));
      });
    });
  }
  /**
   * Obtém o valor de um parâmetro do tipo string.
   * @param {string} name - O nome do parâmetro.
   * @returns {Promise<string>} O valor do parâmetro como string.
   * @async
   */
  async getStringParam(name) {
    return this.parameters.asString(name);
  }
  /**
   * Obtém o valor de um parâmetro do tipo Inteiro.
   * @param {string} name - O nome do parâmetro.
   * @returns {Promise<number>} O valor do parâmetro como número inteiro.
   * @async
   */
  async getIntParam(name) {
    return this.parameters.asInteger(name);
  }
  /**
   * Obtém o valor de um parâmetro do tipo Decimal.
   * @param {string} name - O nome do parâmetro.
   * @returns {Promise<number>} O valor do parâmetro como número decimal.
   * @async
   */
  async getFloatParam(name) {
    return this.parameters.asFloat(name);
  }
  /**
   * Obtém o valor de um parâmetro do tipo booleano.
   * @param {string} name - O nome do parâmetro.
   * @returns {Promise<boolean>} O valor do parâmetro como booleano.
   * @async
   */
  async getBooleanParam(name) {
    return this.parameters.asBoolean(name);
  }
  /**
   * Obtém o valor de um parâmetro do tipo data.
   * @param {string} name - O nome do parâmetro.
   * @returns {Promise<Date>} O valor do parâmetro como objeto Date.
   * @async
   */
  async getDateParam(name) {
    return this.parameters.asDate(name);
  }
  /**
   * Exibe o conteúdo passado em um Popup.
   * @param {HTMLElement} content - O elemento HTML a ser exibido no popup.
   * @param {"auto" | "full"} [size="full"] - O tamanho do popup.
   * @param {boolean} [useHeader=true] - Define se o cabeçalho do popup deve ser usado.
   * @param {Function} [onCloseCallback] - Função a ser chamada quando o popup for fechado.
   * @returns {Promise<void>}
   * @async
   */
  async showPopUp(content, size = "full", useHeader = true, onCloseCallback) {
    this.clearContent(this._popUp);
    this._popUp.addEventListener("ezClosePopup", () => {
      onCloseCallback();
    }, { once: true });
    this._popUp.appendChild(content);
    this._popUp.opened = true;
    this._popUp.heightMode = size;
    this._popUp.useHeader = useHeader;
    this._popUp.autoClose = false;
    if (content.tagName === 'EZ-MODAL-CONTAINER') {
      this._popUp.useHeader = false;
    }
  }
  /**
   * Exibe o conteúdo passado em um Modal.
   * @param {HTMLElement} content - O elemento HTML a ser exibido no modal.
   * @returns {Promise<void>}
   * @async
   */
  async showModal(content) {
    this.clearContent(this._rightModal);
    this._rightModal.appendChild(content);
    this._rightModal.opened = true;
  }
  /**
   * Apresenta uma lista de alertas.
   * Geralmente é utilizado para apresentar resultados de processamentos em lote.
   * @param {Array<AlertItem>} alerts - A lista de alertas a serem exibidos.
   * @returns {Promise<void>}
   */
  showAlerts(alerts) {
    return ApplicationUtils.showAlerts({ alerts });
  }
  /**
   * Fecha o Modal e limpa o conteúdo.
   * @returns {Promise<void>}
   * @async
   */
  async closeModal() {
    this.clearContent(this._rightModal);
    this._rightModal.opened = false;
  }
  /**
   * Fecha o Popup e limpa o conteúdo.
   * @returns {Promise<void>}
   * @async
   */
  async closePopUp() {
    this.clearContent(this._popUp);
    this._popUp.opened = false;
    this._popUp.useHeader = true;
    this._popUp.heightMode = "full";
  }
  /**
   * Verifica se a licença do cliente tem determinado opcional (produto).
   * @param {string} opcional - O nome do opcional ou uma string de opcionais separados por vírgula.
   * @returns {Promise<boolean>} `true` se o cliente tiver o opcional, `false` caso contrário.
   * @async
   */
  async temOpcional(opcional) {
    const opts = opcional.split(",");
    return new Promise((resolve, reject) => {
      this.getAttributeFromHTMLWrapper("opc0009")
        .then(value => {
        if (value === "1") {
          resolve(true);
        }
        else {
          Promise.all(opts.map(opt => this.getAttributeFromHTMLWrapper("opc" + opt)))
            .then(result => {
            resolve(result.includes("1"));
          })
            .catch(error => {
            reject(error);
          });
        }
      })
        .catch(error => {
        reject(error);
      });
    });
  }
  /**
   * Obtém a configuração de um recurso por service broker.
   * @param {string} key - A chave da configuração.
   * @returns {Promise<any>} Os dados da configuração.
   * @async
   */
  async getConfig(key) {
    let payload = {
      "serviceName": "SystemUtilsSP.getConf",
      "requestBody": {
        "config": {
          "chave": key,
          "tipo": "T"
        }
      }
    };
    return new Promise((resolve, reject) => {
      DataFetcher.get()
        .callServiceBroker("SystemUtilsSP.getConf", JSON.stringify(payload))
        .then(result => { var _a; return resolve((_a = result.config) === null || _a === void 0 ? void 0 : _a.data); })
        .catch(error => reject(error));
    });
  }
  /**
   * Retorna se uma feature flag global está ativa ou não.
   */
  async isFeatureActive(featureName) {
    const now = Date.now();
    let payload = {
      "serviceName": "SystemUtilsSP.featureIsActive",
      "requestBody": {
        "featureName": featureName
      }
    };
    if (this._featureFlagsCache.get(featureName) && now < this._featureFlagsCache.get(featureName).expires) {
      return Promise.resolve(this._featureFlagsCache.get(featureName).isActive);
    }
    //Caso ocorra um erro nessa chamada, o reject do error é feito automaticamente 
    const result = await DataFetcher.get().callServiceBroker("SystemUtilsSP.featureIsActive", JSON.stringify(payload));
    const isActive = result.isActive;
    this._featureFlagsCache.set(featureName, {
      isActive: isActive,
      expires: now + this.FEATURE_FLAG_CACHE_DURATION,
    });
    return isActive;
  }
  /**
   * Salva a configuração de determinado recurso.
   * @param {string} key - A chave da configuração.
   * @param {Object} data - Os dados da configuração a serem salvos.
   * @returns {Promise<any>} O resultado da operação de salvamento.
   * @async
   */
  async saveConfig(key, data) {
    let payload = {
      "serviceName": "SystemUtilsSP.saveConf",
      "requestBody": {
        "config": {
          "chave": key,
          "tipo": "T",
          data
        }
      }
    };
    return new Promise((resolve, reject) => {
      DataFetcher.get()
        .callServiceBroker("SystemUtilsSP.saveConf", JSON.stringify(payload))
        .then(result => resolve(result))
        .catch(error => reject(error));
    });
  }
  /**
   * Acessa informações de contexto "empurrados" na abertura da tela.
   * @param {string} attribName - O nome do atributo.
   * @returns {Promise<string>} O valor do atributo.
   * @async
   */
  async getAttributeFromHTMLWrapper(attribName) {
    return Promise.resolve(window[attribName]);
  }
  /**
   * Abre determinada tela, repassando pkObject.
   * @param {string} resourceId - O ID do recurso da tela a ser aberta.
   * @param {Object} pkObject - O objeto de chave primária a ser passado para a tela.
   * @returns {Promise<void>}
   * @async
   */
  async openApp(resourceId, pkObject) {
    Workspace.openAppActivity(resourceId, pkObject);
  }
  /**
   * Realiza a chamada do WebConnection para realizar a exportação de arquivo.
   * @param {string} keyPort - Chave da porta que será requisitada.
   * @param {string} methodName - Nome do tipo de exportação de arquivo que será realizado.
   * @param {IAppletCallerParams} params - Parâmetros necessários para realizar a exportação do arquivo.
   * @returns {Promise<void>}
   * @async
   */
  async webConnection(keyPort, methodName, params) {
    this.getStringParam(keyPort).then((port) => {
      AppletCaller.webConnectionCaller(port, methodName, params);
    });
  }
  getDuPromissesStack(dataUnitName) {
    let stack;
    if (dataUnitName) {
      stack = this._duPromises.get(dataUnitName);
      if (!stack) {
        stack = [];
        this._duPromises.set(dataUnitName, stack);
      }
    }
    return stack || [];
  }
  /**
   * Cria o DataUnit a partir do nome da entidade. É possível armazená-lo no cache
   * passando o dataUnitName, assim, se mais de uma chamada for feita, o mesmo DataUnit será usado.
   * @param {string} entityName - O nome da entidade.
   * @param {string} [dataUnitName] - O nome para identificar o DataUnit no cache.
   * @param {DataUnit} [parentDataUnit] - O DataUnit pai, se houver.
   * @param {string} [configName] - O nome da configuração a ser usada.
   * @param {string} [resourceID] - O ID do recurso. Se não fornecido, usa o da aplicação.
   * @returns {Promise<DataUnit>} O DataUnit criado ou obtido do cache.
   * @async
   */
  async createDataunit(entityName, dataUnitName, parentDataUnit, configName, resourceID) {
    if (resourceID == undefined) {
      resourceID = this.applicationResourceID;
    }
    return new Promise((resolve, reject) => {
      const duPromisses = this.getDuPromissesStack(dataUnitName);
      const waitingDu = duPromisses.length > 0;
      duPromisses.push(new PendingPromise(resolve, reject));
      if (!waitingDu) {
        const dataUnit = this.dataUnitFetcher.getDataUnit(entityName, resourceID, parentDataUnit, configName);
        dataUnit.loadMetadata().then(() => {
          this.processResolveDataUnit(dataUnit, dataUnitName, duPromisses);
        }).catch(reason => {
          while (duPromisses.length > 0) {
            duPromisses.pop().reject(reason);
          }
        });
      }
    });
  }
  processResolveDataUnit(dataUnit, dataUnitName, duPromisses) {
    if (dataUnitName) {
      this.updateDataunitCache(undefined, dataUnitName, dataUnit);
    }
    while (duPromisses.length > 0) {
      duPromisses.pop().resolve(dataUnit);
    }
  }
  /**
   * Atualiza o cache de dataunits da aplicação.
   * @param {string} oldName - Nome do dataunit que está em cache (será removido).
   * @param {string} dataUnitName - Nome do dataunit que será armazenado em cache.
   * @param {DataUnit} dataUnit - Instância do Dataunit para ser armazenado em cache.
   * @returns {Promise<void>}
   * @async
   */
  async updateDataunitCache(oldName, dataUnitName, dataUnit) {
    if (oldName) {
      this._duCache.delete(oldName);
    }
    this._duCache.set(dataUnitName, dataUnit);
  }
  /**
   * Obtém um DataUnit do cache ou cria um caso ainda não tenha sido criado.
   * @param {string} entityName - O nome da entidade.
   * @param {string} dataUnitName - O nome para identificar o DataUnit no cache.
   * @param {DataUnit} [parentDataUnit] - O DataUnit pai, se houver.
   * @param {string} [configName] - O nome da configuração a ser usada.
   * @param {string} [resourceID] - O ID do recurso. Se não fornecido, usa o da aplicação.
   * @returns {Promise<DataUnit>} O DataUnit obtido do cache ou recém-criado.
   * @async
   */
  async getDataUnit(entityName, dataUnitName, parentDataUnit, configName, resourceID) {
    return new Promise((resolve, reject) => {
      const dataUnit = this._duCache.get(dataUnitName);
      if (dataUnit) {
        resolve(dataUnit);
      }
      else {
        this.createDataunit(entityName, dataUnitName, parentDataUnit, configName, resourceID).then(dataUnit => {
          resolve(dataUnit);
        }).catch(reason => reject(reason));
      }
    });
  }
  /**
   * Registra um client event para o DataFetcher da aplicação.
   * @param {String} eventID - Nome do evento para a aplicação se registrar.
   * @param {(clientEvent: IClientEventResponse, dataFetcherReacaller: IDataFetcherRecaller) => void} handler - Função de callback que será chamada quando o client event ocorrer.
   * @returns {Promise<void>}
   * @async
   */
  async addClientEvent(eventID, handler) {
    return new Promise((resolve) => {
      DataFetcher.addClientEvent(eventID, handler);
      resolve();
    });
  }
  /**
   * Remove um client event do DataFetcher da aplicação.
   * @param {String} eventID - Nome do evento a ser removido.
   * @returns {Promise<void>}
   * @async
   */
  async removeClientEvent(eventID) {
    return new Promise((resolve) => {
      DataFetcher.removeClientEvent(eventID);
      resolve();
    });
  }
  /**
   * Verifica se um client event está registrado no DataFetcher da aplicação.
   * @param {String} eventID - Nome do evento a ser verificado.
   * @returns {Promise<boolean>} `true` se o evento estiver registrado, `false` caso contrário.
   * @async
   */
  async hasClientEvent(eventID) {
    return new Promise((resolve) => {
      resolve(DataFetcher.hasClientEvent(eventID));
    });
  }
  get applicationResourceID() {
    if (!this._applicationResourceID) {
      this._applicationResourceID = this.urlParams.get("workspaceResourceID") ||
        this.urlParams.get("resourceID") ||
        Workspace.resourceID ||
        "unknown.resource.id";
    }
    return this._applicationResourceID;
  }
  /**
   * Obtém o resourceID da tela em questão.
   * @returns {Promise<string>} O ID do recurso da aplicação.
   * @async
   */
  async getResourceID() {
    return Promise.resolve(this.applicationResourceID);
  }
  /**
   * Obtém o UserId do usuário logado.
   * @returns {Promise<string>} O ID do usuário.
   * @async
   */
  async getUserID() {
    return Promise.resolve(window["UID"]);
  }
  /**
   * Exibe o diálogo de alerta de acordo com os parâmetros passados.
   * @param {string} title - O título do alerta.
   * @param {string} message - A mensagem do alerta.
   * @param {string} [icon] - O nome do ícone a ser exibido.
   * @param {MessageOptions} [options] - Opções adicionais para a mensagem.
   * @returns {Promise<boolean>}
   * @async
   */
  async alert(title, message, icon, options) {
    return ApplicationUtils.alert(title, message, icon, options);
  }
  /**
   * Exibe o diálogo de erro de acordo com os parâmetros passados.
   * @param {string} title - O título do erro.
   * @param {string} message - A mensagem do erro.
   * @param {string} [icon] - O nome do ícone a ser exibido.
   * @param {MessageOptions} [options] - Opções adicionais para a mensagem.
   * @returns {Promise<boolean>}
   * @async
   */
  async error(title, message, icon, options) {
    return ApplicationUtils.error(title, message, icon, options);
  }
  /**
   * Exibe o diálogo de sucesso de acordo com os parâmetros passados.
   * @param {string} title - O título da mensagem de sucesso.
   * @param {string} message - A mensagem de sucesso.
   * @param {string} [icon] - O nome do ícone a ser exibido.
   * @param {MessageOptions} [options] - Opções adicionais para a mensagem.
   * @returns {Promise<boolean>}
   * @async
   */
  async success(title, message, icon, options) {
    return ApplicationUtils.success(title, message, icon, options);
  }
  /**
   * Exibe um diálogo de mensagem comum.
   * @param {string} title - O título da mensagem.
   * @param {string} message - A mensagem.
   * @param {string} [icon] - O nome do ícone a ser exibido.
   * @param {MessageOptions} [options] - Opções adicionais para a mensagem.
   * @returns {Promise<boolean>}
   * @async
   */
  async message(title, message, icon, options) {
    return ApplicationUtils.message(title, message, icon, options);
  }
  /**
   * Exibe um diálogo de confirmação.
   * @param {string} title - O título da confirmação.
   * @param {string} message - A mensagem da confirmação.
   * @param {string} [icon] - O nome do ícone a ser exibido.
   * @param {DialogType} [dialogType] - O tipo de diálogo.
   * @param {MessageOptions} [options] - Opções adicionais para a mensagem.
   * @returns {Promise<boolean>} `true` se confirmado, `false` caso contrário.
   * @async
   */
  async confirm(title, message, icon, dialogType, options) {
    return ApplicationUtils.confirm(title, message, icon, dialogType, options);
  }
  /**
   * Exibe uma informação efêmera (de segundo plano).
   * @param {string} message - A mensagem a ser exibida.
   * @param {MessageOptions} [options] - Opções adicionais para a mensagem.
   * @returns {Promise<void>}
   * @async
   */
  async info(message, options) {
    return ApplicationUtils.info(message, options);
  }
  /**
   * Obtém os totalizadores da grade.
   * @param {string} name - O nome da configuração de totalizadores.
   * @param {string} resourceID - O ID do recurso.
   * @param {Array<Filter>} filters - A lista de filtros a serem aplicados.
   * @returns {Promise<Map<string, number>>} Um mapa com os nomes dos totalizadores e seus valores.
   * @async
   */
  async loadTotals(name, resourceID, filters) {
    return this.totalsFetcher.fetchTotals(name, resourceID, filters);
  }
  /**
   * Obtém a informação se o último carregamento do dataunit foi feito através de um loadByPk.
   * @returns {Promise<boolean>} `true` se foi carregado por PK, `false` caso contrário.
   * @async
   */
  async isLoadedByPk() {
    return Promise.resolve(this._isLoadedByPk);
  }
  /**
* Remove registro do cache do PreLoader do dataunit.
* Deve ser usado quando existe um dataunit usando loader do application, mas o removeLoader está sendo sobrescrito.
* @param {DataUnit} dataUnit - O DataUnit do qual o registro será removido.
* @param {Array<string>} recordsIDs - Os IDs dos registros a serem removidos.
* @returns {Promise<void>}
* @async
*/
  async preloadMangerRemoveRecord(dataUnit, recordsIDs) {
    const records = recordsIDs.map(id => {
      return { "__record__id__": id };
    });
    PreloadManager.removeRecords(dataUnit, records);
  }
  getCountSkeleton(skeletonHeight, spacingSkeleton, headerHeight) {
    headerHeight = headerHeight || 160;
    const containerHeight = window.innerHeight - headerHeight;
    const skeletonSpacing = spacingSkeleton || 10;
    const totalHeightPerSkeleton = skeletonHeight + skeletonSpacing;
    const skeletonCount = Math.floor(containerHeight / totalHeightPerSkeleton) - 1;
    return skeletonCount || 1;
  }
  getSkeletonRandomWidth() {
    const min = 30;
    const max = 100;
    const randomWidth = Math.floor(Math.random() * (max - min + 1)) + min;
    return `${randomWidth}%`;
  }
  async getAuthList(auth) {
    return await (new MGEAuthorization()).parseFromJSON(auth);
  }
  get urlParams() {
    if (!this._urlParams) {
      this._urlParams = UrlUtils.getQueryParams(location.search);
    }
    return this._urlParams;
  }
  getMessage(key, params) {
    var _a;
    return (_a = this.messagesBuilder) === null || _a === void 0 ? void 0 : _a.getMessage(key, params);
  }
  get dataUnitFetcher() {
    if (!this._dataUnitFetcher) {
      this._dataUnitFetcher = new DataUnitFetcher();
    }
    return this._dataUnitFetcher;
  }
  get totalsFetcher() {
    if (!this._totalsFetcher) {
      this._totalsFetcher = new TotalsFetcher();
    }
    return this._totalsFetcher;
  }
  get pesquisaFetcher() {
    if (!this._pesquisaFetcher) {
      this._pesquisaFetcher = new PesquisaFetcher();
    }
    return this._pesquisaFetcher;
  }
  get authFetcher() {
    if (!this._authFetcher) {
      this._authFetcher = new AuthFetcher();
    }
    return this._authFetcher;
  }
  /**
   * Obtém as opções em componentes de pesquisa.
   * Ex.: snk-config-options
   * @param {ISearchArgument} searchArgument - Argumentos da pesquisa.
   * @param {string} fieldName - Nome do campo no DataUnit.
   * @param {DataUnit} dataUnit - Instância do DataUnit.
   * @param {ISearchCtxOptions} [ctxOptions] - Opções de contexto adicionais.
   * @returns {Promise<Array<IOption> | IOption>} Uma lista de opções ou uma única opção.
   * @async
   */
  async executeSearch(searchArgument, fieldName, dataUnit, ctxOptions) {
    const descriptor = dataUnit === null || dataUnit === void 0 ? void 0 : dataUnit.getField(fieldName);
    if (!descriptor) ;
    else {
      const { mode, argument } = searchArgument;
      const { ENTITYNAME, CODEFIELD, DESCRIPTIONFIELD, ROOTENTITY, DESCRIPTIONENTITY, ISHIERARCHYENTITY } = descriptor.properties;
      const dependencies = descriptor.dependencies;
      let criteria;
      const searchOptions = {
        rootEntity: ROOTENTITY,
        descriptionFieldName: DESCRIPTIONFIELD,
        codeFieldName: CODEFIELD,
        showInactives: false,
        dataUnitId: dataUnit.dataUnitId
      };
      dependencies === null || dependencies === void 0 ? void 0 : dependencies.filter(dep => dep.masterFields).forEach(dependency => {
        var _a;
        if (dependency.type === DependencyType.SEARCHING) {
          if (((_a = dependency.masterFields) === null || _a === void 0 ? void 0 : _a.length) > 0) {
            criteria = {
              expression: dependency.expression,
              params: dependency.masterFields.map(fieldName => {
                const masterDescriptor = dataUnit.getField(fieldName);
                const dataType = (masterDescriptor === null || masterDescriptor === void 0 ? void 0 : masterDescriptor.dataType) || DataType.TEXT;
                const defaultValue = dataType === DataType.DATE ? DateUtils.formatDate(new Date(masterDescriptor === null || masterDescriptor === void 0 ? void 0 : masterDescriptor.defaultValue)) : masterDescriptor === null || masterDescriptor === void 0 ? void 0 : masterDescriptor.defaultValue;
                const value = dataUnit.getFieldValue(fieldName) || defaultValue;
                if (value == undefined) {
                  this.alert(this.getMessage("snkApplication.search.error.title"), this.getMessage("snkApplication.search.error.requiredField", { fieldLabel: masterDescriptor.label }));
                  throw new Error(this.getMessage("snkApplication.search.error.requiredField", { fieldLabel: masterDescriptor.label }));
                }
                return { name: fieldName, value, dataType };
              })
            };
          }
        }
      });
      const allowsNonAnalytic = ctxOptions === null || ctxOptions === void 0 ? void 0 : ctxOptions.allowsNonAnalytic;
      const options = {
        entity: ENTITYNAME,
        entityDescription: DESCRIPTIONENTITY,
        isHierarchyEntity: ISHIERARCHYENTITY,
        criteria,
        searchOptions,
        allowsNonAnalytic
      };
      return (ctxOptions === null || ctxOptions === void 0 ? void 0 : ctxOptions.useSearchPlus) ? this.executePreparedSearchPlus(mode, argument, options) : this.executePreparedSearch(mode, argument, options);
    }
  }
  filterInvalidFields(resp, item, mdByName) {
    let fieldsMetadata = resp.fieldsMetadata.filter((field) => {
      let accept = !StringUtils.isEmpty(item[field.fieldName]) &&
        field.visible !== false &&
        field.type !== 'B' &&
        resp.pkField !== field.fieldName &&
        resp.descriptionField !== field.fieldName &&
        (field.isPrimaryKey || !field.isLinkField) &&
        !(field.type === 'S' && field.presentationType === 'H');
      if (accept) {
        mdByName[field.fieldName] = field;
      }
      //Condição que trata o problema de trazer imagem no entityCard na pesquisa de registros
      if (typeof item[field.fieldName] === 'string' && (item[field.fieldName].indexOf('<img') > -1 || item[field.fieldName].indexOf('<svg') > -1)) {
        return false;
      }
      return accept;
    });
    return fieldsMetadata;
  }
  filterMathFields(matchFields, fields, qtyFields, mdByName) {
    if (matchFields && Array.isArray(matchFields)) {
      matchFields.forEach((matchField) => {
        let fieldMD = ArrayUtils.removeReference(fields, mdByName[matchField]);
        if (fieldMD) {
          fields.unshift(fieldMD);
        }
      });
    }
    fields = fields.slice(0, qtyFields);
    return fields;
  }
  builOptionItem(argument, item, fields, descriptionField, pkField) {
    var _a;
    let exibitionItem = {
      value: StringUtils.highlightValue(argument, item['__matchFields'], (_a = item[pkField]) === null || _a === void 0 ? void 0 : _a.toString(), fields, true),
      label: descriptionField ? StringUtils.highlightValue(argument, item['__matchFields'], item[descriptionField], fields, true) : "",
      details: SearchUtils.buildDetails(argument, fields, item)
    };
    return exibitionItem;
  }
  /**
   * Realiza a pesquisa de registros
   * Ex.: snk-config-options
   * @param {string} mode - O modo da pesquisa ("ADVANCED" ou outro).
   * @param {string} argument - O argumento da pesquisa.
   * @param {any} options - Opções preparadas para a pesquisa.
   * @returns {Promise<Array<IOption> | IOption>} Uma lista de opções ou uma única opção.
   * @async
   */
  async executePreparedSearchPlus(mode, argument, options) {
    return await this.executePreparedSearch(mode, argument, Object.assign(Object.assign({}, options), { useSearchPlus: true }));
  }
  /**
   * Obtém as opções em componentes de pesquisa com base em opções preparadas.
   * Ex.: snk-config-options
   * @param {string} mode - O modo da pesquisa ("ADVANCED" ou outro).
   * @param {string} argument - O argumento da pesquisa.
   * @param {any} options - Opções preparadas para a pesquisa.
   * @returns {Promise<Array<IOption> | IOption>} Uma lista de opções ou uma única opção.
   * @async
   */
  async executePreparedSearch(mode, argument, options) {
    var _a;
    const mdByName = {};
    const { entity, entityDescription, criteria, searchOptions, isHierarchyEntity, allowsNonAnalytic, useSearchPlus } = options;
    if (useSearchPlus) {
      return executePreparedSearchPlus(mode, argument, options, this, this.pesquisaFetcher);
    }
    if (mode === "LOAD_DESCRIPTION") {
      let result = await this.pesquisaFetcher.loadByCode(entity, argument, criteria, searchOptions);
      result = ObjectUtils.stringToObject(result.json.$);
      let descriptionField = result.descriptionField;
      const option = (_a = result.data) === null || _a === void 0 ? void 0 : _a[0];
      if (!option) {
        return {
          value: argument,
          label: ""
        };
      }
      return {
        value: argument,
        label: option[descriptionField]
      };
    }
    else if (mode === "ADVANCED") {
      return new Promise((accept, reject) => {
        const pesquisaContent = document.createElement("snk-pesquisa");
        pesquisaContent[ElementIDUtils.DATA_ELEMENT_ID_ATTRIBUTE_NAME] = `entity_${entity}`;
        pesquisaContent.entityName = entity;
        pesquisaContent.argument = argument;
        pesquisaContent.searchLoader = (text) => this.pesquisaFetcher.loadAdvancedSearch(entity, text, criteria, searchOptions);
        pesquisaContent.isHierarchyEntity = isHierarchyEntity;
        if (isHierarchyEntity) {
          pesquisaContent.treeLoader = (text) => this.pesquisaFetcher.loadTree(entity, text, criteria, searchOptions);
          pesquisaContent.allowsNonAnalytic = allowsNonAnalytic;
        }
        pesquisaContent.selectItem = (option) => {
          accept(option);
          this.clearPopUpTitle();
          this.closePopUp();
        };
        this.setPopUpTitle(entityDescription);
        this.showPopUp(pesquisaContent, undefined, undefined, reject);
      });
    }
    else {
      return new Promise((resolve, reject) => {
        this.pesquisaFetcher.loadAdvancedSearch(entity, argument, criteria, searchOptions)
          .then(result => {
          result = ObjectUtils.stringToObject(result.json.$);
          let descriptionField = result.descriptionField;
          let pkField = result.pkField;
          const list = [];
          result.data.forEach((item) => {
            let fieldsMetadata = this.filterInvalidFields(result, item, mdByName);
            let qtyFields = 6;
            let fields = this.filterMathFields(item['__matchFields'], fieldsMetadata, qtyFields, mdByName);
            list.push(this.builOptionItem(argument, item, fields, descriptionField, pkField));
          });
          resolve(list);
        })
          .catch(error => {
          reject(error);
        });
      });
    }
  }
  /**
   * Obtém `true` caso a tela esteja em modo de debug.
   */
  async isDebugMode() {
    return new Promise(accept => {
      accept(window['isDebugMode']);
    });
  }
  /**
   * Obtém o nome (label) da aplicação.
   * @returns {Promise<string>} O nome da aplicação.
   * @async
   */
  async getAppLabel() {
    return Workspace.getAppLabel(this.applicationResourceID);
  }
  /**
   * Adiciona um listener no fetcher de Pesquisa.
   * @param {string} entityName - O nome da entidade.
   * @param {DataUnit} dataUnit - A instância do DataUnit.
   * @param {ISearchListener} listener - O listener a ser adicionado.
   * @returns {Promise<IRemoveSearchListener>} Uma função para remover o listener.
   * @async
   */
  addSearchListener(entityName, dataUnit, listener) {
    return new Promise(resolve => {
      const removeListener = this.pesquisaFetcher.addSearchListener(entityName, dataUnit.dataUnitId, listener);
      resolve(removeListener);
    });
  }
  /**
    Realiza o import de um JavaScript que está disponível dentro da pasta /public da aplicação.
    @param {string | Array<string>} relativePath - Define o caminho relativo para o arquivo JavaScript a ser importado, ou uma lista de caminhos.
    @returns {Promise<void>}
    @async
   */
  importScript(relativePath) {
    return new Promise((resolve) => {
      this.getApplicationPath().then((appPath) => {
        let paths = [];
        if (!Array.isArray(relativePath)) {
          paths = [relativePath];
        }
        paths.forEach(path => {
          const script = document.createElement('script');
          script.src = `${appPath}/${path}`;
          script.async = true;
          document.body.appendChild(script);
        });
        resolve();
      });
    });
  }
  /**
   * Retorna o path relativo da aplicação.
   * @returns {Promise<string>} O caminho relativo da aplicação.
   * @async
   */
  async getApplicationPath() {
    return new Promise((resolve) => {
      if (window['applicationenv'] !== "dev") {
        resolve(`/${this.getModuleName()}/labsApps/${window["APPLICATION_NAME"]}/build`);
        return;
      }
      resolve('');
    });
  }
  /**
   * Retorna o contexto Sankhya-om da aplicação.
   */
  getModuleName() {
    return window["MGE_MODULE_NAME"] || 'mgefin-bff';
  }
  /**
   * Com base em um campo realiza um "select distinct" respeitando os
   * filtros atuais do dataUnit e um critério de filtro para a própria
   * coluna.
   * @param {DataUnit} dataUnit - A instância do DataUnit.
   * @param {string} fieldName - O nome do campo para o select distinct.
   * @param {string} argument - O argumento de filtro para a coluna.
   * @returns {Promise<Array<any>>} Uma lista de valores distintos.
   * @async
   */
  executeSelectDistinct(dataUnit, fieldName, argument) {
    return this.dataUnitFetcher.loadSelectDistinct(dataUnit, fieldName, argument);
  }
  /**
   * Retorna a instância do DataFetcher utilizado pelo application.
   * @returns {Promise<DataFetcher>} O DataFetcher da aplicação.
   * @async
   */
  getDataFetcher() {
    return Promise.resolve(DataFetcher.get());
  }
  /**
  * Retorna uma promise que será resolvida quando o snk-application estiver carregado e registrado no ApplicationContext.
  * @returns {Promise<SnkApplication>} O componente SnkApplication carregado.
  * @async
  */
  async whenApplicationReady() {
    const isLoadding = ApplicationContext.getContextValue("__SNK__APPLICATION__LOADING__");
    if (isLoadding) {
      return Promise.resolve(this);
    }
    return new Promise((resolve) => {
      this._waitingAppReady.push(() => resolve(this));
    });
  }
  /**
   * Atribui valor para parâmetros de contexto no componente de pesquisa.
   * @param {string} name - Nome do parâmetro.
   * @param {string} value - String conversível de acordo com o tipo do parâmetro.
   * @returns {Promise<void>}
   * @async
   */
  async setSearchFilterContext(name, value) {
    ApplicationContext.setContextValue(`__SNK__APPLICATION__FILTER__CONTEXT(${name})__`, value);
  }
  clearContent(container) {
    if (container) {
      Array.from(container.children).forEach(child => {
        container.removeChild(child);
      });
    }
  }
  async clearPopUpTitle() {
    this._popUp.ezTitle = "";
  }
  async setPopUpTitle(title) {
    this._popUp.ezTitle = title;
  }
  async pkChangeListener() {
    const pkHash = top.window.location.hash.split('/')[2];
    if (this._currentPkParameter === pkHash)
      return;
    const resourceIDfromUrl = this.getResourceIdFromToken();
    const pkObject = UrlUtils.getPkObjectFromUrlToken(top.window.location.hash);
    const redirectFrom = window["redirectFrom"];
    if (pkObject === undefined) {
      return;
    }
    if (!redirectFrom || redirectFrom.split("_")[0].indexOf(resourceIDfromUrl.split("_")[0]) === -1) {
      if (resourceIDfromUrl !== this.applicationResourceID) {
        return;
      }
    }
    const pkParam = { pk: pkObject };
    this._isLoadedByPk = true;
    if (this.loadByPK) {
      this.loadByPK(pkParam, redirectFrom);
      this._currentPkParameter = pkHash;
      return;
    }
    this._loadPkParameter = { pk: pkParam, redirect: redirectFrom };
    this.defaultLoadByPK(pkParam, pkHash);
  }
  getResourceIdFromToken() {
    var _a;
    if (((_a = (top.window.location.pathname)) === null || _a === void 0 ? void 0 : _a.indexOf("tabContent.jsp")) > -1 && (window.location['generateHash'])) {
      return UrlUtils.getResourceIdFromUrlToken(window.location['generateHash'](window.location.hash));
    }
    return UrlUtils.getResourceIdFromUrlToken(top.window.location.hash);
  }
  defaultLoadByPK(pkObject, pkHash) {
    if (!(pkObject === null || pkObject === void 0 ? void 0 : pkObject.pk))
      return;
    const snkDataUnit = this.getFirstDataUnitFromDOM();
    const dataUnit = snkDataUnit.dataUnit;
    if (!dataUnit) {
      console.warn(this.getMessage("snkApplication.dataUnit.initDataUnitError"));
      snkDataUnit.addEventListener("dataUnitReady", (event) => {
        this.loadDataWithPKFilter(pkObject, event.detail);
        this._currentPkParameter = pkHash;
      });
      return;
    }
    this.loadDataWithPKFilter(pkObject, dataUnit);
    this._currentPkParameter = pkHash;
  }
  loadDataWithPKFilter(pkObject, dataUnit) {
    const quickFilter = {
      term: '',
      filter: {
        name: 'LOAD_BY_PK_FILTER',
        expression: this.buildFilterExpressionByPkObject(pkObject),
        params: this.getFilterParamsFromPkObject(pkObject, dataUnit),
      },
    };
    dataUnit.loadData(quickFilter);
  }
  getFirstDataUnitFromDOM() {
    //Primeiro tentamos obeter o dataunit para fazer o loadByPK
    let snkDataUnit = this._element.querySelector("snk-data-unit[data-load-by-pk]");
    if (!snkDataUnit) {
      snkDataUnit = this._element.querySelector("snk-data-unit");
    }
    if (snkDataUnit) {
      return snkDataUnit;
    }
    return undefined;
  }
  getFilterParamsFromPkObject(pkObject, dataUnit) {
    var _a;
    const filterParams = [];
    for (const key in pkObject.pk) {
      if (pkObject.pk.hasOwnProperty(key) && !Array.isArray(pkObject.pk[key])) {
        filterParams.push({
          name: key,
          dataType: ((_a = dataUnit.getField(key)) === null || _a === void 0 ? void 0 : _a.dataType) || this.getDefaultDataTypeLoadByPK(pkObject.pk[key]),
          value: pkObject.pk[key]
        });
      }
    }
    return filterParams;
  }
  getDefaultDataTypeLoadByPK(value) {
    if (typeof value === "number" || value instanceof Number) {
      return DataType.NUMBER;
    }
    if (typeof value === "boolean" || value instanceof Boolean) {
      return DataType.BOOLEAN;
    }
    if (value instanceof Date) {
      return DataType.DATE;
    }
    return DataType.TEXT;
  }
  buildFilterExpressionByPkObject(pkObject) {
    let expression = "";
    for (const field in pkObject.pk) {
      if (!StringUtils.isEmpty(expression)) {
        expression += " AND ";
      }
      if (Array.isArray(pkObject.pk[field])) {
        expression += `${field} IN (${pkObject.pk[field].toString()})`;
      }
      else {
        expression += `${field} = :${field}`;
      }
    }
    return expression;
  }
  async showNewVersionPopup() {
    const modalContaner = document.createElement("ez-modal-container");
    const appLabel = await this.getAppLabel();
    modalContaner.modalTitle = this.getMessage("snkApplication.newVersionPopup.title", { screenName: appLabel });
    modalContaner.okButtonLabel = this.getMessage("snkApplication.newVersionPopup.okButton");
    modalContaner.cancelButtonLabel = this.getMessage("snkApplication.newVersionPopup.cancelButton");
    const modalText = document.createElement("p");
    modalText.innerText = this.getMessage("snkApplication.newVersionPopup.info");
    modalText.className = "ez-text";
    modalContaner.appendChild(modalText);
    modalContaner.addEventListener("ezModalAction", this.newVersionPopupEventListener.bind(this));
    const removePopup = await ApplicationUtils.showPopup({ content: modalContaner });
    this._removeVersionLayoutPopup = async () => {
      await removePopup();
      await this.processPendingActions(this.NEW_VERSION_POPUP_LOCKER);
    };
  }
  async newVersionPopupEventListener(e) {
    if (e.detail === "LOAD")
      return;
    if (e.detail === "OK") {
      Workspace.setScreenToUseV3Layout();
    }
    if (e.detail === "CANCEL") {
      Workspace.setScreenToUseOldLayout();
    }
    this._popUp.opened = false;
    if (this._removeVersionLayoutPopup) {
      await this._removeVersionLayoutPopup();
    }
  }
  async handleShowNewVersionPopup() {
    if (this.hasToShowNewVersionPopup()) {
      await this.showNewVersionPopup();
    }
  }
  hasToShowNewVersionPopup() {
    const urlParams = new URLSearchParams(window.location.search);
    const firstLoadConv = urlParams.get("firstLoadConv");
    return firstLoadConv && firstLoadConv === "S";
  }
  registerPkChangeListener() {
    if (window.hasOwnProperty("onhashchange")) {
      window.onhashchange = this.pkChangeListener.bind(this);
    }
    else {
      setInterval(this.pkChangeListener.bind(this), 100);
    }
  }
  componentWillLoad() {
    ApplicationContext.setContextValue("__SNK__APPLICATION__LOADING__", true);
    this._errorHandler = new SnkErrorHandler(this);
    this.messagesBuilder = new SnkMessageBuilder();
    ApplicationContext.setContextValue("__EZUI__UPLOAD__ADD__URL__", `${UrlUtils.getUrlBase()}/mge/upload/file`);
    ApplicationContext.setContextValue("__EZUI__SEARCH__OPTION__LOADER__", (searchArgument, fieldName, dataUnit, ctxOptions) => {
      return this.executeSearch(searchArgument, fieldName, dataUnit, ctxOptions);
    });
    ApplicationContext.setContextValue("__EZUI__SEARCH__PLUS__OPTION__LOADER__", (searchArgument, fieldName, dataUnit, ctxOptions) => {
      return this.executeSearch(searchArgument, fieldName, dataUnit, Object.assign(Object.assign({}, ctxOptions), { useSearchPlus: true }));
    });
    this.registerPkChangeListener();
    ErrorTracking.init();
    let legacyConfig = {
      gridLegacyConfig: this.gridLegacyConfigName,
      formLegacyConfig: this.formLegacyConfigName
    };
    ConfigStorage.preload(this.applicationResourceID, this.configName, legacyConfig);
    document.addEventListener("click", () => Workspace.applicationClick());
    this._waitingAppReady.forEach(resolve => resolve());
    this.setLayoutFormConfig();
  }
  async setLayoutFormConfig() {
    const response = await this._formConfigFetcher.fetchLayoutFormConfig('formColCfg.' + this.applicationResourceID);
    const config = isNaN(Number(response === null || response === void 0 ? void 0 : response.config)) ? null : Number(response === null || response === void 0 ? void 0 : response.config);
    this._LayoutFormConfigSingleton.setConfig(config);
  }
  connectedCallback() {
    this._isBrowserTypeElectron = UserAgentUtils.isElectron();
    ApplicationContext.setContextValue("__SNK__APPLICATION__", this);
    DataFetcher.addRequestListener(this._requestListener);
  }
  disconnectedCallback() {
    DataFetcher === null || DataFetcher === void 0 ? void 0 : DataFetcher.removeRequestListener(this._requestListener);
    this.removeShortcuts();
    if (this._lockManagerTimer)
      clearTimeout(this._lockManagerTimer);
    if (this._scrimWindowTimer)
      clearTimeout(this._scrimWindowTimer);
  }
  async componentDidLoad() {
    this.applicationLoading.emit(true);
    window.requestAnimationFrame(() => {
      ApplicationContext.setContextValue("__SNK__APPLICATION__LOADING__", false);
      this.applicationLoaded.emit(true);
      this.pkChangeListener();
    });
    ElementIDUtils.addIDInfo(this._element, `resource_${this.applicationResourceID}`);
    await this.handleShowNewVersionPopup();
    this.initKeyboardManager();
    if (this.enableLockManagerLoadingApp) {
      LockManager.addLockManagerCtxId(this._element);
      this.resolveApplicationReady();
    }
    else {
      this._applicationReady = true;
    }
  }
  async showScrimApp(active) {
    if (!this.enableLockManagerLoadingApp || !this._applicationReady || !active) {
      this._activeScrimWindow = false;
      if (this._scrimWindowTimer)
        clearTimeout(this._scrimWindowTimer);
      return;
    }
    this._activeScrimWindow = true;
    this._scrimWindowTimer = setTimeout(async () => {
      if (this._activeScrimWindow) {
        this._activeScrimWindow = false;
        clearTimeout(this._scrimWindowTimer);
      }
    }, this._maxTimerAppLoading);
  }
  async changeTemplateSkeleton(templateSkeletonType) {
    this._templateSkeleton = templateSkeletonType ? templateSkeletonType : this._templateSkeleton;
  }
  /**
   * Marca a aplicação para recarregar, opcionalmente especificando um tipo de esqueleto de carregamento.
   * @param {TEMPLATES_SKELETON} [templateSkeletonType] - O tipo de esqueleto de carregamento a ser exibido.
   * @returns {Promise<void>}
   * @async
   */
  async markToReload(templateSkeletonType) {
    if (!this.enableLockManagerLoadingApp)
      return;
    await this.changeTemplateSkeleton(templateSkeletonType);
    this._applicationReady = false;
    await LockManager.resetLocks(this._element, LockManagerOperation.APP_LOADING);
    this.resolveApplicationReady();
  }
  /**
   * Adiciona um bloqueio de carregamento à aplicação.
   * @param {boolean} [forceReady=false] - Se `true`, força a aplicação para o estado "não pronto" antes de adicionar o bloqueio.
   * @param {TEMPLATES_SKELETON} [templateSkeletonType] - O tipo de esqueleto de carregamento a ser exibido.
   * @returns {Promise<string>} O ID do bloqueio adicionado.
   * @async
   */
  async addLoadingLock(forceReady = false, templateSkeletonType) {
    if (!this.enableLockManagerLoadingApp)
      return;
    await this.changeTemplateSkeleton(templateSkeletonType);
    if (forceReady) {
      this._applicationReady = false;
      this._activeScrimWindow = this._applicationReady ? true : false;
      await LockManager.resetLocks(this._element, LockManagerOperation.APP_LOADING);
    }
    this.resolveApplicationReady();
    return await LockManager.lock(this._element, LockManagerOperation.APP_LOADING);
  }
  async resolveApplicationReady() {
    if (this._applicationReady) {
      return;
    }
    try {
      await this.checkTimeoutLimitLockManager();
      await LockManager.whenHasLock(this._element, LockManagerOperation.APP_LOADING);
      await LockManager.whenResolve(this._element, LockManagerOperation.APP_LOADING, 200);
      await LockManager.resetLocks(this._element, LockManagerOperation.APP_LOADING);
      this._applicationReady = true;
    }
    catch (error) {
      console.warn(error);
      this._applicationReady = true;
    }
  }
  stopTimeoutLockManager() {
    if (this._lockManagerTimer) {
      clearTimeout(this._lockManagerTimer);
    }
  }
  async checkTimeoutLimitLockManager() {
    this.stopTimeoutLockManager();
    if (this._applicationReady)
      return;
    this._lockManagerTimer = setTimeout(async () => {
      if (!this._applicationReady) {
        await LockManager.resetLocks(this._element, LockManagerOperation.APP_LOADING);
        this.stopTimeoutLockManager();
        this._applicationReady = true;
      }
    }, this._maxTimerAppLoading);
  }
  initKeyboardManager() {
    this._keyboardManager
      .bind("ctrl + g", Workspace.searchApp.bind(this), { description: this.getMessage("snkApplication.keyboard.shortcuts.searchApp") })
      .bind("ctrl + d", Workspace.showDesktop.bind(this), { description: this.getMessage("snkApplication.keyboard.shortcuts.showDesktop") })
      .bind("F1", Workspace.openHelp.bind(this), { description: this.getMessage("snkApplication.keyboard.shortcuts.openHelp") });
  }
  removeShortcuts() {
    this._keyboardManager.unbindAllShortcutKeys();
  }
  renderLoadingSkeleton() {
    if (!this.enableLockManagerLoadingApp)
      return;
    if (this._isBrowserTypeElectron) {
      return this.getSpinnerLoadingDefault();
    }
    else {
      switch (this._templateSkeleton) {
        case TEMPLATES_SKELETON.CUSTOM_TEMPLATE:
        case TEMPLATES_SKELETON.GRID:
          return this.getSkeletonTemplateGrid();
        case TEMPLATES_SKELETON.GRID_WITH_SIDEBAR:
          return this.getSkeletonTemplateGridWithSidebar();
        case TEMPLATES_SKELETON.GRID_WITH_PANEL:
          return this.getSkeletonTemplateGridWithPanel();
        case TEMPLATES_SKELETON.FORM_WITH_SIDEBAR:
          return this.getSkeletonTemplateFormWithSidebar();
        default:
          return this.getSkeletonTemplateGrid();
      }
    }
  }
  getLoadingVisibilityStyle() {
    return {
      visibility: this._applicationReady ? "hidden" : "initial",
      display: this._applicationReady ? "none" : "unset"
    };
  }
  getSkeletonTemplateGrid() {
    return (h("div", { class: "loading-hidden", style: this.getLoadingVisibilityStyle() }, h("div", { class: "ez-flex ez-flex--column ez-margin--large ez-margin-top--medium" }, h("div", { class: "ez-margin-bottom--medium" }, h("ez-skeleton", { count: 1, variant: "text", width: "20%", height: "35px", animation: "progress" })), h("div", { class: "" }, h("ez-skeleton", { count: 1, variant: "text", width: "70%", height: "25px", animation: "progress" }))), h("div", { class: "ez-flex ez-flex--justify-start skeleton-content-column ez-margin-horizontal--large", style: { height: "calc(-105px + 100vh)" } }, [1, 2, 3, 4].map((_, index) => (h("div", { class: "ez-margin-right--large", key: index, style: { width: "25%" } }, h("ez-skeleton", { count: this.getCountSkeleton(50, 10), variant: "text", width: "100%", height: "50px", animation: "progress", marginBottom: "10px" })))))));
  }
  getSkeletonTemplateGridWithSidebar() {
    return (h("div", { class: "loading-hidden", style: this.getLoadingVisibilityStyle() }, h("div", { class: "ez-flex ez-flex--column ez-margin--large ez-margin-top--medium" }, h("div", { class: "ez-margin-bottom--medium" }, h("ez-skeleton", { count: 1, variant: "text", width: "20%", height: "35px", animation: "progress" })), h("div", { class: "" }, h("ez-skeleton", { count: 1, variant: "text", width: "70%", height: "25px", animation: "progress" }))), h("div", { class: "ez-flex ez-flex--justify-start skeleton-content-column ez-margin-horizontal--large", style: { height: "calc(100vh - 160px)" } }, h("div", { class: "ez-flex ez-flex--column ez-margin-right--large", style: { width: "25%", overflow: "hidden" } }, Array(this.getCountSkeleton(30, 6)).fill(null).map((_, index) => h("ez-skeleton", { key: index, count: 1, variant: "text", width: this.getSkeletonRandomWidth(), height: "30px", animation: "progress", marginBottom: "10px" }))), h("div", { class: "ez-margin-right--large", style: { width: "75%" } }, h("ez-skeleton", { count: this.getCountSkeleton(50, 10), variant: "text", width: "100%", height: "50px", animation: "progress", marginBottom: "10px" })))));
  }
  getSkeletonTemplateGridWithPanel() {
    return (h("div", { class: "loading-hidden", style: this.getLoadingVisibilityStyle() }, h("div", { class: "ez-margin--medium ez-margin-top--medium ez-padding--medium" }, h("ez-skeleton", { count: 1, variant: "text", width: "70%", height: "25px", animation: "progress" })), h("div", { class: "ez-flex ez-margin--medium ez-margin-top--medium", style: { maxHeight: "calc(-105px + 100vh)", overflow: "hidden" } }, h("div", { class: "", style: { width: "70%", overflow: "hidden" } }, h("div", { class: "ez-padding--medium", style: { height: "50%" } }, h("ez-skeleton", { count: 1, variant: "text", width: "100%", height: "100%", animation: "progress" })), h("div", { class: "ez-padding--medium", style: {} }, h("ez-skeleton", { count: 1, variant: "text", width: "250px", height: "25px", animation: "progress" })), h("div", { class: "ez-flex ez-padding--medium", style: { height: "45%" } }, [1, 2].map(() => (h("div", { style: { width: "50%" } }, h("ez-skeleton", { count: 1, variant: "text", width: "100%", height: "100%", animation: "progress" })))))), h("div", { class: "ez-flex ez-flex--column ez-padding--medium", style: { width: "30%", overflow: "hidden" } }, Array(this.getCountSkeleton(30, 10)).fill(null).map((_, index) => h("ez-skeleton", { key: index, count: 1, variant: "text", width: "100%", height: "50px", animation: "progress", marginBottom: "10px" }))))));
  }
  getSkeletonTemplateFormWithSidebar() {
    return (h("div", { class: "loading-hidden", style: this.getLoadingVisibilityStyle() }, h("div", { class: "ez-margin--medium ez-margin-top--medium ez-padding--medium" }, h("ez-skeleton", { count: 1, variant: "text", width: "70%", height: "25px", animation: "progress" })), h("div", { class: "ez-flex ez-margin--medium ez-margin-top--medium", style: { maxHeight: "calc(-105px + 100vh)", overflow: "hidden" } }, h("div", { class: "ez-flex ez-flex--column ez-margin-right--large", style: { width: "25%", overflow: "hidden" } }, Array(this.getCountSkeleton(30, 6)).fill(null).map((_, index) => h("ez-skeleton", { key: index, count: 1, variant: "text", width: this.getSkeletonRandomWidth(), height: "30px", animation: "progress", marginBottom: "10px" }))), h("div", { class: "ez-flex ez-flex--column", style: { width: "75%" } }, h("div", { class: "ez-padding--medium", style: { width: "100%" } }, h("ez-skeleton", { count: 1, variant: "text", width: "30%", height: "25px", animation: "progress" })), h("div", { class: "ez-padding--medium", style: { height: "45%" } }, h("div", { class: "ez-flex", style: { width: "100%", height: "100%" } }, [1, 2, 3, 4].map((_, columnIndex) => (h("div", { key: columnIndex, class: "ez-padding-right--large", style: { width: "25%", overflow: "hidden" } }, Array(this.getCountSkeleton(50, 20)).fill(null).map((_, index) => h("ez-skeleton", { key: index, count: 1, variant: "text", width: "100%", height: "50px", animation: "progress", marginBottom: "10px" }))))))), h("div", { class: "ez-padding--medium", style: { width: "100%" } }, h("ez-skeleton", { count: 1, variant: "text", width: "30%", height: "25px", animation: "progress" })), h("div", { class: "ez-padding--medium", style: { height: "45%" } }, h("div", { class: "ez-flex", style: { width: "100%", height: "100%" } }, [1, 2, 3, 4].map((_, columnIndex) => (h("div", { key: columnIndex, class: "ez-padding-right--large", style: { width: "25%", overflow: "hidden" } }, Array(this.getCountSkeleton(50, 20)).fill(null).map((_, index) => h("ez-skeleton", { key: index, count: 1, variant: "text", width: "100%", height: "50px", animation: "progress", marginBottom: "10px" })))))))))));
  }
  getSpinnerLoadingDefault() {
    return (h("div", { class: "loading-hidden", style: this.getLoadingVisibilityStyle() }, h("div", { class: "ez-flex ez-size-height--full ez-size-width--full ez-flex--justify-center ez-flex--align-items-center spinner" }, h("ez-icon", { iconName: "sync", size: "x-large", class: "spin" }), h("span", { class: "ez-title ez-title--secondary ez-title--extra-large" }, this.getMessage("snkApplication.loading.text")))));
  }
  render() {
    return (h(Host, { style: {
        visibility: (!this.enableLockManagerLoadingApp || this._applicationReady) ? "unset" : "hidden",
        overflow: (!this.enableLockManagerLoadingApp || this._applicationReady) ? "unset" : "hidden"
      } }, h("div", null, h("ez-loading-bar", { ref: (ref) => this._requestListener.ezLoadingBar = ref }), h("ez-popup", { opened: false, ref: (ref) => this._popUp = ref, onEzClosePopup: () => this.closePopUp() }), h("ez-modal", { opened: false, ref: (ref) => this._rightModal = ref, "modal-size": "small", closeOutsideClick: true, closeEsc: true }), this.renderLoadingSkeleton(), this._activeScrimWindow && (h("div", { class: "ez-scrim ez-scrim--light", style: { cursor: "progress", zIndex: "var(--scrim-z-index)" } })))));
  }
  get _element() { return getElement(this); }
  static get watchers() { return {
    "loadByPK": ["watchPropHandler"]
  }; }
};
class PendingPromise {
  constructor(resolve, reject) {
    this.resolve = resolve;
    this.reject = reject;
  }
}
SnkApplication.style = snkApplicationCss;

export { SnkApplication as snk_application };
