/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
import { l as D, j as ie, o as re, p as se, q as ae, r as oe, s as ne, t as Q, u as d, v as j, w as le, x as ue, y as G, z as ce, A as pe, B as he, C as w, D as U, E as T, F as de, G as v, H as O, I as fe, n as _e } from "./utils.js";
import { p as me } from "./utilities.js";
import ye from "@arcgis/core/portal/PortalItem.js";
import be from "@arcgis/core/WebMap.js";
import ge from "@arcgis/core/WebScene.js";
import P from "@arcgis/core/layers/FeatureLayer.js";
import { getDeclaredVoxelMembers as De, getDeclaredPixelMembers as we } from "@arcgis/core/applications/Components/arcadeEditorUtils.js";
import { isNotNull as m, isNotUndefined as I } from "@arcgis/toolkit/predicate";
import { addLtrMark as Se, setValuesInString as R } from "@arcgis/toolkit/string";
import { s as C, f as J, a as Z, b as S, m as Ie } from "./fields.js";
import { CompletionItemKind as x, InsertTextFormat as V, InsertTextMode as M } from "vscode-languageserver-types";
import { log as h } from "@arcgis/toolkit/log";
import Ce from "@arcgis/core/core/Error.js";
import ve from "@arcgis/core/portal/Portal.js";
import { i as Fe } from "./monaco-importer.js";
import { g as Te } from "./runtime.js";
import { normalizeLocale as Pe } from "@arcgis/toolkit/intl";
import { filterApiLibraryForContext as xe } from "@arcgis/languages-api-utils";
import { Emitter as N, Uri as B } from "monaco-editor";
function Ve(s) {
  switch (s) {
    case "esriFieldTypeOID":
      return "oid";
    case "esriFieldTypeSmallInteger":
      return "small-integer";
    case "esriFieldTypeInteger":
      return "integer";
    case "esriFieldTypeBigInteger":
      return "big-integer";
    case "esriFieldTypeSingle":
      return "single";
    case "esriFieldTypeDouble":
      return "double";
    case "esriFieldTypeDate":
      return "date";
    case "esriFieldTypeDateOnly":
      return "date-only";
    case "esriFieldTypeTimeOnly":
      return "time-only";
    case "esriFieldTypeTimestampOffset":
      return "timestamp-offset";
    case "esriFieldTypeGUID":
      return "guid";
    case "esriFieldTypeGlobalID":
      return "global-id";
    case "esriFieldTypeString":
      return "string";
    case "esriFieldTypeGeometry":
      return "geometry";
    case "esriFieldTypeBlob":
      return "blob";
    case "esriFieldTypeRaster":
      return "raster";
    case "esriFieldTypeXML":
      return "xml";
    default:
      return "string";
  }
}
function Me(s) {
  return {
    fields: s.fields.map((e) => ({
      name: e.name,
      type: Ve(e.type),
      serverType: e.type,
      nullable: e.nullable
    }))
  };
}
function k(s) {
  return typeof s?.query == "object" && s.query ? s.query : {};
}
class Le {
  constructor(e) {
    this.itemId = e.itemId, this.portal = e.portal, this.serviceUrl = e.serviceUrl, this._requestOptions = e.requestOptions;
  }
  /**
   * Fetches information about the datastore.
   *
   * @public
   * @since 5.1
   * @param options - Additional options used for the request.
   * @returns Resolves to datastore information.
   */
  fetchInfo(e) {
    return this.portal.request(this._datastoreUrl, this._createRequestOptions(e));
  }
  /**
   * Fetches datasets for the datastore.
   *
   * @public
   * @since 5.1
   * @param options - Additional options used for the request.
   * @returns Resolves to an array of dataset information.
   */
  async fetchDatasets(e) {
    return (await this.portal.request(
      F(this._datastoreUrl, "datasets"),
      this._createRequestOptions(e)
    )).datasets;
  }
  /**
   * Fetches the table description for the provided table name.
   *
   * @public
   * @since 5.1
   * @param tableName - The table name.
   * @param options - Additional options used for the request.
   * @returns Resolves to the table description.
   */
  async fetchTableDescription(e, t) {
    if (!e)
      throw new Ce("portal:invalid-parameter", 'The "tableName" parameter must be provided.');
    const i = await this.portal.request(
      F(this._datastoreUrl, "tableDescription"),
      {
        ...this._createRequestOptions(t),
        query: {
          ...k(this._requestOptions),
          ...k(t),
          tableName: e
        }
      }
    );
    return Me(i);
  }
  get _datastoreUrl() {
    return F(this.serviceUrl, "datastores", encodeURIComponent(this.itemId));
  }
  _createRequestOptions(e) {
    return {
      ...this._requestOptions,
      ...e
    };
  }
}
function F(s, ...e) {
  const t = s.replaceAll(/\/+$/gu, ""), i = e.filter((r) => !!r).map((r) => r.replaceAll(/^\/+|\/+$/gu, ""));
  return [t, ...i].join("/");
}
const $e = {
  id: "ansi",
  keywords: [],
  functions: [],
  operators: [],
  specialChars: {
    likeWildcardAny: "%",
    likeWildcardOne: "_",
    identifierQuote: { start: '"', end: '"' },
    escapeKey: { start: null, end: null },
    escapeClause: { keyword: "ESCAPE", suffix: null }
  }
}, z = /* @__PURE__ */ new Map(), Ee = {
  ansi: async () => await Promise.resolve($e),
  bigquery: async () => (await import("./bigquery.js")).bigqueryDialect,
  postgres: async () => (await import("./postgres.js")).postgresDialect,
  sqlServer: async () => (await import("./sqlServer.js")).sqlServerDialect
};
async function Ae(s) {
  const e = z.get(s);
  if (e)
    return await e;
  const t = Ee[s]();
  return z.set(s, t), await t;
}
const qe = [
  "SELECT",
  "FROM",
  "WHERE",
  "GROUP",
  "BY",
  "HAVING",
  "ORDER",
  "LIMIT",
  "DISTINCT",
  "AS",
  "JOIN",
  "LEFT",
  "RIGHT",
  "FULL",
  "INNER",
  "OUTER",
  "CROSS",
  "ON",
  "USING",
  "AND",
  "OR",
  "NOT",
  "IN",
  "IS",
  "LIKE",
  "BETWEEN",
  "NULL",
  "TRUE",
  "FALSE",
  "ASC",
  "DESC"
], Ge = ["<=", ">=", "<>", "!=", "=", "<", ">", "+", "-", "*", "/", "%", "||"], Ue = (s, e = {}) => {
  const t = new Set(e.baseKeywords ?? qe);
  for (const r of s.keywords)
    t.add(r.toUpperCase());
  const i = new Set(e.baseOperators ?? Ge);
  for (const r of s.operators)
    i.add(r);
  return {
    keywords: Array.from(t),
    functions: s.functions,
    operators: Array.from(i),
    specialChars: s.specialChars
  };
}, _ = {
  sqlServer: "sql-layer-sql-server",
  postgres: "sql-layer-postgres",
  bigquery: "sql-layer-bigquery"
}, W = _.postgres, Oe = {
  [_.sqlServer]: "sqlServer",
  [_.postgres]: "postgres",
  [_.bigquery]: "bigquery"
  // snowflake and oracle should be prioritized next
};
function Re(s) {
  return Oe[s];
}
async function Ne(s) {
  return Ue(await Ae(Re(s)));
}
const Be = /^[A-Za-z_][A-Za-z0-9_$]*$/u;
function ke(s) {
  return s === "esriDBMS_PostgreSQL" ? W : s === "esriDBMS_SQLServer" ? _.sqlServer : W;
}
function It(s) {
  return s.trim().toLowerCase();
}
function ze(s) {
  return s.specialChars.identifierQuote;
}
function We(s, e) {
  const t = s.trim();
  return t ? Be.test(t) ? e.keywords.includes(t.toUpperCase()) : !0 : !1;
}
function X(s, e) {
  const t = s.trim();
  if (!t || !We(t, e))
    return t;
  const i = ze(e), r = t.replaceAll(i.end, `${i.end}${i.end}`);
  return `${i.start}${r}${i.end}`;
}
function He(s, e) {
  return s.split(".").map((t) => X(t, e)).join(".");
}
function Ct(s) {
  return s.split(".").at(-1) ?? s;
}
function Ke(s) {
  return Ne(ke(s));
}
async function Qe(s, e) {
  const t = new P({ url: `${s.url}/${e.relatedTableId}` });
  return await t.load(), t;
}
function L(s) {
  return (e, t) => {
    if (e.type === "oid")
      return -1;
    if (t.type === "oid")
      return 1;
    if (w(s)) {
      if (e.name === s.subtypeField)
        return -1;
      if (t.name === s.subtypeField)
        return 1;
    }
    if (T(s)) {
      if (e.name === s.typeIdField)
        return -1;
      if (t.name === s.typeIdField)
        return 1;
    }
    return e.name.localeCompare(t.name, "en", { sensitivity: "base" });
  };
}
function H(s, e) {
  return s?.every((t) => t.domains?.[e.name]?.type === "inherited") ?? !1;
}
const je = /^[a-z_$][a-z0-9_$]*$/giu;
function $(s, e = !0) {
  return s.match(je) ? `${e ? "." : ""}${s}` : `["${s}"]`;
}
function Y(s, e) {
  return s ? `${s}${$(e)}` : e;
}
function K(s) {
  return ce(s) ? s.portalItem : null;
}
function vt(s, e, t = !1) {
  let i = e;
  const r = [], a = [];
  return C(s).forEach((o) => {
    i && (i += `  
  
`), i += `**${o.name}** (${o.alias})  
${o.type}`, o.description && (i += `  
'${o.description}`);
    const p = Z(o), c = $(o.name, !1), g = S(o);
    if (r.push({
      name: o.name,
      description: g,
      type: p,
      completion: {
        label: o.name,
        detail: g,
        insertText: c,
        insertTextMode: M.asIs,
        insertTextFormat: V.PlainText,
        kind: x.Field
      }
    }), t) {
      if (!o.alias || o.alias.toLowerCase() === o.name.toLowerCase())
        return;
      let f = `**${o.alias}**  
${o.type}`;
      o.description && (f += `  
'${o.description}`), a.push({
        name: o.alias,
        description: o.name,
        type: p,
        completion: {
          label: o.alias,
          detail: o.name,
          insertText: c,
          insertTextMode: M.asIs,
          insertTextFormat: V.PlainText,
          kind: x.Field,
          documentation: { kind: "markdown", value: f }
        }
      });
    }
  }), [[...r, ...a], i];
}
function Ft(s, e) {
  let t = e;
  const i = [];
  return s.forEach((r) => {
    t && (t += `  
  
`), t += `**${r.name}**  
${r.type}`, r.name && (t += `  
'${r.name}`), i.push({
      name: r.name,
      description: r.name,
      // pixel members are always arrays
      type: "array",
      completion: {
        label: r.name,
        detail: r.name,
        insertText: $(r.name, !1),
        insertTextMode: M.asIs,
        insertTextFormat: V.PlainText,
        kind: x.Field
      }
    });
  }), [i, t];
}
class ee {
  constructor(e, t, i) {
    this._profile = e, this._label = t, this.description = i, this.filterDescription = !1;
  }
  /**
   * Returns the label string.
   */
  getLabel() {
    return this._label == null ? "" : typeof this._label == "string" ? Se(this._label) : R(this._profile?.intlStrings[this._label.code], this._label.formatValues);
  }
  /**
   * Returns the description string.
   */
  getDescription() {
    return this.description == null ? "" : typeof this.description == "string" ? this.description : R(this._profile?.intlStrings[this.description.code], this.description.formatValues);
  }
  /**
   * Returns true if the item pass the filter test
   */
  passFilter(e) {
    return !e || e.test(this.getLabel()) ? !0 : this.filterDescription && e.test(this.getDescription());
  }
}
class E extends ee {
  constructor(e) {
    super(e.profile, e.label, e.description ?? e.declaration?.description), this.declaration = e.declaration ?? {}, this.name = e.declaration?.name ?? "", this.snippet = e.snippet ?? "", this.nonInteractive = e.nonInteractive ?? !1, this.filterDescription = e.filterDescription ?? !1, this.icon = e.icon;
  }
}
class l extends E {
  constructor(e) {
    super(e), this.type = "text", this.isCollection = !1, this.type = e.declaration?.type ?? "text";
  }
  getDescription() {
    return this.description == null ? this._profile?.intlStrings[this.type.toLowerCase()] ?? "" : super.getDescription();
  }
  toProfileVariableDefinition() {
    return { type: this.type, name: "", ...this.declaration };
  }
}
class Je extends E {
  constructor(e) {
    super(e), this.type = "array", this.isCollection = !1, this.elementType = e.declaration?.elementType ?? { type: "number", name: "number" };
  }
  getDescription() {
    return this.description == null ? this._profile?.intlStrings[this.type.toLowerCase()] ?? "" : super.getDescription();
  }
  toProfileVariableDefinition() {
    return { type: this.type, elementType: this.elementType, name: "", ...this.declaration };
  }
}
class b extends E {
  constructor(e, t) {
    super(t), this.owner = e, this.isCollection = !0, this._loaded = !0, this.variables = [];
  }
  get breadcrumb() {
    if (this.owner) {
      const e = this.owner.breadcrumb;
      return e ? `${e} / ${this.name}` : this.name;
    }
    return this.name;
  }
  /**
   * Returns true if the collection has been loaded
   */
  get loaded() {
    return this._loaded;
  }
  /**
   * Returns an url to the associated information
   */
  get informationUrl() {
    return null;
  }
  get informationType() {
    return "";
  }
}
class u extends ee {
  constructor(e, t, i = [], r = !1) {
    super(e, t), this.variables = i, this.isHeader = r, this.type = "group", this.isCollection = !0;
  }
  passFilter() {
    return !0;
  }
}
class y extends b {
  constructor(e, t) {
    super(e, t), this.type = "dictionary", this.dictionaryVariables = [], this.loadPropertyDeclarations(t.declaration?.properties), this.snippet && this.dictionaryVariables.length && (this.variables = [new u(this._profile, this.snippet, this.dictionaryVariables)]);
  }
  async loadSource() {
  }
  loadPropertyDeclarations(e) {
    this.dictionaryVariables = this.createVariableInstances(e), this.variables = this.dictionaryVariables;
  }
  createVariableInstances(e) {
    if (!Array.isArray(e))
      return [];
    const t = [];
    return e.forEach((i) => {
      const r = this.createVariableInstance(i);
      r && t.push(r);
    }), t;
  }
  createVariableInstance(e) {
    const t = Y(this.snippet, e.name);
    switch (e.type) {
      case "number":
      case "text":
      case "boolean":
      case "date":
      case "dateOnly":
      case "time":
      case "geometry":
      case "knowledgeGraph":
        return new l({ profile: this._profile, declaration: e, label: t, snippet: t });
      case "pixel":
        return new Ye(this, { profile: this._profile, declaration: e, label: t, snippet: t });
      case "voxel":
        return new Xe(this, { profile: this._profile, declaration: e, label: t, snippet: t });
      case "feature":
        return new Ze(this, { profile: this._profile, declaration: e, label: t, snippet: t });
      case "featureSet":
        return new q(this, { profile: this._profile, declaration: e, label: t, snippet: t }, [
          new l({ profile: this._profile, label: t, description: "", snippet: t })
        ]);
      case "featureSetCollection":
        return new et(this, {
          profile: this._profile,
          declaration: e,
          label: t,
          snippet: t
        });
      case "dictionary":
        return new y(this, {
          profile: this._profile,
          declaration: e,
          label: t,
          snippet: t
        });
      case "array":
        return new Je({
          profile: this._profile,
          declaration: e,
          label: t,
          snippet: t
        });
      case "dataCatalogDatastore":
        return new tt(this, { profile: this._profile, declaration: e, label: t, snippet: t });
      default:
        return h("error", "Editor profile", "Invalid profile variable", { detail: { declaration: e } }), null;
    }
  }
  toProfileVariableDefinition() {
    return {
      type: this.type,
      name: "",
      ...this.declaration,
      properties: this.dictionaryVariables.map((e) => e.toProfileVariableDefinition())
    };
  }
}
class te extends b {
  constructor(e, t, i) {
    super(e, t), this.relationshipsProperties = i, this._source = null, this._loaded = !1, this._definition = t.declaration?.definition;
  }
  get title() {
    return d(this._source) ? this._source.title ?? "" : "";
  }
  get url() {
    return pe(this._source) ? this._source.url ?? "" : "";
  }
  get informationUrl() {
    return !this.loaded || !this.url ? null : he(this._source) ? `${this.url}/${this._source.layerId}` : this.url;
  }
  get informationType() {
    return this._profile?.intlStrings.layer ?? "layer";
  }
  async loadSource() {
    return m(this._loadPromise) && I(this._loadPromise) ? await this._loadPromise : (this._loadPromise = this._loadSource(), await this._loadPromise);
  }
  _getValueSnippet(e) {
    return ["feature", "voxel", "pixel"].includes(this.type) ? Y(this.snippet, e.name) : e.name;
  }
  _getSubtypeOrDomainNameSnippet(e) {
    return this.type !== "feature" ? null : w(this._source) && e.name === this._source.subtypeField ? `SubtypeName(${this.snippet})` : `DomainName(${this.snippet}, "${e.name}")`;
  }
  _getFieldProperty(e, t) {
    const i = this._getDomainDictionary(e);
    if (i)
      return i;
    const r = this._getValueSnippet(e);
    return new l({
      profile: this._profile,
      label: r,
      description: S(e),
      snippet: r,
      icon: J(e, t),
      filterDescription: !0
    });
  }
  _getMemberProperty(e) {
    const t = this._getValueSnippet(e);
    return new l({
      profile: this._profile,
      label: t,
      description: e.name,
      snippet: t,
      icon: Ie(e),
      filterDescription: !0
    });
  }
  _getDomainDictionary(e) {
    return U(this._source) ? w(this._source) && this._source.subtypeField ? this._getSubtypeDomainDictionary(e) : T(this._source) && this._source.typeIdField ? this._getFeatureTypeDomainDictionary(e) : this._getFieldDomainDictionary(e) : null;
  }
  _getSubtypeDomainDictionary(e) {
    if (!w(this._source))
      return null;
    if (!de(this._source))
      return e.name === this._source.subtypeField ? null : this._getFieldDomainDictionary(e);
    if (e.name === this._source.subtypeField) {
      const r = this._createDomainDictionary(e);
      return r.icon = "subtype", r.variables.push(this._getTypeOrSubtypeDomainGroup(this._source.subtypes, e)), r;
    }
    if (H(this._source.subtypes, e))
      return this._getFieldDomainDictionary(e);
    const t = this._getDomainValuesGroup(this._source.subtypes, e);
    if (!t)
      return null;
    const i = this._createDomainDictionary(e);
    return i.variables.push(t), i;
  }
  _getFeatureTypeDomainDictionary(e) {
    if (!T(this._source))
      return null;
    if (e.name === this._source.typeIdField) {
      const r = this._createDomainDictionary(e);
      return r.variables.push(this._getTypeOrSubtypeDomainGroup(this._source.types, e)), r;
    }
    if (H(this._source.types, e))
      return this._getFieldDomainDictionary(e);
    const t = this._getDomainValuesGroup(this._source.types, e);
    if (!t)
      return null;
    const i = this._createDomainDictionary(e);
    return i.variables.push(t), i;
  }
  _getFieldDomainDictionary(e) {
    if (!U(this._source))
      return null;
    const t = this._source.getFieldDomain(e.name);
    if (!v(t))
      return null;
    const i = this._getCodedValueDomainGroup(t, {
      code: "domainvalues"
    }), r = this._createDomainDictionary(e);
    return r.variables.push(i), r;
  }
  _getTypeOrSubtypeDomainGroup(e, t) {
    if (v(t.domain))
      return this._getCodedValueDomainGroup(t.domain, { code: "subtypes" });
    const i = e?.map((r) => {
      const a = O(r) ? r.code : r.id;
      return new l({
        profile: this._profile,
        label: `${a}`,
        description: r.name,
        snippet: `"${a}"`
      });
    }) ?? [];
    return new u(this._profile, { code: "subtypes" }, i);
  }
  _getCodedValueDomainGroup(e, t) {
    const i = e.codedValues.map(
      (r) => new l({
        profile: this._profile,
        label: `${r.code}`,
        description: r.name,
        snippet: `"${r.code}"`,
        filterDescription: !0
      })
    );
    return new u(this._profile, t, i);
  }
  _getDomainValuesGroup(e, t) {
    const i = [];
    return !e || e.length === 0 || (e.forEach((r) => {
      const a = r.domains?.[t.name];
      if (!a || fe(a) || !v(a))
        return;
      const n = S(t), o = this._getCodedValueDomainGroup(a, {
        code: "domainvaluesfortypeformat",
        formatValues: {
          fieldName: n,
          typeName: r.name
        }
      }), p = O(r) ? r.code : r.id, c = `${p}`, g = `"${p}""`, f = new y(this, {
        profile: this._profile,
        label: c,
        snippet: g,
        description: r.name,
        declaration: { name: n }
      });
      f.variables = [o], i.push(f);
    }), !i.length) ? null : new u(this._profile, { code: "domainvaluesbysubtypes" }, i);
  }
  _createDomainDictionary(e) {
    const t = this._getValueSnippet(e), i = S(e), r = new y(this, {
      profile: this._profile,
      label: t,
      description: i,
      snippet: t,
      icon: "form-dropdown",
      declaration: { name: e.name }
    }), a = new u(this._profile, i, [
      new l({
        profile: this._profile,
        label: t,
        description: "",
        snippet: t
      })
    ]);
    r.variables = [a];
    const n = this._getSubtypeOrDomainNameSnippet(e);
    return n && a.variables.push(
      new l({
        profile: this._profile,
        label: n,
        description: "",
        snippet: n
      })
    ), r;
  }
  async _getRelationshipsProperty() {
    if (!this.relationshipsProperties?.exposeRelationships || !this._profile?.supportFeatureSetFunctions)
      return null;
    const e = this._source;
    if (!_e(e))
      return null;
    const t = new u(this._profile, { code: "relationships" }), i = await Promise.all(
      e.relationships?.map(async (r) => {
        const a = await Qe(e, r);
        if (!Q(a) || r.relatedTableId === this.relationshipsProperties?.sourceTableId)
          return null;
        const n = `FeatureSetByRelationshipName(${this.snippet}, "${r.name}")`;
        return new q(
          this,
          {
            profile: this._profile,
            declaration: { definition: a },
            label: a.title,
            description: "",
            nonInteractive: !0
          },
          [new l({ profile: this._profile, label: n, description: "", snippet: n })],
          { exposeRelationships: !0, sourceTableId: e.layerId }
        );
      }) ?? []
    );
    return t.variables = i.filter(m), t.variables.length ? t : null;
  }
}
class A extends te {
  constructor(e, t, i, r = { exposeRelationships: !0 }) {
    super(e, t, r), this.type = i;
  }
  get title() {
    return d(this._source) ? this._source.title ?? "" : { code: this.type };
  }
  toProfileVariableDefinition() {
    return { type: this.type, name: "", ...this.declaration };
  }
}
class Ze extends A {
  constructor(e, t) {
    super(e, t, "feature", { exposeRelationships: !0 }), this.type = "feature";
  }
  async _loadSource() {
    if (this.loaded)
      return this._source;
    try {
      if (this._source = await j(this._definition), !this._source)
        throw new Error("Invalid definition");
      const e = d(this._source) ? this._source.title ?? "" : "";
      this.variables.push(
        new u(this._profile, e, [
          new l({
            profile: this._profile,
            label: this.snippet,
            description: "",
            snippet: this.snippet
          })
        ])
      );
      const t = new u(this._profile, { code: "values" });
      if (this.variables.push(t), le(this._source)) {
        const a = `Geometry(${this.snippet})`, n = new l({
          profile: this._profile,
          declaration: { name: a },
          label: a,
          description: "Geometry",
          snippet: a,
          icon: "shapes",
          filterDescription: !0
        });
        t.variables.push(n);
      }
      const i = this._source;
      C(this._source.fields).map((a) => i.fields.find((n) => n.name === a.name)).sort(L(i)).forEach((a) => {
        t.variables.push(this._getFieldProperty(a));
      });
      const r = await this._getRelationshipsProperty();
      r && this.variables.push(r);
    } catch (e) {
      h("error", "FeatureVariable", "Error with definition", { detail: { error: e, definition: this._definition } }), this._source = null;
    } finally {
      this._loaded = !0;
    }
    return this._source;
  }
}
class Xe extends A {
  constructor(e, t) {
    super(e, t, "voxel", { exposeRelationships: !1 }), this.type = "voxel", this._source = null;
  }
  async _loadSource() {
    if (this.loaded)
      return this._source;
    try {
      if (!ue(this._definition))
        throw new Error("Invalid definition - not a VoxelLayer");
      if (await this._definition.load(), this._source = this._definition, !this._source)
        throw new Error("Invalid definition");
      const e = d(this._source) ? this._source.title ?? "" : "";
      this.variables.push(
        new u(this._profile, e, [
          new l({
            profile: this._profile,
            label: this.snippet,
            description: "",
            snippet: this.snippet
          })
        ])
      );
      const t = new u(this._profile, { code: "values" });
      this.variables.push(t);
      const i = await De(this._source), r = this._source;
      C(this._source.fields).map((a) => r.fields.find((n) => n.name === a.name)).sort(L(r)).forEach((a) => {
        t.variables.push(this._getFieldProperty(a, i));
      });
    } catch (e) {
      h("error", this.type, "Error with definition", { detail: { error: e, definition: this._definition } }), this._source = null;
    } finally {
      this._loaded = !0;
    }
    return this._source;
  }
}
class Ye extends A {
  constructor(e, t) {
    super(e, t, "pixel", { exposeRelationships: !1 }), this.type = "pixel", this._source = null;
  }
  async _loadSource() {
    if (this.loaded)
      return this._source;
    try {
      if (!G(this._definition))
        throw new Error("Invalid definition - not an ImageryLayer");
      if (await this._definition.load(), this._source = this._definition, !this._source)
        throw new Error("Invalid definition");
      const e = d(this._source) ? this._source.title ?? "" : "";
      this.variables.push(
        new u(this._profile, e, [
          new l({
            profile: this._profile,
            label: this.snippet,
            description: "",
            snippet: this.snippet
          })
        ])
      );
      const t = new u(this._profile, { code: "values" });
      if (this.variables.push(t), !G(this._source))
        throw new Error("Invalid definition - not an ImageryLayer");
      (await we(this._source)).forEach((r) => {
        t.variables.push(this._getMemberProperty(r));
      });
    } catch (e) {
      h("error", this.type, "Error with definition", { detail: { error: e, definition: this._definition } }), this._source = null;
    } finally {
      this._loaded = !0;
    }
    return this._source;
  }
}
class q extends te {
  constructor(e, t, i = [], r) {
    super(e, t, r), this.featureSetSnippets = i, this.type = "featureSet";
  }
  get title() {
    return d(this._source) ? this._source.title ?? "" : { code: "featureset" };
  }
  async _loadSource() {
    if (this.loaded)
      return this._source;
    try {
      if (this._source = await j(this._definition), !this._source)
        throw new Error("Invalid definition");
      this.variables.push(new u(this._profile, this.title, this.featureSetSnippets, !0));
      const e = new u(this._profile, { code: "fields" });
      this.variables.push(e), e.variables = C(this._source.fields).sort(L(this._source)).map((i) => this._getFieldProperty(i));
      const t = await this._getRelationshipsProperty();
      t && this.variables.push(t);
    } catch (e) {
      h("error", this.type, "Error with definition", { detail: { error: e, definition: this._definition } }), this._source = null;
    } finally {
      this._loaded = !0;
    }
    return this._source;
  }
  toProfileVariableDefinition() {
    return { type: this.type, name: "", ...this.declaration, definition: this._definition };
  }
}
class et extends b {
  constructor(e, t) {
    super(e, t), this.type = "featureSetCollection", this._featureSetCollections = null, this._loaded = !1, this._definition = t.declaration?.definition;
  }
  get informationUrl() {
    return !this.loaded || !this._featureSetCollections ? null : typeof this._featureSetCollections.source != "string" ? me(K(this._featureSetCollections.source)) : null;
  }
  get informationType() {
    if (!this.loaded || !this._featureSetCollections)
      return "";
    if (typeof this._featureSetCollections.source == "string")
      return this._profile?.intlStrings.featureservice ?? "featureservice";
    switch (this._featureSetCollections.source.declaredClass) {
      case "esri.WebMap":
        return this._profile?.intlStrings.webmap ?? "webmap";
      case "esri.WebScene":
        return this._profile?.intlStrings.webscene ?? "webscene";
      default:
        return this._profile?.intlStrings.map ?? "map";
    }
  }
  async loadSource() {
    return m(this._loadPromise) && I(this._loadPromise) ? await this._loadPromise : (this._loadPromise = this._loadSource(), await this._loadPromise);
  }
  async _loadSource() {
    if (this.loaded)
      return this._featureSetCollections;
    try {
      if (this._featureSetCollections = await this._featureSetCollectionsFromDefinition(), !this._featureSetCollections)
        throw new Error("Invalid definition");
      const e = typeof this._featureSetCollections.source == "string" ? { code: this._featureSetCollections.source.endsWith("FeatureServer") ? "featureservice" : "mapservice" } : {
        code: "webmapformat",
        formatValues: {
          webMapTitle: K(this._featureSetCollections.source)?.title || "Untitled map"
        }
      }, t = new u(this._profile, e, [
        new l({
          profile: this._profile,
          label: this.snippet,
          description: "",
          snippet: this.snippet
        })
      ]), i = new u(this._profile, { code: "layers" }, this._featureSetCollections.layers), r = new u(this._profile, { code: "tables" }, this._featureSetCollections.tables);
      this.variables.push(t, i, r);
    } catch (e) {
      h("error", this.type, "Error with definition", { detail: { error: e, definition: this._definition } }), this._featureSetCollections = null;
    } finally {
      this._loaded = !0;
    }
    return this._featureSetCollections;
  }
  async _featureSetCollectionsFromDefinition() {
    return this._definition ? re(this._definition) ? await this._featureSetCollectionFromMap(this._definition) : se(this._definition) ? await this._featureSetCollectionFromUrl(this._definition.url) : ae(this._definition) ? await this._featureSetCollectionFromPortalItem(this._definition.portalItem) : null : null;
  }
  async _featureSetCollectionFromMap(e) {
    oe(e) && await e.loadAll(), await Promise.all(e.allTables.map(async (i) => await i.load()));
    const t = this._profile?.policy?.filterFsCollectionLayersFromMap ?? (() => !0);
    return {
      layers: this._convertWebMapLayersToVariables(e.allLayers.filter(t)),
      tables: this._convertWebMapLayersToVariables(e.allTables),
      source: e
    };
  }
  async _featureSetCollectionFromPortalItem(e) {
    const t = new ye(e);
    switch (await t.load(), t.type) {
      case "Web Map": {
        const i = new be({ portalItem: t });
        return await this._featureSetCollectionFromMap(i);
      }
      case "Web Scene": {
        const i = new ge({ portalItem: t });
        return await this._featureSetCollectionFromMap(i);
      }
      case "Feature Service":
        return await this._featureSetCollectionFromUrl(t.url);
      default:
        return h("error", this.type, "Unsupported portal item", { detail: { definition: e } }), null;
    }
  }
  async _featureSetCollectionFromUrl(e) {
    let t = e?.replace(/\/featureserver\/[0-9]*/iu, "/FeatureServer");
    if (t = t?.replace(/\/mapserver\/[0-9]*/iu, "/MapServer"), t = t?.split("?")[0], !t)
      return null;
    const i = await ne(t), r = Promise.all(
      i.layers.map(async (p) => {
        const c = new P({ url: `${t}/${p.id}` });
        return await c.load(), this._createFeatureSetVariable(c);
      })
    ), a = Promise.all(
      i.tables.map(async (p) => {
        const c = new P({ url: `${t}/${p.id}` });
        return await c.load(), this._createFeatureSetVariable(c);
      })
    ), [n, o] = await Promise.all([r, a]);
    return { layers: n, tables: o, source: t };
  }
  _convertWebMapLayersToVariables(e) {
    const t = [];
    return e.toArray().reverse().forEach((i) => {
      if (Q(i)) {
        t.push(this._createFeatureSetVariable(i, !0));
        return;
      }
    }), t;
  }
  _createFeatureSetVariable(e, t = !1) {
    return new q(
      this,
      {
        profile: this._profile,
        declaration: { name: e.title ?? "", definition: e },
        label: t ? e.title : e.sourceJSON.name ?? e.title,
        description: "",
        nonInteractive: !0
      },
      this._makeFeatureSetSnippets(e, t)
    );
  }
  _makeFeatureSetSnippets(e, t = !1) {
    if (!this._profile?.supportFeatureSetFunctions)
      return [];
    if (t) {
      const i = `FeatureSetById(${this.snippet}, "${e.id}")`, r = `FeatureSetByName(${this.snippet}, "${e.title}")`;
      return [
        new l({ profile: this._profile, label: i, description: "", snippet: i }),
        new l({ profile: this._profile, label: r, description: "", snippet: r })
      ];
    } else {
      const i = `FeatureSetById(${this.snippet}, "${e.layerId}")`;
      return [new l({ profile: this._profile, label: i, description: "", snippet: i })];
    }
  }
  toProfileVariableDefinition() {
    return { type: this.type, name: "", ...this.declaration, definition: this._definition };
  }
}
class tt extends b {
  constructor(e, t) {
    super(e, t), this.type = "dataCatalogDatastore", this._catalogDatastore = null, this._datastore = null, this._loaded = !1, this._definition = t.declaration?.definition;
  }
  _serializeDefinitionFromInstance(e) {
    return {
      id: e.itemId ?? "",
      serviceUrl: e.serviceUrl ?? "",
      portal: { url: e.portal?.url ?? "" }
    };
  }
  _getSerializedDefinition() {
    const e = this.declaration.definition;
    if (e)
      return D(e) ? e : this._serializeDefinitionFromInstance(e);
    if (D(this._definition))
      return this._definition;
    if (this._catalogDatastore)
      return this._serializeDefinitionFromInstance(this._catalogDatastore);
    if (this._definition)
      return this._serializeDefinitionFromInstance(this._definition);
  }
  async loadSource() {
    return m(this._loadPromise) && I(this._loadPromise) ? await this._loadPromise : (this._loadPromise = this._loadSource(), await this._loadPromise);
  }
  async _loadSource() {
    if (this.loaded)
      return this._datastore;
    try {
      if (!this._definition)
        throw new Error("No definition provided");
      D(this._definition) ? this._catalogDatastore = await this._dataCatalogDatastoreFromDefinition(this._definition) : this._catalogDatastore = this._definition;
      const e = this._catalogDatastore;
      if (!e)
        throw new Error("Invalid definition");
      const t = await e.fetchInfo();
      this._datastoreInfo = t;
      const i = await e.fetchDatasets(), r = await Ke(t.databasePlatform), a = i.map(
        (n) => new it(
          this,
          {
            profile: this._profile,
            declaration: { name: n.name },
            label: n.name,
            description: n.type,
            snippet: He(n.name, r)
          },
          e,
          n,
          r
        )
      );
      this.variables = a, this._datastore = {
        tables: a,
        source: D(this._definition) ? this._definition : e,
        info: t
      };
    } catch (e) {
      h("error", this.type, "Error with definition", { detail: { error: e, definition: this._definition } }), this._datastore = null;
    } finally {
      this._loaded = !0;
    }
    return this._datastore;
  }
  get datastoreInfo() {
    return this._datastoreInfo;
  }
  get tableVariables() {
    return this.variables.filter(ie);
  }
  async _dataCatalogDatastoreFromDefinition(e) {
    const t = new ve({ url: e.portal.url });
    return await t.load(), new Le({
      itemId: e.id,
      serviceUrl: e.serviceUrl,
      portal: t
    });
  }
  toProfileVariableDefinition() {
    const e = this.declaration, t = this._getSerializedDefinition();
    return {
      type: this.type,
      name: "",
      ...e,
      ...t ? { definition: t } : {}
    };
  }
}
class it extends b {
  constructor(e, t, i, r, a) {
    super(e, t), this._catalogDatastore = i, this.datasetInfo = r, this._dialectSpec = a, this.type = "dictionary", this._fieldInfos = [], this._loaded = !1;
  }
  get fieldInfos() {
    return this._fieldInfos;
  }
  async loadSource() {
    return m(this._loadPromise) && I(this._loadPromise) ? await this._loadPromise : (this._loadPromise = this._loadFields(), await this._loadPromise);
  }
  async _loadFields() {
    if (this.loaded)
      return this._fieldInfos;
    try {
      const e = await this._catalogDatastore.fetchTableDescription(this.datasetInfo.name);
      this._fieldInfos = e.fields, this.variables = this._fieldInfos.map((t) => {
        const i = {
          name: t.name,
          alias: t.name,
          type: t.type
        };
        return new l({
          profile: this._profile,
          declaration: { type: Z(i) },
          label: t.name,
          // TODO: review with QL team / designer
          description: [t.serverType, t.nullable ? "nullable" : "not null"].filter(Boolean).join(" | "),
          snippet: X(t.name, this._dialectSpec),
          icon: J(i),
          filterDescription: !0
        });
      });
    } catch (e) {
      h("error", "DataCatalogDatastoreTableVariable", "Error loading dataset", {
        detail: { error: e, dataset: this.datasetInfo }
      }), this._fieldInfos = [];
    } finally {
      this._loaded = !0;
    }
    return this._fieldInfos;
  }
  toProfileVariableDefinition() {
    return {
      // TODO(editor-profile): this is a type dictionary for now, but should get its own type after
      // https://devtopia.esri.com/WebGIS/arcgis-web-components/issues/1473
      type: "dictionary",
      name: this.datasetInfo.name,
      description: this.datasetInfo.type
    };
  }
}
class Tt extends y {
  constructor(e, t, i = "en", r = {}) {
    super(void 0, {
      profile: null,
      declaration: { properties: [] }
    }), this.definition = e, this.intlStrings = t, this.locale = i, this.policy = r, this.variables = [], this._profile = this, this.loadPropertyDeclarations(e?.variables);
  }
  /**
   * Returns true if the profile supports feature set functions for snippets.
   */
  get supportFeatureSetFunctions() {
    return this.definition?.bundles?.includes("data-access") ?? !1;
  }
  /**
   * Returns the EditorProfile as a json. The EditorProfile may have been updated. This function allows to
   * get the new json representing mutations.
   */
  toEditorProfileDefinition() {
    return {
      ...this.definition,
      variables: this.dictionaryVariables.map((e) => e.toProfileVariableDefinition())
    };
  }
}
const rt = {
  locale: "en"
};
class Pt {
  // #endregion
  constructor(e, t) {
    this.languageId = e, this._apiConfig = t, this._onDidChange = new N(), this._modelToProfileMap = /* @__PURE__ */ new Map(), this._modelToApiContextMap = /* @__PURE__ */ new Map(), this._localeToApiLibraryPromiseMap = /* @__PURE__ */ new Map(), this._onModelContextDidChange = new N(), this._onDidModelContextChangeTimeout = -1, Fe().then((i) => {
      i.onWillDisposeModel((r) => {
        this.disposeForModel(r.uri);
      });
    });
  }
  // #region Protected methods
  _fireModelContextDidChange(e) {
    this._onDidModelContextChangeTimeout === -1 && (this._onDidModelContextChangeTimeout = window.setTimeout(() => {
      this._onDidModelContextChangeTimeout = -1, this._onModelContextDidChange.fire(e);
    }, 0));
  }
  _getApiKey(e) {
    return B.isUri(e) || (e = B.parse(e)), e.toString();
  }
  getWorkerHostExtension() {
  }
  // #endregion
  // #region Public methods
  get onDidChange() {
    return this._onDidChange.event;
  }
  /**
   * Dispose any cached resources for the model
   */
  disposeForModel(e) {
    const t = this._getApiKey(e);
    this._modelToProfileMap.delete(t), this._modelToApiContextMap.delete(t) && this._fireModelContextDidChange(t);
  }
  /**
   * Returns the editor profile for the given model id.
   * @param modelId The model id for which to get the editor profile.
   * @returns The editor profile for the model.
   */
  getEditorProfileForModel(e) {
    return this._modelToProfileMap.get(this._getApiKey(e));
  }
  /**
   * Returns the API context for the given model id.
   * Returns the default context if the model has no context.
   * @param modelId The model id for which to get the API context.
   * @returns The API context for the model.
   */
  getApiContextForModel(e) {
    return this._modelToApiContextMap.get(this._getApiKey(e)) ?? rt;
  }
  /**
   * Set or update api context for the given model id.
   * @param modelId The model id for which to set the context.
   * @param apiContext The api context to set.
   */
  updateApiContextForModel(e, t) {
    const i = this._getApiKey(e), r = this._modelToApiContextMap.get(i) ?? {};
    this._modelToApiContextMap.set(i, { ...r, ...t }), this._fireModelContextDidChange(i);
  }
  get onModelContextDidChange() {
    return this._onModelContextDidChange.event;
  }
  /**
   * Gets the API library for the given model id.
   * @param modelId The model id for which to get the API library.
   * @returns The API library for the model.
   */
  async getApiLibraryForModel(e) {
    const t = this.getApiContextForModel(e), i = this.getApiLibrary(t.locale ?? "en");
    return (await xe(i, t)).categories;
  }
  /**
   * The worker host is used by the worker to invoke methods on the main thread.
   */
  get workerHost() {
    if (!this._workerHost) {
      const t = Object.assign({
        getApiLibrary: async (i) => await this.getApiLibrary(i),
        getLanguageId: () => this.languageId
      }, this.getWorkerHostExtension());
      this._workerHost = t;
    }
    return this._workerHost;
  }
  // #endregion
  //#region Private methods
  async fetchApiLibrary(e) {
    try {
      const { apiPath: t, apiPrefix: i } = this._apiConfig, r = Te(`${t}/${i}${e}.json`), a = await fetch(r);
      return a.ok ? await a.json() : [];
    } catch {
      return [];
    }
  }
  async getApiLibrary(e) {
    const t = Pe(e);
    return this._localeToApiLibraryPromiseMap.has(t) || this._localeToApiLibraryPromiseMap.set(t, this.fetchApiLibrary(t)), await this._localeToApiLibraryPromiseMap.get(t) ?? [];
  }
  // #endregion
}
export {
  Le as D,
  Tt as E,
  Pt as L,
  ke as a,
  tt as b,
  He as c,
  W as d,
  Ct as e,
  vt as f,
  $ as g,
  Ne as h,
  Re as i,
  Ft as m,
  It as n,
  X as q,
  _ as s
};
