{"version":3,"sources":["jsdelivr-header.js","/npm/@georapbox/files-dropzone-element@2.1.1/src/utils/is-valid-file.js","/npm/@georapbox/files-dropzone-element@2.1.1/src/utils/files-selector.js","/npm/@georapbox/files-dropzone-element@2.1.1/src/files-dropzone.js"],"names":[],"mappings":"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","file":"/npm/@georapbox/files-dropzone-element@2.1.1/dist/files-dropzone.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@georapbox/files-dropzone-element@2.1.1/dist/files-dropzone.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","// @ts-check\n\n/**\n * Checks if a file is valid based on the accepted file type specifiers.\n *\n * @param {File} file - The File object to validate.\n * @param {string} [acceptedTypeSpecifiers=''] - The accepted file type specifiers.\n * @returns {boolean} - True if the file is valid, false otherwise.\n */\nexport function isValidFile(file, acceptedTypeSpecifiers = '') {\n  if (!acceptedTypeSpecifiers) {\n    return true;\n  }\n\n  const acceptedMimeTypesList = [\n    ...new Set(\n      acceptedTypeSpecifiers\n        .split(',')\n        .map(v => v.trim())\n        .filter(Boolean)\n    )\n  ];\n\n  const fileMimeType = file.type;\n  const baseMimeType = fileMimeType.replace(/\\/.*$/, '');\n\n  for (const validType of acceptedMimeTypesList) {\n    if (validType.charAt(0) === '.') {\n      if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {\n        return true;\n      }\n    } else if (/\\/\\*$/.test(validType)) {\n      // Check for mime type that looks like \"image/*\" or similar.\n      if (baseMimeType === validType.replace(/\\/.*$/, '')) {\n        return true;\n      }\n    } else {\n      if (fileMimeType === validType) {\n        return true;\n      }\n    }\n  }\n\n  return false;\n}\n","// @ts-check\n\n/**\n * A map of common file extensions and their associated MIME types.\n */\nconst COMMON_MIME_TYPES = new Map([\n  // https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\n  ['aac', 'audio/aac'],\n  ['abw', 'application/x-abiword'],\n  ['arc', 'application/x-freearc'],\n  ['avif', 'image/avif'],\n  ['avi', 'video/x-msvideo'],\n  ['azw', 'application/vnd.amazon.ebook'],\n  ['bin', 'application/octet-stream'],\n  ['bmp', 'image/bmp'],\n  ['bz', 'application/x-bzip'],\n  ['bz2', 'application/x-bzip2'],\n  ['cda', 'application/x-cdf'],\n  ['csh', 'application/x-csh'],\n  ['css', 'text/css'],\n  ['csv', 'text/csv'],\n  ['doc', 'application/msword'],\n  ['docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],\n  ['eot', 'application/vnd.ms-fontobject'],\n  ['epub', 'application/epub+zip'],\n  ['gz', 'application/gzip'],\n  ['gif', 'image/gif'],\n  ['heic', 'image/heic'],\n  ['heif', 'image/heif'],\n  ['htm', 'text/html'],\n  ['html', 'text/html'],\n  ['ico', 'image/vnd.microsoft.icon'],\n  ['ics', 'text/calendar'],\n  ['jar', 'application/java-archive'],\n  ['jpeg', 'image/jpeg'],\n  ['jpg', 'image/jpeg'],\n  ['jxl', 'image/jxl'],\n  ['js', 'text/javascript'],\n  ['json', 'application/json'],\n  ['jsonld', 'application/ld+json'],\n  ['markdown', 'text/markdown'],\n  ['md', 'text/markdown'],\n  ['mid', 'audio/midi'],\n  ['midi', 'audio/midi'],\n  ['mjs', 'text/javascript'],\n  ['mp3', 'audio/mpeg'],\n  ['mp4', 'video/mp4'],\n  ['mpeg', 'video/mpeg'],\n  ['mpkg', 'application/vnd.apple.installer+xml'],\n  ['odp', 'application/vnd.oasis.opendocument.presentation'],\n  ['ods', 'application/vnd.oasis.opendocument.spreadsheet'],\n  ['odt', 'application/vnd.oasis.opendocument.text'],\n  ['oga', 'audio/ogg'],\n  ['ogv', 'video/ogg'],\n  ['ogx', 'application/ogg'],\n  ['opus', 'audio/opus'],\n  ['otf', 'font/otf'],\n  ['png', 'image/png'],\n  ['pdf', 'application/pdf'],\n  ['php', 'application/x-httpd-php'],\n  ['ppt', 'application/vnd.ms-powerpoint'],\n  ['pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],\n  ['rar', 'application/vnd.rar'],\n  ['rtf', 'application/rtf'],\n  ['sh', 'application/x-sh'],\n  ['svg', 'image/svg+xml'],\n  ['swf', 'application/x-shockwave-flash'],\n  ['tar', 'application/x-tar'],\n  ['tif', 'image/tiff'],\n  ['tiff', 'image/tiff'],\n  ['ts', 'video/mp2t'],\n  ['ttf', 'font/ttf'],\n  ['txt', 'text/plain'],\n  ['vsd', 'application/vnd.visio'],\n  ['wav', 'audio/wav'],\n  ['weba', 'audio/webm'],\n  ['webm', 'video/webm'],\n  ['webp', 'image/webp'],\n  ['woff', 'font/woff'],\n  ['woff2', 'font/woff2'],\n  ['xhtml', 'application/xhtml+xml'],\n  ['xls', 'application/vnd.ms-excel'],\n  ['xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],\n  ['xml', 'application/xml'],\n  ['xul', 'application/vnd.mozilla.xul+xml'],\n  ['zip', 'application/zip'],\n  ['7z', 'application/x-7z-compressed'],\n\n  // Others\n  ['mkv', 'video/x-matroska'],\n  ['mov', 'video/quicktime'],\n  ['msg', 'application/vnd.ms-outlook']\n]);\n\nconst FILES_TO_IGNORE = [\n  // Thumbnail cache files for macOS and Windows\n  '.DS_Store', // macOs\n  'Thumbs.db' // Windows\n];\n\n/**\n * Adds a `type` property to the file object if it doesn't have one and the file has an extension.\n * This is needed because Firefox doesn't add a type property to files dragged from the desktop.\n * @bug https://bugzilla.mozilla.org/show_bug.cgi?id=1424689\n *\n * @param {File} file - The file object to add the type property to.\n * @returns {File} - The file object with the type property added.\n */\nconst toFileWithMimeType = file => {\n  const { name } = file;\n  const hasExtension = name && name.lastIndexOf('.') !== -1;\n\n  if (hasExtension && !file.type) {\n    const extension = (name.split('.').pop() || '').toLowerCase();\n    const type = COMMON_MIME_TYPES.get(extension);\n\n    if (type) {\n      Object.defineProperty(file, 'type', {\n        value: type,\n        writable: false,\n        configurable: false,\n        enumerable: true\n      });\n    }\n  }\n\n  return file;\n};\n\n/**\n * Adds a `path` property to the file object if it doesn't have one.\n * If `path` is not provided, the `webkitRelativePath` property of the file will be used\n * or the file's name if `webkitRelativePath` is not available.\n *\n * @param {File} file - The file object to add the path property to.\n * @param {string} [path] - The path to set on the file object.\n * @returns {File} - The file object with the path property added.\n */\nconst toFileWithPath = (file, path) => {\n  const fileWithMimeType = toFileWithMimeType(file);\n\n  // @ts-ignore\n  if (typeof fileWithMimeType.path !== 'string') {\n    const { webkitRelativePath } = file;\n\n    Object.defineProperty(fileWithMimeType, 'path', {\n      value: typeof path === 'string' ? path : webkitRelativePath || file.name,\n      writable: false,\n      configurable: false,\n      enumerable: true\n    });\n  }\n\n  return fileWithMimeType;\n};\n\n/**\n * Wrap `FileSystemDirectoryReader.readEntries` in a promise to make working with read entries easier.\n * https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryReader/readEntries\n *\n * @param {FileSystemDirectoryReader} directoryReader - The directory reader to read entries from.\n * @returns {Promise<FileSystemEntry[]>} - A promise that resolves with an array of `FileSystemEntry` objects.\n */\nconst readEntriesPromise = async directoryReader => {\n  return await new Promise((resolve, reject) => {\n    directoryReader.readEntries(resolve, reject);\n  });\n};\n\n/**\n * Read all entries in a directory or sub-directory\n * by calling `readEntries` until it returns an empty array.\n *\n * @param {FileSystemDirectoryReader} directoryReader - The directory reader to read entries from.\n * @returns {Promise<FileSystemEntry[]>} - A promise that resolves with an array of `FileSystemEntry` objects.\n */\nconst readAllDirectoryEntries = async directoryReader => {\n  const entries = [];\n  let readEntries = await readEntriesPromise(directoryReader);\n\n  while (readEntries.length > 0) {\n    entries.push(...readEntries);\n    readEntries = await readEntriesPromise(directoryReader);\n  }\n\n  return entries;\n};\n\n/**\n * Get a `File` object from a `FileSystemFileEntry` object.\n *\n * @param {FileSystemFileEntry} fileEntry - The file entry to get a `File` object from.\n * @returns {Promise<File>} - A promise that resolves with a `File` object.\n */\nconst getFileFromFileEntry = fileEntry => {\n  return new Promise((resolve, reject) => {\n    fileEntry.file(file => resolve(toFileWithPath(file, fileEntry.fullPath)), reject);\n  });\n};\n\n/**\n * Get an array of `File` objects from a `DataTransferItemList` object.\n *\n * @param {DataTransferItemList} dataTransferItemList - The item list to get an array of `File` objects from.\n * @returns {Promise<File[]>} - A promise that resolves with an array of `File` objects.\n */\nconst getFilesFromDataTransferItemList = async dataTransferItemList => {\n  const files = [];\n\n  // Chromium browsers read only 100 files at a time as per the spec, so we need to use\n  // BFS (Breadth-first search) to traverse the entire directory/file structure.\n  // https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/webkitGetAsEntry#javascript_content\n  const queue = [];\n\n  for (const item of dataTransferItemList) {\n    if (item.kind !== 'file') {\n      // Ignore non-file items, such as links.\n      continue;\n    }\n\n    // https://developer.mozilla.org/docs/Web/API/DataTransferItem/webkitGetAsEntry\n    // This function is implemented as `webkitGetAsEntry()` in non-WebKit browsers\n    // including Firefox at this time but it may be renamed to `getAsEntry()` in the future.\n    // @ts-ignore\n    const entry = item.getAsEntry ? item.getAsEntry() : item.webkitGetAsEntry();\n\n    queue.push(entry);\n  }\n\n  while (queue.length > 0) {\n    const entry = queue.shift();\n\n    if (!entry) {\n      continue;\n    } else if (entry.isFile) {\n      const file = await getFileFromFileEntry(entry);\n\n      if (FILES_TO_IGNORE.indexOf(file.name) === -1) {\n        files.push(file);\n      }\n    } else if (entry.isDirectory) {\n      queue.push(...(await readAllDirectoryEntries(entry.createReader())));\n    }\n  }\n\n  return files;\n};\n\n/**\n * Get an array of `File` objects from a `FileList` object.\n *\n * @param {FileList} fileList - The file list to get an array of `File` objects from.\n * @returns {Promise<File[]>} - A promise that resolves with an array of `File` objects.\n */\nconst getFilesFromFileList = async fileList => {\n  const files = [];\n\n  for (const file of fileList) {\n    if (FILES_TO_IGNORE.indexOf(file.name) === -1) {\n      files.push(toFileWithPath(file));\n    }\n  }\n\n  return files;\n};\n\n/**\n * Get an array of `File` objects from an event.\n * This function supports both `drop` and `change` events.\n *\n * @param {*} evt - The event to get an array of `File` objects from.\n * @returns {Promise<File[]>} - A promise that resolves with an array of `File` objects.\n */\nexport const getFilesFromEvent = async evt => {\n  if (evt.dataTransfer) {\n    return evt.dataTransfer.items\n      ? await getFilesFromDataTransferItemList(evt.dataTransfer.items)\n      : await getFilesFromFileList(evt.dataTransfer.files);\n  }\n\n  return await getFilesFromFileList(evt.target.files);\n};\n","// @ts-check\n\n/**\n * Represents a value that may be of type T, or null.\n *\n * @template T\n * @typedef {T | null} Nullable\n */\n\n/**\n * Stable identifier for error codes used in the `files-dropzone-error` event.\n *\n * @typedef {typeof FilesDropzone.ERROR_CODES[keyof typeof FilesDropzone.ERROR_CODES]} FilesDropzoneErrorCode\n */\n\n/**\n * The detail payload for the `files-dropzone-error` event.\n *\n * @typedef {Object} FilesDropzoneErrorDetail\n * @property {FilesDropzoneErrorCode} code - Stable identifier for the type of error that occurred.\n * @property {unknown} error - The underlying error object or value that triggered the event.\n */\n\n/**\n * Stable identifier for rejection codes used in the various drop-related events.\n *\n * @typedef {typeof FilesDropzone.REJECTION_CODES[keyof typeof FilesDropzone.REJECTION_CODES]} FilesDropzoneRejectionCode\n */\n\nimport { isValidFile } from './utils/is-valid-file.js';\nimport { getFilesFromEvent } from './utils/files-selector.js';\n\nconst css = String.raw;\nconst html = String.raw;\nconst COMPONENT_NAME = 'files-dropzone';\nconst template = document.createElement('template');\n\nconst styles = css`\n  *,\n  *::before,\n  *::after {\n    box-sizing: border-box;\n  }\n\n  :host([hidden]),\n  [hidden] {\n    display: none !important;\n  }\n\n  :host {\n    --dropzone-border-width: 2px;\n    --dropzone-border-style: dashed;\n    --dropzone-border-radius: 0.25rem;\n    --dropzone-border-color: #6c757d;\n    --dropzone-border-color-dragover: #0d6efd;\n    --dropzone-border-color-hover: var(--dropzone-border-color-dragover);\n    --dropzone-background-color: #ffffff;\n    --dropzone-background-color-dragover: #f4f4f5;\n    --dropzone-background-color-hover: var(--dropzone-background-color-dragover);\n    --dropzone-body-color: #3f3f46;\n    --dropzone-body-color-dragover: var(--dropzone-body-color);\n    --dropzone-body-color-hover: var(--dropzone-body-color-dragover);\n    --dropzone-focus-shadow-rgb: 49, 132, 253;\n    --dropzone-focus-box-shadow: 0 0 0 0.25rem rgba(var(--dropzone-focus-shadow-rgb), 0.5);\n    --transition-duration: 0.2s; /* for backwards compatibility */\n    --dropzone-transition-duration: var(--transition-duration);\n\n    display: block;\n  }\n\n  :host(:not([no-style])) .dropzone {\n    border: var(--dropzone-border-width) var(--dropzone-border-style) var(--dropzone-border-color);\n    border-radius: var(--dropzone-border-radius);\n    padding: 3rem 1rem;\n    overflow: hidden;\n    background-color: var(--dropzone-background-color);\n    color: var(--dropzone-body-color);\n    text-align: center;\n    cursor: pointer;\n    transition:\n      border var(--dropzone-transition-duration) ease-in-out,\n      background-color var(--dropzone-transition-duration) ease-in-out,\n      color var(--dropzone-transition-duration) ease-in-out,\n      box-shadow var(--dropzone-transition-duration) ease-in-out;\n  }\n\n  :host(:not([no-style])[disabled]) .dropzone {\n    opacity: 0.8;\n    cursor: not-allowed;\n    user-select: none;\n  }\n\n  :host(:not([no-style]):not([disabled])) .dropzone--dragover {\n    border-color: var(--dropzone-border-color-dragover);\n    background-color: var(--dropzone-background-color-dragover);\n    color: var(--dropzone-body-color-dragover);\n  }\n\n  :host(:not([no-style]):not([disabled])) .dropzone:focus-visible {\n    outline: none;\n    box-shadow: var(--dropzone-focus-box-shadow);\n  }\n\n  @media (hover: hover) {\n    :host(:not([no-style]):not([disabled])) .dropzone:not(.dropzone--dragover):hover {\n      border-color: var(--dropzone-border-color-hover);\n      background-color: var(--dropzone-background-color-hover);\n      color: var(--dropzone-body-color-hover);\n    }\n  }\n`;\n\ntemplate.innerHTML = html`\n  <style>\n    ${styles}\n  </style>\n\n  <input type=\"file\" id=\"file-input\" hidden />\n\n  <div part=\"dropzone\" class=\"dropzone\" id=\"dropzone\" tabindex=\"0\" role=\"button\" aria-disabled=\"false\">\n    <slot><span>Drag 'n' drop files here, or click to select files</span></slot>\n  </div>\n`;\n\n/**\n * @summary A custom element that allows users to drag and drop files into it.\n * @documentation https://github.com/georapbox/files-dropzone-element\n *\n * @tagname files-dropzone - This is the default tag name, unless overridden by the `defineCustomElement` method.\n *\n * @property {string} accept - A comma-separated list of unique file type specifiers describing file types to allow.\n * @property {boolean} disabled - Determines whether the dropzone is disabled.\n * @property {number} maxFiles - The maximum number of files allowed to be dropped.\n * @property {number} maxSize - The maximum file size allowed in bytes.\n * @property {number} minSize - The minimum file size allowed in bytes.\n * @property {boolean} multiple - Allows multiple files to be dropped.\n * @property {boolean} autoFocus - Automatically focuses the dropzone when it's connected to the DOM.\n * @property {boolean} noStyle - Prevents the dropzone from applying any styling.\n *\n * @attribute {string} accept - Reflects the accept property.\n * @attribute {boolean} disabled - Reflects the disabled property.\n * @attribute {number} max-files - Reflects the maxFiles property.\n * @attribute {number} max-size - Reflects the maxSize property.\n * @attribute {number} min-size - Reflects the minSize property.\n * @attribute {boolean} multiple - Reflects the multiple property.\n * @attribute {boolean} auto-focus - Reflects the autoFocus property.\n * @attribute {boolean} no-style - Reflects the noStyle property.\n *\n * @slot - The default slot content of the dropzone.\n *\n * @csspart dropzone - The dropzone element.\n * @csspart dropzone--dragover - The state of the dropzone when dragging over it.\n *\n * @cssproperty --dropzone-border-width - The border width of the dropzone.\n * @cssproperty --dropzone-border-style - The border style of the dropzone.\n * @cssproperty --dropzone-border-radius - The border radius of the dropzone.\n * @cssproperty --dropzone-border-color - The border color of the dropzone.\n * @cssproperty --dropzone-border-color-dragover - The border color of the dropzone when dragging over it.\n * @cssproperty --dropzone-border-color-hover - The border color of the dropzone when hovering over it.\n * @cssproperty --dropzone-background-color - The background color of the dropzone.\n * @cssproperty --dropzone-background-color-dragover - The background color of the dropzone when dragging over it.\n * @cssproperty --dropzone-background-color-hover - The background color of the dropzone when hovering over it.\n * @cssproperty --dropzone-body-color - The text color of the dropzone.\n * @cssproperty --dropzone-body-color-dragover - The text color of the dropzone when dragging over it.\n * @cssproperty --dropzone-body-color-hover - The text color of the dropzone when hovering over it.\n * @cssproperty --dropzone-focus-shadow-rgb - The RGB value of the dropzone's focus shadow.\n * @cssproperty --dropzone-focus-box-shadow - The box shadow of the dropzone when focused.\n * @cssproperty --dropzone-transition-duration - The transition's duration for the dropzone area.\n *\n * @event files-dropzone-drop - Fired when files are dropped.\n * @event files-dropzone-drop-accepted - Fired when files dropped files are accepted.\n * @event files-dropzone-drop-rejected - Fired when files dropped files are rejected.\n * @event files-dropzone-dragenter - Fired when files are dragged into the dropzone.\n * @event files-dropzone-dragover - Fired when files are dragged over the dropzone.\n * @event files-dropzone-dragleave - Fired when files are dragged out of the dropzone.\n * @event files-dropzone-error - Fired when there is any error in the process of reading dropped files or directories.\n *\n * @method defineCustomElement - Static method. Defines a custom element with the given name.\n * @method openFileDialog - Instance method. Opens the file dialog programmatically.\n */\nclass FilesDropzone extends HTMLElement {\n  /**\n   * Central list of error codes used in drop error event.\n   * @readonly\n   */\n  static ERROR_CODES = /** @type {const} */ ({\n    FILE_DIALOG_OPEN_FAILED: 'FILE_DIALOG_OPEN_FAILED',\n    FILE_INPUT_CHANGE_FAILED: 'FILE_INPUT_CHANGE_FAILED',\n    DROP_EVENT_PROCESSING_FAILED: 'DROP_EVENT_PROCESSING_FAILED',\n    UNKNOWN_ERROR: 'UNKNOWN_ERROR'\n  });\n\n  /**\n   * Central list of rejection codes for files that are rejected during the drop process.\n   * @readonly\n   */\n  static REJECTION_CODES = /** @type {const} */ ({\n    TOO_MANY_FILES: 'TOO_MANY_FILES',\n    FILE_TOO_LARGE: 'FILE_TOO_LARGE',\n    FILE_TOO_SMALL: 'FILE_TOO_SMALL',\n    INVALID_MIME_TYPE: 'INVALID_MIME_TYPE'\n  });\n\n  /** @type {Nullable<HTMLInputElement>} */\n  #fileInput = null;\n\n  /** @type {Nullable<HTMLElement>} */\n  #dropzoneEl = null;\n\n  constructor() {\n    super();\n\n    if (!this.shadowRoot) {\n      const shadowRoot = this.attachShadow({ mode: 'open', delegatesFocus: true });\n      shadowRoot.appendChild(template.content.cloneNode(true));\n    }\n\n    if (this.shadowRoot) {\n      this.#fileInput = /** @type {Nullable<HTMLInputElement>} */ (this.shadowRoot.getElementById('file-input'));\n      this.#dropzoneEl = this.shadowRoot.getElementById('dropzone');\n    }\n  }\n\n  static get observedAttributes() {\n    return ['accept', 'disabled', 'multiple'];\n  }\n\n  /**\n   * Lifecycle method that is called when attributes are changed, added, removed, or replaced.\n   *\n   * @param {string} name - The name of the attribute.\n   * @param {string} oldValue - The old value of the attribute.\n   * @param {string} newValue - The new value of the attribute.\n   */\n  attributeChangedCallback(name, oldValue, newValue) {\n    if (name === 'accept' && oldValue !== newValue && this.#fileInput) {\n      this.#fileInput.accept = this.accept;\n    }\n\n    if (name === 'disabled' && oldValue !== newValue && this.#fileInput) {\n      this.#fileInput.disabled = this.disabled;\n\n      if (this.disabled) {\n        this.#dropzoneEl?.removeAttribute('tabindex');\n        this.#dropzoneEl?.setAttribute('aria-disabled', 'true');\n      } else {\n        this.#dropzoneEl?.setAttribute('tabindex', '0');\n        this.#dropzoneEl?.setAttribute('aria-disabled', 'false');\n      }\n    }\n\n    if (name === 'multiple' && oldValue !== newValue && this.#fileInput) {\n      this.#fileInput.multiple = this.multiple;\n    }\n  }\n\n  /**\n   * Lifecycle method that is called when the element is added to the DOM.\n   */\n  connectedCallback() {\n    this.#upgradeProperty('accept');\n    this.#upgradeProperty('disabled');\n    this.#upgradeProperty('maxFiles');\n    this.#upgradeProperty('maxSize');\n    this.#upgradeProperty('minSize');\n    this.#upgradeProperty('multiple');\n    this.#upgradeProperty('autoFocus');\n    this.#upgradeProperty('noStyle');\n\n    this.#fileInput?.addEventListener('change', this.#handleFileInputChange);\n    this.#dropzoneEl?.addEventListener('dragenter', this.#handleDragEnter);\n    this.#dropzoneEl?.addEventListener('dragover', this.#handleDragOver);\n    this.#dropzoneEl?.addEventListener('dragleave', this.#handleDragLeave);\n    this.#dropzoneEl?.addEventListener('drop', this.#handleDrop);\n    this.#dropzoneEl?.addEventListener('click', this.#handleClick);\n    this.#dropzoneEl?.addEventListener('keyup', this.#handleKeyUp);\n\n    this.autoFocus && this.#dropzoneEl?.focus();\n  }\n\n  /**\n   * Lifecycle method that is called when the element is removed from the DOM.\n   */\n  disconnectedCallback() {\n    this.#fileInput?.removeEventListener('change', this.#handleFileInputChange);\n    this.#dropzoneEl?.removeEventListener('dragenter', this.#handleDragEnter);\n    this.#dropzoneEl?.removeEventListener('dragover', this.#handleDragOver);\n    this.#dropzoneEl?.removeEventListener('dragleave', this.#handleDragLeave);\n    this.#dropzoneEl?.removeEventListener('drop', this.#handleDrop);\n    this.#dropzoneEl?.removeEventListener('click', this.#handleClick);\n    this.#dropzoneEl?.removeEventListener('keyup', this.#handleKeyUp);\n  }\n\n  /**\n   * @type {string} - A comma-separated list of unique file type specifiers describing file types to allow.\n   * @attribute accept - Reflects the accept property.\n   */\n  get accept() {\n    return this.getAttribute('accept') || '';\n  }\n\n  set accept(value) {\n    this.setAttribute('accept', value != null ? value.toString() : value);\n  }\n\n  /**\n   * @type {boolean} - Determines whether the dropzone is disabled.\n   * @default false\n   * @attribute disabled - Reflects the disabled property.\n   */\n  get disabled() {\n    return this.hasAttribute('disabled');\n  }\n\n  set disabled(value) {\n    this.toggleAttribute('disabled', !!value);\n  }\n\n  /**\n   * @type {number} - The maximum number of files allowed to be dropped.\n   * @default Infinity\n   * @attribute max-files - Reflects the maxFiles property.\n   */\n  get maxFiles() {\n    const num = Number(this.getAttribute('max-files')) || 0;\n\n    if (num <= 0) {\n      return Infinity;\n    }\n\n    return Math.floor(Math.abs(num));\n  }\n\n  set maxFiles(value) {\n    this.setAttribute('max-files', value != null ? value.toString() : value);\n  }\n\n  /**\n   * @type {number} - The maximum file size allowed in bytes.\n   * @default Infinity\n   * @attribute max-size - Reflects the maxSize property.\n   */\n  get maxSize() {\n    const value = this.getAttribute('max-size');\n\n    if (value === null) {\n      return Infinity;\n    }\n\n    const num = Number(value);\n\n    return Number.isNaN(num) ? Infinity : num;\n  }\n\n  set maxSize(value) {\n    this.setAttribute('max-size', value != null ? value.toString() : value);\n  }\n\n  /**\n   * @type {number} - The minimum file size allowed in bytes.\n   * @default 0\n   * @attribute min-size - Reflects the minSize property.\n   */\n  get minSize() {\n    const value = this.getAttribute('min-size');\n\n    if (value === null) {\n      return 0;\n    }\n\n    const num = Number(value);\n\n    return Number.isNaN(num) ? 0 : num;\n  }\n\n  set minSize(value) {\n    this.setAttribute('min-size', value != null ? value.toString() : value);\n  }\n\n  /**\n   * @type {boolean} - Allows multiple files to be dropped.\n   * @default false\n   * @attribute multiple - Reflects the multiple property.\n   */\n  get multiple() {\n    return this.hasAttribute('multiple');\n  }\n\n  set multiple(value) {\n    this.toggleAttribute('multiple', !!value);\n  }\n\n  /**\n   * @type {boolean} - Automatically focuses the dropzone when it's connected to the DOM.\n   * @default false\n   * @attribute auto-focus - Reflects the autoFocus property.\n   */\n  get autoFocus() {\n    return this.hasAttribute('auto-focus');\n  }\n\n  set autoFocus(value) {\n    this.toggleAttribute('auto-focus', !!value);\n  }\n\n  /**\n   * @type {boolean} - Prevents the dropzone from applying any styling.\n   * @default false\n   * @attribute no-style - Reflects the noStyle property.\n   */\n  get noStyle() {\n    return this.hasAttribute('no-style');\n  }\n\n  set noStyle(value) {\n    this.toggleAttribute('no-style', !!value);\n  }\n\n  /**\n   * Emit a custom event with the given name and detail.\n   *\n   * @template D\n   * @param {string} name - The name of the event.\n   * @param {D} [detail] - The detail payload of the event.\n   * @param {CustomEventInit<D>} [init] - Override the default event initialization options.\n   * @returns {boolean} - Returns false if at least one event listener called `preventDefault()`, otherwise true.\n   */\n  #emitEvent(name, detail, init) {\n    const options = {\n      bubbles: true,\n      composed: true,\n      cancelable: false,\n      ...init,\n      detail\n    };\n    const evt = new CustomEvent(`${COMPONENT_NAME}-${name}`, options);\n    return this.dispatchEvent(evt);\n  }\n\n  /**\n   * Emit a standardized error event with typed detail.\n   *\n   * @param {FilesDropzoneErrorCode} code - Stable identifier for the type of error that occurred.\n   * @param {unknown} error - The underlying error that triggered the event.\n   */\n  #emitErrorEvent(code, error) {\n    /** @type {FilesDropzoneErrorDetail} */\n    const detail = { code, error };\n\n    this.#emitEvent('error', detail);\n  }\n\n  /**\n   * Handles the change event of the file input.\n   *\n   * @param {*} evt - The event object.\n   */\n  #handleFileInputChange = async evt => {\n    try {\n      this.#handleFilesSelect(await getFilesFromEvent(evt));\n    } catch (err) {\n      this.#emitErrorEvent(FilesDropzone.ERROR_CODES.FILE_INPUT_CHANGE_FAILED, err);\n    }\n  };\n\n  /**\n   * Handles the dragenter event of the dropzone.\n   */\n  #handleDragEnter = () => {\n    if (this.disabled) {\n      return;\n    }\n\n    this.#emitEvent('dragenter');\n  };\n\n  /**\n   * Handles the dragover event of the dropzone.\n   *\n   * @param {*} evt - The event object.\n   */\n  #handleDragOver = evt => {\n    evt.preventDefault();\n\n    if (this.disabled) {\n      evt.dataTransfer.dropEffect = 'none';\n      return;\n    }\n\n    evt.dataTransfer.dropEffect = 'copy';\n\n    if (this.#dropzoneEl) {\n      this.#dropzoneEl.classList.add('dropzone--dragover');\n      this.#dropzoneEl.part.add('dropzone--dragover');\n    }\n\n    this.#emitEvent('dragover');\n  };\n\n  /**\n   * Handles the dragleave event of the dropzone.\n   */\n  #handleDragLeave = () => {\n    if (this.disabled) {\n      return;\n    }\n\n    if (this.#dropzoneEl) {\n      this.#dropzoneEl.classList.remove('dropzone--dragover');\n      this.#dropzoneEl.part.remove('dropzone--dragover');\n    }\n\n    this.#emitEvent('dragleave');\n  };\n\n  /**\n   * Handles the drop event of the dropzone.\n   *\n   * @param {*} evt - The event object.\n   */\n  #handleDrop = async evt => {\n    if (this.disabled) {\n      return;\n    }\n\n    evt.preventDefault();\n\n    if (this.#dropzoneEl) {\n      this.#dropzoneEl.classList.remove('dropzone--dragover');\n      this.#dropzoneEl.part.remove('dropzone--dragover');\n    }\n\n    try {\n      this.#handleFilesSelect(await getFilesFromEvent(evt));\n    } catch (err) {\n      this.#emitErrorEvent(FilesDropzone.ERROR_CODES.DROP_EVENT_PROCESSING_FAILED, err);\n    }\n  };\n\n  /**\n   * Handles the click event of the dropzone.\n   */\n  #handleClick = () => {\n    if (this.disabled) {\n      return;\n    }\n\n    this.openFileDialog();\n  };\n\n  /**\n   * Handles the keyup event of the dropzone.\n   *\n   * @param {*} evt - The event object.\n   */\n  #handleKeyUp = evt => {\n    if (this.disabled) {\n      return;\n    }\n\n    if (evt.key === ' ' || evt.key === 'Enter') {\n      this.openFileDialog();\n    }\n  };\n\n  /**\n   * Handles the selection of files.\n   *\n   * @param {File[]} files - The files to handle.\n   */\n  #handleFilesSelect(files) {\n    if (!Array.isArray(files) || !files.length) {\n      return;\n    }\n\n    const acceptedFiles = [];\n    const rejectedFiles = [];\n    const filesLength = files.length;\n\n    // If the component is not in multiple mode, reject all files.\n    if (!this.multiple && filesLength > 1) {\n      for (const file of files) {\n        rejectedFiles.push({\n          file,\n          errors: [\n            {\n              code: FilesDropzone.REJECTION_CODES.TOO_MANY_FILES,\n              message: `Too many files selected. Only 1 file is allowed.`\n            }\n          ]\n        });\n      }\n    } else if (this.multiple && filesLength > this.maxFiles) {\n      // If the component is in multiple mode, but the number of files exceeds\n      // the maxFiles attribute, reject all files.\n      for (const file of files) {\n        rejectedFiles.push({\n          file,\n          errors: [\n            {\n              code: FilesDropzone.REJECTION_CODES.TOO_MANY_FILES,\n              message: `Too many files selected. Only ${this.maxFiles} ${this.maxFiles > 1 ? 'files are' : 'file is'} allowed.`\n            }\n          ]\n        });\n      }\n    } else {\n      // Validate each file. If it's valid, add it to the accepted files array,\n      // otherwise add it to the rejected files array.\n      for (const file of files) {\n        const fileHasValidType = isValidFile(file, this.accept);\n        const fileExceedsMaxSize = file.size > this.maxSize;\n        const fileIsSmallerThanMinSize = file.size < this.minSize;\n\n        if (fileHasValidType && !fileExceedsMaxSize && !fileIsSmallerThanMinSize) {\n          acceptedFiles.push(file);\n        } else {\n          const errors = [];\n\n          if (!fileHasValidType) {\n            errors.push({\n              code: FilesDropzone.REJECTION_CODES.INVALID_MIME_TYPE,\n              message: `File type \"${file.type}\" is not accepted.`\n            });\n          }\n\n          if (fileExceedsMaxSize) {\n            errors.push({\n              code: FilesDropzone.REJECTION_CODES.FILE_TOO_LARGE,\n              message: `File size ${file.size} exceeds the maximum size of ${this.maxSize}.`\n            });\n          }\n\n          if (fileIsSmallerThanMinSize) {\n            errors.push({\n              code: FilesDropzone.REJECTION_CODES.FILE_TOO_SMALL,\n              message: `File size ${file.size} is smaller than the minimum size of ${this.minSize}.`\n            });\n          }\n\n          rejectedFiles.push({ file, errors });\n        }\n      }\n    }\n\n    this.#emitEvent('drop', { acceptedFiles, rejectedFiles });\n\n    if (acceptedFiles.length > 0) {\n      this.#emitEvent('drop-accepted', { acceptedFiles });\n    }\n\n    if (rejectedFiles.length > 0) {\n      this.#emitEvent('drop-rejected', { rejectedFiles });\n    }\n\n    if (this.#fileInput) {\n      this.#fileInput.value = this.#fileInput.defaultValue;\n    }\n  }\n\n  /**\n   * Opens the file dialog programmatically.\n   */\n  openFileDialog() {\n    if (this.disabled || !this.#fileInput) {\n      return;\n    }\n\n    // In modern browsers, use the showPicker() method if available.\n    // This way we are able to detect if the file dialog was blocked by the browser\n    // (e.g. if the method was called outside a user gesture event).\n    if ('showPicker' in HTMLInputElement.prototype && typeof this.#fileInput.showPicker === 'function') {\n      try {\n        this.#fileInput.showPicker();\n      } catch (err) {\n        this.#emitErrorEvent(FilesDropzone.ERROR_CODES.FILE_DIALOG_OPEN_FAILED, err);\n      }\n      return;\n    }\n\n    // Fallback for browsers that do not support showPicker().\n    // This may not work if the method is called outside a user gesture event.\n    // In such cases, the browser may block the file dialog from opening but\n    // most likely it won't throw an error rather just a warning in the console.\n    this.#fileInput.click();\n  }\n\n  /**\n   * This is to safe guard against cases where, for instance, a framework may have added the element to the page and set a\n   * value on one of its properties, but lazy loaded its definition. Without this guard, the upgraded element would miss that\n   * property and the instance property would prevent the class property setter from ever being called.\n   *\n   * https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties\n   *\n   * @param {'accept' | 'disabled' | 'maxFiles' | 'maxSize' | 'minSize' | 'multiple' | 'autoFocus' | 'noStyle'} prop - The property name to upgrade.\n   */\n  #upgradeProperty(prop) {\n    /** @type {any} */\n    const instance = this;\n\n    if (Object.prototype.hasOwnProperty.call(instance, prop)) {\n      const value = instance[prop];\n      delete instance[prop];\n      instance[prop] = value;\n    }\n  }\n\n  /**\n   * Defines a custom element with the given name.\n   * The name must contain a dash (-).\n   *\n   * @param {string} [elementName='files-dropzone'] - The name of the custom element.\n   * @example\n   *\n   * FilesDropzone.defineCustomElement('my-dropzone');\n   */\n  static defineCustomElement(elementName = COMPONENT_NAME) {\n    if (typeof window !== 'undefined' && !window.customElements.get(elementName)) {\n      window.customElements.define(elementName, FilesDropzone);\n    }\n  }\n}\n\nexport { FilesDropzone };\n"]}