/* COPYRIGHT Esri - https://js.arcgis.com/1.2/LICENSE.txt */
import { jsPDF as R } from "jspdf";
import { g as z } from "./runtime.js";
import { a as k } from "./queryUtils.js";
import { Sanitizer as G } from "@esri/arcgis-html-sanitizer";
import * as A from "@esri/solution-common";
import * as I from "@arcgis/core/arcade";
import * as S from "@arcgis/core/intl";
function $(s, t) {
  const e = document.createElement("a");
  e.download !== void 0 && (e.href = URL.createObjectURL(new Blob([decodeURIComponent("%ef%bb%bf"), t.join("")], { type: "text/csv;charset=utf-8;" })), e.download = `${s}.csv` || "export.csv", e.style.visibility = "hidden", document.body.appendChild(e), e.click(), document.body.removeChild(e));
}
function W(s, t) {
  const e = t.map(
    (i) => Object.values(i).map((o) => `"${o}"`).join(",") + `\r
`
  );
  $(s, e);
}
var b;
(function(s) {
  s.A4 = "A4", s.ANSI_A = "ANSI A";
})(b || (b = {}));
class v {
  // Properties are public for testing purposes
  dataPath = "";
  lang = "en";
  title = "";
  fontProps = {
    fontResolutionInchesPerPoint: 1 / 72,
    fontFullHeightRatio: 1.28
  };
  imageOptions = {
    x: 0,
    y: 0,
    width: 0,
    height: 0
    // inches
  };
  lineOptions = {
    x1: 0,
    y1: 0,
    x2: 0,
    y2: 0,
    lineProperties: {
      thickness: 0.1,
      color: "000000",
      opacity: 1
      // 0..1
    }
  };
  pageOptions = {
    pageType: b.ANSI_A,
    width: 8.5,
    height: 11,
    leftMargin: 0.25,
    rightMargin: 0.25,
    topMargin: 0.25,
    bottomMargin: 0.25,
    drawNeatline: !1
  };
  rectangleOptions = {
    left: 0,
    top: 0,
    width: 8.5,
    height: 11,
    lineProperties: {
      thickness: 0.1,
      color: "000000",
      opacity: 1
      // 0..1
    },
    fillColor: "",
    fillOpacity: 1
    // 0..1
  };
  tableOptions = {
    lineProperties: {
      thickness: 0.1,
      color: "",
      opacity: 1
      // 0..1
    },
    textProperties: {
      left: 0,
      top: 0,
      fontPoints: 1,
      fontColor: "000000"
      // i.e., black
    }
  };
  textOptions = {
    left: 0,
    top: 0,
    fontPoints: 1,
    fontColor: "000000"
    // i.e., black
  };
  //-- Static methods ------------------------------------------------------------------------------------------------//
  /**
   * @class PDFCreator
   */
  static getPageSize(t) {
    switch (typeof t == "string" && (t = t === b.A4 ? b.A4 : b.ANSI_A), t) {
      case b.A4:
        return {
          width: 8.25,
          height: 11.708333
        };
      case b.ANSI_A:
        return {
          width: 8.5,
          height: 11
        };
    }
  }
  //-- Public methods ------------------------------------------------------------------------------------------------//
  /**
   * Adds a page to the document being created.
   *
   * @class PDFCreator
   */
  addPage() {
  }
  /**
   * Calculates a color intensity that emulates an opacity being applied to it.
   *
   * @param colorIntensity Color value to start with; range 0..1
   * @param opacity Opacity to apply; range 0..1
   *
   * @return Color intensity emulating the application of opacity. It works by applying the opacity value
   * to the input colorIntensity and adding the inverse of the opacity. E.g., if opacity is 1, the original
   * colorIntensity is returned; if opacity is 0, 1 is returned; if opacity is 0.5; colorIntensity/2 + 0.5 is
   * returned. It's odd, but when applied to an RGB value, it produces the desired effect.
   *
   * @class PDFCreator
   */
  applyOpacity(t, e) {
    return t * e + 1 * (1 - e);
  }
  /**
   * Draws a PNG image into the page.
   *
   * @params imageDataUrl Image to add to page
   * @params options Position information
   *
   * @class PDFCreator
   */
  drawImage(t, e) {
  }
  /**
   * @class PDFCreator
   */
  drawLine(t) {
    const e = {
      ...this.lineOptions,
      ...t
    };
    e.lineProperties = {
      ...this.lineOptions.lineProperties,
      ...t.lineProperties
    }, this.updateLineProperties(e.lineProperties), this.lineOptions = e;
  }
  /**
   * @class PDFCreator
   */
  drawNeatline(t = {
    thickness: 5e-3,
    color: "0000ff",
    opacity: 0.2
  }) {
    this.drawRectangle({
      left: 0,
      top: 0,
      width: this.pageOptions.width - this.pageOptions.leftMargin - this.pageOptions.rightMargin,
      height: this.pageOptions.height - this.pageOptions.topMargin - this.pageOptions.bottomMargin,
      lineProperties: t
    });
  }
  /**
   * @class PDFCreator
   */
  drawRectangle(t) {
    const e = {
      ...this.rectangleOptions,
      ...t
    };
    e.lineProperties = {
      ...this.lineOptions.lineProperties,
      ...t.lineProperties
    }, this.updateLineProperties(e.lineProperties), (this.rectangleOptions.fillColor !== e.fillColor || this.rectangleOptions.fillOpacity !== e.fillOpacity) && this.setFillColor(e.fillColor, e.fillOpacity), this.rectangleOptions = e;
  }
  /**
   * @class PDFCreator
   */
  drawTable(t, e) {
    const i = {};
    i.lineProperties = {
      ...this.tableOptions.lineProperties,
      ...e.lineProperties
    }, i.textProperties = {
      ...this.tableOptions.textProperties,
      ...e.textProperties
    }, this.tableOptions.textProperties.fontPoints !== i.textProperties.fontPoints && this.setFontSize(i.textProperties.fontPoints), this.tableOptions.textProperties.fontColor !== i.textProperties.fontColor && this.setFontColor(i.textProperties.fontColor), this.updateLineProperties(i.lineProperties), this.tableOptions = i;
  }
  /**
   * @class PDFCreator
   */
  drawText(t, e) {
    const i = {
      ...this.textOptions,
      ...e
    };
    this.textOptions.fontPoints !== i.fontPoints && this.setFontSize(i.fontPoints), this.textOptions.fontColor !== i.fontColor && this.setFontColor(i.fontColor), this.textOptions = i;
  }
  /**
   * Calculates document units from top of font ascenders to baseline.
   *
   * @class PDFCreator
   */
  fontAscenderBaselineHeight(t) {
    return t * this.fontProps.fontResolutionInchesPerPoint;
  }
  /**
   * Calculates document units from top of font ascenders to bottom of descenders.
   *
   * @class PDFCreator
   */
  fontAscenderDescenderHeight(t) {
    return this.fontProps.fontFullHeightRatio * this.fontAscenderBaselineHeight(t);
  }
  /**
   * Returns the name of the font file supporting the specified locale.
   *
   * @param lang Locale such as "en" or "zh-tw"
   * @returns Font name, e.g., "0b7681dc140844ee9f409bdac249fbf0-japanese"
   *
   * @class PDFCreator
   */
  getFontFileName(t) {
    let e = "0b7681dc140844ee9f409bdac249fbf0-general";
    return t === "ja" ? e = "0b7681dc140844ee9f409bdac249fbf0-japanese" : t === "ko" ? e = "0b7681dc140844ee9f409bdac249fbf0-korean" : t === "zh-cn" ? e = "0b7681dc140844ee9f409bdac249fbf0-simplified-chinese" : (t === "zh-hk" || t === "zh-tw") && (e = "0b7681dc140844ee9f409bdac249fbf0-traditional-chinese"), e;
  }
  /**
   * Estimates with width of a string.
   *
   * @param text String to estimate
   * @param fontSize Text size in points
   * @returns Estimated width of text using (points x 1/72 inches/point) * 0.6;
   * need to override this generalized function with a specific PDF generator;
   * the 0.6 width:height ratio comes from https://www.fhwa.dot.gov/publications/research/safety/98057/ch03.cfm#width
   *
   * @class PDFCreator
   */
  getTextWidth(t, e) {
    return t.length * e * this.fontProps.fontResolutionInchesPerPoint * 0.6;
  }
  /**
   * @class PDFCreator
   */
  hexToRGB(t, e = 1) {
    const i = /^([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);
    return i ? {
      r: this.applyOpacity(parseInt(i[1], 16) / 255, e),
      g: this.applyOpacity(parseInt(i[2], 16) / 255, e),
      b: this.applyOpacity(parseInt(i[3], 16) / 255, e)
    } : {
      r: 0,
      g: 0,
      b: 0
    };
  }
  /**
   * @class PDFCreator
   */
  async initialize(t = {}, e = "", i = "en", o = "", r = !1) {
    if (JSON.stringify(t) !== "{}") {
      this.pageOptions.pageType = t.pageType === b.A4 ? b.A4 : b.ANSI_A;
      const n = v.getPageSize(this.pageOptions.pageType);
      this.pageOptions.width = n.width, this.pageOptions.height = n.height, this.pageOptions.leftMargin = t.leftMargin ?? this.pageOptions.leftMargin, this.pageOptions.rightMargin = t.rightMargin ?? this.pageOptions.rightMargin, this.pageOptions.topMargin = t.topMargin ?? this.pageOptions.topMargin, this.pageOptions.bottomMargin = t.bottomMargin ?? this.pageOptions.bottomMargin;
    }
    return this.dataPath = e, this.lang = i, this.title = o || "PDF Document", this.pageOptions.drawNeatline = r, Promise.resolve();
  }
  /**
   * @class PDFCreator
   */
  save() {
  }
  /**
   * @class PDFCreator
   */
  setDrawColor(t, e = 1) {
  }
  /**
   * @class PDFCreator
   */
  setFillColor(t, e = 1) {
  }
  /**
   * @class PDFCreator
   */
  setFont(t) {
    return Promise.resolve();
  }
  /**
   * @class PDFCreator
   */
  setFontColor(t) {
  }
  /**
   * @class PDFCreator
   */
  setFontSize(t) {
  }
  /**
   * @class PDFCreator
   */
  setLang(t) {
    return this.lang !== t ? (this.lang = t, this.setFont(t)) : Promise.resolve();
  }
  /**
   * @class PDFCreator
   */
  setLineWidth(t) {
  }
  updateLineProperties(t) {
    this.lineOptions.lineProperties.thickness !== t.thickness && this.setLineWidth(t.thickness), (this.lineOptions.lineProperties.color !== t.color || this.lineOptions.lineProperties.opacity !== t.opacity) && this.setDrawColor(t.color, t.opacity), this.lineOptions.lineProperties = t;
  }
}
class H extends v {
  jsDoc;
  constructor(t = null) {
    super(), this.jsDoc = t;
  }
  //-- Public methods ------------------------------------------------------------------------------------------------//
  /**
   * Adds a page to the document being created.
   *
   * @class PDFCreator_jsPDF
   */
  addPage() {
    super.addPage(), this.jsDoc.addPage(), this.pageOptions.drawNeatline && this.drawNeatline();
  }
  /**
   * Converts a locale into a jsPDF language code.
   *
   * @param lang Locale such as "en" or "en-gb"
   * @returns jsPDF_lang_code jsPDF language code such as "en" or "en-GB", mapping AGO locales "it-it" & "pt-pt"
   * into "it" & "pt", respectively, to match jsPDF offering
   *
   * @class PDFCreator_jsPDF
   */
  convertLocaleToJsPDFLanguageCode(t) {
    let e;
    if (t === "it-it")
      e = "it";
    else if (t === "pt-pt")
      e = "pt";
    else {
      const i = t.split("-");
      i.length === 1 ? e = t : e = i[0] + "-" + i[1].toUpperCase();
    }
    return e;
  }
  /**
   * Draws a PNG image into the page.
   *
   * @params imageDataUrl Image to add to page
   * @params options Position information
   *
   * @class PDFCreator
   */
  drawImage(t, e) {
    this.jsDoc.addImage(t, "PNG", e.x, e.y, e.width, e.height, "", "NONE", 0);
  }
  /**
   * @class PDFCreator_jsPDF
   */
  drawLine(t) {
    super.drawLine(t), this.jsDoc.line(
      this.pageOptions.leftMargin + this.lineOptions.x1,
      this.pageOptions.topMargin + this.lineOptions.y1,
      this.pageOptions.leftMargin + this.lineOptions.x2,
      this.pageOptions.topMargin + this.lineOptions.y2,
      this.lineOptions.lineProperties.color ? "S" : ""
      // line vs. nothing
    );
  }
  /**
   * @class PDFCreator_jsPDF
   */
  drawRectangle(t) {
    super.drawRectangle(t), this.jsDoc.rect(
      this.pageOptions.leftMargin + this.rectangleOptions.left,
      this.pageOptions.topMargin + this.rectangleOptions.top,
      this.rectangleOptions.width,
      this.rectangleOptions.height,
      this.rectangleOptions.lineProperties.color ? this.rectangleOptions.fillColor ? "FD" : "S" : this.rectangleOptions.fillColor ? "F" : ""
      // fill only vs. nothing
    );
  }
  /**
   * @class PDFCreator_jsPDF
   */
  drawTable(t, e) {
    super.drawTable(t, e);
    const i = this.pageOptions.leftMargin + this.textOptions.left, o = this.pageOptions.topMargin + this.textOptions.top;
    this.jsDoc.text(t[0][0], i, o);
  }
  /**
   * @class PDFCreator_jsPDF
   */
  drawText(t, e) {
    super.drawText(t, e);
    let i = this.pageOptions.leftMargin + this.textOptions.left;
    if (this.lang === "ar" || this.lang === "he") {
      const r = this.jsDoc.context2d.measureText(t).width * this.fontProps.fontResolutionInchesPerPoint;
      i = this.pageOptions.width - this.pageOptions.leftMargin - r - this.textOptions.left;
    }
    const o = this.pageOptions.topMargin + this.textOptions.top + this.fontAscenderBaselineHeight(this.textOptions.fontPoints);
    this.jsDoc.text(t, i, o);
  }
  /**
   * Estimates with width of a string.
   *
   * @param {string} text String to estimate
   * @param fontSize Text size in points
   * @returns {number} Estimated width of text in doc units
   *
   * @class PDFCreator_jsPDF
   */
  getTextWidth(t, e) {
    return this.jsDoc.getStringUnitWidth(t) * e / this.jsDoc.internal.scaleFactor;
  }
  /**
   * @class PDFCreator_jsPDF
   */
  async initialize(t = {}, e = "", i = "en", o = "", r = !1) {
    await super.initialize(t, e, i, o, r), this.jsDoc || (this.jsDoc = new R({
      format: t.pageType === b.A4 ? "a4" : "letter",
      orientation: "portrait",
      putOnlyUsedFonts: !0,
      unit: "in"
    })), this.jsDoc.setDocumentProperties({
      title: this.title,
      keywords: "Created with ArcGIS Online"
    }), this.pageOptions.drawNeatline && this.drawNeatline(), await this.setFont(i);
  }
  /**
   * @class PDFCreator_jsPDF
   */
  save() {
    this.jsDoc.save(this.title + ".pdf");
  }
  /**
   * @class PDFCreator_jsPDF
   */
  setDrawColor(t, e = 1) {
    const i = this.hexToRGB(t, e);
    this.jsDoc.setDrawColor(i.r.toString(), i.g.toString(), i.b.toString());
  }
  /**
   * @class PDFCreator_jsPDF
   */
  setFillColor(t, e = 1) {
    const i = this.hexToRGB(t, e);
    this.jsDoc.setFillColor(i.r.toString(), i.g.toString(), i.b.toString());
  }
  /**
   * @class PDFCreator_jsPDF
   */
  setFont(t) {
    this.jsDoc.setLanguage(this.convertLocaleToJsPDFLanguageCode(t));
    const e = this.getFontFileName(t);
    return this.jsDoc.existsFileInVFS(e + ".ttf") ? (this.jsDoc.setFont(e, "normal", "normal"), Promise.resolve()) : fetch(this.dataPath + e + ".txt").then((i) => i.text()).then((i) => (this.jsDoc.addFileToVFS(e + ".ttf", i), this.jsDoc.addFont(e + ".ttf", e, "normal", "normal"), this.jsDoc.setFont(e, "normal", "normal"), Promise.resolve()));
  }
  /**
   * @class PDFCreator_jsPDF
   */
  setFontColor(t) {
    const e = this.hexToRGB(t);
    this.jsDoc.setTextColor(e.r.toString(), e.g.toString(), e.b.toString());
  }
  /**
   * @class PDFCreator_jsPDF
   */
  setFontSize(t) {
    this.jsDoc.setFontSize(t);
  }
  /**
   * @class PDFCreator_jsPDF
   */
  setLineWidth(t) {
    this.jsDoc.setLineWidth(t);
  }
}
function B(s, t = {
  numAcross: 1,
  numDown: 1,
  x0: 0,
  y0: 0,
  width: 1,
  height: 1,
  horizGap: 0,
  vertGap: 0,
  lineProperties: {
    thickness: 0,
    color: "",
    opacity: 1
    // 0..1
  }
}) {
  for (let e = 0; e < t.numDown; ++e)
    for (let i = 0; i < t.numAcross; ++i)
      s.drawRectangle({
        left: t.x0 + i * (t.width + t.horizGap),
        top: t.y0 + e * (t.height + t.vertGap),
        width: t.width,
        height: t.height,
        lineProperties: t.lineProperties
      });
}
class J {
  // Properties are public for testing purposes
  PDFCreator;
  labelFormats;
  //-- Public methods ------------------------------------------------------------------------------------------------//
  /**
   * Add labels to a PDF doc, starting at the beginning of the specified PDF doc page.
   *
   * @param labels Array of labels; each label consists of one or more line strings
   * @param labelSpec Properties describing page dimensions of labels sheet
   * @param startingPageNum The 1-based page number to start printing labels into; page is assumed to be blank & to exist
   * @param heading Line to add at top of label page outside of labels
   * @param progressCallback Callback with percent done in range 0..100
   * @returns Promise which, when resolved, returns the 1-based page number of the last page containing labels
   *
   * @class PDFLabels
   */
  addLabelsToDoc(t, e, i, o, r) {
    return new Promise((n) => {
      const p = e.numLabelsAcross * e.numLabelsDown;
      let l, a, c, h;
      const f = e.labelWidth - 2 * e.labelPadding;
      let O = i;
      const w = e.pageProperties.topMargin - this.PDFCreator.pageOptions.topMargin;
      o && this.drawSupplementalText(o, 0, -0.1);
      for (let F = 0, g = 0; F < t.length; F++) {
        r && r(Math.round(F / t.length * 100));
        let d = t[F].map((y) => y.trim()).filter((y) => y.length > 0);
        if (d.length === 0)
          continue;
        g % p === 0 ? (g > 0 && (this.PDFCreator.addPage(), ++O, o && this.drawSupplementalText(o, 0, -0.1)), l = 0, c = 0, a = 0) : g % e.numLabelsDown === 0 && (c = ++l * (e.labelWidth + e.horizGapIn), a = 0);
        const m = 4;
        let u = e.fontSizePx;
        e.maxNumLabelLines < d.length && (u = Math.max(Math.floor(e.maxNumLabelLines / d.length * e.fontSizePx), m)), u = this._getFontSizeForOverlongLines(d, f, u, m), d = this._clipOverlongLines(d, f, u);
        const P = this.PDFCreator.fontAscenderDescenderHeight(u);
        h = w + a++ * (e.labelHeight + e.vertGapIn), d.forEach((y) => {
          this.PDFCreator.drawText(y, {
            left: c + e.labelPadding,
            top: h + e.labelPadding,
            fontPoints: u,
            fontColor: "000000"
          }), h += P;
        }), ++g;
      }
      r && r(100), n(O);
    });
  }
  drawLabelGuidelines(t, e = null) {
    e !== null && B(this.PDFCreator, {
      // Margins in the page spec are absolute but we draw in within the margins
      x0: t.pageProperties.leftMargin - this.PDFCreator.pageOptions.leftMargin,
      y0: t.pageProperties.topMargin - this.PDFCreator.pageOptions.topMargin,
      numAcross: t.numLabelsAcross,
      numDown: t.numLabelsDown,
      width: t.labelWidth,
      height: t.labelHeight,
      horizGap: t.horizGapIn,
      vertGap: t.vertGapIn,
      lineProperties: e
    });
  }
  /**
   * Draws supplemental text such as a heading or footer.
   *
   * @param text Text to draw
   * @param left Offset from left edge of document to left edge of text
   * @param top Offset from top of document to top of text
   */
  drawSupplementalText(t, e, i) {
    this.PDFCreator.drawText(t, {
      left: e,
      top: i,
      fontPoints: 6,
      fontColor: "000000"
    });
  }
  /**
   * Returns the UI descriptions of the label formats.
   *
   * @returns List of label format descriptions
   *
   * @class PDFLabels
   */
  getAvailableLabelFormats() {
    return this.labelFormats.length > 0 ? this.labelFormats.map((t) => t.descriptionPDF) : [];
  }
  /**
   * Returns the format of the specified label.
   *
   * @param averyPartNumber Avery® label base part number, e.g., "*60" (versus actual part numbers "5160", "8160",
   * "8460", "48160"--all of which are 1" x 2-5/8" rectangular labels)
   * @returns List of label format descriptions
   *
   * @class PDFLabels
   */
  getLabelFormat(t) {
    if (this.labelFormats.length > 0) {
      const e = this.labelFormats.filter((i) => t === i.descriptionPDF.averyPartNumber);
      return e.length > 0 ? e[0] : null;
    } else
      return null;
  }
  /**
   * Loads language font file and label formats into a jsPDF `doc` object.
   *
   * @param PDFCreator PDF-drawing library
   * @throws TypeError "startPDFLabelDoc is stomping on labelFormats property" if the `labelFormats` property
   * is found in doc before the label formats are loaded into the doc.
   *
   * @class PDFLabels
   */
  initialize(t) {
    return this.PDFCreator = t, this._loadLabelFormats(t.dataPath).then((e) => (this.labelFormats = e, Promise.resolve()));
  }
  /**
   * Removes duplicates and empties, trims label lines, and returns a sorted list.
   *
   * @class PDFLabels
   */
  removeDuplicates(t) {
    const i = t.filter((n) => Array.isArray(n) && n.length > 0).map((n) => n.map((p) => p.trim()).join("?")), o = {};
    return i.forEach((n) => o[n] = !0), Object.keys(o).sort().map((n) => n.split("?"));
  }
  //-- Private methods -----------------------------------------------------------------------------------------------//
  /**
   * Calculates the baseline position of the first line of text in a label.
   *
   * @param labelTop Offset from top of document to top of label
   * @param labelHeight Height of each label in doc units
   * @param numLabelLines Number of lines to be drawn in the label
   * @param fontHeight Height of text in doc units
   * @param verticalFontGap Spacing between lines of text in doc units
   * @returns Baseline position
   *
   * @class PDFLabels
   * @private
   */
  _calculateLabelFirstLineBase(t, e, i, o, r) {
    return t + e / 2 + (2 - i) / 2 * o + (1 - i) / 2 * r;
  }
  /**
   * Trims a set of text lines to fit within specified bounds.
   *
   * @param lines Text lines to be trimmed
   * @param maxTextWidth The maximum width permitted for the drawing of the text in doc units
   * @param fontSize Text size in points
   * @returns A copy of lines trimmed as necessary
   *
   * @class PDFLabels
   * @private
   */
  _clipOverlongLines(t, e, i) {
    const o = [];
    return t.forEach((r) => {
      if (r = r.trim(), this.PDFCreator.getTextWidth(r, i) > e) {
        do
          r = r.slice(0, -1);
        while (this.PDFCreator.getTextWidth(r, i) > e);
        r += "...";
      }
      o.push(r);
    }), o;
  }
  /**
   * Trims a set of text lines to fit within specified bounds.
   *
   * @param lines Text lines to be checked
   * @param maxTextWidth The maximum width permitted for the drawing of the text in doc units
   * @param preferredFontSize Initial text size in points
   * @param minimumFontSize The smallest acceptable font size in points
   * @returns The maximum of `minimumFontSize` and the font size in points that should help all lines
   * of the label to fit on the label
   *
   * @class PDFLabels
   * @private
   */
  _getFontSizeForOverlongLines(t, e, i, o) {
    let r = i;
    return t.forEach((n) => {
      if (n = n.trim(), this.PDFCreator.getTextWidth(n, r) > e)
        do
          --r;
        while (this.PDFCreator.getTextWidth(n, r) > e && r > o);
    }), r;
  }
  /**
   * Loads the label formats.
   *
   * @param dataPath Path to the library's data files
   * @returns Promise resolving to the label formats JSON
   *
   * @class PDFLabels
   * @private
   */
  async _loadLabelFormats(t) {
    return await (await fetch(t + "labelFormats.json")).json();
  }
}
function U(s, t, e, i = "", o = "") {
  V(s, t, e, i, o);
}
async function V(s, t, e, i = "", o = "") {
  const r = new H(void 0);
  await r.initialize(
    {
      pageType: "ANSI_A"
    },
    z("assets/arcgis-pdf-creator/"),
    "en",
    s
    // filename without ".pdf"
  );
  const n = new J();
  await n.initialize(r);
  const p = e.labelSpec;
  let l = 1;
  if (o) {
    const a = p.pageProperties, c = v.getPageSize(a.pageType || "");
    r.drawImage(o, {
      x: a.leftMargin || 0,
      y: a.topMargin || 0,
      width: c.width - (a.leftMargin || 0) - (a.rightMargin || 0),
      height: c.height - (a.topMargin || 0) - (a.bottomMargin || 0)
    }), i && n.drawSupplementalText(i, 0, -0.1), t.length > 0 && (r.addPage(), ++l);
  }
  await n.addLabelsToDoc(
    t,
    p,
    l,
    i
    // heading
  ), r.save();
}
const x = "|";
async function j(s, t, e = !0, i = !1, o = !1, r = void 0, n = !1, p = !1) {
  const l = [];
  return Object.keys(t).forEach((c) => {
    const h = t[c], f = h.layerView?.layer || h.layer;
    f && l.push(
      it(s, f, h.ids, e, i, r, n, p)
    ), o && l.push(Promise.resolve([[c]]));
  }), (await Promise.all(l)).reduce((c, h) => c.concat(h), []);
}
async function pt(s, t, e, i = !1, o = !1, r = void 0, n = !1, p = !1) {
  let l = await j(s, t, e, o, !0, r, n, p);
  l = i ? M(l) : l;
  const a = Object.keys(t);
  let c = [];
  return l.forEach((h) => {
    const f = h[0];
    if (a.indexOf(f) < 0)
      c.push(h);
    else {
      const O = T(t, new RegExp(`\\b${f}\\b`));
      W(N(O), c), c = [];
    }
  }), Promise.resolve();
}
async function ht(s, t, e, i = !1, o = "", r = "") {
  let n = await j(s, t);
  const p = T(t);
  n = // Remove empty lines in labels
  n.map((a) => a.filter((c) => c.length > 0)).filter((a) => a.length > 0), n = i ? M(n) : n;
  const l = o || N(p);
  return U(l, n, e, o, r), Promise.resolve();
}
function M(s) {
  const t = s.map((i) => JSON.stringify(i)), e = new Set(t);
  return Array.from(e, (i) => JSON.parse(i));
}
function C(s) {
  for (s = s.replace(/<br\s*\/?>/gi, x), s = s.replace(/<p[^>]*>/gi, x).trim().replace(/^\|/, ""), s = s.replace(/<\/p>/gi, ""), s = s.replace(/\n/gi, "|"), s = new G().sanitize(s), s = s.replace(/<[\s.]*[^<>]*\/?>/gi, "").replace(/\xA0/gi, " ").replace(/&nbsp;/gi, " "), s = s.replace(/\s*\|\s*/g, "|"); s.match(/\|\|/); )
    s = s.replace(/\|\|/, "|");
  return s = s.replace(/^\|/, ""), s = s.replace(/\|$/, ""), s;
}
function D(s, t = !1) {
  const e = [];
  return s.forEach((i) => {
    (i.visible || t) && e.push(`{${i.fieldName}}`);
  }), {
    type: "pattern",
    format: e.join(x)
  };
}
function q(s) {
  return {
    type: "pattern",
    format: C(s)
  };
}
async function K(s) {
  const t = {
    variables: [
      {
        name: "$feature",
        type: "feature"
      },
      {
        name: "$layer",
        type: "featureSet"
      },
      {
        name: "$datastore",
        type: "featureSetCollection"
      },
      {
        name: "$map",
        type: "featureSetCollection"
      }
    ]
  }, e = await I.createArcadeExecutor(s.expression, t);
  return Promise.resolve({
    type: "executor",
    format: e
  });
}
async function Q(s, t) {
  const e = {};
  if (!Array.isArray(t?.popupTemplate?.expressionInfos) || t?.popupTemplate?.expressionInfos.length === 0)
    return Promise.resolve(e);
  const i = /\{expression\/\w+\}/g, o = s.match(i);
  if (!o)
    return Promise.resolve(e);
  const r = {
    variables: [
      {
        name: "$feature",
        type: "feature"
      },
      {
        name: "$layer",
        type: "featureSet"
      },
      {
        name: "$datastore",
        type: "featureSetCollection"
      },
      {
        name: "$map",
        type: "featureSetCollection"
      }
    ]
  }, n = {};
  o.forEach((l) => {
    const a = l.substring(l.indexOf("/") + 1, l.length - 1);
    (t?.popupTemplate?.expressionInfos || []).forEach((c) => {
      c.name === a && (n[a] = I.createArcadeExecutor(c.expression, r));
    });
  });
  const p = Object.values(n);
  return Promise.all(p).then((l) => {
    const a = Object.keys(n);
    for (let c = 0; c < a.length; ++c)
      e[a[c]] = l[c].valueOf();
    return e;
  });
}
function N(s) {
  return s.length > 0 ? s.join(", ") : "download";
}
function X(s) {
  return s.split(x).map((i, o) => {
    const r = i.match(/\{[^\}]*\}/g);
    return r ? r.map((n) => n.substring(1, n.length - 1)).map((n) => n.startsWith("expression/") ? n.substring(n.indexOf("/") + 1) : n).join("__") : `column_${o + 1}`;
  });
}
function Y(s) {
  const t = /\{expression\/\w+\}/g;
  return s.match(t) ?? [];
}
function Z(s, t, e, i, o) {
  const r = s.substring(s.lastIndexOf("/") + 1);
  Number.isNaN(Number.parseInt(r)) && (s += "/" + t.toString());
  const n = {
    definitionExpression: "1=1",
    httpMethod: "POST",
    objectIds: i,
    outFields: "*",
    relationshipId: e,
    url: s
  };
  return o && (n.params = { token: o }), E(n);
}
function E(s, t = [], e = 0) {
  const i = {
    ...s.params,
    resultOffset: e
  };
  return A.queryRelated({
    ...s,
    params: i
    //TODO } as IQueryRelatedOptionsOffset).then((response: IQueryRelatedResponseOffset) => {
  }).then((o) => (t.push(...o.relatedRecordGroups), o.exceededTransferLimit ? E(s, t, e + o.relatedRecordGroups.length) : Promise.resolve(t)));
}
function tt(s) {
  const t = [];
  let e = 0;
  for (; e < s.length; ) {
    const o = s.indexOf("{", e);
    if (o < 0)
      break;
    const r = s.indexOf("}", o);
    if (r < 0)
      break;
    const n = s.substring(o, r + 1);
    t.push(n), e = r + 1;
  }
  const i = Y(s);
  return t.filter((o) => i.indexOf(o) < 0);
}
function et(s) {
  return s.map((t) => t.substring(1, t.length - 1));
}
async function L(s, t, e) {
  let i = {
    layer: t,
    attributeFormats: {},
    relationshipId: void 0,
    labelFormat: {
      type: "unsupported",
      format: void 0
    }
  };
  if (t.popupEnabled && ((t?.popupTemplate?.fieldInfos || []).forEach(
    // Extract any format info that we have
    (o) => {
      o.format && (i.attributeFormats[o.fieldName.toLowerCase()] = o.format);
    }
  ), e && t)) {
    const o = t?.popupTemplate?.content || [], r = o && o.length > 0 ? o[0]?.type : void 0;
    if (r === "relationship") {
      const n = o[0].relationshipId, p = t.relationships?.find((a) => a.id === n);
      let l = s.layers.toArray().concat(s.tables.toArray());
      if (l = l.filter((a) => a.type === "feature" && a.layerId === p?.relatedTableId), l.length > 0)
        i = await L(s, l[0], e), i.relationshipId = n.toString();
      else {
        l = s.layers.toArray().concat(s.tables.toArray());
        const a = [];
        l = l.filter((f) => {
          if (f.type === "feature" && f.layerId != t.layerId && f.url) {
            const O = f.url + "/" + f?.layerId?.toString();
            return a.push(A.getJson(
              O
              /*, authentication*/
            )), !0;
          } else
            return !1;
        });
        const c = await Promise.all(a);
        let h = Promise.resolve(void 0);
        c.some((f, O) => f.relationships && f.relationships.some((w) => w.id === n) ? (h = L(s, l[O], e), !0) : !1) ? (i = await h, i.relationshipId = n.toString()) : i.labelFormat = D(t.popupTemplate?.fieldInfos);
      }
    } else r === "fields" ? (i.labelFormat = D(t.popupTemplate?.fieldInfos), i.labelFormat.format.length === 0 && (i.labelFormat = t.popupTemplate?.title && typeof t.popupTemplate?.title == "string" ? { type: "pattern", format: t.popupTemplate.title } : (
      // Otherwise revert to using attributes
      D(t.popupTemplate?.fieldInfos, !0)
    ))) : r === "text" ? i.labelFormat = q(o[0].text) : r === "expression" ? i.labelFormat = await K(o[0].expressionInfo) : i.labelFormat = D(t.popupTemplate?.fieldInfos);
  }
  return Promise.resolve(i);
}
function T(s, t = /.+/) {
  let e = [];
  return Object.keys(s).forEach((i) => {
    const o = s[i];
    t.test(i) && (e = e.concat(o.selectionSetNames));
  }), e;
}
function _(s, t, e, i, o) {
  if (s === null || typeof s > "u")
    return "";
  if (e && e.type === "coded-value")
    return e.getName(s)?.toString();
  {
    let r = s;
    switch (t) {
      case "date":
        if (i?.dateFormat) {
          const n = o.convertDateFormatToIntlOptions(i.dateFormat);
          r = o.formatDate(r, n);
        } else
          r = o.formatDate(r);
        r = r.replace(/\xe2\x80\xaf/g, "");
        break;
      case "date-only":
        if (i?.dateFormat) {
          const n = o.convertDateFormatToIntlOptions(i.dateFormat);
          r = o.formatDateOnly(r, n);
        } else
          r = o.formatDateOnly(r);
        break;
      case "time-only":
        if (i?.dateFormat) {
          const n = o.convertDateFormatToIntlOptions(i.dateFormat);
          r = o.formatTimeOnly(r, n);
        } else
          r = o.formatTimeOnly(r);
        break;
      case "double":
      case "integer":
      case "long":
      case "small-integer":
        if (i) {
          const n = o.convertNumberFormatToIntlOptions(i);
          r = o.formatNumber(r, n);
        } else
          r = o.formatNumber(r?.toString(), {
            maximumFractionDigits: 100
          });
        break;
    }
    return r;
  }
}
async function it(s, t, e, i = !0, o = !1, r = [], n = !1, p = !1) {
  const l = s?.portalItem?.portal?.credential?.token, a = await L(s, t, i), c = a.layer;
  let h = [];
  if (typeof a.relationshipId < "u") {
    const g = await Z(t.url, t.layerId, a.relationshipId, e, l), d = [];
    g.forEach((u) => {
      u.relatedRecords?.forEach((P) => {
        d.push(P.attributes);
      });
    });
    const m = t.objectIdField;
    if (d.sort((u, P) => u[m] < P[m] ? -1 : u[m] > P[m] ? 1 : 0), h = d.filter((u, P) => P === 0 ? !0 : u[m] !== d[P - 1][m]), h.length === 0)
      return Promise.resolve([]);
  } else {
    const g = r.length > 0 ? r : void 0;
    h = await k(e, c, [], !1, void 0, g);
  }
  const f = {}, O = {}, w = {};
  c.fields && r ? c.fields.forEach((g) => {
    if (!p || r.indexOf((g?.name || "").toLowerCase()) > -1) {
      const d = g.name.toLowerCase();
      f[d] = g.name, w[d] = g.domain, O[d] = g.type;
    }
  }) : r && Object.keys(h[0]).forEach((g) => {
    if (!p || r.indexOf(g.toLowerCase()) > -1) {
      const d = g.toLowerCase();
      f[d] = g;
    }
  });
  const F = a.labelFormat.type === "pattern" ? (
    // Export attributes in format
    await ot(
      t,
      h,
      f,
      O,
      w,
      a.attributeFormats,
      a.labelFormat.format,
      o
    )
  ) : a.labelFormat.type === "executor" ? (
    // Export attributes in expression
    await rt(h, a.labelFormat.format)
  ) : (
    // Export all attributes
    await st(h, O, w, o, n)
  );
  return Promise.resolve(F);
}
async function st(s, t, e, i = !1, o = !1) {
  const r = s.map((n) => Object.keys(n.attributes).map((p) => {
    const l = p.toLowerCase();
    return _(n.attributes[p], t[l], e[l], void 0, S);
  }));
  if (i) {
    const n = [], p = s[0].attributes, l = s[0]?.layer?.fields.reduce((a, c) => (a[c.name] = c.alias, a), {});
    Object.keys(p).forEach((a) => {
      n.push(o && l ? l[a] : a);
    }), r.unshift(n);
  }
  return Promise.resolve(r);
}
async function ot(s, t, e, i, o, r, n, p = !1) {
  const l = tt(n), a = et(l), c = await Q(n, s), h = /\{expression\/\w+\}/g, f = n.match(h) ?? [], O = await Promise.all(
    t.map(async (w) => {
      let F = n;
      for (let m = 0; m < f.length; m++) {
        const u = f[m], P = u.substring(u.indexOf("/") + 1, u.length - 1), y = await c[P].executeAsync({ $feature: w, $layer: s });
        y && (F = F.replace(u, y).replace(/\n/gi, "|"));
      }
      const g = w.attributes ?? w;
      a.forEach((m, u) => {
        const P = m.toLowerCase(), y = _(
          g[e[P]],
          i[P],
          o[P],
          r[P],
          S
        );
        F = F.replace(l[u], y);
      });
      let d = F.split(x);
      return d = d.map((m) => C(m)), d;
    })
  );
  return p && O.unshift(X(n)), Promise.resolve(O);
}
async function rt(s, t) {
  const i = (await Promise.all(
    s.map(async (o) => t.executeAsync({ $feature: o }))
  )).filter((o) => o?.text).map((o) => C(o.text).split(x));
  return Promise.resolve(i);
}
export {
  _,
  ht as a,
  T as b,
  j as c,
  pt as d,
  N as e,
  M as r
};
