PluginProbe
Gutenberg / 23.5.3
Gutenberg v23.5.3
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / scripts / upload-media / index.js

index.js in Gutenberg 23.5.3, at build/scripts/upload-media/index.js

3,059 lines 94.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2 var wp;
3 (wp ||= {}).uploadMedia = (() => {
4 var __create = Object.create;
5 var __defProp = Object.defineProperty;
6 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7 var __getOwnPropNames = Object.getOwnPropertyNames;
8 var __getProtoOf = Object.getPrototypeOf;
9 var __hasOwnProp = Object.prototype.hasOwnProperty;
10 var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11 get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
12 }) : x)(function(x) {
13 if (typeof require !== "undefined") return require.apply(this, arguments);
14 throw Error('Dynamic require of "' + x + '" is not supported');
15 });
16 var __commonJS = (cb, mod) => function __require2() {
17 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18 };
19 var __export = (target, all) => {
20 for (var name in all)
21 __defProp(target, name, { get: all[name], enumerable: true });
22 };
23 var __copyProps = (to, from, except, desc) => {
24 if (from && typeof from === "object" || typeof from === "function") {
25 for (let key of __getOwnPropNames(from))
26 if (!__hasOwnProp.call(to, key) && key !== except)
27 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
28 }
29 return to;
30 };
31 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
32 // If the importer is in node compatibility mode or this is not an ESM
33 // file that has been converted to a CommonJS file using a Babel-
34 // compatible transform (i.e. "__esModule" has not been set), then set
35 // "default" to the CommonJS "module.exports" for node compatibility.
36 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
37 mod
38 ));
39 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
40
41 // package-external:@wordpress/data
42 var require_data = __commonJS({
43 "package-external:@wordpress/data"(exports, module) {
44 module.exports = window.wp.data;
45 }
46 });
47
48 // package-external:@wordpress/i18n
49 var require_i18n = __commonJS({
50 "package-external:@wordpress/i18n"(exports, module) {
51 module.exports = window.wp.i18n;
52 }
53 });
54
55 // package-external:@wordpress/url
56 var require_url = __commonJS({
57 "package-external:@wordpress/url"(exports, module) {
58 module.exports = window.wp.url;
59 }
60 });
61
62 // package-external:@wordpress/blob
63 var require_blob = __commonJS({
64 "package-external:@wordpress/blob"(exports, module) {
65 module.exports = window.wp.blob;
66 }
67 });
68
69 // package-external:@wordpress/private-apis
70 var require_private_apis = __commonJS({
71 "package-external:@wordpress/private-apis"(exports, module) {
72 module.exports = window.wp.privateApis;
73 }
74 });
75
76 // package-external:@wordpress/element
77 var require_element = __commonJS({
78 "package-external:@wordpress/element"(exports, module) {
79 module.exports = window.wp.element;
80 }
81 });
82
83 // package-external:@wordpress/compose
84 var require_compose = __commonJS({
85 "package-external:@wordpress/compose"(exports, module) {
86 module.exports = window.wp.compose;
87 }
88 });
89
90 // vendor-external:react/jsx-runtime
91 var require_jsx_runtime = __commonJS({
92 "vendor-external:react/jsx-runtime"(exports, module) {
93 module.exports = window.ReactJSXRuntime;
94 }
95 });
96
97 // packages/upload-media/build-module/index.mjs
98 var index_exports = {};
99 __export(index_exports, {
100 ErrorCode: () => ErrorCode,
101 MediaUploadProvider: () => provider_default,
102 UploadError: () => UploadError,
103 clearFeatureDetectionCache: () => clearFeatureDetectionCache,
104 detectClientSideMediaSupport: () => detectClientSideMediaSupport,
105 getErrorMessage: () => getErrorMessage,
106 isClientSideMediaSupported: () => isClientSideMediaSupported,
107 isHeicCanvasSupported: () => isHeicCanvasSupported,
108 store: () => store
109 });
110
111 // packages/upload-media/build-module/store/index.mjs
112 var import_data = __toESM(require_data(), 1);
113
114 // packages/upload-media/build-module/store/types.mjs
115 var Type = /* @__PURE__ */ ((Type2) => {
116 Type2["Unknown"] = "REDUX_UNKNOWN";
117 Type2["Add"] = "ADD_ITEM";
118 Type2["Prepare"] = "PREPARE_ITEM";
119 Type2["Cancel"] = "CANCEL_ITEM";
120 Type2["Remove"] = "REMOVE_ITEM";
121 Type2["RetryItem"] = "RETRY_ITEM";
122 Type2["ScheduleRetry"] = "SCHEDULE_RETRY";
123 Type2["PauseItem"] = "PAUSE_ITEM";
124 Type2["ResumeItem"] = "RESUME_ITEM";
125 Type2["PauseQueue"] = "PAUSE_QUEUE";
126 Type2["ResumeQueue"] = "RESUME_QUEUE";
127 Type2["OperationStart"] = "OPERATION_START";
128 Type2["OperationFinish"] = "OPERATION_FINISH";
129 Type2["AddOperations"] = "ADD_OPERATIONS";
130 Type2["CacheBlobUrl"] = "CACHE_BLOB_URL";
131 Type2["RevokeBlobUrls"] = "REVOKE_BLOB_URLS";
132 Type2["UpdateProgress"] = "UPDATE_PROGRESS";
133 Type2["AccumulateSubSize"] = "ACCUMULATE_SUB_SIZE";
134 Type2["UpdateSettings"] = "UPDATE_SETTINGS";
135 return Type2;
136 })(Type || {});
137 var ItemStatus = /* @__PURE__ */ ((ItemStatus2) => {
138 ItemStatus2["Queued"] = "QUEUED";
139 ItemStatus2["Processing"] = "PROCESSING";
140 ItemStatus2["Paused"] = "PAUSED";
141 ItemStatus2["PendingRetry"] = "PENDING_RETRY";
142 ItemStatus2["Uploaded"] = "UPLOADED";
143 ItemStatus2["Error"] = "ERROR";
144 return ItemStatus2;
145 })(ItemStatus || {});
146 var OperationType = /* @__PURE__ */ ((OperationType2) => {
147 OperationType2["Prepare"] = "PREPARE";
148 OperationType2["Upload"] = "UPLOAD";
149 OperationType2["ResizeCrop"] = "RESIZE_CROP";
150 OperationType2["Rotate"] = "ROTATE";
151 OperationType2["TranscodeImage"] = "TRANSCODE_IMAGE";
152 OperationType2["ThumbnailGeneration"] = "THUMBNAIL_GENERATION";
153 OperationType2["Finalize"] = "FINALIZE";
154 OperationType2["DetectUltraHdr"] = "DETECT_ULTRAHDR";
155 return OperationType2;
156 })(OperationType || {});
157
158 // packages/upload-media/build-module/store/constants.mjs
159 var STORE_NAME = "core/upload-media";
160 var DEFAULT_MAX_CONCURRENT_UPLOADS = 5;
161 var DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING = 2;
162 var DEFAULT_RETRY_SETTINGS = {
163 maxRetryAttempts: 3,
164 initialRetryDelayMs: 1e3,
165 maxRetryDelayMs: 3e4,
166 backoffMultiplier: 2,
167 retryJitter: 0.1
168 };
169 var CLIENT_SIDE_SUPPORTED_MIME_TYPES = [
170 "image/jpeg",
171 "image/png",
172 "image/gif",
173 "image/webp",
174 "image/avif"
175 ];
176 var HEIC_MIME_TYPES = [
177 "image/heic",
178 "image/heif"
179 ];
180
181 // packages/upload-media/build-module/store/reducer.mjs
182 var noop = () => {
183 };
184 var DEFAULT_STATE = {
185 queue: [],
186 queueStatus: "active",
187 blobUrls: {},
188 settings: {
189 mediaUpload: noop,
190 maxConcurrentUploads: DEFAULT_MAX_CONCURRENT_UPLOADS,
191 maxConcurrentImageProcessing: DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING,
192 retry: { ...DEFAULT_RETRY_SETTINGS }
193 }
194 };
195 function reducer(state = DEFAULT_STATE, action = { type: Type.Unknown }) {
196 switch (action.type) {
197 case Type.PauseQueue: {
198 return {
199 ...state,
200 queueStatus: "paused"
201 };
202 }
203 case Type.ResumeQueue: {
204 return {
205 ...state,
206 queueStatus: "active"
207 };
208 }
209 case Type.PauseItem:
210 return {
211 ...state,
212 queue: state.queue.map(
213 (item) => item.id === action.id ? {
214 ...item,
215 status: ItemStatus.Paused
216 } : item
217 )
218 };
219 case Type.ResumeItem:
220 return {
221 ...state,
222 queue: state.queue.map(
223 (item) => item.id === action.id ? {
224 ...item,
225 status: ItemStatus.Processing
226 } : item
227 )
228 };
229 case Type.Add:
230 return {
231 ...state,
232 queue: [...state.queue, action.item]
233 };
234 case Type.Cancel:
235 return {
236 ...state,
237 queue: state.queue.map(
238 (item) => item.id === action.id ? {
239 ...item,
240 error: action.error
241 } : item
242 )
243 };
244 case Type.RetryItem:
245 return {
246 ...state,
247 queue: state.queue.map(
248 (item) => item.id === action.id ? {
249 ...item,
250 status: ItemStatus.Processing,
251 error: void 0,
252 retryCount: (item.retryCount ?? 0) + 1,
253 abortController: new AbortController()
254 } : item
255 )
256 };
257 case Type.ScheduleRetry:
258 return {
259 ...state,
260 queue: state.queue.map(
261 (item) => item.id === action.id ? {
262 ...item,
263 status: ItemStatus.PendingRetry,
264 error: action.error,
265 retryCount: action.retryCount,
266 nextRetryTimestamp: action.nextRetryTimestamp
267 } : item
268 )
269 };
270 case Type.Remove:
271 return {
272 ...state,
273 queue: state.queue.filter((item) => item.id !== action.id)
274 };
275 case Type.OperationStart: {
276 return {
277 ...state,
278 queue: state.queue.map(
279 (item) => item.id === action.id ? {
280 ...item,
281 currentOperation: action.operation
282 } : item
283 )
284 };
285 }
286 case Type.AddOperations:
287 return {
288 ...state,
289 queue: state.queue.map((item) => {
290 if (item.id !== action.id) {
291 return item;
292 }
293 return {
294 ...item,
295 operations: [
296 ...item.operations || [],
297 ...action.operations
298 ]
299 };
300 })
301 };
302 case Type.OperationFinish:
303 return {
304 ...state,
305 queue: state.queue.map((item) => {
306 if (item.id !== action.id) {
307 return item;
308 }
309 const operations = item.operations ? item.operations.slice(1) : [];
310 const attachment = item.attachment || action.item.attachment ? {
311 ...item.attachment,
312 ...action.item.attachment
313 } : void 0;
314 return {
315 ...item,
316 currentOperation: void 0,
317 operations,
318 ...action.item,
319 attachment,
320 additionalData: {
321 ...item.additionalData,
322 ...action.item.additionalData
323 }
324 };
325 })
326 };
327 case Type.CacheBlobUrl: {
328 const blobUrls = state.blobUrls[action.id] || [];
329 return {
330 ...state,
331 blobUrls: {
332 ...state.blobUrls,
333 [action.id]: [...blobUrls, action.blobUrl]
334 }
335 };
336 }
337 case Type.RevokeBlobUrls: {
338 const newBlobUrls = { ...state.blobUrls };
339 delete newBlobUrls[action.id];
340 return {
341 ...state,
342 blobUrls: newBlobUrls
343 };
344 }
345 case Type.UpdateProgress:
346 return {
347 ...state,
348 queue: state.queue.map(
349 (item) => item.id === action.id ? {
350 ...item,
351 progress: action.progress
352 } : item
353 )
354 };
355 case Type.AccumulateSubSize:
356 return {
357 ...state,
358 queue: state.queue.map(
359 (item) => item.id === action.id ? {
360 ...item,
361 subSizes: [
362 ...item.subSizes || [],
363 action.subSize
364 ]
365 } : item
366 )
367 };
368 case Type.UpdateSettings: {
369 return {
370 ...state,
371 settings: {
372 ...state.settings,
373 ...action.settings
374 }
375 };
376 }
377 }
378 return state;
379 }
380 var reducer_default = reducer;
381
382 // packages/upload-media/build-module/store/selectors.mjs
383 var selectors_exports = {};
384 __export(selectors_exports, {
385 getItems: () => getItems,
386 getSettings: () => getSettings,
387 isUploading: () => isUploading,
388 isUploadingById: () => isUploadingById,
389 isUploadingByUrl: () => isUploadingByUrl
390 });
391 function getItems(state) {
392 return state.queue;
393 }
394 function isUploading(state) {
395 return state.queue.length >= 1;
396 }
397 function isUploadingByUrl(state, url) {
398 return state.queue.some(
399 (item) => item.attachment?.url === url || item.sourceUrl === url
400 );
401 }
402 function isUploadingById(state, attachmentId) {
403 return state.queue.some(
404 (item) => item.attachment?.id === attachmentId || item.sourceAttachmentId === attachmentId
405 );
406 }
407 function getSettings(state) {
408 return state.settings;
409 }
410
411 // packages/upload-media/build-module/store/private-selectors.mjs
412 var private_selectors_exports = {};
413 __export(private_selectors_exports, {
414 getActiveImageProcessingCount: () => getActiveImageProcessingCount,
415 getActiveUploadCount: () => getActiveUploadCount,
416 getAllItems: () => getAllItems,
417 getBlobUrls: () => getBlobUrls,
418 getFailedItems: () => getFailedItems,
419 getItem: () => getItem,
420 getItemProgress: () => getItemProgress,
421 getPendingImageProcessing: () => getPendingImageProcessing,
422 getPendingUploads: () => getPendingUploads,
423 hasPendingItemsByParentId: () => hasPendingItemsByParentId,
424 isBatchUploaded: () => isBatchUploaded,
425 isPaused: () => isPaused
426 });
427 function getAllItems(state) {
428 return state.queue;
429 }
430 function getItem(state, id) {
431 return state.queue.find((item) => item.id === id);
432 }
433 function isBatchUploaded(state, batchId) {
434 const batchItems = state.queue.filter(
435 (item) => batchId === item.batchId
436 );
437 return batchItems.length === 0;
438 }
439 function isPaused(state) {
440 return state.queueStatus === "paused";
441 }
442 function getBlobUrls(state, id) {
443 return state.blobUrls[id] || [];
444 }
445 function getActiveUploadCount(state) {
446 return state.queue.filter(
447 (item) => item.currentOperation === OperationType.Upload
448 ).length;
449 }
450 function getPendingUploads(state) {
451 return state.queue.filter((item) => {
452 const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
453 return nextOperation === OperationType.Upload && item.currentOperation !== OperationType.Upload;
454 });
455 }
456 function getActiveImageProcessingCount(state) {
457 return state.queue.filter(
458 (item) => item.currentOperation === OperationType.ResizeCrop || item.currentOperation === OperationType.Rotate
459 ).length;
460 }
461 function getPendingImageProcessing(state) {
462 return state.queue.filter((item) => {
463 const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
464 return (nextOperation === OperationType.ResizeCrop || nextOperation === OperationType.Rotate) && item.currentOperation !== OperationType.ResizeCrop && item.currentOperation !== OperationType.Rotate;
465 });
466 }
467 function getFailedItems(state) {
468 return state.queue.filter((item) => item.error !== void 0);
469 }
470 function hasPendingItemsByParentId(state, parentId) {
471 return state.queue.some((item) => item.parentId === parentId);
472 }
473 function getItemProgress(state, id) {
474 const item = state.queue.find((i) => i.id === id);
475 return item?.progress;
476 }
477
478 // packages/upload-media/build-module/store/actions.mjs
479 var actions_exports = {};
480 __export(actions_exports, {
481 addItems: () => addItems,
482 cancelItem: () => cancelItem,
483 executeRetry: () => executeRetry,
484 retryItem: () => retryItem,
485 scheduleRetry: () => scheduleRetry
486 });
487
488 // node_modules/uuid/dist/stringify.js
489 var byteToHex = [];
490 for (let i = 0; i < 256; ++i) {
491 byteToHex.push((i + 256).toString(16).slice(1));
492 }
493 function unsafeStringify(arr, offset = 0) {
494 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();
495 }
496
497 // node_modules/uuid/dist/rng.js
498 var rnds8 = new Uint8Array(16);
499 function rng() {
500 return crypto.getRandomValues(rnds8);
501 }
502
503 // node_modules/uuid/dist/v4.js
504 function v4(options, buf, offset) {
505 if (!buf && !options && crypto.randomUUID) {
506 return crypto.randomUUID();
507 }
508 return _v4(options, buf, offset);
509 }
510 function _v4(options, buf, offset) {
511 options = options || {};
512 const rnds = options.random ?? options.rng?.() ?? rng();
513 if (rnds.length < 16) {
514 throw new Error("Random bytes length must be >= 16");
515 }
516 rnds[6] = rnds[6] & 15 | 64;
517 rnds[8] = rnds[8] & 63 | 128;
518 if (buf) {
519 offset = offset || 0;
520 if (offset < 0 || offset + 16 > buf.length) {
521 throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
522 }
523 for (let i = 0; i < 16; ++i) {
524 buf[offset + i] = rnds[i];
525 }
526 return buf;
527 }
528 return unsafeStringify(rnds);
529 }
530 var v4_default = v4;
531
532 // packages/upload-media/build-module/store/actions.mjs
533 var import_i18n5 = __toESM(require_i18n(), 1);
534
535 // packages/upload-media/build-module/store/utils/retry.mjs
536 function calculateRetryDelay(options) {
537 const { attempt, initialDelay, maxDelay, multiplier, jitter } = options;
538 const exponentialDelay = initialDelay * Math.pow(multiplier, attempt - 1);
539 const cappedDelay = Math.min(exponentialDelay, maxDelay);
540 const jitterFactor = 1 + (Math.random() * 2 - 1) * jitter;
541 return Math.floor(cappedDelay * jitterFactor);
542 }
543 var RETRYABLE_MESSAGE_PATTERNS = [
544 /network/i,
545 /timeout/i,
546 /ECONNRESET/i,
547 /fetch failed/i,
548 /connection/i,
549 /socket/i,
550 /ETIMEDOUT/i,
551 /ENOTFOUND/i,
552 /Could not get a valid response/i,
553 /Failed to fetch/i,
554 /Load failed/i
555 ];
556 function shouldRetryError(error, retryCount, maxRetries) {
557 if (retryCount >= maxRetries) {
558 return false;
559 }
560 const message = typeof error === "string" ? error : error?.message || "";
561 return RETRYABLE_MESSAGE_PATTERNS.some(
562 (pattern) => pattern.test(message)
563 );
564 }
565 var retryTimers = /* @__PURE__ */ new Map();
566 function clearRetryTimer(id) {
567 const pendingTimer = retryTimers.get(id);
568 if (pendingTimer !== void 0) {
569 clearTimeout(pendingTimer);
570 retryTimers.delete(id);
571 }
572 }
573
574 // packages/upload-media/build-module/image-file.mjs
575 var ImageFile = class extends File {
576 width = 0;
577 height = 0;
578 originalWidth = 0;
579 originalHeight = 0;
580 get wasResized() {
581 return (this.originalWidth || 0) > this.width || (this.originalHeight || 0) > this.height;
582 }
583 constructor(file, width, height, originalWidth, originalHeight) {
584 super([file], file.name, {
585 type: file.type,
586 lastModified: file.lastModified
587 });
588 this.width = width;
589 this.height = height;
590 this.originalWidth = originalWidth;
591 this.originalHeight = originalHeight;
592 }
593 };
594
595 // packages/upload-media/build-module/utils.mjs
596 var import_url = __toESM(require_url(), 1);
597 var import_i18n = __toESM(require_i18n(), 1);
598 function convertBlobToFile(fileOrBlob) {
599 if (fileOrBlob instanceof File) {
600 return fileOrBlob;
601 }
602 if ("name" in fileOrBlob && typeof fileOrBlob.name === "string") {
603 return new File([fileOrBlob], fileOrBlob.name, {
604 type: fileOrBlob.type,
605 lastModified: fileOrBlob.lastModified
606 });
607 }
608 const ext = fileOrBlob.type.split("/")[1];
609 const mediaType = "application/pdf" === fileOrBlob.type ? "document" : fileOrBlob.type.split("/")[0];
610 return new File([fileOrBlob], `${mediaType}.${ext}`, {
611 type: fileOrBlob.type
612 });
613 }
614 function renameFile(file, name) {
615 return new File([file], name, {
616 type: file.type,
617 lastModified: file.lastModified
618 });
619 }
620 function cloneFile(file) {
621 return renameFile(file, file.name);
622 }
623 function getFileBasename(name) {
624 return name.includes(".") ? name.split(".").slice(0, -1).join(".") : name;
625 }
626
627 // packages/upload-media/build-module/store/utils/index.mjs
628 var vipsModulePromise;
629 var vipsModule;
630 function loadVipsModule() {
631 if (!vipsModulePromise) {
632 vipsModulePromise = import("@wordpress/vips/worker").then(
633 (mod) => {
634 vipsModule = mod;
635 return mod;
636 }
637 );
638 }
639 return vipsModulePromise;
640 }
641 async function vipsConvertImageFormat(id, file, type, quality, interlaced) {
642 const { vipsConvertImageFormat: convertImageFormat } = await loadVipsModule();
643 const buffer = await convertImageFormat(
644 id,
645 await file.arrayBuffer(),
646 file.type,
647 type,
648 quality,
649 interlaced
650 );
651 const ext = type.split("/")[1];
652 const fileName = `${getFileBasename(file.name)}.${ext}`;
653 return new File([new Blob([buffer])], fileName, {
654 type
655 });
656 }
657 async function vipsHasTransparency(url) {
658 const { vipsHasTransparency: hasTransparency } = await loadVipsModule();
659 const response = await fetch(url);
660 if (!response.ok) {
661 throw new Error(`Failed to fetch image: ${response.status}`);
662 }
663 return hasTransparency(await response.arrayBuffer());
664 }
665 async function vipsGetUltraHdrInfo(buffer) {
666 const { vipsGetUltraHdrInfo: getUltraHdrInfo } = await loadVipsModule();
667 return getUltraHdrInfo(buffer);
668 }
669 async function vipsResizeImage(id, file, resize, smartCrop, addSuffix, signal, scaledSuffix, quality) {
670 if (signal?.aborted) {
671 throw new Error("Operation aborted");
672 }
673 const { vipsResizeImage: resizeImage } = await loadVipsModule();
674 const { buffer, width, height, originalWidth, originalHeight } = await resizeImage(
675 id,
676 await file.arrayBuffer(),
677 file.type,
678 resize,
679 smartCrop,
680 quality
681 );
682 let fileName = file.name;
683 const wasResized = originalWidth > width || originalHeight > height;
684 if (wasResized) {
685 const basename = getFileBasename(file.name);
686 if (scaledSuffix) {
687 fileName = file.name.replace(basename, `${basename}-scaled`);
688 } else if (addSuffix) {
689 fileName = file.name.replace(
690 basename,
691 `${basename}-${width}x${height}`
692 );
693 }
694 }
695 const resultFile = new ImageFile(
696 new File(
697 [new Blob([buffer], { type: file.type })],
698 fileName,
699 {
700 type: file.type
701 }
702 ),
703 width,
704 height,
705 originalWidth,
706 originalHeight
707 );
708 return resultFile;
709 }
710 async function vipsRotateImage(id, file, orientation, signal) {
711 if (signal?.aborted) {
712 throw new Error("Operation aborted");
713 }
714 if (orientation === 1) {
715 return file;
716 }
717 const { vipsRotateImage: rotateImage } = await loadVipsModule();
718 const { buffer, width, height } = await rotateImage(
719 id,
720 await file.arrayBuffer(),
721 file.type,
722 orientation
723 );
724 const basename = getFileBasename(file.name);
725 const fileName = file.name.replace(basename, `${basename}-rotated`);
726 const resultFile = new ImageFile(
727 new File(
728 [new Blob([buffer], { type: file.type })],
729 fileName,
730 {
731 type: file.type
732 }
733 ),
734 width,
735 height
736 );
737 return resultFile;
738 }
739 async function vipsCancelOperations(id) {
740 if (!vipsModule) {
741 return false;
742 }
743 return vipsModule.vipsCancelOperations(id);
744 }
745 function terminateVipsWorker() {
746 if (vipsModule) {
747 vipsModule.terminateVipsWorker();
748 }
749 }
750 var completedVipsOperations = 0;
751 var MAX_VIPS_OPS_BEFORE_RECYCLE = 50;
752 function maybeRecycleVipsWorker(activeImageProcessingCount) {
753 completedVipsOperations++;
754 if (completedVipsOperations >= MAX_VIPS_OPS_BEFORE_RECYCLE && activeImageProcessingCount === 0) {
755 terminateVipsWorker();
756 completedVipsOperations = 0;
757 }
758 }
759
760 // packages/upload-media/build-module/store/utils/debug-logger.mjs
761 function isDebugEnabled() {
762 return true;
763 }
764 function debug(message, ...args) {
765 if (!isDebugEnabled()) {
766 return;
767 }
768 console.debug(`[upload-media] ${message}`, ...args);
769 }
770 function measure(options) {
771 if (!isDebugEnabled()) {
772 return;
773 }
774 const {
775 measureName,
776 startTime,
777 endTime = performance.now(),
778 tooltipText,
779 properties
780 } = options;
781 const detail = {
782 devtools: {
783 dataType: "track-entry",
784 track: "Upload Media",
785 tooltipText,
786 properties: properties?.map(([key, value]) => ({
787 key,
788 value
789 }))
790 }
791 };
792 try {
793 performance.measure(measureName, {
794 start: startTime,
795 end: endTime,
796 detail
797 });
798 } catch {
799 }
800 }
801
802 // packages/upload-media/build-module/upload-error.mjs
803 var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
804 ErrorCode2["EMPTY_FILE"] = "EMPTY_FILE";
805 ErrorCode2["SIZE_ABOVE_LIMIT"] = "SIZE_ABOVE_LIMIT";
806 ErrorCode2["MIME_TYPE_NOT_SUPPORTED"] = "MIME_TYPE_NOT_SUPPORTED";
807 ErrorCode2["MIME_TYPE_NOT_ALLOWED_FOR_USER"] = "MIME_TYPE_NOT_ALLOWED_FOR_USER";
808 ErrorCode2["HEIC_DECODE_ERROR"] = "HEIC_DECODE_ERROR";
809 ErrorCode2["IMAGE_TRANSCODING_ERROR"] = "IMAGE_TRANSCODING_ERROR";
810 ErrorCode2["IMAGE_ROTATION_ERROR"] = "IMAGE_ROTATION_ERROR";
811 ErrorCode2["MEDIA_TRANSCODING_ERROR"] = "MEDIA_TRANSCODING_ERROR";
812 ErrorCode2["GENERAL"] = "GENERAL";
813 return ErrorCode2;
814 })(ErrorCode || {});
815 var UploadError = class extends Error {
816 code;
817 file;
818 constructor({ code, message, file, cause }) {
819 super(message, { cause });
820 Object.setPrototypeOf(this, new.target.prototype);
821 this.code = code;
822 this.file = file;
823 }
824 };
825
826 // packages/upload-media/build-module/validate-mime-type.mjs
827 var import_i18n2 = __toESM(require_i18n(), 1);
828 function validateMimeType(file, allowedTypes) {
829 if (!allowedTypes) {
830 return;
831 }
832 const isAllowedType = allowedTypes.some((allowedType) => {
833 if (allowedType.includes("/")) {
834 return allowedType === file.type;
835 }
836 return file.type.startsWith(`${allowedType}/`);
837 });
838 if (file.type && !isAllowedType) {
839 throw new UploadError({
840 code: ErrorCode.MIME_TYPE_NOT_SUPPORTED,
841 message: (0, import_i18n2.sprintf)(
842 // translators: %s: file name.
843 (0, import_i18n2.__)("%s: Sorry, this file type is not supported here."),
844 file.name
845 ),
846 file
847 });
848 }
849 }
850
851 // packages/upload-media/build-module/validate-mime-type-for-user.mjs
852 var import_i18n3 = __toESM(require_i18n(), 1);
853
854 // packages/upload-media/build-module/get-mime-types-array.mjs
855 function getMimeTypesArray(wpMimeTypesObject) {
856 if (!wpMimeTypesObject) {
857 return null;
858 }
859 return Object.entries(wpMimeTypesObject).flatMap(
860 ([extensionsString, mime]) => {
861 const [type] = mime.split("/");
862 const extensions = extensionsString.split("|");
863 return [
864 mime,
865 ...extensions.map(
866 (extension) => `${type}/${extension}`
867 )
868 ];
869 }
870 );
871 }
872
873 // packages/upload-media/build-module/validate-mime-type-for-user.mjs
874 function validateMimeTypeForUser(file, wpAllowedMimeTypes) {
875 const allowedMimeTypesForUser = getMimeTypesArray(wpAllowedMimeTypes);
876 if (!allowedMimeTypesForUser) {
877 return;
878 }
879 const isAllowedMimeTypeForUser = allowedMimeTypesForUser.includes(
880 file.type
881 );
882 if (file.type && !isAllowedMimeTypeForUser) {
883 throw new UploadError({
884 code: ErrorCode.MIME_TYPE_NOT_ALLOWED_FOR_USER,
885 message: (0, import_i18n3.sprintf)(
886 // translators: %s: file name.
887 (0, import_i18n3.__)(
888 "%s: Sorry, you are not allowed to upload this file type."
889 ),
890 file.name
891 ),
892 file
893 });
894 }
895 }
896
897 // packages/upload-media/build-module/validate-file-size.mjs
898 var import_i18n4 = __toESM(require_i18n(), 1);
899 function validateFileSize(file, maxUploadFileSize) {
900 if (file.size <= 0) {
901 throw new UploadError({
902 code: ErrorCode.EMPTY_FILE,
903 message: (0, import_i18n4.sprintf)(
904 // translators: %s: file name.
905 (0, import_i18n4.__)("%s: This file is empty."),
906 file.name
907 ),
908 file
909 });
910 }
911 if (maxUploadFileSize && file.size > maxUploadFileSize) {
912 throw new UploadError({
913 code: ErrorCode.SIZE_ABOVE_LIMIT,
914 message: (0, import_i18n4.sprintf)(
915 // translators: %s: file name.
916 (0, import_i18n4.__)(
917 "%s: This file exceeds the maximum upload size for this site."
918 ),
919 file.name
920 ),
921 file
922 });
923 }
924 }
925
926 // packages/upload-media/build-module/store/actions.mjs
927 function addItems({
928 files,
929 onChange,
930 onSuccess,
931 onError,
932 onBatchSuccess,
933 additionalData,
934 allowedTypes
935 }) {
936 return async ({ select: select2, dispatch }) => {
937 const batchId = v4_default();
938 for (const file of files) {
939 try {
940 validateMimeType(file, allowedTypes);
941 validateMimeTypeForUser(
942 file,
943 select2.getSettings().allowedMimeTypes
944 );
945 } catch (error) {
946 onError?.(error);
947 continue;
948 }
949 try {
950 validateFileSize(
951 file,
952 select2.getSettings().maxUploadFileSize
953 );
954 } catch (error) {
955 onError?.(error);
956 continue;
957 }
958 dispatch.addItem({
959 file,
960 batchId,
961 onChange,
962 onSuccess,
963 onBatchSuccess,
964 onError,
965 additionalData
966 });
967 }
968 };
969 }
970 function cancelItem(id, error, silent = false) {
971 return async ({ select: select2, dispatch }) => {
972 const item = select2.getItem(id);
973 if (!item) {
974 return;
975 }
976 clearRetryTimer(id);
977 if (!silent && error && !item.parentId && !item.attachment?.id) {
978 const settings = select2.getSettings();
979 const retrySettings = settings.retry;
980 if (retrySettings) {
981 const retryCount = item.retryCount ?? 0;
982 const maxRetries = retrySettings.maxRetryAttempts;
983 if (shouldRetryError(error, retryCount, maxRetries)) {
984 dispatch.scheduleRetry(id, error);
985 return;
986 }
987 }
988 }
989 item.abortController?.abort();
990 await vipsCancelOperations(id);
991 if (!silent) {
992 const { onError } = item;
993 onError?.(error ?? new Error("Upload cancelled"));
994 if (!onError && error && !item.parentId) {
995 console.error("Upload cancelled", error);
996 }
997 } else {
998 debug(
999 `Item cancelled: ${item.file.name} (item ${id}): ${error instanceof Error ? error.message : error}`
1000 );
1001 }
1002 const { currentOperation, parentId, batchId } = item;
1003 dispatch({
1004 type: Type.Cancel,
1005 id,
1006 error
1007 });
1008 dispatch.removeItem(id);
1009 dispatch.revokeBlobUrls(id);
1010 if (currentOperation === OperationType.ResizeCrop || currentOperation === OperationType.Rotate) {
1011 for (const pending of select2.getPendingImageProcessing()) {
1012 dispatch.processItem(pending.id);
1013 }
1014 }
1015 if (currentOperation === OperationType.Upload) {
1016 for (const pending of select2.getPendingUploads()) {
1017 dispatch.processItem(pending.id);
1018 }
1019 }
1020 if (currentOperation === OperationType.ResizeCrop || currentOperation === OperationType.Rotate || currentOperation === OperationType.TranscodeImage) {
1021 maybeRecycleVipsWorker(select2.getActiveImageProcessingCount());
1022 }
1023 if (parentId) {
1024 const parentItem = select2.getItem(parentId);
1025 if (parentItem) {
1026 if (select2.hasPendingItemsByParentId(parentId)) {
1027 if (parentItem.operations && parentItem.operations.length > 0) {
1028 dispatch.processItem(parentId);
1029 }
1030 } else if (parentItem.subSizes && parentItem.subSizes.length > 0) {
1031 if (parentItem.operations && parentItem.operations.length > 0) {
1032 dispatch.processItem(parentId);
1033 }
1034 } else {
1035 const parentAttachmentId = parentItem.attachment?.id;
1036 const { mediaDelete } = select2.getSettings();
1037 if (parentAttachmentId && mediaDelete) {
1038 mediaDelete(parentAttachmentId).catch(() => {
1039 });
1040 }
1041 dispatch.cancelItem(
1042 parentId,
1043 new UploadError({
1044 code: error instanceof UploadError && error.code || ErrorCode.GENERAL,
1045 message: error?.message || (0, import_i18n5.__)("The image could not be uploaded."),
1046 file: parentItem.file,
1047 cause: error instanceof Error ? error : void 0
1048 })
1049 );
1050 }
1051 }
1052 }
1053 if (batchId && select2.isBatchUploaded(batchId)) {
1054 debug(`Batch completed: ${batchId}`);
1055 item.onBatchSuccess?.();
1056 }
1057 };
1058 }
1059 function retryItem(id) {
1060 return async ({ select: select2, dispatch }) => {
1061 const item = select2.getItem(id);
1062 if (!item) {
1063 return;
1064 }
1065 if (!item.error) {
1066 return;
1067 }
1068 dispatch({
1069 type: Type.RetryItem,
1070 id
1071 });
1072 dispatch.processItem(id);
1073 };
1074 }
1075 function scheduleRetry(id, error) {
1076 return async ({ select: select2, dispatch }) => {
1077 const item = select2.getItem(id);
1078 if (!item) {
1079 return;
1080 }
1081 const settings = select2.getSettings();
1082 const retrySettings = settings.retry;
1083 if (!retrySettings) {
1084 return;
1085 }
1086 const currentRetryCount = item.retryCount ?? 0;
1087 const delay = calculateRetryDelay({
1088 attempt: currentRetryCount + 1,
1089 initialDelay: retrySettings.initialRetryDelayMs,
1090 maxDelay: retrySettings.maxRetryDelayMs,
1091 multiplier: retrySettings.backoffMultiplier,
1092 jitter: retrySettings.retryJitter
1093 });
1094 const timerId = setTimeout(() => {
1095 retryTimers.delete(id);
1096 dispatch.executeRetry(id);
1097 }, delay);
1098 retryTimers.set(id, timerId);
1099 dispatch({
1100 type: Type.ScheduleRetry,
1101 id,
1102 error,
1103 retryCount: currentRetryCount,
1104 nextRetryTimestamp: Date.now() + delay
1105 });
1106 };
1107 }
1108 function executeRetry(id) {
1109 return async ({ select: select2, dispatch }) => {
1110 const item = select2.getItem(id);
1111 if (!item || item.status !== ItemStatus.PendingRetry) {
1112 return;
1113 }
1114 if (select2.isPaused()) {
1115 return;
1116 }
1117 dispatch({
1118 type: Type.RetryItem,
1119 id
1120 });
1121 dispatch.processItem(id);
1122 };
1123 }
1124
1125 // packages/upload-media/build-module/store/private-actions.mjs
1126 var private_actions_exports = {};
1127 __export(private_actions_exports, {
1128 addItem: () => addItem,
1129 addSideloadItem: () => addSideloadItem,
1130 detectUltraHdr: () => detectUltraHdr,
1131 finalizeItem: () => finalizeItem,
1132 finishOperation: () => finishOperation,
1133 generateThumbnails: () => generateThumbnails,
1134 getTranscodeImageOperation: () => getTranscodeImageOperation,
1135 pauseItem: () => pauseItem,
1136 pauseQueue: () => pauseQueue,
1137 prepareItem: () => prepareItem,
1138 processItem: () => processItem,
1139 removeItem: () => removeItem,
1140 resizeCropItem: () => resizeCropItem,
1141 resumeQueue: () => resumeQueue,
1142 revokeBlobUrls: () => revokeBlobUrls,
1143 rotateItem: () => rotateItem,
1144 sideloadItem: () => sideloadItem,
1145 transcodeImageItem: () => transcodeImageItem,
1146 updateItemProgress: () => updateItemProgress,
1147 updateSettings: () => updateSettings,
1148 uploadItem: () => uploadItem
1149 });
1150 var import_blob = __toESM(require_blob(), 1);
1151 var import_i18n6 = __toESM(require_i18n(), 1);
1152
1153 // packages/upload-media/build-module/heic-parser.mjs
1154 var Reader = class {
1155 view;
1156 buffer;
1157 pos;
1158 constructor(buffer, offset = 0) {
1159 this.buffer = buffer;
1160 this.view = new DataView(buffer);
1161 this.pos = offset;
1162 }
1163 u8() {
1164 const v = this.view.getUint8(this.pos);
1165 this.pos += 1;
1166 return v;
1167 }
1168 u16() {
1169 const v = this.view.getUint16(this.pos);
1170 this.pos += 2;
1171 return v;
1172 }
1173 u32() {
1174 const v = this.view.getUint32(this.pos);
1175 this.pos += 4;
1176 return v;
1177 }
1178 u64() {
1179 const hi = this.view.getUint32(this.pos);
1180 const lo = this.view.getUint32(this.pos + 4);
1181 this.pos += 8;
1182 return hi * 4294967296 + lo;
1183 }
1184 /**
1185 * Read a variable-width unsigned integer (0, 4 or 8 bytes).
1186 *
1187 * @param size Byte width to read (0, 4, or 8).
1188 */
1189 uN(size) {
1190 if (size === 0) {
1191 return 0;
1192 }
1193 if (size === 4) {
1194 return this.u32();
1195 }
1196 if (size === 8) {
1197 return this.u64();
1198 }
1199 throw new Error(`Unsupported uint size: ${size}`);
1200 }
1201 str(len) {
1202 let s = "";
1203 for (let i = 0; i < len; i++) {
1204 s += String.fromCharCode(this.view.getUint8(this.pos + i));
1205 }
1206 this.pos += len;
1207 return s;
1208 }
1209 bytes(len) {
1210 const b = new Uint8Array(this.buffer, this.pos, len);
1211 this.pos += len;
1212 return new Uint8Array(b);
1213 }
1214 };
1215 function readBox(r) {
1216 if (r.pos + 8 > r.view.byteLength) {
1217 return null;
1218 }
1219 const offset = r.pos;
1220 let size = r.u32();
1221 const type = r.str(4);
1222 let headerSize = 8;
1223 if (size === 1) {
1224 size = r.u64();
1225 headerSize = 16;
1226 } else if (size === 0) {
1227 size = r.view.byteLength - offset;
1228 }
1229 return { type, offset, size, headerSize };
1230 }
1231 function findBoxes(r, start, end) {
1232 const boxes = [];
1233 r.pos = start;
1234 while (r.pos < end) {
1235 const box = readBox(r);
1236 if (!box || box.size < 8) {
1237 break;
1238 }
1239 boxes.push(box);
1240 r.pos = box.offset + box.size;
1241 }
1242 return boxes;
1243 }
1244 function findBox(r, start, end, type) {
1245 r.pos = start;
1246 while (r.pos < end) {
1247 const box = readBox(r);
1248 if (!box || box.size < 8) {
1249 break;
1250 }
1251 if (box.type === type) {
1252 return box;
1253 }
1254 r.pos = box.offset + box.size;
1255 }
1256 return void 0;
1257 }
1258 function parsePitm(r, box) {
1259 r.pos = box.offset + box.headerSize;
1260 const version = r.u8();
1261 r.pos += 3;
1262 return version === 0 ? r.u16() : r.u32();
1263 }
1264 function parseIloc(r, box) {
1265 r.pos = box.offset + box.headerSize;
1266 const version = r.u8();
1267 r.pos += 3;
1268 const byte1 = r.u8();
1269 const offsetSize = byte1 >> 4 & 15;
1270 const lengthSize = byte1 & 15;
1271 const byte2 = r.u8();
1272 const baseOffsetSize = byte2 >> 4 & 15;
1273 const indexSize = version >= 1 ? byte2 & 15 : 0;
1274 const itemCount = version < 2 ? r.u16() : r.u32();
1275 const items = /* @__PURE__ */ new Map();
1276 for (let i = 0; i < itemCount; i++) {
1277 const itemId = version < 2 ? r.u16() : r.u32();
1278 let constructionMethod = 0;
1279 if (version === 1 || version === 2) {
1280 const cm = r.u16();
1281 constructionMethod = cm & 15;
1282 }
1283 r.u16();
1284 const baseOffset = r.uN(baseOffsetSize);
1285 const extentCount = r.u16();
1286 const extents = [];
1287 for (let j = 0; j < extentCount; j++) {
1288 if (version >= 1) {
1289 r.uN(indexSize);
1290 }
1291 const extOffset = r.uN(offsetSize);
1292 const extLength = r.uN(lengthSize);
1293 extents.push({
1294 offset: baseOffset + extOffset,
1295 length: extLength
1296 });
1297 }
1298 items.set(itemId, { constructionMethod, extents });
1299 }
1300 return items;
1301 }
1302 function parseIpma(r, box) {
1303 r.pos = box.offset + box.headerSize;
1304 const vf = r.u32();
1305 const version = vf >>> 24;
1306 const flags = vf & 16777215;
1307 const largeIndex = (flags & 1) !== 0;
1308 const entryCount = r.u32();
1309 const associations = /* @__PURE__ */ new Map();
1310 for (let i = 0; i < entryCount; i++) {
1311 const itemId = version < 1 ? r.u16() : r.u32();
1312 const assocCount = r.u8();
1313 const indices = [];
1314 for (let j = 0; j < assocCount; j++) {
1315 if (largeIndex) {
1316 indices.push(r.u16() & 32767);
1317 } else {
1318 indices.push(r.u8() & 127);
1319 }
1320 }
1321 associations.set(itemId, indices);
1322 }
1323 return associations;
1324 }
1325 function parseIspe(r, box) {
1326 r.pos = box.offset + box.headerSize + 4;
1327 return { width: r.u32(), height: r.u32() };
1328 }
1329 function parseIrot(r, box) {
1330 r.pos = box.offset + box.headerSize;
1331 return (r.u8() & 3) * 90;
1332 }
1333 function parseIinf(r, box) {
1334 r.pos = box.offset + box.headerSize;
1335 const version = r.u8();
1336 r.pos += 3;
1337 const entryCount = version === 0 ? r.u16() : r.u32();
1338 const itemTypes = /* @__PURE__ */ new Map();
1339 const entriesStart = r.pos;
1340 const boxEnd = box.offset + box.size;
1341 const infeBoxes = findBoxes(r, entriesStart, boxEnd);
1342 for (let i = 0; i < Math.min(entryCount, infeBoxes.length); i++) {
1343 const infe = infeBoxes[i];
1344 if (infe.type !== "infe") {
1345 continue;
1346 }
1347 r.pos = infe.offset + infe.headerSize;
1348 const infeVersion = r.u8();
1349 r.pos += 3;
1350 if (infeVersion >= 2) {
1351 const itemId = infeVersion === 2 ? r.u16() : r.u32();
1352 r.u16();
1353 const itemType = r.str(4);
1354 itemTypes.set(itemId, itemType);
1355 }
1356 }
1357 return itemTypes;
1358 }
1359 function parseIref(r, box, refType) {
1360 r.pos = box.offset + box.headerSize;
1361 const version = r.u8();
1362 r.pos += 3;
1363 const refs = /* @__PURE__ */ new Map();
1364 const boxEnd = box.offset + box.size;
1365 while (r.pos < boxEnd) {
1366 const refBox = readBox(r);
1367 if (!refBox || refBox.size < 8) {
1368 break;
1369 }
1370 r.pos = refBox.offset + refBox.headerSize;
1371 const fromId = version === 0 ? r.u16() : r.u32();
1372 const refCount = r.u16();
1373 const toIds = [];
1374 for (let i = 0; i < refCount; i++) {
1375 toIds.push(version === 0 ? r.u16() : r.u32());
1376 }
1377 if (refBox.type === refType) {
1378 refs.set(fromId, toIds);
1379 }
1380 r.pos = refBox.offset + refBox.size;
1381 }
1382 return refs;
1383 }
1384 function reverseBits32(n) {
1385 n = n >>> 1 & 1431655765 | (n & 1431655765) << 1;
1386 n = n >>> 2 & 858993459 | (n & 858993459) << 2;
1387 n = n >>> 4 & 252645135 | (n & 252645135) << 4;
1388 n = n >>> 8 & 16711935 | (n & 16711935) << 8;
1389 n = n >>> 16 | n << 16;
1390 return n >>> 0;
1391 }
1392 function buildCodecString(r, recordOffset) {
1393 r.pos = recordOffset;
1394 r.u8();
1395 const byte1 = r.u8();
1396 const profileSpace = byte1 >> 6 & 3;
1397 const tierFlag = byte1 >> 5 & 1;
1398 const profileIdc = byte1 & 31;
1399 const compatFlags = r.u32();
1400 const constraintBytes = r.bytes(6);
1401 const levelIdc = r.u8();
1402 const spacePrefix = profileSpace > 0 ? String.fromCharCode(64 + profileSpace) : "";
1403 const compatHex = reverseBits32(compatFlags).toString(16).toUpperCase();
1404 const tierChar = tierFlag ? "H" : "L";
1405 let lastNonZero = -1;
1406 for (let i = 5; i >= 0; i--) {
1407 if (constraintBytes[i] !== 0) {
1408 lastNonZero = i;
1409 break;
1410 }
1411 }
1412 let constraintStr = "";
1413 if (lastNonZero >= 0) {
1414 const parts = [];
1415 for (let i = 0; i <= lastNonZero; i++) {
1416 parts.push(constraintBytes[i].toString(16).toUpperCase());
1417 }
1418 constraintStr = "." + parts.join(".");
1419 }
1420 return `hvc1.${spacePrefix}${profileIdc}.${compatHex}.${tierChar}${levelIdc}${constraintStr}`;
1421 }
1422 function readItemData(buffer, loc, idatOffset) {
1423 const baseOffset = loc.constructionMethod === 1 ? idatOffset : 0;
1424 if (loc.extents.length === 1) {
1425 const ext = loc.extents[0];
1426 const start = baseOffset + ext.offset;
1427 return new Uint8Array(buffer.slice(start, start + ext.length));
1428 }
1429 let totalLength = 0;
1430 for (const ext of loc.extents) {
1431 totalLength += ext.length;
1432 }
1433 const data = new Uint8Array(totalLength);
1434 let pos = 0;
1435 for (const ext of loc.extents) {
1436 const start = baseOffset + ext.offset;
1437 data.set(
1438 new Uint8Array(buffer.slice(start, start + ext.length)),
1439 pos
1440 );
1441 pos += ext.length;
1442 }
1443 return data;
1444 }
1445 function findHvcProperties(propIndices, properties) {
1446 let hvcCBox;
1447 let ispeBox;
1448 let irotBox;
1449 for (const idx of propIndices) {
1450 if (idx < 1 || idx > properties.length) {
1451 continue;
1452 }
1453 const prop = properties[idx - 1];
1454 if (prop.type === "hvcC" && !hvcCBox) {
1455 hvcCBox = prop;
1456 }
1457 if (prop.type === "ispe" && !ispeBox) {
1458 ispeBox = prop;
1459 }
1460 if (prop.type === "irot" && !irotBox) {
1461 irotBox = prop;
1462 }
1463 }
1464 if (!hvcCBox) {
1465 throw new Error("No HEVC configuration (hvcC) found");
1466 }
1467 if (!ispeBox) {
1468 throw new Error("No image dimensions (ispe) found");
1469 }
1470 return { hvcCBox, ispeBox, irotBox };
1471 }
1472 function parseHeic(buffer) {
1473 const r = new Reader(buffer);
1474 const fileEnd = buffer.byteLength;
1475 const metaBox = findBox(r, 0, fileEnd, "meta");
1476 if (!metaBox) {
1477 throw new Error("No meta box found in HEIC file");
1478 }
1479 const metaChildStart = metaBox.offset + metaBox.headerSize + 4;
1480 const metaEnd = metaBox.offset + metaBox.size;
1481 const children = findBoxes(r, metaChildStart, metaEnd);
1482 const pitmBox = children.find((b) => b.type === "pitm");
1483 const ilocBox = children.find((b) => b.type === "iloc");
1484 const iprpBox = children.find((b) => b.type === "iprp");
1485 const iinfBox = children.find((b) => b.type === "iinf");
1486 const irefBox = children.find((b) => b.type === "iref");
1487 const idatBox = children.find((b) => b.type === "idat");
1488 const idatOffset = idatBox ? idatBox.offset + idatBox.headerSize : 0;
1489 if (!pitmBox || !ilocBox || !iprpBox) {
1490 throw new Error("Missing required boxes (pitm, iloc, iprp) in HEIC");
1491 }
1492 const primaryId = parsePitm(r, pitmBox);
1493 const locations = parseIloc(r, ilocBox);
1494 const iprpStart = iprpBox.offset + iprpBox.headerSize;
1495 const iprpEnd = iprpBox.offset + iprpBox.size;
1496 const iprpChildren = findBoxes(r, iprpStart, iprpEnd);
1497 const ipcoBox = iprpChildren.find((b) => b.type === "ipco");
1498 const ipmaBox = iprpChildren.find((b) => b.type === "ipma");
1499 if (!ipcoBox || !ipmaBox) {
1500 throw new Error("Missing ipco or ipma in HEIC properties");
1501 }
1502 const allAssoc = parseIpma(r, ipmaBox);
1503 const ipcoStart = ipcoBox.offset + ipcoBox.headerSize;
1504 const ipcoEnd = ipcoBox.offset + ipcoBox.size;
1505 const properties = findBoxes(r, ipcoStart, ipcoEnd);
1506 let primaryItemType = "hvc1";
1507 if (iinfBox) {
1508 const itemTypes = parseIinf(r, iinfBox);
1509 const t = itemTypes.get(primaryId);
1510 if (t) {
1511 primaryItemType = t;
1512 }
1513 }
1514 if (primaryItemType === "grid") {
1515 return parseGridImage(
1516 r,
1517 buffer,
1518 primaryId,
1519 locations,
1520 allAssoc,
1521 properties,
1522 irefBox,
1523 idatOffset
1524 );
1525 }
1526 const primaryLoc = locations.get(primaryId);
1527 if (!primaryLoc || primaryLoc.extents.length === 0) {
1528 throw new Error(`No location data for primary item ${primaryId}`);
1529 }
1530 const primaryPropIndices = allAssoc.get(primaryId);
1531 if (!primaryPropIndices || primaryPropIndices.length === 0) {
1532 throw new Error("No property associations for primary item");
1533 }
1534 const { hvcCBox, ispeBox, irotBox } = findHvcProperties(
1535 primaryPropIndices,
1536 properties
1537 );
1538 const hvcCDataStart = hvcCBox.offset + hvcCBox.headerSize;
1539 const hvcCDataSize = hvcCBox.size - hvcCBox.headerSize;
1540 const description = new Uint8Array(
1541 buffer.slice(hvcCDataStart, hvcCDataStart + hvcCDataSize)
1542 );
1543 const codecString = buildCodecString(r, hvcCDataStart);
1544 const { width, height } = parseIspe(r, ispeBox);
1545 const rotation = irotBox ? parseIrot(r, irotBox) : 0;
1546 return {
1547 codecString,
1548 description,
1549 tiles: [
1550 {
1551 data: readItemData(buffer, primaryLoc, idatOffset),
1552 x: 0,
1553 y: 0
1554 }
1555 ],
1556 tileWidth: width,
1557 tileHeight: height,
1558 outputWidth: width,
1559 outputHeight: height,
1560 rotation
1561 };
1562 }
1563 function parseGridImage(r, buffer, gridItemId, locations, allAssoc, properties, irefBox, idatOffset) {
1564 const gridLoc = locations.get(gridItemId);
1565 if (!gridLoc || gridLoc.extents.length === 0) {
1566 throw new Error("No location data for grid item");
1567 }
1568 const gridData = readItemData(buffer, gridLoc, idatOffset);
1569 const largeFields = gridData.length > 1 && (gridData[1] & 1) !== 0;
1570 const minGridSize = largeFields ? 12 : 8;
1571 if (gridData.length < minGridSize) {
1572 throw new Error(
1573 `Grid descriptor too short: ${gridData.length} bytes`
1574 );
1575 }
1576 const rows = gridData[2] + 1;
1577 const columns = gridData[3] + 1;
1578 const gv = new DataView(gridData.buffer, gridData.byteOffset);
1579 let outputWidth;
1580 let outputHeight;
1581 if (largeFields) {
1582 outputWidth = gv.getUint32(4);
1583 outputHeight = gv.getUint32(8);
1584 } else {
1585 outputWidth = gv.getUint16(4);
1586 outputHeight = gv.getUint16(6);
1587 }
1588 if (!irefBox) {
1589 throw new Error("Grid image requires iref box");
1590 }
1591 const dimgRefs = parseIref(r, irefBox, "dimg");
1592 const tileItemIds = dimgRefs.get(gridItemId);
1593 if (!tileItemIds || tileItemIds.length === 0) {
1594 throw new Error("No tile references found for grid item");
1595 }
1596 const expectedTiles = rows * columns;
1597 if (tileItemIds.length < expectedTiles) {
1598 throw new Error(
1599 `Grid expects ${expectedTiles} tiles but found ${tileItemIds.length}`
1600 );
1601 }
1602 const firstTileProps = allAssoc.get(tileItemIds[0]);
1603 if (!firstTileProps || firstTileProps.length === 0) {
1604 throw new Error("No property associations for tile item");
1605 }
1606 const { hvcCBox, ispeBox } = findHvcProperties(
1607 firstTileProps,
1608 properties
1609 );
1610 const gridProps = allAssoc.get(gridItemId) || [];
1611 let irotBox;
1612 for (const idx of gridProps) {
1613 if (idx >= 1 && idx <= properties.length) {
1614 const prop = properties[idx - 1];
1615 if (prop.type === "irot") {
1616 irotBox = prop;
1617 break;
1618 }
1619 }
1620 }
1621 const hvcCDataStart = hvcCBox.offset + hvcCBox.headerSize;
1622 const hvcCDataSize = hvcCBox.size - hvcCBox.headerSize;
1623 const description = new Uint8Array(
1624 buffer.slice(hvcCDataStart, hvcCDataStart + hvcCDataSize)
1625 );
1626 const codecString = buildCodecString(r, hvcCDataStart);
1627 const { width: tileWidth, height: tileHeight } = parseIspe(r, ispeBox);
1628 const tiles = [];
1629 for (let row = 0; row < rows; row++) {
1630 for (let col = 0; col < columns; col++) {
1631 const tileIdx = row * columns + col;
1632 const tileId = tileItemIds[tileIdx];
1633 const tileLoc = locations.get(tileId);
1634 if (!tileLoc || tileLoc.extents.length === 0) {
1635 throw new Error(`No location data for tile item ${tileId}`);
1636 }
1637 tiles.push({
1638 data: readItemData(buffer, tileLoc, idatOffset),
1639 x: col * tileWidth,
1640 y: row * tileHeight
1641 });
1642 }
1643 }
1644 const rotation = irotBox ? parseIrot(r, irotBox) : 0;
1645 return {
1646 codecString,
1647 description,
1648 tiles,
1649 tileWidth,
1650 tileHeight,
1651 outputWidth,
1652 outputHeight,
1653 rotation
1654 };
1655 }
1656
1657 // packages/upload-media/build-module/canvas-utils.mjs
1658 async function canvasConvertToJpeg(file, quality = 0.82) {
1659 const baseName = getFileBasename(file.name);
1660 try {
1661 const bitmap = await createImageBitmap(file);
1662 try {
1663 const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
1664 const ctx = canvas.getContext("2d");
1665 if (!ctx) {
1666 throw new Error("Could not get canvas 2d context");
1667 }
1668 ctx.drawImage(bitmap, 0, 0);
1669 const jpegBlob = await canvas.convertToBlob({
1670 type: "image/jpeg",
1671 quality
1672 });
1673 return new File([jpegBlob], `${baseName}.jpg`, {
1674 type: "image/jpeg"
1675 });
1676 } finally {
1677 bitmap.close();
1678 }
1679 } catch {
1680 }
1681 if (typeof ImageDecoder !== "undefined") {
1682 const supported = await ImageDecoder.isTypeSupported(file.type);
1683 if (supported) {
1684 const decoder = new ImageDecoder({
1685 type: file.type,
1686 data: file.stream()
1687 });
1688 try {
1689 const { image: videoFrame } = await decoder.decode();
1690 try {
1691 const canvas = new OffscreenCanvas(
1692 videoFrame.displayWidth,
1693 videoFrame.displayHeight
1694 );
1695 const ctx = canvas.getContext("2d");
1696 if (!ctx) {
1697 throw new Error("Could not get canvas 2d context");
1698 }
1699 ctx.drawImage(videoFrame, 0, 0);
1700 const jpegBlob = await canvas.convertToBlob({
1701 type: "image/jpeg",
1702 quality
1703 });
1704 return new File([jpegBlob], `${baseName}.jpg`, {
1705 type: "image/jpeg"
1706 });
1707 } finally {
1708 videoFrame.close();
1709 }
1710 } finally {
1711 decoder.close();
1712 }
1713 }
1714 }
1715 if (typeof VideoDecoder !== "undefined") {
1716 try {
1717 const heicData = parseHeic(await file.arrayBuffer());
1718 const support = await VideoDecoder.isConfigSupported({
1719 codec: heicData.codecString
1720 });
1721 if (support.supported) {
1722 const canvas = new OffscreenCanvas(
1723 heicData.outputWidth,
1724 heicData.outputHeight
1725 );
1726 const ctx = canvas.getContext("2d");
1727 if (!ctx) {
1728 throw new Error("Could not get canvas 2d context");
1729 }
1730 for (const tile of heicData.tiles) {
1731 const frame = await decodeHevcFrame(
1732 heicData.codecString,
1733 heicData.description,
1734 heicData.tileWidth,
1735 heicData.tileHeight,
1736 tile.data
1737 );
1738 try {
1739 ctx.drawImage(frame, tile.x, tile.y);
1740 } finally {
1741 frame.close();
1742 }
1743 }
1744 const outputCanvas = applyRotation(canvas, heicData.rotation);
1745 const jpegBlob = await outputCanvas.convertToBlob({
1746 type: "image/jpeg",
1747 quality
1748 });
1749 return new File([jpegBlob], `${baseName}.jpg`, {
1750 type: "image/jpeg"
1751 });
1752 }
1753 } catch {
1754 }
1755 }
1756 throw new Error(
1757 "This browser cannot decode HEIC images. Please use Safari or convert to JPEG before uploading."
1758 );
1759 }
1760 function applyRotation(source, rotation) {
1761 if (rotation === 0) {
1762 return source;
1763 }
1764 const swap = rotation === 90 || rotation === 270;
1765 const w = swap ? source.height : source.width;
1766 const h = swap ? source.width : source.height;
1767 const rotated = new OffscreenCanvas(w, h);
1768 const ctx = rotated.getContext("2d");
1769 if (!ctx) {
1770 return source;
1771 }
1772 ctx.translate(w / 2, h / 2);
1773 ctx.rotate(-rotation * Math.PI / 180);
1774 ctx.drawImage(source, -source.width / 2, -source.height / 2);
1775 return rotated;
1776 }
1777 function decodeHevcFrame(codec, description, width, height, data) {
1778 return new Promise((resolve, reject) => {
1779 const decoder = new VideoDecoder({
1780 output: (frame) => {
1781 decoder.close();
1782 resolve(frame);
1783 },
1784 error: (e) => {
1785 if (decoder.state !== "closed") {
1786 decoder.close();
1787 }
1788 reject(e);
1789 }
1790 });
1791 decoder.configure({
1792 codec,
1793 codedWidth: width,
1794 codedHeight: height,
1795 description
1796 });
1797 decoder.decode(
1798 new EncodedVideoChunk({
1799 type: "key",
1800 timestamp: 0,
1801 data
1802 })
1803 );
1804 decoder.flush().catch((e) => {
1805 if (decoder.state !== "closed") {
1806 decoder.close();
1807 }
1808 reject(e);
1809 });
1810 });
1811 }
1812
1813 // packages/upload-media/build-module/feature-detection.mjs
1814 var cachedResult = null;
1815 function detectClientSideMediaSupport() {
1816 if (cachedResult !== null) {
1817 return cachedResult;
1818 }
1819 if (typeof WebAssembly === "undefined") {
1820 cachedResult = {
1821 supported: false,
1822 reason: "WebAssembly is not supported in this browser."
1823 };
1824 return cachedResult;
1825 }
1826 if (typeof SharedArrayBuffer === "undefined") {
1827 cachedResult = {
1828 supported: false,
1829 reason: "SharedArrayBuffer is not available. This may be due to missing cross-origin isolation headers."
1830 };
1831 return cachedResult;
1832 }
1833 if (typeof Worker === "undefined") {
1834 cachedResult = {
1835 supported: false,
1836 reason: "Web Workers are not supported in this browser."
1837 };
1838 return cachedResult;
1839 }
1840 if (typeof navigator !== "undefined" && "deviceMemory" in navigator && navigator.deviceMemory <= 2) {
1841 cachedResult = {
1842 supported: false,
1843 reason: "Device has insufficient memory for client-side media processing."
1844 };
1845 return cachedResult;
1846 }
1847 if (typeof navigator !== "undefined" && "hardwareConcurrency" in navigator && navigator.hardwareConcurrency < 2) {
1848 cachedResult = {
1849 supported: false,
1850 reason: "Device has insufficient CPU cores for client-side media processing."
1851 };
1852 return cachedResult;
1853 }
1854 if (typeof navigator !== "undefined") {
1855 const connection = navigator.connection;
1856 if (connection) {
1857 if (connection.saveData) {
1858 cachedResult = {
1859 supported: false,
1860 reason: "Data saver mode is enabled."
1861 };
1862 return cachedResult;
1863 }
1864 if (connection.effectiveType === "slow-2g" || connection.effectiveType === "2g") {
1865 cachedResult = {
1866 supported: false,
1867 reason: "Network connection is too slow for client-side media processing."
1868 };
1869 return cachedResult;
1870 }
1871 }
1872 }
1873 if (typeof window !== "undefined") {
1874 try {
1875 const testBlob = new Blob([""], {
1876 type: "application/javascript"
1877 });
1878 const testUrl = URL.createObjectURL(testBlob);
1879 try {
1880 const testWorker = new Worker(testUrl);
1881 testWorker.terminate();
1882 } finally {
1883 URL.revokeObjectURL(testUrl);
1884 }
1885 } catch {
1886 cachedResult = {
1887 supported: false,
1888 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."
1889 };
1890 return cachedResult;
1891 }
1892 }
1893 cachedResult = { supported: true };
1894 return cachedResult;
1895 }
1896 function isClientSideMediaSupported() {
1897 return detectClientSideMediaSupport().supported;
1898 }
1899 function isHeicCanvasSupported() {
1900 return typeof createImageBitmap !== "undefined" && typeof OffscreenCanvas !== "undefined";
1901 }
1902 function clearFeatureDetectionCache() {
1903 cachedResult = null;
1904 }
1905 var BYTES_PER_PIXEL = 4;
1906 var INTERLACED_MEMORY_BUDGET = 0.5 * 1024 * 1024 * 1024;
1907 var BASELINE_MEMORY_BUDGET = 0.9 * 1024 * 1024 * 1024;
1908 function exceedsClientProcessingMemory(dimensions) {
1909 const { width, height, interlaced } = dimensions;
1910 const estimatedBytes = width * height * BYTES_PER_PIXEL;
1911 const budget = interlaced ? INTERLACED_MEMORY_BUDGET : BASELINE_MEMORY_BUDGET;
1912 return estimatedBytes > budget;
1913 }
1914
1915 // packages/upload-media/build-module/get-image-dimensions.mjs
1916 var MAX_HEADER_BYTES = 512 * 1024;
1917 function parseJpeg(view) {
1918 let offset = 2;
1919 while (offset < view.byteLength) {
1920 if (view.getUint8(offset) !== 255) {
1921 return null;
1922 }
1923 while (offset < view.byteLength && view.getUint8(offset) === 255) {
1924 offset++;
1925 }
1926 if (offset >= view.byteLength) {
1927 return null;
1928 }
1929 const marker = view.getUint8(offset);
1930 offset++;
1931 if (marker === 1 || marker >= 208 && marker <= 217) {
1932 continue;
1933 }
1934 if (marker === 218) {
1935 return null;
1936 }
1937 if (offset + 2 > view.byteLength) {
1938 return null;
1939 }
1940 const segmentLength = view.getUint16(offset);
1941 if (segmentLength < 2) {
1942 return null;
1943 }
1944 const isStartOfFrame = marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204;
1945 if (isStartOfFrame) {
1946 if (offset + 7 > view.byteLength) {
1947 return null;
1948 }
1949 const height = view.getUint16(offset + 3);
1950 const width = view.getUint16(offset + 5);
1951 const interlaced = marker === 194 || marker === 198 || marker === 202 || marker === 206;
1952 return { width, height, interlaced };
1953 }
1954 offset += segmentLength;
1955 }
1956 return null;
1957 }
1958 function parsePng(view) {
1959 if (view.byteLength < 29) {
1960 return null;
1961 }
1962 const isIhdr = view.getUint8(12) === 73 && // I
1963 view.getUint8(13) === 72 && // H
1964 view.getUint8(14) === 68 && // D
1965 view.getUint8(15) === 82;
1966 if (!isIhdr) {
1967 return null;
1968 }
1969 const width = view.getUint32(16);
1970 const height = view.getUint32(20);
1971 const interlaceMethod = view.getUint8(28);
1972 return { width, height, interlaced: interlaceMethod !== 0 };
1973 }
1974 async function getImageDimensions(file) {
1975 try {
1976 const headerBytes = Math.min(file.size, MAX_HEADER_BYTES);
1977 const buffer = await file.slice(0, headerBytes).arrayBuffer();
1978 const view = new DataView(buffer);
1979 if (view.byteLength >= 3 && view.getUint16(0) === 65496) {
1980 return parseJpeg(view);
1981 }
1982 if (view.byteLength >= 8 && view.getUint32(0) === 2303741511 && view.getUint32(4) === 218765834) {
1983 return parsePng(view);
1984 }
1985 return null;
1986 } catch {
1987 return null;
1988 }
1989 }
1990
1991 // packages/upload-media/build-module/stub-file.mjs
1992 var StubFile = class extends File {
1993 constructor(fileName = "stub-file") {
1994 super([], fileName);
1995 }
1996 };
1997
1998 // packages/upload-media/build-module/store/private-actions.mjs
1999 var DEFAULT_OUTPUT_QUALITY = 0.82;
2000 var ultraHdrItems = /* @__PURE__ */ new Set();
2001 function addItem({
2002 file: fileOrBlob,
2003 batchId,
2004 onChange,
2005 onSuccess,
2006 onBatchSuccess,
2007 onError,
2008 additionalData = {},
2009 sourceUrl,
2010 sourceAttachmentId,
2011 abortController,
2012 operations
2013 }) {
2014 return async ({ dispatch }) => {
2015 const itemId = v4_default();
2016 const file = convertBlobToFile(fileOrBlob);
2017 let blobUrl;
2018 if (!(file instanceof StubFile)) {
2019 blobUrl = (0, import_blob.createBlobURL)(file);
2020 dispatch({
2021 type: Type.CacheBlobUrl,
2022 id: itemId,
2023 blobUrl
2024 });
2025 }
2026 dispatch({
2027 type: Type.Add,
2028 item: {
2029 id: itemId,
2030 batchId,
2031 status: ItemStatus.Processing,
2032 sourceFile: cloneFile(file),
2033 file,
2034 attachment: {
2035 url: blobUrl
2036 },
2037 additionalData: {
2038 generate_sub_sizes: false,
2039 ...additionalData
2040 },
2041 onChange,
2042 onSuccess,
2043 onBatchSuccess,
2044 onError,
2045 sourceUrl,
2046 sourceAttachmentId,
2047 abortController: abortController || new AbortController(),
2048 operations: Array.isArray(operations) ? operations : [OperationType.Prepare]
2049 }
2050 });
2051 dispatch.processItem(itemId);
2052 };
2053 }
2054 function addSideloadItem({
2055 file,
2056 onChange,
2057 additionalData,
2058 operations,
2059 batchId,
2060 parentId
2061 }) {
2062 return ({ dispatch }) => {
2063 const itemId = v4_default();
2064 dispatch({
2065 type: Type.Add,
2066 item: {
2067 id: itemId,
2068 batchId,
2069 status: ItemStatus.Processing,
2070 sourceFile: cloneFile(file),
2071 file,
2072 onChange,
2073 additionalData: {
2074 ...additionalData
2075 },
2076 parentId,
2077 operations: Array.isArray(operations) ? operations : [OperationType.Prepare],
2078 abortController: new AbortController()
2079 }
2080 });
2081 dispatch.processItem(itemId);
2082 };
2083 }
2084 function processItem(id) {
2085 return async ({ select: select2, dispatch }) => {
2086 if (select2.isPaused()) {
2087 return;
2088 }
2089 const item = select2.getItem(id);
2090 if (!item) {
2091 return;
2092 }
2093 const {
2094 attachment,
2095 onChange,
2096 onSuccess,
2097 onBatchSuccess,
2098 batchId,
2099 parentId
2100 } = item;
2101 const operation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
2102 const operationArgs = Array.isArray(item.operations?.[0]) ? item.operations[0][1] : void 0;
2103 if (operation === OperationType.Upload) {
2104 const settings = select2.getSettings();
2105 const activeCount = select2.getActiveUploadCount();
2106 if (activeCount >= settings.maxConcurrentUploads) {
2107 return;
2108 }
2109 }
2110 if (operation === OperationType.ResizeCrop || operation === OperationType.Rotate) {
2111 const settings = select2.getSettings();
2112 const activeCount = select2.getActiveImageProcessingCount();
2113 if (activeCount >= settings.maxConcurrentImageProcessing) {
2114 return;
2115 }
2116 }
2117 if (attachment) {
2118 const isHeicUrl = attachment.url && /\.hei[cf]$/i.test(attachment.url);
2119 if (!isHeicUrl) {
2120 onChange?.([attachment]);
2121 }
2122 }
2123 if (!operation) {
2124 if (parentId || !parentId && !select2.hasPendingItemsByParentId(id)) {
2125 if (attachment) {
2126 onSuccess?.([attachment]);
2127 }
2128 dispatch.removeItem(id);
2129 dispatch.revokeBlobUrls(id);
2130 if (batchId && select2.isBatchUploaded(batchId)) {
2131 onBatchSuccess?.();
2132 }
2133 }
2134 if (parentId && batchId && select2.isBatchUploaded(batchId)) {
2135 const parentItem = select2.getItem(parentId);
2136 if (!parentItem) {
2137 return;
2138 }
2139 if (parentItem.operations && parentItem.operations.length > 0) {
2140 dispatch.processItem(parentId);
2141 return;
2142 }
2143 if (attachment) {
2144 parentItem.onSuccess?.([attachment]);
2145 }
2146 dispatch.removeItem(parentId);
2147 dispatch.revokeBlobUrls(parentId);
2148 if (parentItem.batchId && select2.isBatchUploaded(parentItem.batchId)) {
2149 parentItem.onBatchSuccess?.();
2150 }
2151 }
2152 return;
2153 }
2154 if (operation === OperationType.Finalize && select2.hasPendingItemsByParentId(id)) {
2155 return;
2156 }
2157 dispatch({
2158 type: Type.OperationStart,
2159 id,
2160 operation
2161 });
2162 switch (operation) {
2163 case OperationType.Prepare:
2164 dispatch.prepareItem(item.id);
2165 break;
2166 case OperationType.ResizeCrop:
2167 dispatch.resizeCropItem(
2168 item.id,
2169 operationArgs
2170 );
2171 break;
2172 case OperationType.Rotate:
2173 dispatch.rotateItem(
2174 item.id,
2175 operationArgs
2176 );
2177 break;
2178 case OperationType.TranscodeImage:
2179 dispatch.transcodeImageItem(
2180 item.id,
2181 operationArgs
2182 );
2183 break;
2184 case OperationType.Upload:
2185 if (item.parentId) {
2186 dispatch.sideloadItem(id);
2187 } else {
2188 dispatch.uploadItem(id);
2189 }
2190 break;
2191 case OperationType.ThumbnailGeneration:
2192 dispatch.generateThumbnails(id);
2193 break;
2194 case OperationType.Finalize:
2195 dispatch.finalizeItem(id);
2196 break;
2197 case OperationType.DetectUltraHdr:
2198 dispatch.detectUltraHdr(id);
2199 break;
2200 }
2201 };
2202 }
2203 function pauseQueue() {
2204 return {
2205 type: Type.PauseQueue
2206 };
2207 }
2208 function resumeQueue() {
2209 return async ({ select: select2, dispatch }) => {
2210 dispatch({
2211 type: Type.ResumeQueue
2212 });
2213 for (const item of select2.getAllItems()) {
2214 if (item.status === ItemStatus.PendingRetry) {
2215 dispatch.executeRetry(item.id);
2216 } else {
2217 dispatch.processItem(item.id);
2218 }
2219 }
2220 };
2221 }
2222 function pauseItem(id) {
2223 return async ({ dispatch }) => {
2224 dispatch({
2225 type: Type.PauseItem,
2226 id
2227 });
2228 };
2229 }
2230 function removeItem(id) {
2231 return async ({ select: select2, dispatch }) => {
2232 const item = select2.getItem(id);
2233 if (!item) {
2234 return;
2235 }
2236 ultraHdrItems.delete(id);
2237 clearRetryTimer(id);
2238 dispatch({
2239 type: Type.Remove,
2240 id
2241 });
2242 if (select2.getAllItems().length === 0) {
2243 terminateVipsWorker();
2244 }
2245 };
2246 }
2247 function finishOperation(id, updates) {
2248 return async ({ select: select2, dispatch }) => {
2249 const item = select2.getItem(id);
2250 const previousOperation = item?.currentOperation;
2251 dispatch({
2252 type: Type.OperationFinish,
2253 id,
2254 item: updates
2255 });
2256 dispatch.processItem(id);
2257 if (previousOperation === OperationType.Upload) {
2258 const pendingUploads = select2.getPendingUploads();
2259 for (const pendingItem of pendingUploads) {
2260 dispatch.processItem(pendingItem.id);
2261 }
2262 }
2263 if (previousOperation === OperationType.ResizeCrop || previousOperation === OperationType.Rotate) {
2264 const pendingItems = select2.getPendingImageProcessing();
2265 for (const pendingItem of pendingItems) {
2266 dispatch.processItem(pendingItem.id);
2267 }
2268 }
2269 if (previousOperation === OperationType.ResizeCrop || previousOperation === OperationType.Rotate || previousOperation === OperationType.TranscodeImage) {
2270 maybeRecycleVipsWorker(select2.getActiveImageProcessingCount());
2271 }
2272 };
2273 }
2274 var VALID_IMAGE_FORMATS = ["jpeg", "webp", "avif", "png", "gif"];
2275 function isValidImageFormat(format) {
2276 return VALID_IMAGE_FORMATS.includes(format);
2277 }
2278 async function getTranscodeImageOperation(file, outputMimeType, interlaced = false) {
2279 if (file.type === "image/png" && outputMimeType === "image/jpeg") {
2280 const blobUrl = (0, import_blob.createBlobURL)(file);
2281 try {
2282 const hasAlpha = await vipsHasTransparency(blobUrl);
2283 if (hasAlpha) {
2284 return null;
2285 }
2286 } catch {
2287 return null;
2288 } finally {
2289 (0, import_blob.revokeBlobURL)(blobUrl);
2290 }
2291 }
2292 const formatPart = outputMimeType.split("/")[1];
2293 if (!isValidImageFormat(formatPart)) {
2294 return null;
2295 }
2296 return [
2297 OperationType.TranscodeImage,
2298 {
2299 outputFormat: formatPart,
2300 outputQuality: DEFAULT_OUTPUT_QUALITY,
2301 interlaced
2302 }
2303 ];
2304 }
2305 function prepareItem(id) {
2306 return async ({ select: select2, dispatch }) => {
2307 const item = select2.getItem(id);
2308 if (!item) {
2309 return;
2310 }
2311 const { file } = item;
2312 const operations = [];
2313 const settings = select2.getSettings();
2314 let heicJpeg = null;
2315 const isImage = file.type.startsWith("image/");
2316 const isVipsSupported = CLIENT_SIDE_SUPPORTED_MIME_TYPES.includes(
2317 file.type
2318 );
2319 const isHeic = HEIC_MIME_TYPES.includes(file.type);
2320 let tooLargeForClient = false;
2321 if (isImage && isVipsSupported) {
2322 const dimensions = await getImageDimensions(file);
2323 if (dimensions && exceedsClientProcessingMemory(dimensions)) {
2324 tooLargeForClient = true;
2325 }
2326 }
2327 if (file.type === "image/jpeg" && !tooLargeForClient) {
2328 operations.push(OperationType.DetectUltraHdr);
2329 }
2330 if (isImage && isVipsSupported && !tooLargeForClient) {
2331 operations.push(
2332 OperationType.Upload,
2333 OperationType.ThumbnailGeneration,
2334 OperationType.Finalize
2335 );
2336 } else if (isImage && isHeic) {
2337 try {
2338 heicJpeg = await canvasConvertToJpeg(
2339 file,
2340 settings.imageQuality ?? DEFAULT_OUTPUT_QUALITY
2341 );
2342 } catch {
2343 dispatch.cancelItem(
2344 id,
2345 new UploadError({
2346 code: ErrorCode.HEIC_DECODE_ERROR,
2347 message: "This browser cannot decode HEIC images and the server does not support them either. Please convert to JPEG before uploading.",
2348 file
2349 })
2350 );
2351 return;
2352 }
2353 operations.push(
2354 OperationType.Upload,
2355 OperationType.ThumbnailGeneration,
2356 OperationType.Finalize
2357 );
2358 } else {
2359 operations.push(OperationType.Upload);
2360 }
2361 dispatch({
2362 type: Type.AddOperations,
2363 id,
2364 operations
2365 });
2366 let updates;
2367 if (isHeic && heicJpeg) {
2368 const vipsAvailable = isClientSideMediaSupported();
2369 updates = {
2370 file: heicJpeg,
2371 sourceFile: heicJpeg,
2372 originalHeicFile: item.file,
2373 additionalData: {
2374 ...item.additionalData,
2375 generate_sub_sizes: !vipsAvailable,
2376 convert_format: true
2377 }
2378 };
2379 } else if (!isVipsSupported || !isImage || tooLargeForClient) {
2380 updates = {
2381 additionalData: {
2382 ...item.additionalData,
2383 generate_sub_sizes: true,
2384 convert_format: true
2385 }
2386 };
2387 } else {
2388 updates = {
2389 additionalData: {
2390 ...item.additionalData,
2391 generate_sub_sizes: false
2392 }
2393 };
2394 }
2395 dispatch.finishOperation(id, updates);
2396 };
2397 }
2398 function detectUltraHdr(id) {
2399 return async ({ select: select2, dispatch }) => {
2400 const item = select2.getItem(id);
2401 if (!item) {
2402 return;
2403 }
2404 let info;
2405 try {
2406 const buffer = await item.file.arrayBuffer();
2407 info = await vipsGetUltraHdrInfo(buffer);
2408 } catch {
2409 }
2410 if (info) {
2411 ultraHdrItems.add(id);
2412 }
2413 dispatch.finishOperation(id, {});
2414 };
2415 }
2416 function uploadItem(id) {
2417 return async ({ select: select2, dispatch }) => {
2418 const item = select2.getItem(id);
2419 if (!item) {
2420 return;
2421 }
2422 const startTime = performance.now();
2423 let finished = false;
2424 const finishUpload = (attachment) => {
2425 if (finished) {
2426 return;
2427 }
2428 finished = true;
2429 measure({
2430 measureName: `Upload ${item.file.name}`,
2431 startTime,
2432 tooltipText: item.file.name,
2433 properties: [
2434 ["Item ID", item.id],
2435 ["File name", item.file.name]
2436 ]
2437 });
2438 dispatch.finishOperation(id, { attachment });
2439 };
2440 select2.getSettings().mediaUpload({
2441 filesList: [item.file],
2442 additionalData: item.additionalData,
2443 signal: item.abortController?.signal,
2444 onFileChange: ([attachment]) => {
2445 if (attachment && !(0, import_blob.isBlobURL)(attachment.url)) {
2446 finishUpload(attachment);
2447 }
2448 },
2449 onSuccess: ([attachment]) => {
2450 finishUpload(attachment);
2451 },
2452 onError: (error) => {
2453 dispatch.cancelItem(id, error);
2454 }
2455 });
2456 };
2457 }
2458 function sideloadItem(id) {
2459 return async ({ select: select2, dispatch }) => {
2460 const item = select2.getItem(id);
2461 if (!item) {
2462 return;
2463 }
2464 const { post, ...additionalData } = item.additionalData;
2465 const mediaSideload = select2.getSettings().mediaSideload;
2466 if (!mediaSideload) {
2467 dispatch.finishOperation(id, {});
2468 return;
2469 }
2470 const startTime = performance.now();
2471 mediaSideload({
2472 file: item.file,
2473 attachmentId: post,
2474 additionalData,
2475 signal: item.abortController?.signal,
2476 onSuccess: (subSize) => {
2477 measure({
2478 measureName: `Sideload ${item.file.name}`,
2479 startTime,
2480 tooltipText: item.file.name,
2481 properties: [
2482 ["Item ID", item.id],
2483 ["File name", item.file.name]
2484 ]
2485 });
2486 if (item.parentId) {
2487 dispatch({
2488 type: Type.AccumulateSubSize,
2489 id: item.parentId,
2490 subSize
2491 });
2492 }
2493 dispatch.finishOperation(id, {});
2494 },
2495 onError: (error) => {
2496 dispatch.cancelItem(id, error);
2497 }
2498 });
2499 };
2500 }
2501 function resizeCropItem(id, args) {
2502 return async ({ select: select2, dispatch }) => {
2503 const item = select2.getItem(id);
2504 if (!item) {
2505 return;
2506 }
2507 if (!args?.resize) {
2508 dispatch.finishOperation(id, {
2509 file: item.file
2510 });
2511 return;
2512 }
2513 const startTime = performance.now();
2514 const addSuffix = Boolean(item.parentId);
2515 const scaledSuffix = Boolean(args.isThresholdResize);
2516 try {
2517 const file = await vipsResizeImage(
2518 item.id,
2519 item.file,
2520 args.resize,
2521 false,
2522 // smartCrop
2523 addSuffix,
2524 item.abortController?.signal,
2525 scaledSuffix
2526 );
2527 measure({
2528 measureName: `ResizeCrop ${item.file.name}`,
2529 startTime,
2530 tooltipText: item.file.name,
2531 properties: [
2532 ["Item ID", item.id],
2533 ["File name", item.file.name]
2534 ]
2535 });
2536 const blobUrl = (0, import_blob.createBlobURL)(file);
2537 dispatch({
2538 type: Type.CacheBlobUrl,
2539 id,
2540 blobUrl
2541 });
2542 dispatch.finishOperation(id, {
2543 file,
2544 attachment: {
2545 url: blobUrl
2546 }
2547 });
2548 } catch (error) {
2549 dispatch.cancelItem(
2550 id,
2551 new UploadError({
2552 code: ErrorCode.IMAGE_TRANSCODING_ERROR,
2553 message: (0, import_i18n6.__)(
2554 "The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading."
2555 ),
2556 file: item.file,
2557 cause: error instanceof Error ? error : void 0
2558 })
2559 );
2560 }
2561 };
2562 }
2563 function rotateItem(id, args) {
2564 return async ({ select: select2, dispatch }) => {
2565 const item = select2.getItem(id);
2566 if (!item) {
2567 return;
2568 }
2569 if (!args?.orientation || args.orientation === 1) {
2570 dispatch.finishOperation(id, {
2571 file: item.file
2572 });
2573 return;
2574 }
2575 const startTime = performance.now();
2576 try {
2577 const file = await vipsRotateImage(
2578 item.id,
2579 item.file,
2580 args.orientation,
2581 item.abortController?.signal
2582 );
2583 measure({
2584 measureName: `Rotate ${item.file.name}`,
2585 startTime,
2586 tooltipText: item.file.name,
2587 properties: [
2588 ["Item ID", item.id],
2589 ["File name", item.file.name]
2590 ]
2591 });
2592 const blobUrl = (0, import_blob.createBlobURL)(file);
2593 dispatch({
2594 type: Type.CacheBlobUrl,
2595 id,
2596 blobUrl
2597 });
2598 dispatch.finishOperation(id, {
2599 file,
2600 attachment: {
2601 url: blobUrl
2602 }
2603 });
2604 } catch (error) {
2605 dispatch.cancelItem(
2606 id,
2607 new UploadError({
2608 code: ErrorCode.IMAGE_ROTATION_ERROR,
2609 message: (0, import_i18n6.__)(
2610 "The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading."
2611 ),
2612 file: item.file,
2613 cause: error instanceof Error ? error : void 0
2614 })
2615 );
2616 }
2617 };
2618 }
2619 function transcodeImageItem(id, args) {
2620 return async ({ select: select2, dispatch }) => {
2621 const item = select2.getItem(id);
2622 if (!item) {
2623 return;
2624 }
2625 if (!args?.outputFormat) {
2626 dispatch.finishOperation(id, {
2627 file: item.file
2628 });
2629 return;
2630 }
2631 const startTime = performance.now();
2632 const outputMimeType = `image/${args.outputFormat}`;
2633 const quality = args.outputQuality ?? DEFAULT_OUTPUT_QUALITY;
2634 const interlaced = args.interlaced ?? false;
2635 try {
2636 const file = await vipsConvertImageFormat(
2637 item.id,
2638 item.file,
2639 outputMimeType,
2640 quality,
2641 interlaced
2642 );
2643 measure({
2644 measureName: `Transcode ${item.file.name}`,
2645 startTime,
2646 tooltipText: item.file.name,
2647 properties: [
2648 ["Item ID", item.id],
2649 ["File name", item.file.name]
2650 ]
2651 });
2652 const blobUrl = (0, import_blob.createBlobURL)(file);
2653 dispatch({
2654 type: Type.CacheBlobUrl,
2655 id,
2656 blobUrl
2657 });
2658 dispatch.finishOperation(id, {
2659 file,
2660 attachment: {
2661 url: blobUrl
2662 }
2663 });
2664 } catch (error) {
2665 dispatch.cancelItem(
2666 id,
2667 new UploadError({
2668 code: ErrorCode.MEDIA_TRANSCODING_ERROR,
2669 message: "Image could not be transcoded to the target format",
2670 file: item.file,
2671 cause: error instanceof Error ? error : void 0
2672 })
2673 );
2674 }
2675 };
2676 }
2677 function generateThumbnails(id) {
2678 return async ({ select: select2, dispatch }) => {
2679 const item = select2.getItem(id);
2680 if (!item) {
2681 return;
2682 }
2683 if (!item.attachment) {
2684 dispatch.finishOperation(id, {});
2685 return;
2686 }
2687 const attachment = item.attachment;
2688 const settings = select2.getSettings();
2689 if (item.originalHeicFile && attachment.id) {
2690 dispatch.addSideloadItem({
2691 file: item.originalHeicFile,
2692 batchId: v4_default(),
2693 parentId: item.id,
2694 additionalData: {
2695 post: attachment.id,
2696 image_size: "original-heic",
2697 convert_format: false
2698 },
2699 operations: [OperationType.Upload]
2700 });
2701 }
2702 {
2703 const needsRotation = attachment.exif_orientation && attachment.exif_orientation !== 1 && !item.file.name.includes("-scaled");
2704 if (needsRotation && attachment.id) {
2705 try {
2706 const rotatedFile = await vipsRotateImage(
2707 item.id,
2708 item.sourceFile,
2709 attachment.exif_orientation,
2710 item.abortController?.signal
2711 );
2712 dispatch.addSideloadItem({
2713 file: rotatedFile,
2714 batchId: v4_default(),
2715 parentId: item.id,
2716 additionalData: {
2717 post: attachment.id,
2718 image_size: "original",
2719 convert_format: false
2720 },
2721 operations: [OperationType.Upload]
2722 });
2723 } catch {
2724 console.warn(
2725 "Failed to rotate image, continuing with thumbnails"
2726 );
2727 }
2728 }
2729 }
2730 if (!item.parentId && attachment.missing_image_sizes && attachment.missing_image_sizes.length > 0) {
2731 const allImageSizes = settings.allImageSizes || {};
2732 const sizesToGenerate = attachment.missing_image_sizes;
2733 const thumbnailSource = item.sourceFile;
2734 const file = attachment.filename ? renameFile(thumbnailSource, attachment.filename) : thumbnailSource;
2735 const batchId = v4_default();
2736 const isUltraHdr = ultraHdrItems.has(item.id);
2737 const outputMimeType = attachment.image_output_format;
2738 const interlaced = attachment.image_save_progressive ?? false;
2739 let thumbnailTranscodeOperation = null;
2740 if (!isUltraHdr && outputMimeType) {
2741 thumbnailTranscodeOperation = await getTranscodeImageOperation(
2742 thumbnailSource,
2743 outputMimeType,
2744 interlaced
2745 );
2746 }
2747 const dimensionGroups = /* @__PURE__ */ new Map();
2748 for (const name of sizesToGenerate) {
2749 const imageSize = allImageSizes[name];
2750 if (!imageSize) {
2751 console.warn(
2752 `Image size "${name}" not found in configuration`
2753 );
2754 continue;
2755 }
2756 const key = `${imageSize.width}x${imageSize.height}x${imageSize.crop}`;
2757 const group = dimensionGroups.get(key);
2758 if (group) {
2759 group.push(name);
2760 } else {
2761 dimensionGroups.set(key, [name]);
2762 }
2763 }
2764 for (const [, names] of dimensionGroups) {
2765 const imageSize = allImageSizes[names[0]];
2766 const thumbnailOperations = [
2767 [OperationType.ResizeCrop, { resize: imageSize }]
2768 ];
2769 if (!isUltraHdr && thumbnailTranscodeOperation) {
2770 thumbnailOperations.push(thumbnailTranscodeOperation);
2771 }
2772 thumbnailOperations.push(OperationType.Upload);
2773 const imageSizeParam = names.length === 1 ? names[0] : names;
2774 dispatch.addSideloadItem({
2775 file,
2776 batchId,
2777 parentId: item.id,
2778 additionalData: {
2779 // Sideloading does not use the parent post ID but the
2780 // attachment ID as the image sizes need to be added to it.
2781 post: attachment.id,
2782 image_size: imageSizeParam,
2783 convert_format: false
2784 },
2785 operations: thumbnailOperations
2786 });
2787 }
2788 {
2789 const { bigImageSizeThreshold } = settings;
2790 if (bigImageSizeThreshold && attachment.id) {
2791 const bitmap = await createImageBitmap(thumbnailSource);
2792 const needsScaling = bitmap.width > bigImageSizeThreshold || bitmap.height > bigImageSizeThreshold;
2793 bitmap.close();
2794 if (needsScaling) {
2795 const sourceForScaled = attachment.filename ? renameFile(thumbnailSource, attachment.filename) : thumbnailSource;
2796 const scaledOperations = [
2797 [
2798 OperationType.ResizeCrop,
2799 {
2800 resize: {
2801 width: bigImageSizeThreshold,
2802 height: bigImageSizeThreshold
2803 },
2804 isThresholdResize: true
2805 }
2806 ]
2807 ];
2808 if (!isUltraHdr && thumbnailTranscodeOperation) {
2809 scaledOperations.push(
2810 thumbnailTranscodeOperation
2811 );
2812 }
2813 scaledOperations.push(OperationType.Upload);
2814 dispatch.addSideloadItem({
2815 file: sourceForScaled,
2816 batchId,
2817 parentId: item.id,
2818 additionalData: {
2819 post: attachment.id,
2820 image_size: "scaled",
2821 convert_format: false
2822 },
2823 operations: scaledOperations
2824 });
2825 }
2826 }
2827 }
2828 }
2829 dispatch.finishOperation(id, {});
2830 };
2831 }
2832 function finalizeItem(id) {
2833 return async ({ select: select2, dispatch }) => {
2834 const item = select2.getItem(id);
2835 if (!item) {
2836 return;
2837 }
2838 const attachment = item.attachment;
2839 const { mediaFinalize } = select2.getSettings();
2840 const updates = {};
2841 if (attachment?.id && mediaFinalize) {
2842 try {
2843 const updatedAttachment = await mediaFinalize(
2844 attachment.id,
2845 item.subSizes || []
2846 );
2847 if (updatedAttachment) {
2848 updates.attachment = updatedAttachment;
2849 }
2850 } catch (error) {
2851 console.warn("Media finalization failed:", error);
2852 }
2853 }
2854 dispatch.finishOperation(id, updates);
2855 };
2856 }
2857 function revokeBlobUrls(id) {
2858 return async ({ select: select2, dispatch }) => {
2859 const blobUrls = select2.getBlobUrls(id);
2860 for (const blobUrl of blobUrls) {
2861 (0, import_blob.revokeBlobURL)(blobUrl);
2862 }
2863 dispatch({
2864 type: Type.RevokeBlobUrls,
2865 id
2866 });
2867 };
2868 }
2869 function updateItemProgress(id, progress) {
2870 return async ({ dispatch }) => {
2871 dispatch({
2872 type: Type.UpdateProgress,
2873 id,
2874 progress
2875 });
2876 };
2877 }
2878 function updateSettings(settings) {
2879 return {
2880 type: Type.UpdateSettings,
2881 settings
2882 };
2883 }
2884
2885 // packages/upload-media/build-module/lock-unlock.mjs
2886 var import_private_apis = __toESM(require_private_apis(), 1);
2887 var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)(
2888 "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
2889 "@wordpress/upload-media"
2890 );
2891
2892 // packages/upload-media/build-module/store/index.mjs
2893 var storeConfig = {
2894 reducer: reducer_default,
2895 selectors: selectors_exports,
2896 actions: actions_exports
2897 };
2898 var store = (0, import_data.createReduxStore)(STORE_NAME, {
2899 reducer: reducer_default,
2900 selectors: selectors_exports,
2901 actions: actions_exports
2902 });
2903 if (!(0, import_data.select)(store)) {
2904 (0, import_data.register)(store);
2905 }
2906 unlock(store).registerPrivateActions(private_actions_exports);
2907 unlock(store).registerPrivateSelectors(private_selectors_exports);
2908
2909 // packages/upload-media/build-module/components/provider/index.mjs
2910 var import_element2 = __toESM(require_element(), 1);
2911 var import_data3 = __toESM(require_data(), 1);
2912
2913 // packages/upload-media/build-module/components/provider/with-registry-provider.mjs
2914 var import_element = __toESM(require_element(), 1);
2915 var import_data2 = __toESM(require_data(), 1);
2916 var import_compose = __toESM(require_compose(), 1);
2917 var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
2918 function getSubRegistry(subRegistries, registry, useSubRegistry) {
2919 if (!useSubRegistry) {
2920 return registry;
2921 }
2922 let subRegistry = subRegistries.get(registry);
2923 if (!subRegistry) {
2924 subRegistry = (0, import_data2.createRegistry)({}, registry);
2925 subRegistry.registerStore(STORE_NAME, storeConfig);
2926 subRegistries.set(registry, subRegistry);
2927 }
2928 return subRegistry;
2929 }
2930 var withRegistryProvider = (0, import_compose.createHigherOrderComponent)(
2931 (WrappedComponent) => ({ useSubRegistry = true, ...props }) => {
2932 const registry = (0, import_data2.useRegistry)();
2933 const [subRegistries] = (0, import_element.useState)(() => /* @__PURE__ */ new WeakMap());
2934 const subRegistry = getSubRegistry(
2935 subRegistries,
2936 registry,
2937 useSubRegistry
2938 );
2939 if (subRegistry === registry) {
2940 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WrappedComponent, { registry, ...props });
2941 }
2942 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_data2.RegistryProvider, { value: subRegistry, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WrappedComponent, { registry: subRegistry, ...props }) });
2943 },
2944 "withRegistryProvider"
2945 );
2946 var with_registry_provider_default = withRegistryProvider;
2947
2948 // packages/upload-media/build-module/components/provider/index.mjs
2949 var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
2950 var MediaUploadProvider = with_registry_provider_default((props) => {
2951 const { children, settings } = props;
2952 const { updateSettings: updateSettings2 } = unlock((0, import_data3.useDispatch)(store));
2953 (0, import_element2.useEffect)(() => {
2954 updateSettings2(settings);
2955 }, [settings, updateSettings2]);
2956 return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
2957 });
2958 var provider_default = MediaUploadProvider;
2959
2960 // packages/upload-media/build-module/error-messages.mjs
2961 var import_i18n7 = __toESM(require_i18n(), 1);
2962 function getErrorMessage(code, fileName) {
2963 const messages = {
2964 [ErrorCode.EMPTY_FILE]: {
2965 title: (0, import_i18n7.__)("Empty file"),
2966 description: (0, import_i18n7.sprintf)(
2967 /* translators: %s: file name */
2968 (0, import_i18n7.__)('"%s" is empty.'),
2969 fileName
2970 ),
2971 action: (0, import_i18n7.__)("Please choose a different file.")
2972 },
2973 [ErrorCode.SIZE_ABOVE_LIMIT]: {
2974 title: (0, import_i18n7.__)("File too large"),
2975 description: (0, import_i18n7.sprintf)(
2976 /* translators: %s: file name */
2977 (0, import_i18n7.__)('"%s" exceeds the maximum upload size.'),
2978 fileName
2979 ),
2980 action: (0, import_i18n7.__)("Please reduce the file size and try again.")
2981 },
2982 [ErrorCode.MIME_TYPE_NOT_SUPPORTED]: {
2983 title: (0, import_i18n7.__)("Unsupported file type"),
2984 description: (0, import_i18n7.sprintf)(
2985 /* translators: %s: file name */
2986 (0, import_i18n7.__)('"%s" is not a supported file type.'),
2987 fileName
2988 ),
2989 action: (0, import_i18n7.__)("Please upload a different file format.")
2990 },
2991 [ErrorCode.MIME_TYPE_NOT_ALLOWED_FOR_USER]: {
2992 title: (0, import_i18n7.__)("File type not allowed"),
2993 description: (0, import_i18n7.sprintf)(
2994 /* translators: %s: file name */
2995 (0, import_i18n7.__)('You are not allowed to upload "%s".'),
2996 fileName
2997 ),
2998 action: (0, import_i18n7.__)("Please contact your site administrator.")
2999 },
3000 [ErrorCode.HEIC_DECODE_ERROR]: {
3001 title: (0, import_i18n7.__)("HEIC decode failed"),
3002 description: (0, import_i18n7.sprintf)(
3003 /* translators: %s: file name */
3004 (0, import_i18n7.__)('Failed to decode HEIC file "%s".'),
3005 fileName
3006 ),
3007 action: (0, import_i18n7.__)("Try converting the image to JPEG or PNG first.")
3008 },
3009 [ErrorCode.IMAGE_TRANSCODING_ERROR]: {
3010 title: (0, import_i18n7.__)("Image processing failed"),
3011 description: (0, import_i18n7.sprintf)(
3012 /* translators: %s: file name */
3013 (0, import_i18n7.__)('Failed to process "%s".'),
3014 fileName
3015 ),
3016 action: (0, import_i18n7.__)("The image may be corrupted. Try a different file.")
3017 },
3018 [ErrorCode.IMAGE_ROTATION_ERROR]: {
3019 title: (0, import_i18n7.__)("Image rotation failed"),
3020 description: (0, import_i18n7.sprintf)(
3021 /* translators: %s: file name */
3022 (0, import_i18n7.__)('Failed to rotate "%s".'),
3023 fileName
3024 ),
3025 action: (0, import_i18n7.__)("The image may be corrupted. Try a different file.")
3026 },
3027 [ErrorCode.MEDIA_TRANSCODING_ERROR]: {
3028 title: (0, import_i18n7.__)("Media processing failed"),
3029 description: (0, import_i18n7.sprintf)(
3030 /* translators: %s: file name */
3031 (0, import_i18n7.__)('Failed to convert "%s" to the target format.'),
3032 fileName
3033 ),
3034 action: (0, import_i18n7.__)("The file may be corrupted. Try a different file.")
3035 },
3036 [ErrorCode.GENERAL]: {
3037 title: (0, import_i18n7.__)("Upload failed"),
3038 description: (0, import_i18n7.sprintf)(
3039 /* translators: %s: file name */
3040 (0, import_i18n7.__)('Failed to upload "%s".'),
3041 fileName
3042 ),
3043 action: (0, import_i18n7.__)("Please try again.")
3044 }
3045 };
3046 return messages[code] || {
3047 title: (0, import_i18n7.__)("Upload failed"),
3048 description: (0, import_i18n7.sprintf)(
3049 /* translators: %s: file name */
3050 (0, import_i18n7.__)('Failed to upload "%s".'),
3051 fileName
3052 ),
3053 action: (0, import_i18n7.__)("Please try again.")
3054 };
3055 }
3056 return __toCommonJS(index_exports);
3057 })();
3058 //# sourceMappingURL=index.js.map
3059