[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/ -> upload-media.js (source)

   1  (function() {
   2  "use strict";
   3  var wp;
   4  (wp ||= {}).uploadMedia = (() => {
   5    var __create = Object.create;
   6    var __defProp = Object.defineProperty;
   7    var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
   8    var __getOwnPropNames = Object.getOwnPropertyNames;
   9    var __getProtoOf = Object.getPrototypeOf;
  10    var __hasOwnProp = Object.prototype.hasOwnProperty;
  11    var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
  12      get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
  13    }) : x)(function(x) {
  14      if (typeof require !== "undefined") return require.apply(this, arguments);
  15      throw Error('Dynamic require of "' + x + '" is not supported');
  16    });
  17    var __commonJS = (cb, mod) => function __require2() {
  18      return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
  19    };
  20    var __export = (target, all) => {
  21      for (var name in all)
  22        __defProp(target, name, { get: all[name], enumerable: true });
  23    };
  24    var __copyProps = (to, from, except, desc) => {
  25      if (from && typeof from === "object" || typeof from === "function") {
  26        for (let key of __getOwnPropNames(from))
  27          if (!__hasOwnProp.call(to, key) && key !== except)
  28            __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  29      }
  30      return to;
  31    };
  32    var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  33      // If the importer is in node compatibility mode or this is not an ESM
  34      // file that has been converted to a CommonJS file using a Babel-
  35      // compatible transform (i.e. "__esModule" has not been set), then set
  36      // "default" to the CommonJS "module.exports" for node compatibility.
  37      isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  38      mod
  39    ));
  40    var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  41  
  42    // package-external:@wordpress/data
  43    var require_data = __commonJS({
  44      "package-external:@wordpress/data"(exports, module) {
  45        module.exports = window.wp.data;
  46      }
  47    });
  48  
  49    // package-external:@wordpress/i18n
  50    var require_i18n = __commonJS({
  51      "package-external:@wordpress/i18n"(exports, module) {
  52        module.exports = window.wp.i18n;
  53      }
  54    });
  55  
  56    // package-external:@wordpress/blob
  57    var require_blob = __commonJS({
  58      "package-external:@wordpress/blob"(exports, module) {
  59        module.exports = window.wp.blob;
  60      }
  61    });
  62  
  63    // package-external:@wordpress/private-apis
  64    var require_private_apis = __commonJS({
  65      "package-external:@wordpress/private-apis"(exports, module) {
  66        module.exports = window.wp.privateApis;
  67      }
  68    });
  69  
  70    // package-external:@wordpress/element
  71    var require_element = __commonJS({
  72      "package-external:@wordpress/element"(exports, module) {
  73        module.exports = window.wp.element;
  74      }
  75    });
  76  
  77    // package-external:@wordpress/compose
  78    var require_compose = __commonJS({
  79      "package-external:@wordpress/compose"(exports, module) {
  80        module.exports = window.wp.compose;
  81      }
  82    });
  83  
  84    // vendor-external:react/jsx-runtime
  85    var require_jsx_runtime = __commonJS({
  86      "vendor-external:react/jsx-runtime"(exports, module) {
  87        module.exports = window.ReactJSXRuntime;
  88      }
  89    });
  90  
  91    // packages/upload-media/build-module/index.mjs
  92    var index_exports = {};
  93    __export(index_exports, {
  94      ErrorCode: () => ErrorCode,
  95      MediaUploadProvider: () => provider_default,
  96      UploadError: () => UploadError,
  97      clearFeatureDetectionCache: () => clearFeatureDetectionCache,
  98      detectClientSideMediaSupport: () => detectClientSideMediaSupport,
  99      getErrorMessage: () => getErrorMessage,
 100      getHeicConversionAdvice: () => getHeicConversionAdvice,
 101      getHeicUnsupportedMessage: () => getHeicUnsupportedMessage,
 102      isClientSideMediaSupported: () => isClientSideMediaSupported,
 103      isHeicCanvasSupported: () => isHeicCanvasSupported,
 104      isHeicFile: () => isHeicFile,
 105      store: () => store
 106    });
 107  
 108    // packages/upload-media/build-module/store/index.mjs
 109    var import_data = __toESM(require_data(), 1);
 110  
 111    // packages/upload-media/build-module/store/types.mjs
 112    var Type = /* @__PURE__ */ ((Type2) => {
 113      Type2["Unknown"] = "REDUX_UNKNOWN";
 114      Type2["Add"] = "ADD_ITEM";
 115      Type2["Prepare"] = "PREPARE_ITEM";
 116      Type2["Cancel"] = "CANCEL_ITEM";
 117      Type2["Remove"] = "REMOVE_ITEM";
 118      Type2["RetryItem"] = "RETRY_ITEM";
 119      Type2["ScheduleRetry"] = "SCHEDULE_RETRY";
 120      Type2["PauseItem"] = "PAUSE_ITEM";
 121      Type2["ResumeItem"] = "RESUME_ITEM";
 122      Type2["PauseQueue"] = "PAUSE_QUEUE";
 123      Type2["ResumeQueue"] = "RESUME_QUEUE";
 124      Type2["OperationStart"] = "OPERATION_START";
 125      Type2["OperationFinish"] = "OPERATION_FINISH";
 126      Type2["AddOperations"] = "ADD_OPERATIONS";
 127      Type2["CacheBlobUrl"] = "CACHE_BLOB_URL";
 128      Type2["RevokeBlobUrls"] = "REVOKE_BLOB_URLS";
 129      Type2["UpdateProgress"] = "UPDATE_PROGRESS";
 130      Type2["AccumulateSubSize"] = "ACCUMULATE_SUB_SIZE";
 131      Type2["UpdateSettings"] = "UPDATE_SETTINGS";
 132      return Type2;
 133    })(Type || {});
 134    var ItemStatus = /* @__PURE__ */ ((ItemStatus2) => {
 135      ItemStatus2["Queued"] = "QUEUED";
 136      ItemStatus2["Processing"] = "PROCESSING";
 137      ItemStatus2["Paused"] = "PAUSED";
 138      ItemStatus2["PendingRetry"] = "PENDING_RETRY";
 139      ItemStatus2["Uploaded"] = "UPLOADED";
 140      ItemStatus2["Error"] = "ERROR";
 141      return ItemStatus2;
 142    })(ItemStatus || {});
 143    var OperationType = /* @__PURE__ */ ((OperationType2) => {
 144      OperationType2["Prepare"] = "PREPARE";
 145      OperationType2["Upload"] = "UPLOAD";
 146      OperationType2["ResizeCrop"] = "RESIZE_CROP";
 147      OperationType2["Rotate"] = "ROTATE";
 148      OperationType2["TranscodeImage"] = "TRANSCODE_IMAGE";
 149      OperationType2["TranscodeGif"] = "TRANSCODE_GIF";
 150      OperationType2["ThumbnailGeneration"] = "THUMBNAIL_GENERATION";
 151      OperationType2["Finalize"] = "FINALIZE";
 152      OperationType2["DetectUltraHdr"] = "DETECT_ULTRAHDR";
 153      return OperationType2;
 154    })(OperationType || {});
 155  
 156    // packages/upload-media/build-module/store/constants.mjs
 157    var STORE_NAME = "core/upload-media";
 158    var DEFAULT_MAX_CONCURRENT_UPLOADS = 5;
 159    var DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING = 2;
 160    var DEFAULT_RETRY_SETTINGS = {
 161      maxRetryAttempts: 3,
 162      initialRetryDelayMs: 1e3,
 163      maxRetryDelayMs: 3e4,
 164      backoffMultiplier: 2,
 165      retryJitter: 0.1
 166    };
 167    var CLIENT_SIDE_SUPPORTED_MIME_TYPES = [
 168      "image/jpeg",
 169      "image/png",
 170      "image/gif",
 171      "image/webp",
 172      "image/avif"
 173    ];
 174    var HEIC_MIME_TYPES = [
 175      "image/heic",
 176      "image/heif"
 177    ];
 178  
 179    // packages/upload-media/build-module/store/reducer.mjs
 180    var noop = () => {
 181    };
 182    var DEFAULT_STATE = {
 183      queue: [],
 184      queueStatus: "active",
 185      blobUrls: {},
 186      settings: {
 187        mediaUpload: noop,
 188        maxConcurrentUploads: DEFAULT_MAX_CONCURRENT_UPLOADS,
 189        maxConcurrentImageProcessing: DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING,
 190        retry: { ...DEFAULT_RETRY_SETTINGS }
 191      },
 192      failureCount: 0
 193    };
 194    function reducer(state = DEFAULT_STATE, action = { type: Type.Unknown }) {
 195      switch (action.type) {
 196        case Type.PauseQueue: {
 197          return {
 198            ...state,
 199            queueStatus: "paused"
 200          };
 201        }
 202        case Type.ResumeQueue: {
 203          return {
 204            ...state,
 205            queueStatus: "active"
 206          };
 207        }
 208        case Type.PauseItem:
 209          return {
 210            ...state,
 211            queue: state.queue.map(
 212              (item) => item.id === action.id ? {
 213                ...item,
 214                status: ItemStatus.Paused
 215              } : item
 216            )
 217          };
 218        case Type.ResumeItem:
 219          return {
 220            ...state,
 221            queue: state.queue.map(
 222              (item) => item.id === action.id ? {
 223                ...item,
 224                status: ItemStatus.Processing
 225              } : item
 226            )
 227          };
 228        case Type.Add:
 229          return {
 230            ...state,
 231            queue: [...state.queue, action.item]
 232          };
 233        case Type.Cancel: {
 234          const cancelled = state.queue.find(
 235            (item) => item.id === action.id
 236          );
 237          return {
 238            ...state,
 239            failureCount: cancelled && !cancelled.parentId ? state.failureCount + 1 : state.failureCount,
 240            queue: state.queue.map(
 241              (item) => item.id === action.id ? {
 242                ...item,
 243                error: action.error
 244              } : item
 245            )
 246          };
 247        }
 248        case Type.RetryItem:
 249          return {
 250            ...state,
 251            queue: state.queue.map(
 252              (item) => item.id === action.id ? {
 253                ...item,
 254                status: ItemStatus.Processing,
 255                error: void 0,
 256                retryCount: (item.retryCount ?? 0) + 1,
 257                abortController: new AbortController(),
 258                /*
 259                 * The failed operation is still recorded on
 260                 * the item: nothing finishes it when it
 261                 * fails, and while the item waits out the
 262                 * backoff that is what keeps it out of the
 263                 * concurrency pools. Clear it now that the
 264                 * item is about to run again, so processItem
 265                 * does not mistake it for an operation still
 266                 * in flight and skip the retry.
 267                 */
 268                currentOperation: void 0
 269              } : item
 270            )
 271          };
 272        case Type.ScheduleRetry:
 273          return {
 274            ...state,
 275            queue: state.queue.map(
 276              (item) => item.id === action.id ? {
 277                ...item,
 278                status: ItemStatus.PendingRetry,
 279                error: action.error,
 280                retryCount: action.retryCount,
 281                nextRetryTimestamp: action.nextRetryTimestamp
 282              } : item
 283            )
 284          };
 285        case Type.Remove:
 286          return {
 287            ...state,
 288            queue: state.queue.filter((item) => item.id !== action.id)
 289          };
 290        case Type.OperationStart: {
 291          return {
 292            ...state,
 293            queue: state.queue.map(
 294              (item) => item.id === action.id ? {
 295                ...item,
 296                currentOperation: action.operation
 297              } : item
 298            )
 299          };
 300        }
 301        case Type.AddOperations:
 302          return {
 303            ...state,
 304            queue: state.queue.map((item) => {
 305              if (item.id !== action.id) {
 306                return item;
 307              }
 308              return {
 309                ...item,
 310                operations: [
 311                  ...item.operations || [],
 312                  ...action.operations
 313                ]
 314              };
 315            })
 316          };
 317        case Type.OperationFinish:
 318          return {
 319            ...state,
 320            queue: state.queue.map((item) => {
 321              if (item.id !== action.id) {
 322                return item;
 323              }
 324              const operations = item.operations ? item.operations.slice(1) : [];
 325              const attachment = item.attachment || action.item.attachment ? {
 326                ...item.attachment,
 327                ...action.item.attachment
 328              } : void 0;
 329              return {
 330                ...item,
 331                currentOperation: void 0,
 332                operations,
 333                ...action.item,
 334                attachment,
 335                additionalData: {
 336                  ...item.additionalData,
 337                  ...action.item.additionalData
 338                }
 339              };
 340            })
 341          };
 342        case Type.CacheBlobUrl: {
 343          const blobUrls = state.blobUrls[action.id] || [];
 344          return {
 345            ...state,
 346            blobUrls: {
 347              ...state.blobUrls,
 348              [action.id]: [...blobUrls, action.blobUrl]
 349            }
 350          };
 351        }
 352        case Type.RevokeBlobUrls: {
 353          const newBlobUrls = { ...state.blobUrls };
 354          delete newBlobUrls[action.id];
 355          return {
 356            ...state,
 357            blobUrls: newBlobUrls
 358          };
 359        }
 360        case Type.UpdateProgress:
 361          return {
 362            ...state,
 363            queue: state.queue.map(
 364              (item) => item.id === action.id ? {
 365                ...item,
 366                progress: action.progress
 367              } : item
 368            )
 369          };
 370        case Type.AccumulateSubSize:
 371          return {
 372            ...state,
 373            queue: state.queue.map(
 374              (item) => item.id === action.id ? {
 375                ...item,
 376                subSizes: [
 377                  ...item.subSizes || [],
 378                  action.subSize
 379                ]
 380              } : item
 381            )
 382          };
 383        case Type.UpdateSettings: {
 384          return {
 385            ...state,
 386            settings: {
 387              ...state.settings,
 388              ...action.settings
 389            }
 390          };
 391        }
 392      }
 393      return state;
 394    }
 395    var reducer_default = reducer;
 396  
 397    // packages/upload-media/build-module/store/selectors.mjs
 398    var selectors_exports = {};
 399    __export(selectors_exports, {
 400      getItems: () => getItems,
 401      getSettings: () => getSettings,
 402      isUploading: () => isUploading,
 403      isUploadingById: () => isUploadingById,
 404      isUploadingByUrl: () => isUploadingByUrl
 405    });
 406    function getItems(state) {
 407      return state.queue;
 408    }
 409    function isUploading(state) {
 410      return state.queue.length >= 1;
 411    }
 412    function isUploadingByUrl(state, url) {
 413      return state.queue.some(
 414        (item) => item.attachment?.url === url || item.sourceUrl === url
 415      );
 416    }
 417    function isUploadingById(state, attachmentId) {
 418      return state.queue.some(
 419        (item) => item.attachment?.id === attachmentId || item.sourceAttachmentId === attachmentId
 420      );
 421    }
 422    function getSettings(state) {
 423      return state.settings;
 424    }
 425  
 426    // packages/upload-media/build-module/store/private-selectors.mjs
 427    var private_selectors_exports = {};
 428    __export(private_selectors_exports, {
 429      getActiveImageProcessingCount: () => getActiveImageProcessingCount,
 430      getActiveUploadCount: () => getActiveUploadCount,
 431      getActiveVideoProcessingCount: () => getActiveVideoProcessingCount,
 432      getAllItems: () => getAllItems,
 433      getBlobUrls: () => getBlobUrls,
 434      getFailedItems: () => getFailedItems,
 435      getFailureCount: () => getFailureCount,
 436      getItem: () => getItem,
 437      getItemProgress: () => getItemProgress,
 438      getPendingImageProcessing: () => getPendingImageProcessing,
 439      getPendingUploads: () => getPendingUploads,
 440      getPendingVideoProcessing: () => getPendingVideoProcessing,
 441      hasPendingItemsByParentId: () => hasPendingItemsByParentId,
 442      isBatchUploaded: () => isBatchUploaded,
 443      isPaused: () => isPaused
 444    });
 445    function getAllItems(state) {
 446      return state.queue;
 447    }
 448    function getFailureCount(state) {
 449      return state.failureCount;
 450    }
 451    function getItem(state, id) {
 452      return state.queue.find((item) => item.id === id);
 453    }
 454    function isBatchUploaded(state, batchId) {
 455      const batchItems = state.queue.filter(
 456        (item) => batchId === item.batchId
 457      );
 458      return batchItems.length === 0;
 459    }
 460    function isPaused(state) {
 461      return state.queueStatus === "paused";
 462    }
 463    function getBlobUrls(state, id) {
 464      return state.blobUrls[id] || [];
 465    }
 466    function getActiveUploadCount(state) {
 467      return state.queue.filter(
 468        (item) => item.currentOperation === OperationType.Upload
 469      ).length;
 470    }
 471    function getPendingUploads(state) {
 472      return state.queue.filter((item) => {
 473        const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
 474        return nextOperation === OperationType.Upload && item.currentOperation !== OperationType.Upload;
 475      });
 476    }
 477    function getActiveImageProcessingCount(state) {
 478      return state.queue.filter(
 479        (item) => item.currentOperation === OperationType.ResizeCrop || item.currentOperation === OperationType.Rotate
 480      ).length;
 481    }
 482    function getActiveVideoProcessingCount(state) {
 483      return state.queue.filter(
 484        (item) => item.currentOperation === OperationType.TranscodeGif
 485      ).length;
 486    }
 487    function getPendingImageProcessing(state) {
 488      return state.queue.filter((item) => {
 489        const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
 490        return (nextOperation === OperationType.ResizeCrop || nextOperation === OperationType.Rotate) && item.currentOperation !== OperationType.ResizeCrop && item.currentOperation !== OperationType.Rotate;
 491      });
 492    }
 493    function getPendingVideoProcessing(state) {
 494      return state.queue.filter((item) => {
 495        const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
 496        return nextOperation === OperationType.TranscodeGif && item.currentOperation !== OperationType.TranscodeGif;
 497      });
 498    }
 499    function getFailedItems(state) {
 500      return state.queue.filter((item) => item.error !== void 0);
 501    }
 502    function hasPendingItemsByParentId(state, parentId) {
 503      return state.queue.some((item) => item.parentId === parentId);
 504    }
 505    function getItemProgress(state, id) {
 506      const item = state.queue.find((i) => i.id === id);
 507      return item?.progress;
 508    }
 509  
 510    // packages/upload-media/build-module/store/actions.mjs
 511    var actions_exports = {};
 512    __export(actions_exports, {
 513      addItems: () => addItems,
 514      cancelItem: () => cancelItem,
 515      executeRetry: () => executeRetry,
 516      retryItem: () => retryItem,
 517      scheduleRetry: () => scheduleRetry
 518    });
 519  
 520    // node_modules/.store/uuid@14.0.2-ALlTd6-Rf9bZs703d7TIjQ/node_modules/uuid/dist/stringify.js
 521    var byteToHex = [];
 522    for (let i = 0; i < 256; ++i) {
 523      byteToHex.push((i + 256).toString(16).slice(1));
 524    }
 525    function unsafeStringify(arr, offset = 0) {
 526      return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
 527    }
 528  
 529    // node_modules/.store/uuid@14.0.2-ALlTd6-Rf9bZs703d7TIjQ/node_modules/uuid/dist/rng.js
 530    var rnds8 = new Uint8Array(16);
 531    function rng() {
 532      return crypto.getRandomValues(rnds8);
 533    }
 534  
 535    // node_modules/.store/uuid@14.0.2-ALlTd6-Rf9bZs703d7TIjQ/node_modules/uuid/dist/v4.js
 536    function v4(options, buf, offset) {
 537      if (!buf && !options && crypto.randomUUID) {
 538        return crypto.randomUUID();
 539      }
 540      return _v4(options, buf, offset);
 541    }
 542    function _v4(options, buf, offset) {
 543      options = options || {};
 544      const rnds = options.random ?? options.rng?.() ?? rng();
 545      if (rnds.length < 16) {
 546        throw new Error("Random bytes length must be >= 16");
 547      }
 548      rnds[6] = rnds[6] & 15 | 64;
 549      rnds[8] = rnds[8] & 63 | 128;
 550      if (buf) {
 551        offset = offset || 0;
 552        if (offset < 0 || offset + 16 > buf.length) {
 553          throw new RangeError(`UUID byte range $offset}:$offset + 15} is out of buffer bounds`);
 554        }
 555        for (let i = 0; i < 16; ++i) {
 556          buf[offset + i] = rnds[i];
 557        }
 558        return buf;
 559      }
 560      return unsafeStringify(rnds);
 561    }
 562    var v4_default = v4;
 563  
 564    // packages/upload-media/build-module/store/actions.mjs
 565    var import_i18n4 = __toESM(require_i18n(), 1);
 566  
 567    // packages/upload-media/build-module/store/utils/retry.mjs
 568    function calculateRetryDelay(options) {
 569      const { attempt, initialDelay, maxDelay, multiplier, jitter } = options;
 570      const exponentialDelay = initialDelay * Math.pow(multiplier, attempt - 1);
 571      const cappedDelay = Math.min(exponentialDelay, maxDelay);
 572      const jitterFactor = 1 + (Math.random() * 2 - 1) * jitter;
 573      return Math.floor(cappedDelay * jitterFactor);
 574    }
 575    var RETRYABLE_MESSAGE_PATTERNS = [
 576      /network/i,
 577      /timeout/i,
 578      /ECONNRESET/i,
 579      /fetch failed/i,
 580      /connection/i,
 581      /socket/i,
 582      /ETIMEDOUT/i,
 583      /ENOTFOUND/i,
 584      /Could not get a valid response/i,
 585      /Failed to fetch/i,
 586      /Load failed/i
 587    ];
 588    function shouldRetryError(error, retryCount, maxRetries) {
 589      if (retryCount >= maxRetries) {
 590        return false;
 591      }
 592      const message = typeof error === "string" ? error : error?.message || "";
 593      return RETRYABLE_MESSAGE_PATTERNS.some(
 594        (pattern) => pattern.test(message)
 595      );
 596    }
 597    var retryTimers = /* @__PURE__ */ new Map();
 598    function clearRetryTimer(id) {
 599      const pendingTimer = retryTimers.get(id);
 600      if (pendingTimer !== void 0) {
 601        clearTimeout(pendingTimer);
 602        retryTimers.delete(id);
 603      }
 604    }
 605  
 606    // packages/upload-media/build-module/feature-detection.mjs
 607    var cachedResult = null;
 608    function detectClientSideMediaSupport() {
 609      if (cachedResult !== null) {
 610        return cachedResult;
 611      }
 612      if (typeof WebAssembly === "undefined") {
 613        cachedResult = {
 614          supported: false,
 615          reason: "WebAssembly is not supported in this browser."
 616        };
 617        return cachedResult;
 618      }
 619      if (typeof SharedArrayBuffer === "undefined") {
 620        cachedResult = {
 621          supported: false,
 622          reason: "SharedArrayBuffer is not available. This may be due to missing cross-origin isolation headers."
 623        };
 624        return cachedResult;
 625      }
 626      if (typeof Worker === "undefined") {
 627        cachedResult = {
 628          supported: false,
 629          reason: "Web Workers are not supported in this browser."
 630        };
 631        return cachedResult;
 632      }
 633      if (typeof navigator !== "undefined" && "deviceMemory" in navigator && navigator.deviceMemory <= 2) {
 634        cachedResult = {
 635          supported: false,
 636          reason: "Device has insufficient memory for client-side media processing."
 637        };
 638        return cachedResult;
 639      }
 640      if (typeof navigator !== "undefined" && "hardwareConcurrency" in navigator && navigator.hardwareConcurrency < 2) {
 641        cachedResult = {
 642          supported: false,
 643          reason: "Device has insufficient CPU cores for client-side media processing."
 644        };
 645        return cachedResult;
 646      }
 647      if (typeof navigator !== "undefined") {
 648        const connection = navigator.connection;
 649        if (connection) {
 650          if (connection.saveData) {
 651            cachedResult = {
 652              supported: false,
 653              reason: "Data saver mode is enabled."
 654            };
 655            return cachedResult;
 656          }
 657          if (connection.effectiveType === "slow-2g" || connection.effectiveType === "2g") {
 658            cachedResult = {
 659              supported: false,
 660              reason: "Network connection is too slow for client-side media processing."
 661            };
 662            return cachedResult;
 663          }
 664        }
 665      }
 666      if (typeof window !== "undefined") {
 667        try {
 668          const testBlob = new Blob([""], {
 669            type: "application/javascript"
 670          });
 671          const testUrl = URL.createObjectURL(testBlob);
 672          try {
 673            const testWorker = new Worker(testUrl);
 674            testWorker.terminate();
 675          } finally {
 676            URL.revokeObjectURL(testUrl);
 677          }
 678        } catch {
 679          cachedResult = {
 680            supported: false,
 681            reason: "The site's Content Security Policy (CSP) does not allow blob: workers. The worker-src directive must include blob: to enable client-side media processing."
 682          };
 683          return cachedResult;
 684        }
 685      }
 686      cachedResult = { supported: true };
 687      return cachedResult;
 688    }
 689    function isClientSideMediaSupported() {
 690      return detectClientSideMediaSupport().supported;
 691    }
 692    function isHeicCanvasSupported() {
 693      return typeof createImageBitmap !== "undefined" && typeof OffscreenCanvas !== "undefined";
 694    }
 695    function clearFeatureDetectionCache() {
 696      cachedResult = null;
 697    }
 698    var BYTES_PER_PIXEL = 4;
 699    var INTERLACED_MEMORY_BUDGET = 0.75 * 1024 * 1024 * 1024;
 700    var BASELINE_MEMORY_BUDGET = 1.5 * 1024 * 1024 * 1024;
 701    function exceedsClientProcessingMemory(dimensions) {
 702      const { width, height, interlaced } = dimensions;
 703      const estimatedBytes = width * height * BYTES_PER_PIXEL;
 704      const budget = interlaced ? INTERLACED_MEMORY_BUDGET : BASELINE_MEMORY_BUDGET;
 705      return estimatedBytes > budget;
 706    }
 707  
 708    // packages/upload-media/build-module/image-file.mjs
 709    var ImageFile = class extends File {
 710      width = 0;
 711      height = 0;
 712      originalWidth = 0;
 713      originalHeight = 0;
 714      get wasResized() {
 715        return (this.originalWidth || 0) > this.width || (this.originalHeight || 0) > this.height;
 716      }
 717      constructor(file, width, height, originalWidth, originalHeight) {
 718        super([file], file.name, {
 719          type: file.type,
 720          lastModified: file.lastModified
 721        });
 722        this.width = width;
 723        this.height = height;
 724        this.originalWidth = originalWidth;
 725        this.originalHeight = originalHeight;
 726      }
 727    };
 728  
 729    // packages/upload-media/build-module/utils.mjs
 730    function convertBlobToFile(fileOrBlob) {
 731      if (fileOrBlob instanceof File) {
 732        return fileOrBlob;
 733      }
 734      if ("name" in fileOrBlob && typeof fileOrBlob.name === "string") {
 735        return new File([fileOrBlob], fileOrBlob.name, {
 736          type: fileOrBlob.type,
 737          lastModified: fileOrBlob.lastModified
 738        });
 739      }
 740      const ext = fileOrBlob.type.split("/")[1];
 741      const mediaType = "application/pdf" === fileOrBlob.type ? "document" : fileOrBlob.type.split("/")[0];
 742      return new File([fileOrBlob], `$mediaType}.$ext}`, {
 743        type: fileOrBlob.type
 744      });
 745    }
 746    function renameFile(file, name) {
 747      return new File([file], name, {
 748        type: file.type,
 749        lastModified: file.lastModified
 750      });
 751    }
 752    function cloneFile(file) {
 753      return renameFile(file, file.name);
 754    }
 755    function getFileBasename(name) {
 756      return name.includes(".") ? name.split(".").slice(0, -1).join(".") : name;
 757    }
 758    function isAnimatedGif(buffer) {
 759      const view = new Uint8Array(buffer);
 760      if (view.length < 4 || view[0] !== 71 || view[1] !== 73 || view[2] !== 70 || view[3] !== 56) {
 761        return false;
 762      }
 763      let frameCount = 0;
 764      for (let i = 0; i < view.length - 2; i++) {
 765        if (view[i] === 0 && view[i + 1] === 33 && view[i + 2] === 249) {
 766          frameCount++;
 767          if (frameCount > 1) {
 768            return true;
 769          }
 770        }
 771      }
 772      return false;
 773    }
 774    var FILE_TYPE_BOX_BYTES = 64;
 775    var HEIC_BRANDS = [
 776      "heic",
 777      "heix",
 778      "heim",
 779      "heis",
 780      "hevc",
 781      "hevx",
 782      "hevm",
 783      "hevs",
 784      "mif1",
 785      "msf1"
 786    ];
 787    var AVIF_BRANDS = ["avif", "avis"];
 788    function isHeicBuffer(buffer) {
 789      const view = new Uint8Array(buffer);
 790      const readBrand = (offset) => String.fromCharCode(...view.subarray(offset, offset + 4));
 791      if (view.length < 12 || readBrand(4) !== "ftyp") {
 792        return false;
 793      }
 794      const boxEnd = Math.min(
 795        view.length,
 796        new DataView(buffer).getUint32(0)
 797      );
 798      const brands = [readBrand(8)];
 799      for (let offset = 16; offset + 4 <= boxEnd; offset += 4) {
 800        brands.push(readBrand(offset));
 801      }
 802      if (brands.some((brand) => AVIF_BRANDS.includes(brand))) {
 803        return false;
 804      }
 805      return brands.some((brand) => HEIC_BRANDS.includes(brand));
 806    }
 807    async function isHeicFile(file) {
 808      if (HEIC_MIME_TYPES.includes(file.type)) {
 809        return true;
 810      }
 811      if (file.type && !file.type.startsWith("image/")) {
 812        return false;
 813      }
 814      try {
 815        return isHeicBuffer(
 816          await file.slice(0, FILE_TYPE_BOX_BYTES).arrayBuffer()
 817        );
 818      } catch {
 819        return false;
 820      }
 821    }
 822  
 823    // packages/upload-media/build-module/store/utils/index.mjs
 824    var vipsModulePromise;
 825    var vipsModule;
 826    function loadVipsModule() {
 827      if (!vipsModulePromise) {
 828        vipsModulePromise = import("@wordpress/vips/worker").then(
 829          (mod) => {
 830            vipsModule = mod;
 831            return mod;
 832          }
 833        );
 834      }
 835      return vipsModulePromise;
 836    }
 837    async function vipsConvertImageFormat(id, file, type, options = {}) {
 838      const { vipsConvertImageFormat: convertImageFormat } = await loadVipsModule();
 839      const buffer = await convertImageFormat(
 840        id,
 841        await file.arrayBuffer(),
 842        file.type,
 843        type,
 844        options
 845      );
 846      const ext = type.split("/")[1];
 847      const fileName = `$getFileBasename(file.name)}.$ext}`;
 848      return new File([new Blob([buffer])], fileName, {
 849        type
 850      });
 851    }
 852    async function vipsEncodeCanvasAsJpeg(id, canvas, source, quality) {
 853      const { width, height } = canvas;
 854      if (exceedsClientProcessingMemory({ width, height, interlaced: true })) {
 855        return null;
 856      }
 857      const { vipsEncodePixelsAsJpeg: encodePixelsAsJpeg } = await loadVipsModule();
 858      const ctx = canvas.getContext("2d");
 859      if (!ctx) {
 860        throw new Error("Could not get canvas 2d context");
 861      }
 862      const pixels = ctx.getImageData(0, 0, width, height).data.buffer;
 863      const buffer = await encodePixelsAsJpeg(id, pixels, width, height, {
 864        quality,
 865        metadataSource: await source.arrayBuffer()
 866      });
 867      return new Blob([buffer], { type: "image/jpeg" });
 868    }
 869    async function vipsHasTransparency(url) {
 870      const { vipsHasTransparency: hasTransparency } = await loadVipsModule();
 871      const response = await fetch(url);
 872      if (!response.ok) {
 873        throw new Error(`Failed to fetch image: $response.status}`);
 874      }
 875      return hasTransparency(await response.arrayBuffer());
 876    }
 877    async function vipsGetUltraHdrInfo(buffer) {
 878      const { vipsGetUltraHdrInfo: getUltraHdrInfo } = await loadVipsModule();
 879      return getUltraHdrInfo(buffer);
 880    }
 881    async function vipsResizeImage(id, file, resize, options = {}) {
 882      const {
 883        smartCrop = false,
 884        addSuffix = false,
 885        signal,
 886        scaledSuffix,
 887        quality,
 888        stripMeta,
 889        maxBitdepth,
 890        preserveAnimation
 891      } = options;
 892      if (signal?.aborted) {
 893        throw new Error("Operation aborted");
 894      }
 895      const { vipsResizeImage: resizeImage } = await loadVipsModule();
 896      const { buffer, width, height, originalWidth, originalHeight } = await resizeImage(id, await file.arrayBuffer(), file.type, resize, {
 897        smartCrop,
 898        quality,
 899        stripMeta,
 900        maxBitdepth,
 901        preserveAnimation
 902      });
 903      let fileName = file.name;
 904      const wasResized = originalWidth > width || originalHeight > height;
 905      if (wasResized) {
 906        const basename = getFileBasename(file.name);
 907        if (scaledSuffix) {
 908          fileName = file.name.replace(basename, `$basename}-scaled`);
 909        } else if (addSuffix) {
 910          fileName = file.name.replace(
 911            basename,
 912            `$basename}-$width}x$height}`
 913          );
 914        }
 915      }
 916      const resultFile = new ImageFile(
 917        new File(
 918          [new Blob([buffer], { type: file.type })],
 919          fileName,
 920          {
 921            type: file.type
 922          }
 923        ),
 924        width,
 925        height,
 926        originalWidth,
 927        originalHeight
 928      );
 929      return resultFile;
 930    }
 931    async function vipsRotateImage(id, file, orientation, signal) {
 932      if (signal?.aborted) {
 933        throw new Error("Operation aborted");
 934      }
 935      if (orientation === 1) {
 936        return file;
 937      }
 938      const { vipsRotateImage: rotateImage } = await loadVipsModule();
 939      const { buffer, width, height } = await rotateImage(
 940        id,
 941        await file.arrayBuffer(),
 942        file.type,
 943        orientation
 944      );
 945      const basename = getFileBasename(file.name);
 946      const fileName = file.name.replace(basename, `$basename}-rotated`);
 947      const resultFile = new ImageFile(
 948        new File(
 949          [new Blob([buffer], { type: file.type })],
 950          fileName,
 951          {
 952            type: file.type
 953          }
 954        ),
 955        width,
 956        height
 957      );
 958      return resultFile;
 959    }
 960    async function vipsCancelOperations(id) {
 961      if (!vipsModule) {
 962        return false;
 963      }
 964      return vipsModule.vipsCancelOperations(id);
 965    }
 966    function terminateVipsWorker() {
 967      if (vipsModule) {
 968        vipsModule.terminateVipsWorker();
 969      }
 970    }
 971    var completedVipsOperations = 0;
 972    var MAX_VIPS_OPS_BEFORE_RECYCLE = 50;
 973    function maybeRecycleVipsWorker(activeImageProcessingCount) {
 974      completedVipsOperations++;
 975      if (completedVipsOperations >= MAX_VIPS_OPS_BEFORE_RECYCLE && activeImageProcessingCount === 0) {
 976        terminateVipsWorker();
 977        completedVipsOperations = 0;
 978      }
 979    }
 980  
 981    // packages/upload-media/build-module/store/utils/video-conversion.mjs
 982    var UNSUPPORTED_ERROR_PREFIX = "Unsupported";
 983    var SIZE_LIMIT_ERROR_PREFIX = `$UNSUPPORTED_ERROR_PREFIX}: GIF exceeds maximum conversion size`;
 984    var CONVERSION_TIMEOUT_ERROR_PREFIX = "GIF to video conversion timed out";
 985    var DEFAULT_CONVERSION_TIMEOUT = 3e4;
 986    function isUnsupportedConversionError(error) {
 987      return error instanceof Error && error.message.startsWith(UNSUPPORTED_ERROR_PREFIX);
 988    }
 989    function isSizeLimitConversionError(error) {
 990      return error instanceof Error && error.message.startsWith(SIZE_LIMIT_ERROR_PREFIX);
 991    }
 992    function isConversionTimeoutError(error) {
 993      return error instanceof Error && error.message.startsWith(CONVERSION_TIMEOUT_ERROR_PREFIX);
 994    }
 995    var videoConversionModulePromise;
 996    var videoConversionModule;
 997    function loadVideoConversionModule() {
 998      if (!videoConversionModulePromise) {
 999        videoConversionModulePromise = import("@wordpress/video-conversion/worker").then((mod) => {
1000          videoConversionModule = mod;
1001          return mod;
1002        }).catch((error) => {
1003          videoConversionModulePromise = void 0;
1004          throw error;
1005        });
1006      }
1007      return videoConversionModulePromise;
1008    }
1009    async function convertGifToVideo(id, file, outputMimeType, {
1010      maxDimensions,
1011      timeout = DEFAULT_CONVERSION_TIMEOUT,
1012      maxTotalPixels
1013    } = {}) {
1014      const mod = await loadVideoConversionModule();
1015      const conversion = mod.convertGifToVideo(
1016        id,
1017        file,
1018        outputMimeType,
1019        maxDimensions,
1020        maxTotalPixels
1021      );
1022      let buffer;
1023      if (timeout > 0) {
1024        let timer;
1025        try {
1026          buffer = await Promise.race([
1027            conversion,
1028            new Promise((_, reject) => {
1029              timer = setTimeout(() => {
1030                reject(
1031                  new Error(
1032                    `$CONVERSION_TIMEOUT_ERROR_PREFIX} after $timeout}ms`
1033                  )
1034                );
1035              }, timeout);
1036            })
1037          ]);
1038        } catch (error) {
1039          if (isConversionTimeoutError(error)) {
1040            conversion.catch(() => {
1041            });
1042            mod.cancelGifToVideoOperations(id).catch(() => {
1043            });
1044          }
1045          throw error;
1046        } finally {
1047          clearTimeout(timer);
1048        }
1049      } else {
1050        buffer = await conversion;
1051      }
1052      const ext = outputMimeType === "video/webm" ? "webm" : "mp4";
1053      const fileName = `$getFileBasename(file.name)}.$ext}`;
1054      return new File(
1055        [new Blob([buffer], { type: outputMimeType })],
1056        fileName,
1057        { type: outputMimeType }
1058      );
1059    }
1060    async function cancelGifToVideoOperations(id) {
1061      const mod = videoConversionModule ?? (videoConversionModulePromise ? await videoConversionModulePromise.catch(() => void 0) : void 0);
1062      if (!mod) {
1063        return false;
1064      }
1065      return mod.cancelGifToVideoOperations(id);
1066    }
1067    function terminateVideoConversionWorker() {
1068      if (videoConversionModule) {
1069        videoConversionModule.terminateVideoConversionWorker();
1070        return;
1071      }
1072      if (videoConversionModulePromise) {
1073        void videoConversionModulePromise.then((mod) => mod.terminateVideoConversionWorker()).catch(() => {
1074        });
1075      }
1076    }
1077  
1078    // packages/upload-media/build-module/store/utils/debug-logger.mjs
1079    function isDebugEnabled() {
1080      return true;
1081    }
1082    function debug(message, ...args) {
1083      if (!isDebugEnabled()) {
1084        return;
1085      }
1086      console.debug(`[upload-media] $message}`, ...args);
1087    }
1088    function measure(options) {
1089      if (!isDebugEnabled()) {
1090        return;
1091      }
1092      const {
1093        measureName,
1094        startTime,
1095        endTime = performance.now(),
1096        tooltipText,
1097        properties
1098      } = options;
1099      const detail = {
1100        devtools: {
1101          dataType: "track-entry",
1102          track: "Upload Media",
1103          tooltipText,
1104          properties: properties?.map(([key, value]) => ({
1105            key,
1106            value
1107          }))
1108        }
1109      };
1110      try {
1111        performance.measure(measureName, {
1112          start: startTime,
1113          end: endTime,
1114          detail
1115        });
1116      } catch {
1117      }
1118    }
1119  
1120    // packages/upload-media/build-module/upload-error.mjs
1121    var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
1122      ErrorCode2["EMPTY_FILE"] = "EMPTY_FILE";
1123      ErrorCode2["SIZE_ABOVE_LIMIT"] = "SIZE_ABOVE_LIMIT";
1124      ErrorCode2["MIME_TYPE_NOT_SUPPORTED"] = "MIME_TYPE_NOT_SUPPORTED";
1125      ErrorCode2["MIME_TYPE_NOT_ALLOWED_FOR_USER"] = "MIME_TYPE_NOT_ALLOWED_FOR_USER";
1126      ErrorCode2["HEIC_DECODE_ERROR"] = "HEIC_DECODE_ERROR";
1127      ErrorCode2["IMAGE_TRANSCODING_ERROR"] = "IMAGE_TRANSCODING_ERROR";
1128      ErrorCode2["IMAGE_ROTATION_ERROR"] = "IMAGE_ROTATION_ERROR";
1129      ErrorCode2["MEDIA_TRANSCODING_ERROR"] = "MEDIA_TRANSCODING_ERROR";
1130      ErrorCode2["GIF_TRANSCODING_ERROR"] = "GIF_TRANSCODING_ERROR";
1131      ErrorCode2["MEDIA_FINALIZE_ERROR"] = "MEDIA_FINALIZE_ERROR";
1132      ErrorCode2["GENERAL"] = "GENERAL";
1133      return ErrorCode2;
1134    })(ErrorCode || {});
1135    var UploadError = class extends Error {
1136      code;
1137      file;
1138      constructor({ code, message, file, cause }) {
1139        super(message, { cause });
1140        Object.setPrototypeOf(this, new.target.prototype);
1141        this.code = code;
1142        this.file = file;
1143      }
1144    };
1145  
1146    // packages/upload-media/build-module/validate-mime-type.mjs
1147    var import_i18n = __toESM(require_i18n(), 1);
1148    function validateMimeType(file, allowedTypes) {
1149      if (!allowedTypes) {
1150        return;
1151      }
1152      const isAllowedType = allowedTypes.some((allowedType) => {
1153        if (allowedType.includes("/")) {
1154          return allowedType === file.type;
1155        }
1156        return file.type.startsWith(`$allowedType}/`);
1157      });
1158      if (file.type && !isAllowedType) {
1159        throw new UploadError({
1160          code: ErrorCode.MIME_TYPE_NOT_SUPPORTED,
1161          message: (0, import_i18n.sprintf)(
1162            // translators: %s: file name.
1163            (0, import_i18n.__)("%s: Sorry, this file type is not supported here."),
1164            file.name
1165          ),
1166          file
1167        });
1168      }
1169    }
1170  
1171    // packages/upload-media/build-module/validate-mime-type-for-user.mjs
1172    var import_i18n2 = __toESM(require_i18n(), 1);
1173  
1174    // packages/upload-media/build-module/get-mime-types-array.mjs
1175    function getMimeTypesArray(wpMimeTypesObject) {
1176      if (!wpMimeTypesObject) {
1177        return null;
1178      }
1179      return Object.entries(wpMimeTypesObject).flatMap(
1180        ([extensionsString, mime]) => {
1181          const [type] = mime.split("/");
1182          const extensions = extensionsString.split("|");
1183          return [
1184            mime,
1185            ...extensions.map(
1186              (extension) => `$type}/$extension}`
1187            )
1188          ];
1189        }
1190      );
1191    }
1192  
1193    // packages/upload-media/build-module/validate-mime-type-for-user.mjs
1194    function validateMimeTypeForUser(file, wpAllowedMimeTypes) {
1195      const allowedMimeTypesForUser = getMimeTypesArray(wpAllowedMimeTypes);
1196      if (!allowedMimeTypesForUser) {
1197        return;
1198      }
1199      const isAllowedMimeTypeForUser = allowedMimeTypesForUser.includes(
1200        file.type
1201      );
1202      if (file.type && !isAllowedMimeTypeForUser) {
1203        throw new UploadError({
1204          code: ErrorCode.MIME_TYPE_NOT_ALLOWED_FOR_USER,
1205          message: (0, import_i18n2.sprintf)(
1206            // translators: %s: file name.
1207            (0, import_i18n2.__)(
1208              "%s: Sorry, you are not allowed to upload this file type."
1209            ),
1210            file.name
1211          ),
1212          file
1213        });
1214      }
1215    }
1216  
1217    // packages/upload-media/build-module/validate-file-size.mjs
1218    var import_i18n3 = __toESM(require_i18n(), 1);
1219    function validateFileSize(file, maxUploadFileSize) {
1220      if (file.size <= 0) {
1221        throw new UploadError({
1222          code: ErrorCode.EMPTY_FILE,
1223          message: (0, import_i18n3.sprintf)(
1224            // translators: %s: file name.
1225            (0, import_i18n3.__)("%s: This file is empty."),
1226            file.name
1227          ),
1228          file
1229        });
1230      }
1231      if (maxUploadFileSize && file.size > maxUploadFileSize) {
1232        throw new UploadError({
1233          code: ErrorCode.SIZE_ABOVE_LIMIT,
1234          message: (0, import_i18n3.sprintf)(
1235            // translators: %s: file name.
1236            (0, import_i18n3.__)(
1237              "%s: This file exceeds the maximum upload size for this site."
1238            ),
1239            file.name
1240          ),
1241          file
1242        });
1243      }
1244    }
1245  
1246    // packages/upload-media/build-module/store/actions.mjs
1247    function addItems({
1248      files,
1249      onChange,
1250      onSuccess,
1251      onError,
1252      onBatchSuccess,
1253      additionalData,
1254      allowedTypes
1255    }) {
1256      return async ({ select: select2, dispatch }) => {
1257        const batchId = v4_default();
1258        for (const file of files) {
1259          try {
1260            validateMimeType(file, allowedTypes);
1261            validateMimeTypeForUser(
1262              file,
1263              select2.getSettings().allowedMimeTypes
1264            );
1265          } catch (error) {
1266            onError?.(error);
1267            continue;
1268          }
1269          try {
1270            validateFileSize(
1271              file,
1272              select2.getSettings().maxUploadFileSize
1273            );
1274          } catch (error) {
1275            onError?.(error);
1276            continue;
1277          }
1278          dispatch.addItem({
1279            file,
1280            batchId,
1281            onChange,
1282            onSuccess,
1283            onBatchSuccess,
1284            onError,
1285            additionalData
1286          });
1287        }
1288      };
1289    }
1290    function cancelItem(id, error, silent = false) {
1291      return async ({ select: select2, dispatch }) => {
1292        const item = select2.getItem(id);
1293        if (!item) {
1294          return;
1295        }
1296        clearRetryTimer(id);
1297        if (!silent && error && !item.parentId && !item.attachment?.id) {
1298          const settings = select2.getSettings();
1299          const retrySettings = settings.retry;
1300          if (retrySettings) {
1301            const retryCount = item.retryCount ?? 0;
1302            const maxRetries = retrySettings.maxRetryAttempts;
1303            if (shouldRetryError(error, retryCount, maxRetries)) {
1304              dispatch.scheduleRetry(id, error);
1305              return;
1306            }
1307          }
1308        }
1309        item.abortController?.abort();
1310        vipsCancelOperations(id).catch(() => {
1311        });
1312        cancelGifToVideoOperations(id).catch(() => {
1313        });
1314        if (!silent) {
1315          const { onError } = item;
1316          onError?.(error ?? new Error("Upload cancelled"));
1317          if (!onError && error && !item.parentId) {
1318            console.error("Upload cancelled", error);
1319          }
1320        } else {
1321          debug(
1322            `Item cancelled: $item.file.name} (item $id}): $error instanceof Error ? error.message : error}`
1323          );
1324        }
1325        const { currentOperation, parentId, batchId } = item;
1326        dispatch({
1327          type: Type.Cancel,
1328          id,
1329          error
1330        });
1331        dispatch.removeItem(id);
1332        dispatch.revokeBlobUrls(id);
1333        if (currentOperation === OperationType.ResizeCrop || currentOperation === OperationType.Rotate) {
1334          for (const pending of select2.getPendingImageProcessing()) {
1335            dispatch.processItem(pending.id);
1336          }
1337        }
1338        if (currentOperation === OperationType.Upload) {
1339          for (const pending of select2.getPendingUploads()) {
1340            dispatch.processItem(pending.id);
1341          }
1342        }
1343        if (currentOperation === OperationType.TranscodeGif) {
1344          for (const pending of select2.getPendingVideoProcessing()) {
1345            dispatch.processItem(pending.id);
1346          }
1347        }
1348        if (currentOperation === OperationType.ResizeCrop || currentOperation === OperationType.Rotate || currentOperation === OperationType.TranscodeImage) {
1349          maybeRecycleVipsWorker(select2.getActiveImageProcessingCount());
1350        }
1351        if (parentId) {
1352          const parentItem = select2.getItem(parentId);
1353          if (parentItem) {
1354            const isOptionalCompanion = item.additionalData?.image_size === "animated_video" || item.additionalData?.image_size === "animated_video_poster";
1355            if (select2.hasPendingItemsByParentId(parentId)) {
1356              if (parentItem.operations && parentItem.operations.length > 0) {
1357                dispatch.processItem(parentId);
1358              }
1359            } else if (parentItem.subSizes && parentItem.subSizes.length > 0 || isOptionalCompanion) {
1360              if (parentItem.operations && parentItem.operations.length > 0) {
1361                dispatch.processItem(parentId);
1362              }
1363            } else {
1364              const parentAttachmentId = parentItem.attachment?.id;
1365              const { mediaDelete } = select2.getSettings();
1366              if (parentAttachmentId && mediaDelete) {
1367                mediaDelete(parentAttachmentId).catch(() => {
1368                });
1369              }
1370              await dispatch.cancelItem(
1371                parentId,
1372                new UploadError({
1373                  code: error instanceof UploadError && error.code || ErrorCode.GENERAL,
1374                  message: error?.message || (0, import_i18n4.__)("The image could not be uploaded."),
1375                  file: parentItem.file,
1376                  cause: error instanceof Error ? error : void 0
1377                })
1378              );
1379            }
1380          }
1381        }
1382        if (batchId && select2.isBatchUploaded(batchId)) {
1383          debug(`Batch completed: $batchId}`);
1384          item.onBatchSuccess?.();
1385        }
1386      };
1387    }
1388    function retryItem(id) {
1389      return async ({ select: select2, dispatch }) => {
1390        const item = select2.getItem(id);
1391        if (!item) {
1392          return;
1393        }
1394        if (!item.error) {
1395          return;
1396        }
1397        dispatch({
1398          type: Type.RetryItem,
1399          id
1400        });
1401        dispatch.processItem(id);
1402      };
1403    }
1404    function scheduleRetry(id, error) {
1405      return async ({ select: select2, dispatch }) => {
1406        const item = select2.getItem(id);
1407        if (!item) {
1408          return;
1409        }
1410        const settings = select2.getSettings();
1411        const retrySettings = settings.retry;
1412        if (!retrySettings) {
1413          return;
1414        }
1415        const currentRetryCount = item.retryCount ?? 0;
1416        const delay = calculateRetryDelay({
1417          attempt: currentRetryCount + 1,
1418          initialDelay: retrySettings.initialRetryDelayMs,
1419          maxDelay: retrySettings.maxRetryDelayMs,
1420          multiplier: retrySettings.backoffMultiplier,
1421          jitter: retrySettings.retryJitter
1422        });
1423        const timerId = setTimeout(() => {
1424          retryTimers.delete(id);
1425          dispatch.executeRetry(id);
1426        }, delay);
1427        retryTimers.set(id, timerId);
1428        dispatch({
1429          type: Type.ScheduleRetry,
1430          id,
1431          error,
1432          retryCount: currentRetryCount,
1433          nextRetryTimestamp: Date.now() + delay
1434        });
1435      };
1436    }
1437    function executeRetry(id) {
1438      return async ({ select: select2, dispatch }) => {
1439        const item = select2.getItem(id);
1440        if (!item || item.status !== ItemStatus.PendingRetry) {
1441          return;
1442        }
1443        if (select2.isPaused()) {
1444          return;
1445        }
1446        dispatch({
1447          type: Type.RetryItem,
1448          id
1449        });
1450        dispatch.processItem(id);
1451      };
1452    }
1453  
1454    // packages/upload-media/build-module/store/private-actions.mjs
1455    var private_actions_exports = {};
1456    __export(private_actions_exports, {
1457      addItem: () => addItem,
1458      addSideloadItem: () => addSideloadItem,
1459      detectUltraHdr: () => detectUltraHdr,
1460      finalizeItem: () => finalizeItem,
1461      finishOperation: () => finishOperation,
1462      generateThumbnails: () => generateThumbnails,
1463      getTranscodeImageOperation: () => getTranscodeImageOperation,
1464      pauseItem: () => pauseItem,
1465      pauseQueue: () => pauseQueue,
1466      prepareItem: () => prepareItem,
1467      processItem: () => processItem,
1468      removeItem: () => removeItem,
1469      resizeCropItem: () => resizeCropItem,
1470      resumeQueue: () => resumeQueue,
1471      revokeBlobUrls: () => revokeBlobUrls,
1472      rotateItem: () => rotateItem,
1473      sideloadItem: () => sideloadItem,
1474      transcodeGifItem: () => transcodeGifItem,
1475      transcodeImageItem: () => transcodeImageItem,
1476      updateItemProgress: () => updateItemProgress,
1477      updateSettings: () => updateSettings,
1478      uploadItem: () => uploadItem
1479    });
1480    var import_blob = __toESM(require_blob(), 1);
1481    var import_i18n6 = __toESM(require_i18n(), 1);
1482  
1483    // packages/upload-media/build-module/heic-parser.mjs
1484    var Reader = class {
1485      view;
1486      buffer;
1487      pos;
1488      constructor(buffer, offset = 0) {
1489        this.buffer = buffer;
1490        this.view = new DataView(buffer);
1491        this.pos = offset;
1492      }
1493      u8() {
1494        const v = this.view.getUint8(this.pos);
1495        this.pos += 1;
1496        return v;
1497      }
1498      u16() {
1499        const v = this.view.getUint16(this.pos);
1500        this.pos += 2;
1501        return v;
1502      }
1503      u32() {
1504        const v = this.view.getUint32(this.pos);
1505        this.pos += 4;
1506        return v;
1507      }
1508      u64() {
1509        const hi = this.view.getUint32(this.pos);
1510        const lo = this.view.getUint32(this.pos + 4);
1511        this.pos += 8;
1512        return hi * 4294967296 + lo;
1513      }
1514      /**
1515       * Read a variable-width unsigned integer (0, 4 or 8 bytes).
1516       *
1517       * @param size Byte width to read (0, 4, or 8).
1518       */
1519      uN(size) {
1520        if (size === 0) {
1521          return 0;
1522        }
1523        if (size === 4) {
1524          return this.u32();
1525        }
1526        if (size === 8) {
1527          return this.u64();
1528        }
1529        throw new Error(`Unsupported uint size: $size}`);
1530      }
1531      str(len) {
1532        let s = "";
1533        for (let i = 0; i < len; i++) {
1534          s += String.fromCharCode(this.view.getUint8(this.pos + i));
1535        }
1536        this.pos += len;
1537        return s;
1538      }
1539      bytes(len) {
1540        const b = new Uint8Array(this.buffer, this.pos, len);
1541        this.pos += len;
1542        return new Uint8Array(b);
1543      }
1544    };
1545    function readBox(r) {
1546      if (r.pos + 8 > r.view.byteLength) {
1547        return null;
1548      }
1549      const offset = r.pos;
1550      let size = r.u32();
1551      const type = r.str(4);
1552      let headerSize = 8;
1553      if (size === 1) {
1554        size = r.u64();
1555        headerSize = 16;
1556      } else if (size === 0) {
1557        size = r.view.byteLength - offset;
1558      }
1559      return { type, offset, size, headerSize };
1560    }
1561    function findBoxes(r, start, end) {
1562      const boxes = [];
1563      r.pos = start;
1564      while (r.pos < end) {
1565        const box = readBox(r);
1566        if (!box || box.size < 8) {
1567          break;
1568        }
1569        boxes.push(box);
1570        r.pos = box.offset + box.size;
1571      }
1572      return boxes;
1573    }
1574    function findBox(r, start, end, type) {
1575      r.pos = start;
1576      while (r.pos < end) {
1577        const box = readBox(r);
1578        if (!box || box.size < 8) {
1579          break;
1580        }
1581        if (box.type === type) {
1582          return box;
1583        }
1584        r.pos = box.offset + box.size;
1585      }
1586      return void 0;
1587    }
1588    function parsePitm(r, box) {
1589      r.pos = box.offset + box.headerSize;
1590      const version = r.u8();
1591      r.pos += 3;
1592      return version === 0 ? r.u16() : r.u32();
1593    }
1594    function parseIloc(r, box) {
1595      r.pos = box.offset + box.headerSize;
1596      const version = r.u8();
1597      r.pos += 3;
1598      const byte1 = r.u8();
1599      const offsetSize = byte1 >> 4 & 15;
1600      const lengthSize = byte1 & 15;
1601      const byte2 = r.u8();
1602      const baseOffsetSize = byte2 >> 4 & 15;
1603      const indexSize = version >= 1 ? byte2 & 15 : 0;
1604      const itemCount = version < 2 ? r.u16() : r.u32();
1605      const items = /* @__PURE__ */ new Map();
1606      for (let i = 0; i < itemCount; i++) {
1607        const itemId = version < 2 ? r.u16() : r.u32();
1608        let constructionMethod = 0;
1609        if (version === 1 || version === 2) {
1610          const cm = r.u16();
1611          constructionMethod = cm & 15;
1612        }
1613        r.u16();
1614        const baseOffset = r.uN(baseOffsetSize);
1615        const extentCount = r.u16();
1616        const extents = [];
1617        for (let j = 0; j < extentCount; j++) {
1618          if (version >= 1) {
1619            r.uN(indexSize);
1620          }
1621          const extOffset = r.uN(offsetSize);
1622          const extLength = r.uN(lengthSize);
1623          extents.push({
1624            offset: baseOffset + extOffset,
1625            length: extLength
1626          });
1627        }
1628        items.set(itemId, { constructionMethod, extents });
1629      }
1630      return items;
1631    }
1632    function parseIpma(r, box) {
1633      r.pos = box.offset + box.headerSize;
1634      const vf = r.u32();
1635      const version = vf >>> 24;
1636      const flags = vf & 16777215;
1637      const largeIndex = (flags & 1) !== 0;
1638      const entryCount = r.u32();
1639      const associations = /* @__PURE__ */ new Map();
1640      for (let i = 0; i < entryCount; i++) {
1641        const itemId = version < 1 ? r.u16() : r.u32();
1642        const assocCount = r.u8();
1643        const indices = [];
1644        for (let j = 0; j < assocCount; j++) {
1645          if (largeIndex) {
1646            indices.push(r.u16() & 32767);
1647          } else {
1648            indices.push(r.u8() & 127);
1649          }
1650        }
1651        associations.set(itemId, indices);
1652      }
1653      return associations;
1654    }
1655    function parseIspe(r, box) {
1656      r.pos = box.offset + box.headerSize + 4;
1657      return { width: r.u32(), height: r.u32() };
1658    }
1659    function parseIrot(r, box) {
1660      r.pos = box.offset + box.headerSize;
1661      return (r.u8() & 3) * 90;
1662    }
1663    function parseIinf(r, box) {
1664      r.pos = box.offset + box.headerSize;
1665      const version = r.u8();
1666      r.pos += 3;
1667      const entryCount = version === 0 ? r.u16() : r.u32();
1668      const itemTypes = /* @__PURE__ */ new Map();
1669      const entriesStart = r.pos;
1670      const boxEnd = box.offset + box.size;
1671      const infeBoxes = findBoxes(r, entriesStart, boxEnd);
1672      for (let i = 0; i < Math.min(entryCount, infeBoxes.length); i++) {
1673        const infe = infeBoxes[i];
1674        if (infe.type !== "infe") {
1675          continue;
1676        }
1677        r.pos = infe.offset + infe.headerSize;
1678        const infeVersion = r.u8();
1679        r.pos += 3;
1680        if (infeVersion >= 2) {
1681          const itemId = infeVersion === 2 ? r.u16() : r.u32();
1682          r.u16();
1683          const itemType = r.str(4);
1684          itemTypes.set(itemId, itemType);
1685        }
1686      }
1687      return itemTypes;
1688    }
1689    function parseIref(r, box, refType) {
1690      r.pos = box.offset + box.headerSize;
1691      const version = r.u8();
1692      r.pos += 3;
1693      const refs = /* @__PURE__ */ new Map();
1694      const boxEnd = box.offset + box.size;
1695      while (r.pos < boxEnd) {
1696        const refBox = readBox(r);
1697        if (!refBox || refBox.size < 8) {
1698          break;
1699        }
1700        r.pos = refBox.offset + refBox.headerSize;
1701        const fromId = version === 0 ? r.u16() : r.u32();
1702        const refCount = r.u16();
1703        const toIds = [];
1704        for (let i = 0; i < refCount; i++) {
1705          toIds.push(version === 0 ? r.u16() : r.u32());
1706        }
1707        if (refBox.type === refType) {
1708          refs.set(fromId, toIds);
1709        }
1710        r.pos = refBox.offset + refBox.size;
1711      }
1712      return refs;
1713    }
1714    function reverseBits32(n) {
1715      n = n >>> 1 & 1431655765 | (n & 1431655765) << 1;
1716      n = n >>> 2 & 858993459 | (n & 858993459) << 2;
1717      n = n >>> 4 & 252645135 | (n & 252645135) << 4;
1718      n = n >>> 8 & 16711935 | (n & 16711935) << 8;
1719      n = n >>> 16 | n << 16;
1720      return n >>> 0;
1721    }
1722    function buildCodecString(r, recordOffset) {
1723      r.pos = recordOffset;
1724      r.u8();
1725      const byte1 = r.u8();
1726      const profileSpace = byte1 >> 6 & 3;
1727      const tierFlag = byte1 >> 5 & 1;
1728      const profileIdc = byte1 & 31;
1729      const compatFlags = r.u32();
1730      const constraintBytes = r.bytes(6);
1731      const levelIdc = r.u8();
1732      const spacePrefix = profileSpace > 0 ? String.fromCharCode(64 + profileSpace) : "";
1733      const compatHex = reverseBits32(compatFlags).toString(16).toUpperCase();
1734      const tierChar = tierFlag ? "H" : "L";
1735      let lastNonZero = -1;
1736      for (let i = 5; i >= 0; i--) {
1737        if (constraintBytes[i] !== 0) {
1738          lastNonZero = i;
1739          break;
1740        }
1741      }
1742      let constraintStr = "";
1743      if (lastNonZero >= 0) {
1744        const parts = [];
1745        for (let i = 0; i <= lastNonZero; i++) {
1746          parts.push(constraintBytes[i].toString(16).toUpperCase());
1747        }
1748        constraintStr = "." + parts.join(".");
1749      }
1750      return `hvc1.$spacePrefix}$profileIdc}.$compatHex}.$tierChar}$levelIdc}$constraintStr}`;
1751    }
1752    function readItemData(buffer, loc, idatOffset) {
1753      const baseOffset = loc.constructionMethod === 1 ? idatOffset : 0;
1754      for (const ext of loc.extents) {
1755        if (baseOffset + ext.offset + ext.length > buffer.byteLength) {
1756          throw new Error(
1757            "HEIC item data extends past the end of the file"
1758          );
1759        }
1760      }
1761      if (loc.extents.length === 1) {
1762        const ext = loc.extents[0];
1763        const start = baseOffset + ext.offset;
1764        return new Uint8Array(buffer.slice(start, start + ext.length));
1765      }
1766      let totalLength = 0;
1767      for (const ext of loc.extents) {
1768        totalLength += ext.length;
1769      }
1770      const data = new Uint8Array(totalLength);
1771      let pos = 0;
1772      for (const ext of loc.extents) {
1773        const start = baseOffset + ext.offset;
1774        data.set(
1775          new Uint8Array(buffer.slice(start, start + ext.length)),
1776          pos
1777        );
1778        pos += ext.length;
1779      }
1780      return data;
1781    }
1782    function findHvcProperties(propIndices, properties) {
1783      let hvcCBox;
1784      let ispeBox;
1785      let irotBox;
1786      for (const idx of propIndices) {
1787        if (idx < 1 || idx > properties.length) {
1788          continue;
1789        }
1790        const prop = properties[idx - 1];
1791        if (prop.type === "hvcC" && !hvcCBox) {
1792          hvcCBox = prop;
1793        }
1794        if (prop.type === "ispe" && !ispeBox) {
1795          ispeBox = prop;
1796        }
1797        if (prop.type === "irot" && !irotBox) {
1798          irotBox = prop;
1799        }
1800      }
1801      if (!hvcCBox) {
1802        throw new Error("No HEVC configuration (hvcC) found");
1803      }
1804      if (!ispeBox) {
1805        throw new Error("No image dimensions (ispe) found");
1806      }
1807      return { hvcCBox, ispeBox, irotBox };
1808    }
1809    function parseHeic(buffer) {
1810      const r = new Reader(buffer);
1811      const fileEnd = buffer.byteLength;
1812      const metaBox = findBox(r, 0, fileEnd, "meta");
1813      if (!metaBox) {
1814        throw new Error("No meta box found in HEIC file");
1815      }
1816      const metaChildStart = metaBox.offset + metaBox.headerSize + 4;
1817      const metaEnd = metaBox.offset + metaBox.size;
1818      const children = findBoxes(r, metaChildStart, metaEnd);
1819      const pitmBox = children.find((b) => b.type === "pitm");
1820      const ilocBox = children.find((b) => b.type === "iloc");
1821      const iprpBox = children.find((b) => b.type === "iprp");
1822      const iinfBox = children.find((b) => b.type === "iinf");
1823      const irefBox = children.find((b) => b.type === "iref");
1824      const idatBox = children.find((b) => b.type === "idat");
1825      const idatOffset = idatBox ? idatBox.offset + idatBox.headerSize : 0;
1826      if (!pitmBox || !ilocBox || !iprpBox) {
1827        throw new Error("Missing required boxes (pitm, iloc, iprp) in HEIC");
1828      }
1829      const primaryId = parsePitm(r, pitmBox);
1830      const locations = parseIloc(r, ilocBox);
1831      const iprpStart = iprpBox.offset + iprpBox.headerSize;
1832      const iprpEnd = iprpBox.offset + iprpBox.size;
1833      const iprpChildren = findBoxes(r, iprpStart, iprpEnd);
1834      const ipcoBox = iprpChildren.find((b) => b.type === "ipco");
1835      const ipmaBox = iprpChildren.find((b) => b.type === "ipma");
1836      if (!ipcoBox || !ipmaBox) {
1837        throw new Error("Missing ipco or ipma in HEIC properties");
1838      }
1839      const allAssoc = parseIpma(r, ipmaBox);
1840      const ipcoStart = ipcoBox.offset + ipcoBox.headerSize;
1841      const ipcoEnd = ipcoBox.offset + ipcoBox.size;
1842      const properties = findBoxes(r, ipcoStart, ipcoEnd);
1843      let primaryItemType = "hvc1";
1844      if (iinfBox) {
1845        const itemTypes = parseIinf(r, iinfBox);
1846        const t = itemTypes.get(primaryId);
1847        if (t) {
1848          primaryItemType = t;
1849        }
1850      }
1851      if (primaryItemType === "grid") {
1852        return parseGridImage(
1853          r,
1854          buffer,
1855          primaryId,
1856          locations,
1857          allAssoc,
1858          properties,
1859          irefBox,
1860          idatOffset
1861        );
1862      }
1863      const primaryLoc = locations.get(primaryId);
1864      if (!primaryLoc || primaryLoc.extents.length === 0) {
1865        throw new Error(`No location data for primary item $primaryId}`);
1866      }
1867      const primaryPropIndices = allAssoc.get(primaryId);
1868      if (!primaryPropIndices || primaryPropIndices.length === 0) {
1869        throw new Error("No property associations for primary item");
1870      }
1871      const { hvcCBox, ispeBox, irotBox } = findHvcProperties(
1872        primaryPropIndices,
1873        properties
1874      );
1875      const hvcCDataStart = hvcCBox.offset + hvcCBox.headerSize;
1876      const hvcCDataSize = hvcCBox.size - hvcCBox.headerSize;
1877      const description = new Uint8Array(
1878        buffer.slice(hvcCDataStart, hvcCDataStart + hvcCDataSize)
1879      );
1880      const codecString = buildCodecString(r, hvcCDataStart);
1881      const { width, height } = parseIspe(r, ispeBox);
1882      const rotation = irotBox ? parseIrot(r, irotBox) : 0;
1883      return {
1884        codecString,
1885        description,
1886        tiles: [
1887          {
1888            data: readItemData(buffer, primaryLoc, idatOffset),
1889            x: 0,
1890            y: 0
1891          }
1892        ],
1893        tileWidth: width,
1894        tileHeight: height,
1895        outputWidth: width,
1896        outputHeight: height,
1897        rotation,
1898        exifOrientation: rotation === 0 ? getUnappliedExifOrientation(buffer) : 1
1899      };
1900    }
1901    function parseGridImage(r, buffer, gridItemId, locations, allAssoc, properties, irefBox, idatOffset) {
1902      const gridLoc = locations.get(gridItemId);
1903      if (!gridLoc || gridLoc.extents.length === 0) {
1904        throw new Error("No location data for grid item");
1905      }
1906      const gridData = readItemData(buffer, gridLoc, idatOffset);
1907      const largeFields = gridData.length > 1 && (gridData[1] & 1) !== 0;
1908      const minGridSize = largeFields ? 12 : 8;
1909      if (gridData.length < minGridSize) {
1910        throw new Error(
1911          `Grid descriptor too short: $gridData.length} bytes`
1912        );
1913      }
1914      const rows = gridData[2] + 1;
1915      const columns = gridData[3] + 1;
1916      const gv = new DataView(gridData.buffer, gridData.byteOffset);
1917      let outputWidth;
1918      let outputHeight;
1919      if (largeFields) {
1920        outputWidth = gv.getUint32(4);
1921        outputHeight = gv.getUint32(8);
1922      } else {
1923        outputWidth = gv.getUint16(4);
1924        outputHeight = gv.getUint16(6);
1925      }
1926      if (!irefBox) {
1927        throw new Error("Grid image requires iref box");
1928      }
1929      const dimgRefs = parseIref(r, irefBox, "dimg");
1930      const tileItemIds = dimgRefs.get(gridItemId);
1931      if (!tileItemIds || tileItemIds.length === 0) {
1932        throw new Error("No tile references found for grid item");
1933      }
1934      const expectedTiles = rows * columns;
1935      if (tileItemIds.length < expectedTiles) {
1936        throw new Error(
1937          `Grid expects $expectedTiles} tiles but found $tileItemIds.length}`
1938        );
1939      }
1940      const firstTileProps = allAssoc.get(tileItemIds[0]);
1941      if (!firstTileProps || firstTileProps.length === 0) {
1942        throw new Error("No property associations for tile item");
1943      }
1944      const { hvcCBox, ispeBox } = findHvcProperties(
1945        firstTileProps,
1946        properties
1947      );
1948      const gridProps = allAssoc.get(gridItemId) || [];
1949      let irotBox;
1950      for (const idx of gridProps) {
1951        if (idx >= 1 && idx <= properties.length) {
1952          const prop = properties[idx - 1];
1953          if (prop.type === "irot") {
1954            irotBox = prop;
1955            break;
1956          }
1957        }
1958      }
1959      const hvcCDataStart = hvcCBox.offset + hvcCBox.headerSize;
1960      const hvcCDataSize = hvcCBox.size - hvcCBox.headerSize;
1961      const description = new Uint8Array(
1962        buffer.slice(hvcCDataStart, hvcCDataStart + hvcCDataSize)
1963      );
1964      const codecString = buildCodecString(r, hvcCDataStart);
1965      const { width: tileWidth, height: tileHeight } = parseIspe(r, ispeBox);
1966      const tiles = [];
1967      for (let row = 0; row < rows; row++) {
1968        for (let col = 0; col < columns; col++) {
1969          const tileIdx = row * columns + col;
1970          const tileId = tileItemIds[tileIdx];
1971          const tileLoc = locations.get(tileId);
1972          if (!tileLoc || tileLoc.extents.length === 0) {
1973            throw new Error(`No location data for tile item $tileId}`);
1974          }
1975          tiles.push({
1976            data: readItemData(buffer, tileLoc, idatOffset),
1977            x: col * tileWidth,
1978            y: row * tileHeight
1979          });
1980        }
1981      }
1982      const rotation = irotBox ? parseIrot(r, irotBox) : 0;
1983      return {
1984        codecString,
1985        description,
1986        tiles,
1987        tileWidth,
1988        tileHeight,
1989        outputWidth,
1990        outputHeight,
1991        rotation,
1992        exifOrientation: rotation === 0 ? getUnappliedExifOrientation(buffer) : 1
1993      };
1994    }
1995    function readTiffOrientation(payload) {
1996      if (payload.length < 8) {
1997        return 1;
1998      }
1999      const view = new DataView(
2000        payload.buffer,
2001        payload.byteOffset,
2002        payload.byteLength
2003      );
2004      let tiffStart = 0;
2005      const firstWord = view.getUint16(0);
2006      if (firstWord !== 18761 && firstWord !== 19789) {
2007        tiffStart = view.getUint32(0) + 4;
2008      }
2009      if (tiffStart + 8 > payload.length) {
2010        return 1;
2011      }
2012      const byteOrder = view.getUint16(tiffStart);
2013      let little;
2014      if (byteOrder === 18761) {
2015        little = true;
2016      } else if (byteOrder === 19789) {
2017        little = false;
2018      } else {
2019        return 1;
2020      }
2021      const ifd0 = tiffStart + view.getUint32(tiffStart + 4, little);
2022      if (ifd0 + 2 > payload.length) {
2023        return 1;
2024      }
2025      const entryCount = view.getUint16(ifd0, little);
2026      for (let i = 0; i < entryCount; i++) {
2027        const entry = ifd0 + 2 + i * 12;
2028        if (entry + 12 > payload.length) {
2029          break;
2030        }
2031        if (view.getUint16(entry, little) === 274) {
2032          const value = view.getUint16(entry + 8, little);
2033          return value >= 1 && value <= 8 ? value : 1;
2034        }
2035      }
2036      return 1;
2037    }
2038    function findMeta(r) {
2039      const metaBox = findBox(r, 0, r.view.byteLength, "meta");
2040      if (!metaBox) {
2041        return null;
2042      }
2043      const start = metaBox.offset + metaBox.headerSize + 4;
2044      const end = metaBox.offset + metaBox.size;
2045      return { box: metaBox, children: findBoxes(r, start, end) };
2046    }
2047    function parseExifOrientation(buffer) {
2048      try {
2049        const r = new Reader(buffer);
2050        const meta = findMeta(r);
2051        if (!meta) {
2052          return 1;
2053        }
2054        const iinfBox = meta.children.find((b) => b.type === "iinf");
2055        const ilocBox = meta.children.find((b) => b.type === "iloc");
2056        if (!iinfBox || !ilocBox) {
2057          return 1;
2058        }
2059        const itemTypes = parseIinf(r, iinfBox);
2060        let exifItemId;
2061        for (const [id, type] of itemTypes) {
2062          if (type === "Exif") {
2063            exifItemId = id;
2064            break;
2065          }
2066        }
2067        if (exifItemId === void 0) {
2068          return 1;
2069        }
2070        const loc = parseIloc(r, ilocBox).get(exifItemId);
2071        if (!loc || loc.extents.length === 0) {
2072          return 1;
2073        }
2074        const idatBox = meta.children.find((b) => b.type === "idat");
2075        const idatOffset = idatBox ? idatBox.offset + idatBox.headerSize : 0;
2076        return readTiffOrientation(readItemData(buffer, loc, idatOffset));
2077      } catch {
2078        return 1;
2079      }
2080    }
2081    function hasNativeTransform(r) {
2082      const meta = findMeta(r);
2083      if (!meta) {
2084        return false;
2085      }
2086      const iprp = meta.children.find((b) => b.type === "iprp");
2087      if (!iprp) {
2088        return false;
2089      }
2090      const ipco = findBox(
2091        r,
2092        iprp.offset + iprp.headerSize,
2093        iprp.offset + iprp.size,
2094        "ipco"
2095      );
2096      if (!ipco) {
2097        return false;
2098      }
2099      const start = ipco.offset + ipco.headerSize;
2100      const end = ipco.offset + ipco.size;
2101      return Boolean(
2102        findBox(r, start, end, "irot") || findBox(r, start, end, "imir")
2103      );
2104    }
2105    function getUnappliedExifOrientation(buffer) {
2106      try {
2107        if (hasNativeTransform(new Reader(buffer))) {
2108          return 1;
2109        }
2110      } catch {
2111        return 1;
2112      }
2113      return parseExifOrientation(buffer);
2114    }
2115  
2116    // packages/upload-media/build-module/heic-support.mjs
2117    var import_i18n5 = __toESM(require_i18n(), 1);
2118    function detectBrowserFamily() {
2119      if (typeof navigator === "undefined") {
2120        return null;
2121      }
2122      const brands = navigator.userAgentData?.brands;
2123      if (brands?.length) {
2124        if (brands.some(({ brand }) => /Chromium/i.test(brand))) {
2125          return "chromium";
2126        }
2127      }
2128      const userAgent = navigator.userAgent || "";
2129      if (/Firefox|FxiOS/i.test(userAgent)) {
2130        return "firefox";
2131      }
2132      if (/Chrome|Chromium|CriOS|Edg|OPR/i.test(userAgent)) {
2133        return "chromium";
2134      }
2135      if (/Safari/i.test(userAgent)) {
2136        return "safari";
2137      }
2138      return null;
2139    }
2140    function detectPlatform() {
2141      if (typeof navigator === "undefined") {
2142        return "other";
2143      }
2144      const platform = navigator.userAgentData?.platform || navigator.userAgent || "";
2145      if (/iPhone|iPad|iPod|iOS/i.test(platform)) {
2146        return "other";
2147      }
2148      if (/macOS|Mac OS X|Macintosh/i.test(platform)) {
2149        return "macos";
2150      }
2151      if (/Windows/i.test(platform)) {
2152        return "windows";
2153      }
2154      if (/Android|CrOS|Chrome OS/i.test(platform)) {
2155        return "other";
2156      }
2157      if (/Linux|X11/i.test(platform)) {
2158        return "linux";
2159      }
2160      return "other";
2161    }
2162    function getBrowserName() {
2163      if (detectBrowserFamily() === "chromium") {
2164        const brands = navigator.userAgentData?.brands ?? [];
2165        const userAgent = navigator.userAgent || "";
2166        if (brands.some(({ brand }) => /Edge/i.test(brand)) || /Edg\//i.test(userAgent)) {
2167          return "Edge";
2168        }
2169        if (brands.some(({ brand }) => /Opera/i.test(brand)) || /OPR\//i.test(userAgent)) {
2170          return "Opera";
2171        }
2172        return "Chrome";
2173      }
2174      switch (detectBrowserFamily()) {
2175        case "firefox":
2176          return "Firefox";
2177        case "safari":
2178          return "Safari";
2179        default:
2180          return null;
2181      }
2182    }
2183    function getHeicConversionAdvice() {
2184      const platform = detectPlatform();
2185      const family = detectBrowserFamily();
2186      if (platform === "macos") {
2187        if (family === "chromium") {
2188          return (0, import_i18n5.__)(
2189            "Safari usually can, or you can upload a JPEG instead."
2190          );
2191        }
2192        if (family !== "safari") {
2193          return (0, import_i18n5.__)(
2194            "Safari or Chrome usually can, or you can upload a JPEG instead."
2195          );
2196        }
2197      }
2198      if (platform === "windows" && family === "firefox") {
2199        return (0, import_i18n5.__)("Chrome or Edge might, or you can upload a JPEG instead.");
2200      }
2201      return (0, import_i18n5.__)("You can upload a JPEG instead.");
2202    }
2203    function getHeicUnsupportedMessage() {
2204      const platform = detectPlatform();
2205      const family = detectBrowserFamily();
2206      const browserName = getBrowserName();
2207      let cause;
2208      if (platform === "linux") {
2209        cause = (0, import_i18n5.__)(
2210          "HEIC photos can't be decoded on Linux, so unfortunately we couldn't convert this one."
2211        );
2212      } else if (family === "firefox") {
2213        cause = (0, import_i18n5.__)(
2214          "Firefox can't read HEIC photos, so we couldn't convert this one."
2215        );
2216      } else if (browserName && platform === "windows") {
2217        cause = (0, import_i18n5.sprintf)(
2218          /* translators: %s: browser name, e.g. "Chrome". */
2219          (0, import_i18n5.__)(
2220            "%s couldn't decode HEIC on this PC, so we couldn't convert this one."
2221          ),
2222          browserName
2223        );
2224      } else if (browserName && platform === "macos") {
2225        cause = (0, import_i18n5.sprintf)(
2226          /* translators: %s: browser name, e.g. "Safari". */
2227          (0, import_i18n5.__)(
2228            "%s couldn't decode HEIC on this Mac, so we couldn't convert this one."
2229          ),
2230          browserName
2231        );
2232      } else if (browserName) {
2233        cause = (0, import_i18n5.sprintf)(
2234          /* translators: %s: browser name, e.g. "Chrome". */
2235          (0, import_i18n5.__)(
2236            "%s couldn't decode HEIC on this device, so we couldn't convert this one."
2237          ),
2238          browserName
2239        );
2240      } else {
2241        cause = (0, import_i18n5.__)(
2242          "This browser can't read HEIC photos, so we couldn't convert this one."
2243        );
2244      }
2245      return `$cause} $getHeicConversionAdvice()}`;
2246    }
2247  
2248    // packages/upload-media/build-module/canvas-utils.mjs
2249    var IMAGE_DECODER_TIMEOUT = 15e3;
2250    var HeicUnsupportedError = class extends Error {
2251    };
2252    async function canvasConvertToJpeg(file, quality = 0.82, encode) {
2253      const canvas = await decodeToCanvas(file);
2254      const jpegBlob = await encodeCanvas(canvas, quality, encode);
2255      return new File([jpegBlob], `$getFileBasename(file.name)}.jpg`, {
2256        type: "image/jpeg"
2257      });
2258    }
2259    async function encodeCanvas(canvas, quality, encode) {
2260      if (encode) {
2261        try {
2262          const encoded = await encode(canvas, quality);
2263          if (encoded) {
2264            return encoded;
2265          }
2266        } catch {
2267        }
2268      }
2269      return canvas.convertToBlob({ type: "image/jpeg", quality });
2270    }
2271    async function decodeToCanvas(file) {
2272      try {
2273        const bitmap = await createImageBitmap(file);
2274        try {
2275          const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
2276          const ctx = canvas.getContext("2d");
2277          if (!ctx) {
2278            throw new Error("Could not get canvas 2d context");
2279          }
2280          ctx.drawImage(bitmap, 0, 0);
2281          return canvas;
2282        } finally {
2283          bitmap.close();
2284        }
2285      } catch {
2286      }
2287      if (typeof ImageDecoder !== "undefined") {
2288        const supported = await ImageDecoder.isTypeSupported(file.type);
2289        if (supported) {
2290          const decoder = new ImageDecoder({
2291            type: file.type,
2292            data: file.stream()
2293          });
2294          let videoFrame;
2295          let timeoutId;
2296          let timedOut = false;
2297          try {
2298            const decoded = await Promise.race([
2299              decoder.decode(),
2300              new Promise((_resolve, reject) => {
2301                timeoutId = setTimeout(() => {
2302                  timedOut = true;
2303                  decoder.close();
2304                  reject(
2305                    new Error("ImageDecoder decode timed out")
2306                  );
2307                }, IMAGE_DECODER_TIMEOUT);
2308              })
2309            ]);
2310            videoFrame = decoded.image;
2311          } catch (error) {
2312            if (!timedOut) {
2313              throw error;
2314            }
2315          } finally {
2316            clearTimeout(timeoutId);
2317            if (!timedOut) {
2318              decoder.close();
2319            }
2320          }
2321          if (videoFrame) {
2322            try {
2323              const canvas = new OffscreenCanvas(
2324                videoFrame.displayWidth,
2325                videoFrame.displayHeight
2326              );
2327              const ctx = canvas.getContext("2d");
2328              if (!ctx) {
2329                throw new Error("Could not get canvas 2d context");
2330              }
2331              ctx.drawImage(videoFrame, 0, 0);
2332              return canvas;
2333            } finally {
2334              videoFrame.close();
2335            }
2336          }
2337        }
2338      }
2339      let heicData;
2340      try {
2341        heicData = parseHeic(await file.arrayBuffer());
2342      } catch (error) {
2343        throw new Error("The HEIC file could not be parsed", {
2344          cause: error
2345        });
2346      }
2347      if (typeof VideoDecoder !== "undefined") {
2348        let supported = false;
2349        try {
2350          const support = await VideoDecoder.isConfigSupported({
2351            codec: heicData.codecString
2352          });
2353          supported = support.supported === true;
2354        } catch {
2355        }
2356        if (supported) {
2357          const canvas = new OffscreenCanvas(
2358            heicData.outputWidth,
2359            heicData.outputHeight
2360          );
2361          const ctx = canvas.getContext("2d");
2362          if (!ctx) {
2363            throw new Error("Could not get canvas 2d context");
2364          }
2365          for (const tile of heicData.tiles) {
2366            const frame = await decodeHevcFrame(
2367              heicData.codecString,
2368              heicData.description,
2369              heicData.tileWidth,
2370              heicData.tileHeight,
2371              tile.data
2372            );
2373            try {
2374              ctx.drawImage(frame, tile.x, tile.y);
2375            } finally {
2376              frame.close();
2377            }
2378          }
2379          return heicData.rotation !== 0 ? applyRotation(canvas, heicData.rotation) : applyExifOrientation(canvas, heicData.exifOrientation);
2380        }
2381      }
2382      throw new HeicUnsupportedError(getHeicUnsupportedMessage());
2383    }
2384    function applyRotation(source, rotation) {
2385      if (rotation === 0) {
2386        return source;
2387      }
2388      const swap = rotation === 90 || rotation === 270;
2389      const w = swap ? source.height : source.width;
2390      const h = swap ? source.width : source.height;
2391      const rotated = new OffscreenCanvas(w, h);
2392      const ctx = rotated.getContext("2d");
2393      if (!ctx) {
2394        return source;
2395      }
2396      ctx.translate(w / 2, h / 2);
2397      ctx.rotate(-rotation * Math.PI / 180);
2398      ctx.drawImage(source, -source.width / 2, -source.height / 2);
2399      return rotated;
2400    }
2401    function applyExifOrientation(source, orientation) {
2402      if (orientation <= 1 || orientation > 8) {
2403        return source;
2404      }
2405      const { width: sw, height: sh } = source;
2406      const swap = orientation >= 5;
2407      const out = new OffscreenCanvas(swap ? sh : sw, swap ? sw : sh);
2408      const ctx = out.getContext("2d");
2409      if (!ctx) {
2410        return source;
2411      }
2412      switch (orientation) {
2413        case 2:
2414          ctx.transform(-1, 0, 0, 1, sw, 0);
2415          break;
2416        case 3:
2417          ctx.transform(-1, 0, 0, -1, sw, sh);
2418          break;
2419        case 4:
2420          ctx.transform(1, 0, 0, -1, 0, sh);
2421          break;
2422        case 5:
2423          ctx.transform(0, 1, 1, 0, 0, 0);
2424          break;
2425        case 6:
2426          ctx.transform(0, 1, -1, 0, sh, 0);
2427          break;
2428        case 7:
2429          ctx.transform(0, -1, -1, 0, sh, sw);
2430          break;
2431        case 8:
2432          ctx.transform(0, -1, 1, 0, 0, sw);
2433          break;
2434      }
2435      ctx.drawImage(source, 0, 0);
2436      return out;
2437    }
2438    function decodeHevcFrame(codec, description, width, height, data) {
2439      return new Promise((resolve, reject) => {
2440        const decoder = new VideoDecoder({
2441          output: (frame) => {
2442            decoder.close();
2443            resolve(frame);
2444          },
2445          error: (e) => {
2446            if (decoder.state !== "closed") {
2447              decoder.close();
2448            }
2449            reject(e);
2450          }
2451        });
2452        decoder.configure({
2453          codec,
2454          codedWidth: width,
2455          codedHeight: height,
2456          description
2457        });
2458        decoder.decode(
2459          new EncodedVideoChunk({
2460            type: "key",
2461            timestamp: 0,
2462            data
2463          })
2464        );
2465        decoder.flush().catch((e) => {
2466          if (decoder.state !== "closed") {
2467            decoder.close();
2468          }
2469          reject(e);
2470        });
2471      });
2472    }
2473  
2474    // packages/upload-media/build-module/get-image-dimensions.mjs
2475    var MAX_HEADER_BYTES = 512 * 1024;
2476    function parseJpeg(view) {
2477      let offset = 2;
2478      while (offset < view.byteLength) {
2479        if (view.getUint8(offset) !== 255) {
2480          return null;
2481        }
2482        while (offset < view.byteLength && view.getUint8(offset) === 255) {
2483          offset++;
2484        }
2485        if (offset >= view.byteLength) {
2486          return null;
2487        }
2488        const marker = view.getUint8(offset);
2489        offset++;
2490        if (marker === 1 || marker >= 208 && marker <= 217) {
2491          continue;
2492        }
2493        if (marker === 218) {
2494          return null;
2495        }
2496        if (offset + 2 > view.byteLength) {
2497          return null;
2498        }
2499        const segmentLength = view.getUint16(offset);
2500        if (segmentLength < 2) {
2501          return null;
2502        }
2503        const isStartOfFrame = marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204;
2504        if (isStartOfFrame) {
2505          if (offset + 7 > view.byteLength) {
2506            return null;
2507          }
2508          const height = view.getUint16(offset + 3);
2509          const width = view.getUint16(offset + 5);
2510          const interlaced = marker === 194 || marker === 198 || marker === 202 || marker === 206;
2511          return { width, height, interlaced };
2512        }
2513        offset += segmentLength;
2514      }
2515      return null;
2516    }
2517    function parsePng(view) {
2518      if (view.byteLength < 29) {
2519        return null;
2520      }
2521      const isIhdr = view.getUint8(12) === 73 && // I
2522      view.getUint8(13) === 72 && // H
2523      view.getUint8(14) === 68 && // D
2524      view.getUint8(15) === 82;
2525      if (!isIhdr) {
2526        return null;
2527      }
2528      const width = view.getUint32(16);
2529      const height = view.getUint32(20);
2530      const interlaceMethod = view.getUint8(28);
2531      return { width, height, interlaced: interlaceMethod !== 0 };
2532    }
2533    async function getImageDimensions(file) {
2534      try {
2535        const headerBytes = Math.min(file.size, MAX_HEADER_BYTES);
2536        const buffer = await file.slice(0, headerBytes).arrayBuffer();
2537        const view = new DataView(buffer);
2538        if (view.byteLength >= 3 && view.getUint16(0) === 65496) {
2539          return parseJpeg(view);
2540        }
2541        if (view.byteLength >= 8 && view.getUint32(0) === 2303741511 && view.getUint32(4) === 218765834) {
2542          return parsePng(view);
2543        }
2544        return null;
2545      } catch {
2546        return null;
2547      }
2548    }
2549  
2550    // packages/upload-media/build-module/stub-file.mjs
2551    var StubFile = class extends File {
2552      constructor(fileName = "stub-file") {
2553        super([], fileName);
2554      }
2555    };
2556  
2557    // packages/upload-media/build-module/store/private-actions.mjs
2558    var DEFAULT_OUTPUT_QUALITY = 0.82;
2559    var ultraHdrItems = /* @__PURE__ */ new Set();
2560    function addItem({
2561      file: fileOrBlob,
2562      batchId,
2563      onChange,
2564      onSuccess,
2565      onBatchSuccess,
2566      onError,
2567      additionalData = {},
2568      sourceUrl,
2569      sourceAttachmentId,
2570      abortController,
2571      operations
2572    }) {
2573      return async ({ dispatch }) => {
2574        const itemId = v4_default();
2575        const file = convertBlobToFile(fileOrBlob);
2576        let blobUrl;
2577        if (!(file instanceof StubFile)) {
2578          blobUrl = (0, import_blob.createBlobURL)(file);
2579          dispatch({
2580            type: Type.CacheBlobUrl,
2581            id: itemId,
2582            blobUrl
2583          });
2584        }
2585        dispatch({
2586          type: Type.Add,
2587          item: {
2588            id: itemId,
2589            batchId,
2590            status: ItemStatus.Processing,
2591            sourceFile: cloneFile(file),
2592            file,
2593            attachment: {
2594              url: blobUrl
2595            },
2596            additionalData: {
2597              generate_sub_sizes: false,
2598              ...additionalData
2599            },
2600            onChange,
2601            onSuccess,
2602            onBatchSuccess,
2603            onError,
2604            sourceUrl,
2605            sourceAttachmentId,
2606            abortController: abortController || new AbortController(),
2607            operations: Array.isArray(operations) ? operations : [OperationType.Prepare]
2608          }
2609        });
2610        dispatch.processItem(itemId);
2611      };
2612    }
2613    function addSideloadItem({
2614      file,
2615      onChange,
2616      additionalData,
2617      operations,
2618      batchId,
2619      parentId
2620    }) {
2621      return ({ dispatch }) => {
2622        const itemId = v4_default();
2623        dispatch({
2624          type: Type.Add,
2625          item: {
2626            id: itemId,
2627            batchId,
2628            status: ItemStatus.Processing,
2629            sourceFile: cloneFile(file),
2630            file,
2631            onChange,
2632            additionalData: {
2633              ...additionalData
2634            },
2635            parentId,
2636            operations: Array.isArray(operations) ? operations : [OperationType.Prepare],
2637            abortController: new AbortController()
2638          }
2639        });
2640        dispatch.processItem(itemId);
2641      };
2642    }
2643    function processItem(id) {
2644      return async ({ select: select2, dispatch }) => {
2645        if (select2.isPaused()) {
2646          return;
2647        }
2648        const item = select2.getItem(id);
2649        if (!item) {
2650          return;
2651        }
2652        if (item.currentOperation) {
2653          return;
2654        }
2655        const {
2656          attachment,
2657          onChange,
2658          onSuccess,
2659          onBatchSuccess,
2660          batchId,
2661          parentId
2662        } = item;
2663        const operation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
2664        const operationArgs = Array.isArray(item.operations?.[0]) ? item.operations[0][1] : void 0;
2665        if (operation === OperationType.Upload) {
2666          const settings = select2.getSettings();
2667          const activeCount = select2.getActiveUploadCount();
2668          if (activeCount >= settings.maxConcurrentUploads) {
2669            return;
2670          }
2671        }
2672        if (operation === OperationType.ResizeCrop || operation === OperationType.Rotate) {
2673          const settings = select2.getSettings();
2674          const activeCount = select2.getActiveImageProcessingCount();
2675          if (activeCount >= settings.maxConcurrentImageProcessing) {
2676            return;
2677          }
2678        }
2679        if (operation === OperationType.TranscodeGif) {
2680          const activeCount = select2.getActiveVideoProcessingCount();
2681          if (activeCount >= 1) {
2682            return;
2683          }
2684        }
2685        if (attachment) {
2686          const isHeicUrl = attachment.url && /\.hei[cf]$/i.test(attachment.url);
2687          if (!isHeicUrl) {
2688            onChange?.([attachment]);
2689          }
2690        }
2691        if (!operation) {
2692          if (parentId || !parentId && !select2.hasPendingItemsByParentId(id)) {
2693            if (attachment) {
2694              onSuccess?.([attachment]);
2695            }
2696            dispatch.removeItem(id);
2697            dispatch.revokeBlobUrls(id);
2698            if (batchId && select2.isBatchUploaded(batchId)) {
2699              onBatchSuccess?.();
2700            }
2701          }
2702          if (parentId && batchId && select2.isBatchUploaded(batchId)) {
2703            const parentItem = select2.getItem(parentId);
2704            if (!parentItem) {
2705              return;
2706            }
2707            if (parentItem.operations && parentItem.operations.length > 0) {
2708              dispatch.processItem(parentId);
2709              return;
2710            }
2711            if (attachment) {
2712              parentItem.onSuccess?.([attachment]);
2713            }
2714            dispatch.removeItem(parentId);
2715            dispatch.revokeBlobUrls(parentId);
2716            if (parentItem.batchId && select2.isBatchUploaded(parentItem.batchId)) {
2717              parentItem.onBatchSuccess?.();
2718            }
2719          }
2720          return;
2721        }
2722        if (operation === OperationType.Finalize && select2.hasPendingItemsByParentId(id)) {
2723          return;
2724        }
2725        dispatch({
2726          type: Type.OperationStart,
2727          id,
2728          operation
2729        });
2730        debug(
2731          `Starting operation $operation} for $item.file.name} (item $item.id})`
2732        );
2733        switch (operation) {
2734          case OperationType.Prepare:
2735            dispatch.prepareItem(item.id);
2736            break;
2737          case OperationType.ResizeCrop:
2738            dispatch.resizeCropItem(
2739              item.id,
2740              operationArgs
2741            );
2742            break;
2743          case OperationType.Rotate:
2744            dispatch.rotateItem(
2745              item.id,
2746              operationArgs
2747            );
2748            break;
2749          case OperationType.TranscodeImage:
2750            dispatch.transcodeImageItem(
2751              item.id,
2752              operationArgs
2753            );
2754            break;
2755          case OperationType.TranscodeGif:
2756            dispatch.transcodeGifItem(
2757              item.id,
2758              operationArgs
2759            );
2760            break;
2761          case OperationType.Upload:
2762            if (item.parentId) {
2763              dispatch.sideloadItem(id);
2764            } else {
2765              dispatch.uploadItem(id);
2766            }
2767            break;
2768          case OperationType.ThumbnailGeneration:
2769            dispatch.generateThumbnails(id);
2770            break;
2771          case OperationType.Finalize:
2772            dispatch.finalizeItem(id);
2773            break;
2774          case OperationType.DetectUltraHdr:
2775            dispatch.detectUltraHdr(id);
2776            break;
2777        }
2778      };
2779    }
2780    function pauseQueue() {
2781      return {
2782        type: Type.PauseQueue
2783      };
2784    }
2785    function resumeQueue() {
2786      return async ({ select: select2, dispatch }) => {
2787        dispatch({
2788          type: Type.ResumeQueue
2789        });
2790        for (const item of select2.getAllItems()) {
2791          if (item.status === ItemStatus.PendingRetry) {
2792            dispatch.executeRetry(item.id);
2793          } else {
2794            dispatch.processItem(item.id);
2795          }
2796        }
2797      };
2798    }
2799    function pauseItem(id) {
2800      return async ({ dispatch }) => {
2801        dispatch({
2802          type: Type.PauseItem,
2803          id
2804        });
2805      };
2806    }
2807    function removeItem(id) {
2808      return async ({ select: select2, dispatch }) => {
2809        const item = select2.getItem(id);
2810        if (!item) {
2811          return;
2812        }
2813        ultraHdrItems.delete(id);
2814        clearRetryTimer(id);
2815        dispatch({
2816          type: Type.Remove,
2817          id
2818        });
2819        if (select2.getAllItems().length === 0) {
2820          terminateVipsWorker();
2821          terminateVideoConversionWorker();
2822        }
2823      };
2824    }
2825    function finishOperation(id, updates) {
2826      return async ({ select: select2, dispatch }) => {
2827        const item = select2.getItem(id);
2828        const previousOperation = item?.currentOperation;
2829        dispatch({
2830          type: Type.OperationFinish,
2831          id,
2832          item: updates
2833        });
2834        dispatch.processItem(id);
2835        if (previousOperation === OperationType.Upload) {
2836          const pendingUploads = select2.getPendingUploads();
2837          for (const pendingItem of pendingUploads) {
2838            dispatch.processItem(pendingItem.id);
2839          }
2840        }
2841        if (previousOperation === OperationType.ResizeCrop || previousOperation === OperationType.Rotate) {
2842          const pendingItems = select2.getPendingImageProcessing();
2843          for (const pendingItem of pendingItems) {
2844            dispatch.processItem(pendingItem.id);
2845          }
2846        }
2847        if (previousOperation === OperationType.TranscodeGif) {
2848          const pendingItems = select2.getPendingVideoProcessing();
2849          for (const pendingItem of pendingItems) {
2850            dispatch.processItem(pendingItem.id);
2851          }
2852        }
2853        if (previousOperation === OperationType.ResizeCrop || previousOperation === OperationType.Rotate || previousOperation === OperationType.TranscodeImage) {
2854          maybeRecycleVipsWorker(select2.getActiveImageProcessingCount());
2855        }
2856      };
2857    }
2858    var VALID_IMAGE_FORMATS = ["jpeg", "webp", "avif", "png", "gif"];
2859    function isValidImageFormat(format) {
2860      return VALID_IMAGE_FORMATS.includes(format);
2861    }
2862    async function getTranscodeImageOperation(file, outputMimeType, interlaced = false, quality = DEFAULT_OUTPUT_QUALITY) {
2863      if (file.type === "image/png" && outputMimeType === "image/jpeg") {
2864        const blobUrl = (0, import_blob.createBlobURL)(file);
2865        try {
2866          const hasAlpha = await vipsHasTransparency(blobUrl);
2867          if (hasAlpha) {
2868            return null;
2869          }
2870        } catch {
2871          return null;
2872        } finally {
2873          (0, import_blob.revokeBlobURL)(blobUrl);
2874        }
2875      }
2876      const formatPart = outputMimeType.split("/")[1];
2877      if (!isValidImageFormat(formatPart)) {
2878        return null;
2879      }
2880      return [
2881        OperationType.TranscodeImage,
2882        {
2883          outputFormat: formatPart,
2884          outputQuality: quality,
2885          interlaced
2886        }
2887      ];
2888    }
2889    function prepareItem(id) {
2890      return async ({ select: select2, dispatch }) => {
2891        const item = select2.getItem(id);
2892        if (!item) {
2893          return;
2894        }
2895        const { file } = item;
2896        const operations = [];
2897        const settings = select2.getSettings();
2898        if (file.type === "image/gif" && settings.gifConvert !== false && typeof ImageDecoder !== "undefined" && typeof VideoEncoder !== "undefined") {
2899          let isAnimated = false;
2900          try {
2901            isAnimated = isAnimatedGif(await file.arrayBuffer());
2902          } catch {
2903            isAnimated = false;
2904          }
2905          if (isAnimated) {
2906            let hasTransparency = false;
2907            const blobUrl = (0, import_blob.createBlobURL)(file);
2908            try {
2909              hasTransparency = await vipsHasTransparency(blobUrl);
2910            } catch {
2911              hasTransparency = true;
2912            } finally {
2913              (0, import_blob.revokeBlobURL)(blobUrl);
2914            }
2915            if (!hasTransparency) {
2916              operations.push(
2917                OperationType.Upload,
2918                OperationType.ThumbnailGeneration,
2919                OperationType.Finalize
2920              );
2921              dispatch({
2922                type: Type.AddOperations,
2923                id,
2924                operations
2925              });
2926              dispatch.finishOperation(id, {
2927                animatedGifFile: item.file
2928              });
2929              return;
2930            }
2931          }
2932        }
2933        let heicJpeg = null;
2934        const isHeic = await isHeicFile(file);
2935        const isMisnamedHeic = isHeic && !HEIC_MIME_TYPES.includes(file.type);
2936        const isImage = file.type.startsWith("image/") || isHeic;
2937        const isVipsSupported = !isHeic && CLIENT_SIDE_SUPPORTED_MIME_TYPES.includes(file.type);
2938        const heicFile = isMisnamedHeic ? new File([file], `$getFileBasename(file.name)}.heic`, {
2939          type: HEIC_MIME_TYPES[0],
2940          lastModified: file.lastModified
2941        }) : file;
2942        let tooLargeForClient = false;
2943        if (isImage && isVipsSupported) {
2944          const dimensions = await getImageDimensions(file);
2945          if (dimensions && exceedsClientProcessingMemory(dimensions)) {
2946            tooLargeForClient = true;
2947          }
2948        }
2949        if (file.type === "image/jpeg" && !isHeic && !tooLargeForClient) {
2950          operations.push(OperationType.DetectUltraHdr);
2951        }
2952        if (isImage && isVipsSupported && !tooLargeForClient) {
2953          operations.push(
2954            OperationType.Upload,
2955            OperationType.ThumbnailGeneration,
2956            OperationType.Finalize
2957          );
2958        } else if (isImage && isHeic) {
2959          const encode = isClientSideMediaSupported() ? (canvas, quality) => vipsEncodeCanvasAsJpeg(id, canvas, heicFile, quality) : void 0;
2960          try {
2961            heicJpeg = await canvasConvertToJpeg(
2962              heicFile,
2963              settings.imageQuality ?? DEFAULT_OUTPUT_QUALITY,
2964              encode
2965            );
2966          } catch (error) {
2967            const unsupported = error instanceof HeicUnsupportedError;
2968            dispatch.cancelItem(
2969              id,
2970              new UploadError({
2971                code: unsupported ? ErrorCode.HEIC_DECODE_ERROR : ErrorCode.IMAGE_TRANSCODING_ERROR,
2972                message: unsupported ? getHeicUnsupportedMessage() : (0, import_i18n6.__)(
2973                  "This HEIC image could not be converted. Try converting it to JPEG before uploading."
2974                ),
2975                file,
2976                cause: error instanceof Error ? error : void 0
2977              })
2978            );
2979            return;
2980          }
2981          operations.push(
2982            OperationType.Upload,
2983            OperationType.ThumbnailGeneration,
2984            OperationType.Finalize
2985          );
2986        } else {
2987          operations.push(OperationType.Upload);
2988        }
2989        dispatch({
2990          type: Type.AddOperations,
2991          id,
2992          operations
2993        });
2994        let updates;
2995        if (isHeic && heicJpeg) {
2996          const vipsAvailable = isClientSideMediaSupported();
2997          updates = {
2998            file: heicJpeg,
2999            sourceFile: heicJpeg,
3000            originalHeicFile: heicFile,
3001            additionalData: {
3002              ...item.additionalData,
3003              generate_sub_sizes: !vipsAvailable,
3004              convert_format: true
3005            }
3006          };
3007        } else if (!isVipsSupported || !isImage || tooLargeForClient) {
3008          updates = {
3009            additionalData: {
3010              ...item.additionalData,
3011              generate_sub_sizes: true,
3012              convert_format: true
3013            }
3014          };
3015        } else {
3016          updates = {
3017            additionalData: {
3018              ...item.additionalData,
3019              generate_sub_sizes: false
3020            }
3021          };
3022        }
3023        dispatch.finishOperation(id, updates);
3024      };
3025    }
3026    function detectUltraHdr(id) {
3027      return async ({ select: select2, dispatch }) => {
3028        const item = select2.getItem(id);
3029        if (!item) {
3030          return;
3031        }
3032        let info;
3033        try {
3034          const buffer = await item.file.arrayBuffer();
3035          info = await vipsGetUltraHdrInfo(buffer);
3036        } catch {
3037        }
3038        if (info) {
3039          ultraHdrItems.add(id);
3040        }
3041        dispatch.finishOperation(id, {});
3042      };
3043    }
3044    function uploadItem(id) {
3045      return async ({ select: select2, dispatch }) => {
3046        const item = select2.getItem(id);
3047        if (!item) {
3048          return;
3049        }
3050        const startTime = performance.now();
3051        let finished = false;
3052        const finishUpload = (attachment) => {
3053          if (finished) {
3054            return;
3055          }
3056          finished = true;
3057          measure({
3058            measureName: `Upload $item.file.name}`,
3059            startTime,
3060            tooltipText: item.file.name,
3061            properties: [
3062              ["Item ID", item.id],
3063              ["File name", item.file.name]
3064            ]
3065          });
3066          dispatch.finishOperation(id, { attachment });
3067        };
3068        select2.getSettings().mediaUpload({
3069          filesList: [item.file],
3070          additionalData: item.additionalData,
3071          signal: item.abortController?.signal,
3072          // The queue's own items drive upload progress UI and save
3073          // locking; without this, consumers that track uploads themselves
3074          // (e.g. the editor's progress snackbar) would count this file a
3075          // second time.
3076          isTransportOnly: true,
3077          onFileChange: ([attachment]) => {
3078            if (attachment && !(0, import_blob.isBlobURL)(attachment.url)) {
3079              finishUpload(attachment);
3080            }
3081          },
3082          onSuccess: ([attachment]) => {
3083            finishUpload(attachment);
3084          },
3085          onError: (error) => {
3086            dispatch.cancelItem(id, error);
3087          }
3088        });
3089      };
3090    }
3091    function sideloadItem(id) {
3092      return async ({ select: select2, dispatch }) => {
3093        const item = select2.getItem(id);
3094        if (!item) {
3095          return;
3096        }
3097        const { post, ...additionalData } = item.additionalData;
3098        const mediaSideload = select2.getSettings().mediaSideload;
3099        if (!mediaSideload) {
3100          dispatch.finishOperation(id, {});
3101          return;
3102        }
3103        const startTime = performance.now();
3104        mediaSideload({
3105          file: item.file,
3106          attachmentId: post,
3107          additionalData,
3108          signal: item.abortController?.signal,
3109          onSuccess: (subSize) => {
3110            measure({
3111              measureName: `Sideload $item.file.name}`,
3112              startTime,
3113              tooltipText: item.file.name,
3114              properties: [
3115                ["Item ID", item.id],
3116                ["File name", item.file.name]
3117              ]
3118            });
3119            if (item.parentId) {
3120              dispatch({
3121                type: Type.AccumulateSubSize,
3122                id: item.parentId,
3123                subSize
3124              });
3125            }
3126            dispatch.finishOperation(id, {});
3127          },
3128          onError: (error) => {
3129            dispatch.cancelItem(id, error);
3130          }
3131        });
3132      };
3133    }
3134    function resizeCropItem(id, args) {
3135      return async ({ select: select2, dispatch }) => {
3136        const item = select2.getItem(id);
3137        if (!item) {
3138          return;
3139        }
3140        if (!args?.resize) {
3141          dispatch.finishOperation(id, {
3142            file: item.file
3143          });
3144          return;
3145        }
3146        const startTime = performance.now();
3147        const addSuffix = Boolean(item.parentId);
3148        const scaledSuffix = Boolean(args.isThresholdResize);
3149        const {
3150          imageStripMeta,
3151          imageMaxBitDepth,
3152          generateAnimatedImageSubsizes
3153        } = select2.getSettings();
3154        try {
3155          const file = await vipsResizeImage(
3156            item.id,
3157            item.file,
3158            args.resize,
3159            {
3160              smartCrop: false,
3161              addSuffix,
3162              signal: item.abortController?.signal,
3163              scaledSuffix,
3164              quality: args.quality,
3165              stripMeta: imageStripMeta,
3166              maxBitdepth: imageMaxBitDepth,
3167              preserveAnimation: false !== generateAnimatedImageSubsizes
3168            }
3169          );
3170          measure({
3171            measureName: `ResizeCrop $item.file.name}`,
3172            startTime,
3173            tooltipText: item.file.name,
3174            properties: [
3175              ["Item ID", item.id],
3176              ["File name", item.file.name]
3177            ]
3178          });
3179          const blobUrl = (0, import_blob.createBlobURL)(file);
3180          dispatch({
3181            type: Type.CacheBlobUrl,
3182            id,
3183            blobUrl
3184          });
3185          dispatch.finishOperation(id, {
3186            file,
3187            attachment: {
3188              url: blobUrl
3189            }
3190          });
3191        } catch (error) {
3192          dispatch.cancelItem(
3193            id,
3194            new UploadError({
3195              code: ErrorCode.IMAGE_TRANSCODING_ERROR,
3196              message: (0, import_i18n6.__)(
3197                "The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading."
3198              ),
3199              file: item.file,
3200              cause: error instanceof Error ? error : void 0
3201            })
3202          );
3203        }
3204      };
3205    }
3206    function rotateItem(id, args) {
3207      return async ({ select: select2, dispatch }) => {
3208        const item = select2.getItem(id);
3209        if (!item) {
3210          return;
3211        }
3212        if (!args?.orientation || args.orientation === 1) {
3213          dispatch.finishOperation(id, {
3214            file: item.file
3215          });
3216          return;
3217        }
3218        const startTime = performance.now();
3219        try {
3220          const file = await vipsRotateImage(
3221            item.id,
3222            item.file,
3223            args.orientation,
3224            item.abortController?.signal
3225          );
3226          measure({
3227            measureName: `Rotate $item.file.name}`,
3228            startTime,
3229            tooltipText: item.file.name,
3230            properties: [
3231              ["Item ID", item.id],
3232              ["File name", item.file.name]
3233            ]
3234          });
3235          const blobUrl = (0, import_blob.createBlobURL)(file);
3236          dispatch({
3237            type: Type.CacheBlobUrl,
3238            id,
3239            blobUrl
3240          });
3241          dispatch.finishOperation(id, {
3242            file,
3243            attachment: {
3244              url: blobUrl
3245            }
3246          });
3247        } catch (error) {
3248          dispatch.cancelItem(
3249            id,
3250            new UploadError({
3251              code: ErrorCode.IMAGE_ROTATION_ERROR,
3252              message: (0, import_i18n6.__)(
3253                "The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading."
3254              ),
3255              file: item.file,
3256              cause: error instanceof Error ? error : void 0
3257            })
3258          );
3259        }
3260      };
3261    }
3262    function transcodeImageItem(id, args) {
3263      return async ({ select: select2, dispatch }) => {
3264        const item = select2.getItem(id);
3265        if (!item) {
3266          return;
3267        }
3268        if (!args?.outputFormat) {
3269          dispatch.finishOperation(id, {
3270            file: item.file
3271          });
3272          return;
3273        }
3274        const startTime = performance.now();
3275        const outputMimeType = `image/$args.outputFormat}`;
3276        const quality = args.outputQuality ?? DEFAULT_OUTPUT_QUALITY;
3277        const interlaced = args.interlaced ?? false;
3278        const { imageStripMeta, imageMaxBitDepth } = select2.getSettings();
3279        try {
3280          const file = await vipsConvertImageFormat(
3281            item.id,
3282            item.file,
3283            outputMimeType,
3284            {
3285              quality,
3286              interlaced,
3287              stripMeta: imageStripMeta,
3288              maxBitdepth: imageMaxBitDepth
3289            }
3290          );
3291          measure({
3292            measureName: `Transcode $item.file.name}`,
3293            startTime,
3294            tooltipText: item.file.name,
3295            properties: [
3296              ["Item ID", item.id],
3297              ["File name", item.file.name]
3298            ]
3299          });
3300          const blobUrl = (0, import_blob.createBlobURL)(file);
3301          dispatch({
3302            type: Type.CacheBlobUrl,
3303            id,
3304            blobUrl
3305          });
3306          dispatch.finishOperation(id, {
3307            file,
3308            attachment: {
3309              url: blobUrl
3310            }
3311          });
3312        } catch (error) {
3313          dispatch.cancelItem(
3314            id,
3315            new UploadError({
3316              code: ErrorCode.MEDIA_TRANSCODING_ERROR,
3317              message: "Image could not be transcoded to the target format",
3318              file: item.file,
3319              cause: error instanceof Error ? error : void 0
3320            })
3321          );
3322        }
3323      };
3324    }
3325    function transcodeGifItem(id, args) {
3326      return async ({ select: select2, dispatch }) => {
3327        const item = select2.getItem(id);
3328        if (!item) {
3329          return;
3330        }
3331        const outputFormat = args?.outputFormat ?? "mp4";
3332        const outputMimeType = `video/$outputFormat}`;
3333        const gifFile = item.file;
3334        try {
3335          const file = await convertGifToVideo(
3336            item.id,
3337            gifFile,
3338            outputMimeType,
3339            {
3340              timeout: args?.timeout,
3341              maxTotalPixels: args?.maxTotalPixels
3342            }
3343          );
3344          dispatch.finishOperation(id, { file });
3345          dispatch.addSideloadItem({
3346            file: gifFile,
3347            batchId: v4_default(),
3348            parentId: item.parentId,
3349            additionalData: {
3350              post: item.additionalData?.post,
3351              image_size: "animated_video_poster",
3352              convert_format: false
3353            },
3354            operations: [
3355              [
3356                OperationType.TranscodeImage,
3357                {
3358                  outputFormat: "jpeg",
3359                  outputQuality: DEFAULT_OUTPUT_QUALITY,
3360                  interlaced: false
3361                }
3362              ],
3363              OperationType.Upload
3364            ]
3365          });
3366        } catch (error) {
3367          if (isUnsupportedConversionError(error)) {
3368            if (isSizeLimitConversionError(error)) {
3369              debug(
3370                `Skipping GIF to video conversion: $error instanceof Error ? error.message : error}`
3371              );
3372            }
3373            dispatch.cancelItem(
3374              id,
3375              new Error("Animated GIF conversion unsupported"),
3376              true
3377            );
3378            return;
3379          }
3380          if (isConversionTimeoutError(error)) {
3381            debug(
3382              `GIF to video conversion timed out; keeping the original GIF only: $error instanceof Error ? error.message : error}`
3383            );
3384            dispatch.cancelItem(
3385              id,
3386              new Error("Animated GIF conversion timed out"),
3387              true
3388            );
3389            return;
3390          }
3391          console.error(
3392            "[video-conversion] GIF to video conversion failed:",
3393            error
3394          );
3395          dispatch.cancelItem(
3396            id,
3397            new UploadError({
3398              code: ErrorCode.GIF_TRANSCODING_ERROR,
3399              message: "Animated GIF could not be converted to video",
3400              file: item.file,
3401              cause: error instanceof Error ? error : void 0
3402            }),
3403            true
3404          );
3405        }
3406      };
3407    }
3408    function generateThumbnails(id) {
3409      return async ({ select: select2, dispatch }) => {
3410        const item = select2.getItem(id);
3411        if (!item) {
3412          return;
3413        }
3414        if (!item.attachment) {
3415          dispatch.finishOperation(id, {});
3416          return;
3417        }
3418        const attachment = item.attachment;
3419        const settings = select2.getSettings();
3420        if (item.originalHeicFile && attachment.id) {
3421          dispatch.addSideloadItem({
3422            file: item.originalHeicFile,
3423            batchId: v4_default(),
3424            parentId: item.id,
3425            additionalData: {
3426              post: attachment.id,
3427              image_size: "source_original",
3428              convert_format: false
3429            },
3430            operations: [OperationType.Upload]
3431          });
3432        }
3433        if (item.animatedGifFile && attachment.id) {
3434          const outputFormat = settings.videoOutputFormat === "video/webm" ? "webm" : "mp4";
3435          dispatch.addSideloadItem({
3436            file: item.animatedGifFile,
3437            batchId: v4_default(),
3438            parentId: item.id,
3439            additionalData: {
3440              post: attachment.id,
3441              image_size: "animated_video",
3442              convert_format: false
3443            },
3444            operations: [
3445              [
3446                OperationType.TranscodeGif,
3447                {
3448                  outputFormat
3449                }
3450              ],
3451              OperationType.Upload
3452            ]
3453          });
3454        }
3455        let exifOrientation = attachment.exif_orientation || 1;
3456        const sourceType = item.sourceFile.type;
3457        const isHeifFamily = sourceType === "image/avif" || sourceType === "image/heif";
3458        let needsClientRotation = false;
3459        if (isHeifFamily) {
3460          exifOrientation = getUnappliedExifOrientation(
3461            await item.sourceFile.arrayBuffer()
3462          );
3463          needsClientRotation = exifOrientation !== 1;
3464        }
3465        let rotatedSource;
3466        {
3467          const needsRotation = exifOrientation !== 1 && !item.file.name.includes("-scaled");
3468          if ((needsRotation || needsClientRotation) && attachment.id) {
3469            try {
3470              rotatedSource = await vipsRotateImage(
3471                item.id,
3472                item.sourceFile,
3473                exifOrientation,
3474                item.abortController?.signal
3475              );
3476            } catch {
3477              console.warn(
3478                "Failed to rotate image, continuing with thumbnails"
3479              );
3480            }
3481          }
3482          if (needsRotation && rotatedSource && attachment.id) {
3483            dispatch.addSideloadItem({
3484              file: rotatedSource,
3485              batchId: v4_default(),
3486              parentId: item.id,
3487              additionalData: {
3488                post: attachment.id,
3489                image_size: "original",
3490                convert_format: false
3491              },
3492              operations: [OperationType.Upload]
3493            });
3494          }
3495        }
3496        if (!item.parentId && attachment.missing_image_sizes && attachment.missing_image_sizes.length > 0) {
3497          const allImageSizes = settings.allImageSizes || {};
3498          const sizesToGenerate = attachment.missing_image_sizes;
3499          const thumbnailSource = needsClientRotation && rotatedSource ? rotatedSource : item.sourceFile;
3500          const file = attachment.filename ? renameFile(thumbnailSource, attachment.filename) : thumbnailSource;
3501          const batchId = v4_default();
3502          const isUltraHdr = ultraHdrItems.has(item.id);
3503          const outputMimeType = attachment.image_output_format;
3504          const interlaced = attachment.image_save_progressive ?? false;
3505          const imageQuality = attachment.image_quality;
3506          const fallbackQuality = settings.imageQuality ?? DEFAULT_OUTPUT_QUALITY;
3507          const defaultQuality = typeof imageQuality?.default === "number" ? imageQuality.default / 100 : fallbackQuality;
3508          const qualityForSize = (sizeName) => {
3509            const sized = imageQuality?.sizes?.[sizeName];
3510            if (typeof sized === "number") {
3511              return sized / 100;
3512            }
3513            return defaultQuality;
3514          };
3515          let thumbnailTranscodeOperation = null;
3516          if (!isUltraHdr && outputMimeType) {
3517            thumbnailTranscodeOperation = await getTranscodeImageOperation(
3518              thumbnailSource,
3519              outputMimeType,
3520              interlaced,
3521              defaultQuality
3522            );
3523          }
3524          const dimensionGroups = /* @__PURE__ */ new Map();
3525          for (const name of sizesToGenerate) {
3526            const imageSize = allImageSizes[name];
3527            if (!imageSize) {
3528              console.warn(
3529                `Image size "$name}" not found in configuration`
3530              );
3531              continue;
3532            }
3533            const key = `$imageSize.width}x$imageSize.height}x$imageSize.crop}`;
3534            const group = dimensionGroups.get(key);
3535            if (group) {
3536              group.push(name);
3537            } else {
3538              dimensionGroups.set(key, [name]);
3539            }
3540          }
3541          for (const [, names] of dimensionGroups) {
3542            const imageSize = allImageSizes[names[0]];
3543            const sizeQuality = qualityForSize(names[0]);
3544            const thumbnailOperations = [
3545              [
3546                OperationType.ResizeCrop,
3547                { resize: imageSize, quality: sizeQuality }
3548              ]
3549            ];
3550            if (!isUltraHdr && thumbnailTranscodeOperation) {
3551              thumbnailOperations.push([
3552                thumbnailTranscodeOperation[0],
3553                {
3554                  ...thumbnailTranscodeOperation[1],
3555                  outputQuality: sizeQuality
3556                }
3557              ]);
3558            }
3559            thumbnailOperations.push(OperationType.Upload);
3560            const imageSizeParam = names.length === 1 ? names[0] : names;
3561            dispatch.addSideloadItem({
3562              file,
3563              batchId,
3564              parentId: item.id,
3565              additionalData: {
3566                // Sideloading does not use the parent post ID but the
3567                // attachment ID as the image sizes need to be added to it.
3568                post: attachment.id,
3569                image_size: imageSizeParam,
3570                convert_format: false
3571              },
3572              operations: thumbnailOperations
3573            });
3574          }
3575          {
3576            const { bigImageSizeThreshold } = settings;
3577            if (bigImageSizeThreshold && attachment.id) {
3578              const bitmap = await createImageBitmap(thumbnailSource);
3579              const needsScaling = bitmap.width > bigImageSizeThreshold || bitmap.height > bigImageSizeThreshold;
3580              bitmap.close();
3581              if (needsScaling) {
3582                const sourceForScaled = attachment.filename ? renameFile(thumbnailSource, attachment.filename) : thumbnailSource;
3583                const scaledOperations = [
3584                  [
3585                    OperationType.ResizeCrop,
3586                    {
3587                      resize: {
3588                        width: bigImageSizeThreshold,
3589                        height: bigImageSizeThreshold
3590                      },
3591                      isThresholdResize: true,
3592                      quality: defaultQuality
3593                    }
3594                  ]
3595                ];
3596                if (!isUltraHdr && thumbnailTranscodeOperation) {
3597                  scaledOperations.push(
3598                    thumbnailTranscodeOperation
3599                  );
3600                }
3601                scaledOperations.push(OperationType.Upload);
3602                dispatch.addSideloadItem({
3603                  file: sourceForScaled,
3604                  batchId,
3605                  parentId: item.id,
3606                  additionalData: {
3607                    post: attachment.id,
3608                    image_size: "scaled",
3609                    convert_format: false
3610                  },
3611                  operations: scaledOperations
3612                });
3613              }
3614            }
3615          }
3616        }
3617        dispatch.finishOperation(id, {});
3618      };
3619    }
3620    function finalizeItem(id) {
3621      return async ({ select: select2, dispatch }) => {
3622        const item = select2.getItem(id);
3623        if (!item) {
3624          return;
3625        }
3626        const attachment = item.attachment;
3627        const { mediaFinalize } = select2.getSettings();
3628        const updates = {};
3629        if (attachment?.id && mediaFinalize) {
3630          try {
3631            const updatedAttachment = await mediaFinalize(
3632              attachment.id,
3633              item.subSizes || []
3634            );
3635            if (updatedAttachment) {
3636              updates.attachment = updatedAttachment;
3637            }
3638          } catch (error) {
3639            console.warn("Media finalization failed:", error);
3640            dispatch.cancelItem(
3641              id,
3642              new UploadError({
3643                code: ErrorCode.MEDIA_FINALIZE_ERROR,
3644                message: (0, import_i18n6.__)("Could not finalize the upload."),
3645                file: item.file
3646              })
3647            );
3648            return;
3649          }
3650        }
3651        dispatch.finishOperation(id, updates);
3652      };
3653    }
3654    function revokeBlobUrls(id) {
3655      return async ({ select: select2, dispatch }) => {
3656        const blobUrls = select2.getBlobUrls(id);
3657        for (const blobUrl of blobUrls) {
3658          (0, import_blob.revokeBlobURL)(blobUrl);
3659        }
3660        dispatch({
3661          type: Type.RevokeBlobUrls,
3662          id
3663        });
3664      };
3665    }
3666    function updateItemProgress(id, progress) {
3667      return async ({ dispatch }) => {
3668        dispatch({
3669          type: Type.UpdateProgress,
3670          id,
3671          progress
3672        });
3673      };
3674    }
3675    function updateSettings(settings) {
3676      return {
3677        type: Type.UpdateSettings,
3678        settings
3679      };
3680    }
3681  
3682    // packages/upload-media/build-module/lock-unlock.mjs
3683    var import_private_apis = __toESM(require_private_apis(), 1);
3684    var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)(
3685      "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
3686      "@wordpress/upload-media"
3687    );
3688  
3689    // packages/upload-media/build-module/store/index.mjs
3690    var storeConfig = {
3691      reducer: reducer_default,
3692      selectors: selectors_exports,
3693      actions: actions_exports
3694    };
3695    var store = (0, import_data.createReduxStore)(STORE_NAME, {
3696      reducer: reducer_default,
3697      selectors: selectors_exports,
3698      actions: actions_exports
3699    });
3700    if (!(0, import_data.select)(store)) {
3701      (0, import_data.register)(store);
3702    }
3703    unlock(store).registerPrivateActions(private_actions_exports);
3704    unlock(store).registerPrivateSelectors(private_selectors_exports);
3705  
3706    // packages/upload-media/build-module/components/provider/index.mjs
3707    var import_element2 = __toESM(require_element(), 1);
3708    var import_data3 = __toESM(require_data(), 1);
3709  
3710    // packages/upload-media/build-module/components/provider/with-registry-provider.mjs
3711    var import_element = __toESM(require_element(), 1);
3712    var import_data2 = __toESM(require_data(), 1);
3713    var import_compose = __toESM(require_compose(), 1);
3714    var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
3715    function getSubRegistry(subRegistries, registry, useSubRegistry) {
3716      if (!useSubRegistry) {
3717        return registry;
3718      }
3719      let subRegistry = subRegistries.get(registry);
3720      if (!subRegistry) {
3721        subRegistry = (0, import_data2.createRegistry)({}, registry);
3722        subRegistry.registerStore(STORE_NAME, storeConfig);
3723        subRegistries.set(registry, subRegistry);
3724      }
3725      return subRegistry;
3726    }
3727    var withRegistryProvider = (0, import_compose.createHigherOrderComponent)(
3728      (WrappedComponent) => ({ useSubRegistry = true, ...props }) => {
3729        const registry = (0, import_data2.useRegistry)();
3730        const [subRegistries] = (0, import_element.useState)(() => /* @__PURE__ */ new WeakMap());
3731        const subRegistry = getSubRegistry(
3732          subRegistries,
3733          registry,
3734          useSubRegistry
3735        );
3736        if (subRegistry === registry) {
3737          return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WrappedComponent, { registry, ...props });
3738        }
3739        return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_data2.RegistryProvider, { value: subRegistry, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WrappedComponent, { registry: subRegistry, ...props }) });
3740      },
3741      "withRegistryProvider"
3742    );
3743    var with_registry_provider_default = withRegistryProvider;
3744  
3745    // packages/upload-media/build-module/components/provider/index.mjs
3746    var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
3747    var MediaUploadProvider = with_registry_provider_default((props) => {
3748      const { children, settings } = props;
3749      const { updateSettings: updateSettings2 } = unlock((0, import_data3.useDispatch)(store));
3750      (0, import_element2.useEffect)(() => {
3751        updateSettings2(settings);
3752      }, [settings, updateSettings2]);
3753      return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
3754    });
3755    var provider_default = MediaUploadProvider;
3756  
3757    // packages/upload-media/build-module/error-messages.mjs
3758    var import_i18n7 = __toESM(require_i18n(), 1);
3759    function getErrorMessage(code, fileName) {
3760      const messages = {
3761        [ErrorCode.EMPTY_FILE]: {
3762          title: (0, import_i18n7.__)("Empty file"),
3763          description: (0, import_i18n7.sprintf)(
3764            /* translators: %s: file name */
3765            (0, import_i18n7.__)('"%s" is empty.'),
3766            fileName
3767          ),
3768          action: (0, import_i18n7.__)("Please choose a different file.")
3769        },
3770        [ErrorCode.SIZE_ABOVE_LIMIT]: {
3771          title: (0, import_i18n7.__)("File too large"),
3772          description: (0, import_i18n7.sprintf)(
3773            /* translators: %s: file name */
3774            (0, import_i18n7.__)('"%s" exceeds the maximum upload size.'),
3775            fileName
3776          ),
3777          action: (0, import_i18n7.__)("Please reduce the file size and try again.")
3778        },
3779        [ErrorCode.MIME_TYPE_NOT_SUPPORTED]: {
3780          title: (0, import_i18n7.__)("Unsupported file type"),
3781          description: (0, import_i18n7.sprintf)(
3782            /* translators: %s: file name */
3783            (0, import_i18n7.__)('"%s" is not a supported file type.'),
3784            fileName
3785          ),
3786          action: (0, import_i18n7.__)("Please upload a different file format.")
3787        },
3788        [ErrorCode.MIME_TYPE_NOT_ALLOWED_FOR_USER]: {
3789          title: (0, import_i18n7.__)("File type not allowed"),
3790          description: (0, import_i18n7.sprintf)(
3791            /* translators: %s: file name */
3792            (0, import_i18n7.__)('You are not allowed to upload "%s".'),
3793            fileName
3794          ),
3795          action: (0, import_i18n7.__)("Please contact your site administrator.")
3796        },
3797        [ErrorCode.HEIC_DECODE_ERROR]: {
3798          title: (0, import_i18n7.__)("HEIC decode failed"),
3799          description: (0, import_i18n7.sprintf)(
3800            /* translators: %s: file name */
3801            (0, import_i18n7.__)('Failed to decode HEIC file "%s".'),
3802            fileName
3803          ),
3804          action: getHeicConversionAdvice()
3805        },
3806        [ErrorCode.IMAGE_TRANSCODING_ERROR]: {
3807          title: (0, import_i18n7.__)("Image processing failed"),
3808          description: (0, import_i18n7.sprintf)(
3809            /* translators: %s: file name */
3810            (0, import_i18n7.__)('Failed to process "%s".'),
3811            fileName
3812          ),
3813          action: (0, import_i18n7.__)("The image may be corrupted. Try a different file.")
3814        },
3815        [ErrorCode.IMAGE_ROTATION_ERROR]: {
3816          title: (0, import_i18n7.__)("Image rotation failed"),
3817          description: (0, import_i18n7.sprintf)(
3818            /* translators: %s: file name */
3819            (0, import_i18n7.__)('Failed to rotate "%s".'),
3820            fileName
3821          ),
3822          action: (0, import_i18n7.__)("The image may be corrupted. Try a different file.")
3823        },
3824        [ErrorCode.MEDIA_TRANSCODING_ERROR]: {
3825          title: (0, import_i18n7.__)("Media processing failed"),
3826          description: (0, import_i18n7.sprintf)(
3827            /* translators: %s: file name */
3828            (0, import_i18n7.__)('Failed to convert "%s" to the target format.'),
3829            fileName
3830          ),
3831          action: (0, import_i18n7.__)("The file may be corrupted. Try a different file.")
3832        },
3833        [ErrorCode.MEDIA_FINALIZE_ERROR]: {
3834          title: (0, import_i18n7.__)("Upload failed"),
3835          description: (0, import_i18n7.sprintf)(
3836            /* translators: %s: file name */
3837            (0, import_i18n7.__)('Could not finalize the upload of "%s".'),
3838            fileName
3839          ),
3840          action: (0, import_i18n7.__)("Please try again.")
3841        },
3842        [ErrorCode.GENERAL]: {
3843          title: (0, import_i18n7.__)("Upload failed"),
3844          description: (0, import_i18n7.sprintf)(
3845            /* translators: %s: file name */
3846            (0, import_i18n7.__)('Failed to upload "%s".'),
3847            fileName
3848          ),
3849          action: (0, import_i18n7.__)("Please try again.")
3850        }
3851      };
3852      return messages[code] || {
3853        title: (0, import_i18n7.__)("Upload failed"),
3854        description: (0, import_i18n7.sprintf)(
3855          /* translators: %s: file name */
3856          (0, import_i18n7.__)('Failed to upload "%s".'),
3857          fileName
3858        ),
3859        action: (0, import_i18n7.__)("Please try again.")
3860      };
3861    }
3862    return __toCommonJS(index_exports);
3863  })();
3864  (window.wp ||= {}).uploadMedia = wp.uploadMedia;
3865  })();


Generated : Sun Nov 1 08:20:35 2026 Cross-referenced by PHPXref