@tldraw/utils 3.16.0-next.fe14f1b4181f → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +0 -4
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/file.js +0 -8
- package/dist-cjs/lib/file.js.map +2 -2
- package/dist-cjs/lib/media/media.js +1 -1
- package/dist-cjs/lib/media/media.js.map +1 -1
- package/dist-cjs/lib/media/png.js +4 -4
- package/dist-cjs/lib/media/png.js.map +1 -1
- package/dist-cjs/lib/reordering.js +6 -3
- package/dist-cjs/lib/reordering.js.map +2 -2
- package/dist-esm/index.d.mts +0 -4
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/file.mjs +0 -8
- package/dist-esm/lib/file.mjs.map +2 -2
- package/dist-esm/lib/media/media.mjs +1 -1
- package/dist-esm/lib/media/media.mjs.map +1 -1
- package/dist-esm/lib/media/png.mjs +4 -4
- package/dist-esm/lib/media/png.mjs.map +1 -1
- package/dist-esm/lib/reordering.mjs +6 -7
- package/dist-esm/lib/reordering.mjs.map +2 -2
- package/package.json +2 -2
- package/src/lib/file.ts +0 -9
- package/src/lib/media/media.ts +1 -1
- package/src/lib/media/png.ts +4 -4
- package/src/lib/reordering.ts +7 -7
package/dist-cjs/index.d.ts
CHANGED
|
@@ -103,10 +103,6 @@ export declare type Expand<T> = T extends infer O ? {
|
|
|
103
103
|
* @public
|
|
104
104
|
*/
|
|
105
105
|
export declare class FileHelpers {
|
|
106
|
-
/**
|
|
107
|
-
* @deprecated Use `urlToArrayBuffer` instead.
|
|
108
|
-
*/
|
|
109
|
-
static dataUrlToArrayBuffer(dataURL: string): Promise<ArrayBuffer>;
|
|
110
106
|
/**
|
|
111
107
|
* @param url - The url of the file.
|
|
112
108
|
*/
|
package/dist-cjs/index.js
CHANGED
|
@@ -167,7 +167,7 @@ var import_version2 = require("./lib/version");
|
|
|
167
167
|
var import_warn = require("./lib/warn");
|
|
168
168
|
(0, import_version.registerTldrawLibraryVersion)(
|
|
169
169
|
"@tldraw/utils",
|
|
170
|
-
"
|
|
170
|
+
"4.0.0",
|
|
171
171
|
"cjs"
|
|
172
172
|
);
|
|
173
173
|
//# sourceMappingURL=index.js.map
|
package/dist-cjs/lib/file.js
CHANGED
|
@@ -23,14 +23,6 @@ __export(file_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(file_exports);
|
|
24
24
|
var import_network = require("./network");
|
|
25
25
|
class FileHelpers {
|
|
26
|
-
/**
|
|
27
|
-
* @deprecated Use `urlToArrayBuffer` instead.
|
|
28
|
-
*/
|
|
29
|
-
static async dataUrlToArrayBuffer(dataURL) {
|
|
30
|
-
return (0, import_network.fetch)(dataURL).then(function(result) {
|
|
31
|
-
return result.arrayBuffer();
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
26
|
/**
|
|
35
27
|
* @param url - The url of the file.
|
|
36
28
|
*/
|
package/dist-cjs/lib/file.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/file.ts"],
|
|
4
|
-
"sourcesContent": ["import { fetch } from './network'\n\n/**\n * Helpers for files\n *\n * @public\n */\nexport class FileHelpers {\n\t/**\n\t * @
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAsB;AAOf,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA,EAIxB,aAAa,
|
|
4
|
+
"sourcesContent": ["import { fetch } from './network'\n\n/**\n * Helpers for files\n *\n * @public\n */\nexport class FileHelpers {\n\t/**\n\t * @param url - The url of the file.\n\t */\n\tstatic async urlToArrayBuffer(url: string) {\n\t\tconst response = await fetch(url)\n\t\treturn await response.arrayBuffer()\n\t}\n\n\tstatic async urlToBlob(url: string) {\n\t\tconst response = await fetch(url)\n\t\treturn await response.blob()\n\t}\n\n\tstatic async urlToDataUrl(url: string) {\n\t\tif (url.startsWith('data:')) return url\n\t\tconst blob = await FileHelpers.urlToBlob(url)\n\t\treturn await FileHelpers.blobToDataUrl(blob)\n\t}\n\n\t/**\n\t * Convert a file to a base64 encoded data url.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const A = FileHelpers.toDataUrl(myImageFile)\n\t * ```\n\t *\n\t * @param file - The file as a blob.\n\t */\n\tstatic async blobToDataUrl(file: Blob): Promise<string> {\n\t\treturn await new Promise((resolve, reject) => {\n\t\t\tif (file) {\n\t\t\t\tconst reader = new FileReader()\n\t\t\t\treader.onload = () => resolve(reader.result as string)\n\t\t\t\treader.onerror = (error) => reject(error)\n\t\t\t\treader.onabort = (error) => reject(error)\n\t\t\t\treader.readAsDataURL(file)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Convert a file to a unicode text string.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const A = FileHelpers.fileToDataUrl(myTextFile)\n\t * ```\n\t *\n\t * @param file - The file as a blob.\n\t */\n\tstatic async blobToText(file: Blob): Promise<string> {\n\t\treturn await new Promise((resolve, reject) => {\n\t\t\tif (file) {\n\t\t\t\tconst reader = new FileReader()\n\t\t\t\treader.onload = () => resolve(reader.result as string)\n\t\t\t\treader.onerror = (error) => reject(error)\n\t\t\t\treader.onabort = (error) => reject(error)\n\t\t\t\treader.readAsText(file)\n\t\t\t}\n\t\t})\n\t}\n\n\tstatic rewriteMimeType(blob: Blob, newMimeType: string): Blob\n\tstatic rewriteMimeType(blob: File, newMimeType: string): File\n\tstatic rewriteMimeType(blob: Blob | File, newMimeType: string): Blob | File {\n\t\tif (blob.type === newMimeType) return blob\n\t\tif (blob instanceof File) {\n\t\t\treturn new File([blob], blob.name, { type: newMimeType })\n\t\t}\n\t\treturn new Blob([blob], { type: newMimeType })\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAsB;AAOf,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA,EAIxB,aAAa,iBAAiB,KAAa;AAC1C,UAAM,WAAW,UAAM,sBAAM,GAAG;AAChC,WAAO,MAAM,SAAS,YAAY;AAAA,EACnC;AAAA,EAEA,aAAa,UAAU,KAAa;AACnC,UAAM,WAAW,UAAM,sBAAM,GAAG;AAChC,WAAO,MAAM,SAAS,KAAK;AAAA,EAC5B;AAAA,EAEA,aAAa,aAAa,KAAa;AACtC,QAAI,IAAI,WAAW,OAAO,EAAG,QAAO;AACpC,UAAM,OAAO,MAAM,YAAY,UAAU,GAAG;AAC5C,WAAO,MAAM,YAAY,cAAc,IAAI;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,aAAa,cAAc,MAA6B;AACvD,WAAO,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC7C,UAAI,MAAM;AACT,cAAM,SAAS,IAAI,WAAW;AAC9B,eAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,cAAc,IAAI;AAAA,MAC1B;AAAA,IACD,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,aAAa,WAAW,MAA6B;AACpD,WAAO,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC7C,UAAI,MAAM;AACT,cAAM,SAAS,IAAI,WAAW;AAC9B,eAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,WAAW,IAAI;AAAA,MACvB;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAIA,OAAO,gBAAgB,MAAmB,aAAkC;AAC3E,QAAI,KAAK,SAAS,YAAa,QAAO;AACtC,QAAI,gBAAgB,MAAM;AACzB,aAAO,IAAI,KAAK,CAAC,IAAI,GAAG,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAAA,IACzD;AACA,WAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,YAAY,CAAC;AAAA,EAC9C;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -188,7 +188,7 @@ class MediaHelpers {
|
|
|
188
188
|
const physChunk = import_png.PngHelpers.findChunk(view, "pHYs");
|
|
189
189
|
if (physChunk) {
|
|
190
190
|
const physData = import_png.PngHelpers.parsePhys(view, physChunk.dataOffset);
|
|
191
|
-
if (physData.unit ===
|
|
191
|
+
if (physData.unit === 1 && physData.ppux === physData.ppuy) {
|
|
192
192
|
const pixelsPerMeter = 72 / 0.0254;
|
|
193
193
|
const pixelRatio = Math.max(physData.ppux / pixelsPerMeter, 1);
|
|
194
194
|
return {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/media/media.ts"],
|
|
4
|
-
"sourcesContent": ["import { promiseWithResolve } from '../control'\nimport { Image } from '../network'\nimport { isApngAnimated } from './apng'\nimport { isAvifAnimated } from './avif'\nimport { isGifAnimated } from './gif'\nimport { PngHelpers } from './png'\nimport { isWebpAnimated } from './webp'\n\n/** @public */\nexport const DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES = Object.freeze(['image/svg+xml' as const])\n/** @public */\nexport const DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES = Object.freeze([\n\t'image/jpeg' as const,\n\t'image/png' as const,\n\t'image/webp' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES = Object.freeze([\n\t'image/gif' as const,\n\t'image/apng' as const,\n\t'image/avif' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_IMAGE_TYPES = Object.freeze([\n\t...DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES,\n\t...DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES,\n\t...DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES,\n])\n/** @public */\nexport const DEFAULT_SUPPORT_VIDEO_TYPES = Object.freeze([\n\t'video/mp4' as const,\n\t'video/webm' as const,\n\t'video/quicktime' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_MEDIA_TYPES = Object.freeze([\n\t...DEFAULT_SUPPORTED_IMAGE_TYPES,\n\t...DEFAULT_SUPPORT_VIDEO_TYPES,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_MEDIA_TYPE_LIST = DEFAULT_SUPPORTED_MEDIA_TYPES.join(',')\n\n/**\n * Helpers for media\n *\n * @public\n */\nexport class MediaHelpers {\n\t/**\n\t * Load a video from a url.\n\t * @public\n\t */\n\tstatic loadVideo(src: string): Promise<HTMLVideoElement> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst video = document.createElement('video')\n\t\t\tvideo.onloadeddata = () => resolve(video)\n\t\t\tvideo.onerror = (e) => {\n\t\t\t\tconsole.error(e)\n\t\t\t\treject(new Error('Could not load video'))\n\t\t\t}\n\t\t\tvideo.crossOrigin = 'anonymous'\n\t\t\tvideo.src = src\n\t\t})\n\t}\n\n\tstatic async getVideoFrameAsDataUrl(video: HTMLVideoElement, time = 0): Promise<string> {\n\t\tconst promise = promiseWithResolve<string>()\n\t\tlet didSetTime = false\n\n\t\tconst onReadyStateChanged = () => {\n\t\t\tif (!didSetTime) {\n\t\t\t\tif (video.readyState >= video.HAVE_METADATA) {\n\t\t\t\t\tdidSetTime = true\n\t\t\t\t\tvideo.currentTime = time\n\t\t\t\t} else {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (video.readyState >= video.HAVE_CURRENT_DATA) {\n\t\t\t\tconst canvas = document.createElement('canvas')\n\t\t\t\tcanvas.width = video.videoWidth\n\t\t\t\tcanvas.height = video.videoHeight\n\t\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\t\tif (!ctx) {\n\t\t\t\t\tthrow new Error('Could not get 2d context')\n\t\t\t\t}\n\t\t\t\tctx.drawImage(video, 0, 0)\n\t\t\t\tpromise.resolve(canvas.toDataURL())\n\t\t\t}\n\t\t}\n\t\tconst onError = (e: Event) => {\n\t\t\tconsole.error(e)\n\t\t\tpromise.reject(new Error('Could not get video frame'))\n\t\t}\n\n\t\tvideo.addEventListener('loadedmetadata', onReadyStateChanged)\n\t\tvideo.addEventListener('loadeddata', onReadyStateChanged)\n\t\tvideo.addEventListener('canplay', onReadyStateChanged)\n\t\tvideo.addEventListener('seeked', onReadyStateChanged)\n\n\t\tvideo.addEventListener('error', onError)\n\t\tvideo.addEventListener('stalled', onError)\n\n\t\tonReadyStateChanged()\n\n\t\ttry {\n\t\t\treturn await promise\n\t\t} finally {\n\t\t\tvideo.removeEventListener('loadedmetadata', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('loadeddata', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('canplay', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('seeked', onReadyStateChanged)\n\n\t\t\tvideo.removeEventListener('error', onError)\n\t\t\tvideo.removeEventListener('stalled', onError)\n\t\t}\n\t}\n\n\t/**\n\t * Load an image from a url.\n\t * @public\n\t */\n\tstatic getImageAndDimensions(\n\t\tsrc: string\n\t): Promise<{ w: number; h: number; image: HTMLImageElement }> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst img = Image()\n\t\t\timg.onload = () => {\n\t\t\t\tlet dimensions\n\t\t\t\tif (img.naturalWidth) {\n\t\t\t\t\tdimensions = {\n\t\t\t\t\t\tw: img.naturalWidth,\n\t\t\t\t\t\th: img.naturalHeight,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Sigh, Firefox doesn't have naturalWidth or naturalHeight for SVGs. :-/\n\t\t\t\t\t// We have to attach to dom and use clientWidth/clientHeight.\n\t\t\t\t\tdocument.body.appendChild(img)\n\t\t\t\t\tdimensions = {\n\t\t\t\t\t\tw: img.clientWidth,\n\t\t\t\t\t\th: img.clientHeight,\n\t\t\t\t\t}\n\t\t\t\t\tdocument.body.removeChild(img)\n\t\t\t\t}\n\t\t\t\tresolve({ ...dimensions, image: img })\n\t\t\t}\n\t\t\timg.onerror = (e) => {\n\t\t\t\tconsole.error(e)\n\t\t\t\treject(new Error('Could not load image'))\n\t\t\t}\n\t\t\timg.crossOrigin = 'anonymous'\n\t\t\timg.referrerPolicy = 'strict-origin-when-cross-origin'\n\t\t\timg.style.visibility = 'hidden'\n\t\t\timg.style.position = 'absolute'\n\t\t\timg.style.opacity = '0'\n\t\t\timg.style.zIndex = '-9999'\n\t\t\timg.src = src\n\t\t})\n\t}\n\n\t/**\n\t * Get the size of a video blob\n\t *\n\t * @param blob - A SharedBlob containing the video\n\t * @public\n\t */\n\tstatic async getVideoSize(blob: Blob): Promise<{ w: number; h: number }> {\n\t\treturn MediaHelpers.usingObjectURL(blob, async (url) => {\n\t\t\tconst video = await MediaHelpers.loadVideo(url)\n\t\t\treturn { w: video.videoWidth, h: video.videoHeight }\n\t\t})\n\t}\n\n\t/**\n\t * Get the size of an image blob\n\t *\n\t * @param blob - A Blob containing the image.\n\t * @public\n\t */\n\tstatic async getImageSize(blob: Blob): Promise<{ w: number; h: number }> {\n\t\tconst { w, h } = await MediaHelpers.usingObjectURL(blob, MediaHelpers.getImageAndDimensions)\n\n\t\ttry {\n\t\t\tif (blob.type === 'image/png') {\n\t\t\t\tconst view = new DataView(await blob.arrayBuffer())\n\t\t\t\tif (PngHelpers.isPng(view, 0)) {\n\t\t\t\t\tconst physChunk = PngHelpers.findChunk(view, 'pHYs')\n\t\t\t\t\tif (physChunk) {\n\t\t\t\t\t\tconst physData = PngHelpers.parsePhys(view, physChunk.dataOffset)\n\t\t\t\t\t\tif (physData.unit ===
|
|
4
|
+
"sourcesContent": ["import { promiseWithResolve } from '../control'\nimport { Image } from '../network'\nimport { isApngAnimated } from './apng'\nimport { isAvifAnimated } from './avif'\nimport { isGifAnimated } from './gif'\nimport { PngHelpers } from './png'\nimport { isWebpAnimated } from './webp'\n\n/** @public */\nexport const DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES = Object.freeze(['image/svg+xml' as const])\n/** @public */\nexport const DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES = Object.freeze([\n\t'image/jpeg' as const,\n\t'image/png' as const,\n\t'image/webp' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES = Object.freeze([\n\t'image/gif' as const,\n\t'image/apng' as const,\n\t'image/avif' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_IMAGE_TYPES = Object.freeze([\n\t...DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES,\n\t...DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES,\n\t...DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES,\n])\n/** @public */\nexport const DEFAULT_SUPPORT_VIDEO_TYPES = Object.freeze([\n\t'video/mp4' as const,\n\t'video/webm' as const,\n\t'video/quicktime' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_MEDIA_TYPES = Object.freeze([\n\t...DEFAULT_SUPPORTED_IMAGE_TYPES,\n\t...DEFAULT_SUPPORT_VIDEO_TYPES,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_MEDIA_TYPE_LIST = DEFAULT_SUPPORTED_MEDIA_TYPES.join(',')\n\n/**\n * Helpers for media\n *\n * @public\n */\nexport class MediaHelpers {\n\t/**\n\t * Load a video from a url.\n\t * @public\n\t */\n\tstatic loadVideo(src: string): Promise<HTMLVideoElement> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst video = document.createElement('video')\n\t\t\tvideo.onloadeddata = () => resolve(video)\n\t\t\tvideo.onerror = (e) => {\n\t\t\t\tconsole.error(e)\n\t\t\t\treject(new Error('Could not load video'))\n\t\t\t}\n\t\t\tvideo.crossOrigin = 'anonymous'\n\t\t\tvideo.src = src\n\t\t})\n\t}\n\n\tstatic async getVideoFrameAsDataUrl(video: HTMLVideoElement, time = 0): Promise<string> {\n\t\tconst promise = promiseWithResolve<string>()\n\t\tlet didSetTime = false\n\n\t\tconst onReadyStateChanged = () => {\n\t\t\tif (!didSetTime) {\n\t\t\t\tif (video.readyState >= video.HAVE_METADATA) {\n\t\t\t\t\tdidSetTime = true\n\t\t\t\t\tvideo.currentTime = time\n\t\t\t\t} else {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (video.readyState >= video.HAVE_CURRENT_DATA) {\n\t\t\t\tconst canvas = document.createElement('canvas')\n\t\t\t\tcanvas.width = video.videoWidth\n\t\t\t\tcanvas.height = video.videoHeight\n\t\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\t\tif (!ctx) {\n\t\t\t\t\tthrow new Error('Could not get 2d context')\n\t\t\t\t}\n\t\t\t\tctx.drawImage(video, 0, 0)\n\t\t\t\tpromise.resolve(canvas.toDataURL())\n\t\t\t}\n\t\t}\n\t\tconst onError = (e: Event) => {\n\t\t\tconsole.error(e)\n\t\t\tpromise.reject(new Error('Could not get video frame'))\n\t\t}\n\n\t\tvideo.addEventListener('loadedmetadata', onReadyStateChanged)\n\t\tvideo.addEventListener('loadeddata', onReadyStateChanged)\n\t\tvideo.addEventListener('canplay', onReadyStateChanged)\n\t\tvideo.addEventListener('seeked', onReadyStateChanged)\n\n\t\tvideo.addEventListener('error', onError)\n\t\tvideo.addEventListener('stalled', onError)\n\n\t\tonReadyStateChanged()\n\n\t\ttry {\n\t\t\treturn await promise\n\t\t} finally {\n\t\t\tvideo.removeEventListener('loadedmetadata', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('loadeddata', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('canplay', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('seeked', onReadyStateChanged)\n\n\t\t\tvideo.removeEventListener('error', onError)\n\t\t\tvideo.removeEventListener('stalled', onError)\n\t\t}\n\t}\n\n\t/**\n\t * Load an image from a url.\n\t * @public\n\t */\n\tstatic getImageAndDimensions(\n\t\tsrc: string\n\t): Promise<{ w: number; h: number; image: HTMLImageElement }> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst img = Image()\n\t\t\timg.onload = () => {\n\t\t\t\tlet dimensions\n\t\t\t\tif (img.naturalWidth) {\n\t\t\t\t\tdimensions = {\n\t\t\t\t\t\tw: img.naturalWidth,\n\t\t\t\t\t\th: img.naturalHeight,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Sigh, Firefox doesn't have naturalWidth or naturalHeight for SVGs. :-/\n\t\t\t\t\t// We have to attach to dom and use clientWidth/clientHeight.\n\t\t\t\t\tdocument.body.appendChild(img)\n\t\t\t\t\tdimensions = {\n\t\t\t\t\t\tw: img.clientWidth,\n\t\t\t\t\t\th: img.clientHeight,\n\t\t\t\t\t}\n\t\t\t\t\tdocument.body.removeChild(img)\n\t\t\t\t}\n\t\t\t\tresolve({ ...dimensions, image: img })\n\t\t\t}\n\t\t\timg.onerror = (e) => {\n\t\t\t\tconsole.error(e)\n\t\t\t\treject(new Error('Could not load image'))\n\t\t\t}\n\t\t\timg.crossOrigin = 'anonymous'\n\t\t\timg.referrerPolicy = 'strict-origin-when-cross-origin'\n\t\t\timg.style.visibility = 'hidden'\n\t\t\timg.style.position = 'absolute'\n\t\t\timg.style.opacity = '0'\n\t\t\timg.style.zIndex = '-9999'\n\t\t\timg.src = src\n\t\t})\n\t}\n\n\t/**\n\t * Get the size of a video blob\n\t *\n\t * @param blob - A SharedBlob containing the video\n\t * @public\n\t */\n\tstatic async getVideoSize(blob: Blob): Promise<{ w: number; h: number }> {\n\t\treturn MediaHelpers.usingObjectURL(blob, async (url) => {\n\t\t\tconst video = await MediaHelpers.loadVideo(url)\n\t\t\treturn { w: video.videoWidth, h: video.videoHeight }\n\t\t})\n\t}\n\n\t/**\n\t * Get the size of an image blob\n\t *\n\t * @param blob - A Blob containing the image.\n\t * @public\n\t */\n\tstatic async getImageSize(blob: Blob): Promise<{ w: number; h: number }> {\n\t\tconst { w, h } = await MediaHelpers.usingObjectURL(blob, MediaHelpers.getImageAndDimensions)\n\n\t\ttry {\n\t\t\tif (blob.type === 'image/png') {\n\t\t\t\tconst view = new DataView(await blob.arrayBuffer())\n\t\t\t\tif (PngHelpers.isPng(view, 0)) {\n\t\t\t\t\tconst physChunk = PngHelpers.findChunk(view, 'pHYs')\n\t\t\t\t\tif (physChunk) {\n\t\t\t\t\t\tconst physData = PngHelpers.parsePhys(view, physChunk.dataOffset)\n\t\t\t\t\t\tif (physData.unit === 1 && physData.ppux === physData.ppuy) {\n\t\t\t\t\t\t\t// Calculate pixels per meter:\n\t\t\t\t\t\t\t// - 1 inch = 0.0254 meters\n\t\t\t\t\t\t\t// - 72 DPI is 72 dots per inch\n\t\t\t\t\t\t\t// - pixels per meter = 72 / 0.0254\n\t\t\t\t\t\t\tconst pixelsPerMeter = 72 / 0.0254\n\t\t\t\t\t\t\tconst pixelRatio = Math.max(physData.ppux / pixelsPerMeter, 1)\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tw: Math.round(w / pixelRatio),\n\t\t\t\t\t\t\t\th: Math.round(h / pixelRatio),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(err)\n\t\t\treturn { w, h }\n\t\t}\n\t\treturn { w, h }\n\t}\n\n\tstatic async isAnimated(file: Blob): Promise<boolean> {\n\t\tif (file.type === 'image/gif') {\n\t\t\treturn isGifAnimated(await file.arrayBuffer())\n\t\t}\n\n\t\tif (file.type === 'image/avif') {\n\t\t\treturn isAvifAnimated(await file.arrayBuffer())\n\t\t}\n\n\t\tif (file.type === 'image/webp') {\n\t\t\treturn isWebpAnimated(await file.arrayBuffer())\n\t\t}\n\n\t\tif (file.type === 'image/apng') {\n\t\t\treturn isApngAnimated(await file.arrayBuffer())\n\t\t}\n\n\t\treturn false\n\t}\n\n\tstatic isAnimatedImageType(mimeType: string | null): boolean {\n\t\treturn DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES.includes((mimeType as any) || '')\n\t}\n\n\tstatic isStaticImageType(mimeType: string | null): boolean {\n\t\treturn DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES.includes((mimeType as any) || '')\n\t}\n\n\tstatic isVectorImageType(mimeType: string | null): boolean {\n\t\treturn DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES.includes((mimeType as any) || '')\n\t}\n\n\tstatic isImageType(mimeType: string): boolean {\n\t\treturn DEFAULT_SUPPORTED_IMAGE_TYPES.includes((mimeType as any) || '')\n\t}\n\n\tstatic async usingObjectURL<T>(blob: Blob, fn: (url: string) => Promise<T>): Promise<T> {\n\t\tconst url = URL.createObjectURL(blob)\n\t\ttry {\n\t\t\treturn await fn(url)\n\t\t} finally {\n\t\t\tURL.revokeObjectURL(url)\n\t\t}\n\t}\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -342,7 +342,7 @@ class PngHelpers {
|
|
|
342
342
|
return {
|
|
343
343
|
ppux: view.getUint32(offset),
|
|
344
344
|
ppuy: view.getUint32(offset + 4),
|
|
345
|
-
unit: view.getUint8(offset +
|
|
345
|
+
unit: view.getUint8(offset + 8)
|
|
346
346
|
};
|
|
347
347
|
}
|
|
348
348
|
static findChunk(view, type) {
|
|
@@ -369,9 +369,9 @@ class PngHelpers {
|
|
|
369
369
|
pHYsDataView.setUint8(5, "H".charCodeAt(0));
|
|
370
370
|
pHYsDataView.setUint8(6, "Y".charCodeAt(0));
|
|
371
371
|
pHYsDataView.setUint8(7, "s".charCodeAt(0));
|
|
372
|
-
const
|
|
373
|
-
pHYsDataView.setInt32(8,
|
|
374
|
-
pHYsDataView.setInt32(12,
|
|
372
|
+
const DPI_72 = 2835.5;
|
|
373
|
+
pHYsDataView.setInt32(8, DPI_72 * dpr);
|
|
374
|
+
pHYsDataView.setInt32(12, DPI_72 * dpr);
|
|
375
375
|
pHYsDataView.setInt8(16, 1);
|
|
376
376
|
const crcBit = new Uint8Array(pHYsData.slice(4, 17));
|
|
377
377
|
pHYsDataView.setInt32(17, crc(crcBit));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/media/png.ts"],
|
|
4
|
-
"sourcesContent": ["/*!\n * MIT License: https://github.com/alexgorbatchev/crc/blob/master/LICENSE\n * Copyright: 2014 Alex Gorbatchev\n * Code: crc32, https://github.com/alexgorbatchev/crc/blob/master/src/calculators/crc32.ts\n */\n\ntype BufferInput = string | ArrayBuffer | Buffer\n\ninterface CRCCalculator<T = BufferInput | Uint8Array> {\n\t(value: T, previous?: number): number\n}\n\nlet TABLE: Array<number> | Int32Array = [\n\t0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,\n\t0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,\n\t0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\n\t0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,\n\t0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n\t0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\n\t0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,\n\t0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,\n\t0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\n\t0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n\t0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,\n\t0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\n\t0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,\n\t0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,\n\t0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n\t0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,\n\t0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,\n\t0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\n\t0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,\n\t0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n\t0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\n\t0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,\n\t0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,\n\t0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\n\t0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n\t0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,\n\t0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\n\t0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,\n\t0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,\n\t0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n\t0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,\n\t0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,\n]\n\nif (typeof Int32Array !== 'undefined') {\n\tTABLE = new Int32Array(TABLE)\n}\n\nconst crc: CRCCalculator<Uint8Array> = (current, previous) => {\n\tlet crc = previous === 0 ? 0 : ~~previous! ^ -1\n\n\tfor (let index = 0; index < current.length; index++) {\n\t\tcrc = TABLE[(crc ^ current[index]) & 0xff] ^ (crc >>> 8)\n\t}\n\n\treturn crc ^ -1\n}\n\nconst LEN_SIZE = 4\nconst CRC_SIZE = 4\n\n/** @public */\nexport class PngHelpers {\n\tstatic isPng(view: DataView, offset: number) {\n\t\tif (\n\t\t\tview.getUint8(offset + 0) === 0x89 &&\n\t\t\tview.getUint8(offset + 1) === 0x50 &&\n\t\t\tview.getUint8(offset + 2) === 0x4e &&\n\t\t\tview.getUint8(offset + 3) === 0x47 &&\n\t\t\tview.getUint8(offset + 4) === 0x0d &&\n\t\t\tview.getUint8(offset + 5) === 0x0a &&\n\t\t\tview.getUint8(offset + 6) === 0x1a &&\n\t\t\tview.getUint8(offset + 7) === 0x0a\n\t\t) {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tstatic getChunkType(view: DataView, offset: number) {\n\t\treturn [\n\t\t\tString.fromCharCode(view.getUint8(offset)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 1)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 2)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 3)),\n\t\t].join('')\n\t}\n\n\tstatic readChunks(view: DataView, offset = 0) {\n\t\tconst chunks: Record<string, { dataOffset: number; size: number; start: number }> = {}\n\t\tif (!PngHelpers.isPng(view, offset)) {\n\t\t\tthrow new Error('Not a PNG')\n\t\t}\n\t\toffset += 8\n\n\t\twhile (offset <= view.buffer.byteLength) {\n\t\t\tconst start = offset\n\t\t\tconst len = view.getInt32(offset)\n\t\t\toffset += 4\n\t\t\tconst chunkType = PngHelpers.getChunkType(view, offset)\n\n\t\t\tif (chunkType === 'IDAT' && chunks[chunkType]) {\n\t\t\t\toffset += len + LEN_SIZE + CRC_SIZE\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (chunkType === 'IEND') {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tchunks[chunkType] = {\n\t\t\t\tstart,\n\t\t\t\tdataOffset: offset + 4,\n\t\t\t\tsize: len,\n\t\t\t}\n\t\t\toffset += len + LEN_SIZE + CRC_SIZE\n\t\t}\n\n\t\treturn chunks\n\t}\n\n\tstatic parsePhys(view: DataView, offset: number) {\n\t\treturn {\n\t\t\tppux: view.getUint32(offset),\n\t\t\tppuy: view.getUint32(offset + 4),\n\t\t\tunit: view.getUint8(offset +
|
|
4
|
+
"sourcesContent": ["/*!\n * MIT License: https://github.com/alexgorbatchev/crc/blob/master/LICENSE\n * Copyright: 2014 Alex Gorbatchev\n * Code: crc32, https://github.com/alexgorbatchev/crc/blob/master/src/calculators/crc32.ts\n */\n\ntype BufferInput = string | ArrayBuffer | Buffer\n\ninterface CRCCalculator<T = BufferInput | Uint8Array> {\n\t(value: T, previous?: number): number\n}\n\nlet TABLE: Array<number> | Int32Array = [\n\t0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,\n\t0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,\n\t0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\n\t0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,\n\t0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n\t0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\n\t0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,\n\t0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,\n\t0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\n\t0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n\t0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,\n\t0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\n\t0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,\n\t0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,\n\t0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n\t0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,\n\t0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,\n\t0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\n\t0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,\n\t0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n\t0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\n\t0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,\n\t0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,\n\t0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\n\t0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n\t0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,\n\t0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\n\t0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,\n\t0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,\n\t0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n\t0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,\n\t0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,\n]\n\nif (typeof Int32Array !== 'undefined') {\n\tTABLE = new Int32Array(TABLE)\n}\n\nconst crc: CRCCalculator<Uint8Array> = (current, previous) => {\n\tlet crc = previous === 0 ? 0 : ~~previous! ^ -1\n\n\tfor (let index = 0; index < current.length; index++) {\n\t\tcrc = TABLE[(crc ^ current[index]) & 0xff] ^ (crc >>> 8)\n\t}\n\n\treturn crc ^ -1\n}\n\nconst LEN_SIZE = 4\nconst CRC_SIZE = 4\n\n/** @public */\nexport class PngHelpers {\n\tstatic isPng(view: DataView, offset: number) {\n\t\tif (\n\t\t\tview.getUint8(offset + 0) === 0x89 &&\n\t\t\tview.getUint8(offset + 1) === 0x50 &&\n\t\t\tview.getUint8(offset + 2) === 0x4e &&\n\t\t\tview.getUint8(offset + 3) === 0x47 &&\n\t\t\tview.getUint8(offset + 4) === 0x0d &&\n\t\t\tview.getUint8(offset + 5) === 0x0a &&\n\t\t\tview.getUint8(offset + 6) === 0x1a &&\n\t\t\tview.getUint8(offset + 7) === 0x0a\n\t\t) {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tstatic getChunkType(view: DataView, offset: number) {\n\t\treturn [\n\t\t\tString.fromCharCode(view.getUint8(offset)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 1)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 2)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 3)),\n\t\t].join('')\n\t}\n\n\tstatic readChunks(view: DataView, offset = 0) {\n\t\tconst chunks: Record<string, { dataOffset: number; size: number; start: number }> = {}\n\t\tif (!PngHelpers.isPng(view, offset)) {\n\t\t\tthrow new Error('Not a PNG')\n\t\t}\n\t\toffset += 8\n\n\t\twhile (offset <= view.buffer.byteLength) {\n\t\t\tconst start = offset\n\t\t\tconst len = view.getInt32(offset)\n\t\t\toffset += 4\n\t\t\tconst chunkType = PngHelpers.getChunkType(view, offset)\n\n\t\t\tif (chunkType === 'IDAT' && chunks[chunkType]) {\n\t\t\t\toffset += len + LEN_SIZE + CRC_SIZE\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (chunkType === 'IEND') {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tchunks[chunkType] = {\n\t\t\t\tstart,\n\t\t\t\tdataOffset: offset + 4,\n\t\t\t\tsize: len,\n\t\t\t}\n\t\t\toffset += len + LEN_SIZE + CRC_SIZE\n\t\t}\n\n\t\treturn chunks\n\t}\n\n\tstatic parsePhys(view: DataView, offset: number) {\n\t\treturn {\n\t\t\tppux: view.getUint32(offset),\n\t\t\tppuy: view.getUint32(offset + 4),\n\t\t\tunit: view.getUint8(offset + 8),\n\t\t}\n\t}\n\n\tstatic findChunk(view: DataView, type: string) {\n\t\tconst chunks = PngHelpers.readChunks(view)\n\t\treturn chunks[type]\n\t}\n\n\tstatic setPhysChunk(view: DataView, dpr = 1, options?: BlobPropertyBag) {\n\t\tlet offset = 46\n\t\tlet size = 0\n\t\tconst res1 = PngHelpers.findChunk(view, 'pHYs')\n\t\tif (res1) {\n\t\t\toffset = res1.start\n\t\t\tsize = res1.size\n\t\t}\n\n\t\tconst res2 = PngHelpers.findChunk(view, 'IDAT')\n\t\tif (res2) {\n\t\t\toffset = res2.start\n\t\t\tsize = 0\n\t\t}\n\n\t\tconst pHYsData = new ArrayBuffer(21)\n\t\tconst pHYsDataView = new DataView(pHYsData)\n\n\t\tpHYsDataView.setUint32(0, 9)\n\n\t\tpHYsDataView.setUint8(4, 'p'.charCodeAt(0))\n\t\tpHYsDataView.setUint8(5, 'H'.charCodeAt(0))\n\t\tpHYsDataView.setUint8(6, 'Y'.charCodeAt(0))\n\t\tpHYsDataView.setUint8(7, 's'.charCodeAt(0))\n\n\t\tconst DPI_72 = 2835.5\n\n\t\tpHYsDataView.setInt32(8, DPI_72 * dpr)\n\t\tpHYsDataView.setInt32(12, DPI_72 * dpr)\n\t\tpHYsDataView.setInt8(16, 1)\n\n\t\tconst crcBit = new Uint8Array(pHYsData.slice(4, 17))\n\t\tpHYsDataView.setInt32(17, crc(crcBit))\n\n\t\tconst startBuf = view.buffer.slice(0, offset)\n\t\tconst endBuf = view.buffer.slice(offset + size)\n\n\t\treturn new Blob([startBuf as ArrayBuffer, pHYsData, endBuf as ArrayBuffer], options)\n\t}\n}\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,IAAI,QAAoC;AAAA,EACvC;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EA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",
|
|
6
6
|
"names": ["crc"]
|
|
7
7
|
}
|
|
@@ -30,12 +30,15 @@ __export(reordering_exports, {
|
|
|
30
30
|
validateIndexKey: () => validateIndexKey
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(reordering_exports);
|
|
33
|
-
var
|
|
34
|
-
const
|
|
33
|
+
var import_jittered_fractional_indexing = require("jittered-fractional-indexing");
|
|
34
|
+
const generateNKeysBetweenWithNoJitter = (a, b, n) => {
|
|
35
|
+
return (0, import_jittered_fractional_indexing.generateNKeysBetween)(a, b, n, { jitterBits: 0 });
|
|
36
|
+
};
|
|
37
|
+
const generateKeysFn = process.env.NODE_ENV === "test" ? generateNKeysBetweenWithNoJitter : import_jittered_fractional_indexing.generateNKeysBetween;
|
|
35
38
|
const ZERO_INDEX_KEY = "a0";
|
|
36
39
|
function validateIndexKey(index) {
|
|
37
40
|
try {
|
|
38
|
-
(0,
|
|
41
|
+
(0, import_jittered_fractional_indexing.generateKeyBetween)(index, null);
|
|
39
42
|
} catch {
|
|
40
43
|
throw new Error("invalid index: " + index);
|
|
41
44
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/reordering.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import { generateKeyBetween, generateNKeysBetween } from 'jittered-fractional-indexing'\n\nconst generateNKeysBetweenWithNoJitter = (a: string | null, b: string | null, n: number) => {\n\treturn generateNKeysBetween(a, b, n, { jitterBits: 0 })\n}\n\nconst generateKeysFn =\n\tprocess.env.NODE_ENV === 'test' ? generateNKeysBetweenWithNoJitter : generateNKeysBetween\n\n/**\n * A string made up of an integer part followed by a fraction part. The fraction point consists of\n * zero or more digits with no trailing zeros. Based on\n * {@link https://observablehq.com/@dgreensp/implementing-fractional-indexing}.\n *\n * @public\n */\nexport type IndexKey = string & { __brand: 'indexKey' }\n\n/**\n * The index key for the first index - 'a0'.\n * @public\n */\nexport const ZERO_INDEX_KEY = 'a0' as IndexKey\n\n/** @internal */\nexport function validateIndexKey(index: string): asserts index is IndexKey {\n\ttry {\n\t\tgenerateKeyBetween(index, null)\n\t} catch {\n\t\tthrow new Error('invalid index: ' + index)\n\t}\n}\n\n/**\n * Get a number of indices between two indices.\n * @param below - The index below.\n * @param above - The index above.\n * @param n - The number of indices to get.\n * @public\n */\nexport function getIndicesBetween(\n\tbelow: IndexKey | null | undefined,\n\tabove: IndexKey | null | undefined,\n\tn: number\n) {\n\treturn generateKeysFn(below ?? null, above ?? null, n) as IndexKey[]\n}\n\n/**\n * Get a number of indices above an index.\n * @param below - The index below.\n * @param n - The number of indices to get.\n * @public\n */\nexport function getIndicesAbove(below: IndexKey | null | undefined, n: number) {\n\treturn generateKeysFn(below ?? null, null, n) as IndexKey[]\n}\n\n/**\n * Get a number of indices below an index.\n * @param above - The index above.\n * @param n - The number of indices to get.\n * @public\n */\nexport function getIndicesBelow(above: IndexKey | null | undefined, n: number) {\n\treturn generateKeysFn(null, above ?? null, n) as IndexKey[]\n}\n\n/**\n * Get the index between two indices.\n * @param below - The index below.\n * @param above - The index above.\n * @public\n */\nexport function getIndexBetween(\n\tbelow: IndexKey | null | undefined,\n\tabove: IndexKey | null | undefined\n) {\n\treturn generateKeysFn(below ?? null, above ?? null, 1)[0] as IndexKey\n}\n\n/**\n * Get the index above a given index.\n * @param below - The index below.\n * @public\n */\nexport function getIndexAbove(below: IndexKey | null | undefined = null) {\n\treturn generateKeysFn(below, null, 1)[0] as IndexKey\n}\n\n/**\n * Get the index below a given index.\n * @param above - The index above.\n * @public\n */\nexport function getIndexBelow(above: IndexKey | null | undefined = null) {\n\treturn generateKeysFn(null, above, 1)[0] as IndexKey\n}\n\n/**\n * Get n number of indices, starting at an index.\n * @param n - The number of indices to get.\n * @param start - The index to start at.\n * @public\n */\nexport function getIndices(n: number, start = 'a1' as IndexKey) {\n\treturn [start, ...generateKeysFn(start, null, n)] as IndexKey[]\n}\n\n/**\n * Sort by index.\n * @param a - An object with an index property.\n * @param b - An object with an index property.\n * @public */\nexport function sortByIndex<T extends { index: IndexKey }>(a: T, b: T) {\n\tif (a.index < b.index) {\n\t\treturn -1\n\t} else if (a.index > b.index) {\n\t\treturn 1\n\t}\n\treturn 0\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0CAAyD;AAEzD,MAAM,mCAAmC,CAAC,GAAkB,GAAkB,MAAc;AAC3F,aAAO,0DAAqB,GAAG,GAAG,GAAG,EAAE,YAAY,EAAE,CAAC;AACvD;AAEA,MAAM,iBACL,QAAQ,IAAI,aAAa,SAAS,mCAAmC;AAe/D,MAAM,iBAAiB;AAGvB,SAAS,iBAAiB,OAA0C;AAC1E,MAAI;AACH,gEAAmB,OAAO,IAAI;AAAA,EAC/B,QAAQ;AACP,UAAM,IAAI,MAAM,oBAAoB,KAAK;AAAA,EAC1C;AACD;AASO,SAAS,kBACf,OACA,OACA,GACC;AACD,SAAO,eAAe,SAAS,MAAM,SAAS,MAAM,CAAC;AACtD;AAQO,SAAS,gBAAgB,OAAoC,GAAW;AAC9E,SAAO,eAAe,SAAS,MAAM,MAAM,CAAC;AAC7C;AAQO,SAAS,gBAAgB,OAAoC,GAAW;AAC9E,SAAO,eAAe,MAAM,SAAS,MAAM,CAAC;AAC7C;AAQO,SAAS,gBACf,OACA,OACC;AACD,SAAO,eAAe,SAAS,MAAM,SAAS,MAAM,CAAC,EAAE,CAAC;AACzD;AAOO,SAAS,cAAc,QAAqC,MAAM;AACxE,SAAO,eAAe,OAAO,MAAM,CAAC,EAAE,CAAC;AACxC;AAOO,SAAS,cAAc,QAAqC,MAAM;AACxE,SAAO,eAAe,MAAM,OAAO,CAAC,EAAE,CAAC;AACxC;AAQO,SAAS,WAAW,GAAW,QAAQ,MAAkB;AAC/D,SAAO,CAAC,OAAO,GAAG,eAAe,OAAO,MAAM,CAAC,CAAC;AACjD;AAOO,SAAS,YAA2C,GAAM,GAAM;AACtE,MAAI,EAAE,QAAQ,EAAE,OAAO;AACtB,WAAO;AAAA,EACR,WAAW,EAAE,QAAQ,EAAE,OAAO;AAC7B,WAAO;AAAA,EACR;AACA,SAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/index.d.mts
CHANGED
|
@@ -103,10 +103,6 @@ export declare type Expand<T> = T extends infer O ? {
|
|
|
103
103
|
* @public
|
|
104
104
|
*/
|
|
105
105
|
export declare class FileHelpers {
|
|
106
|
-
/**
|
|
107
|
-
* @deprecated Use `urlToArrayBuffer` instead.
|
|
108
|
-
*/
|
|
109
|
-
static dataUrlToArrayBuffer(dataURL: string): Promise<ArrayBuffer>;
|
|
110
106
|
/**
|
|
111
107
|
* @param url - The url of the file.
|
|
112
108
|
*/
|
package/dist-esm/index.mjs
CHANGED
|
@@ -100,7 +100,7 @@ import { registerTldrawLibraryVersion as registerTldrawLibraryVersion2 } from ".
|
|
|
100
100
|
import { warnDeprecatedGetter, warnOnce } from "./lib/warn.mjs";
|
|
101
101
|
registerTldrawLibraryVersion(
|
|
102
102
|
"@tldraw/utils",
|
|
103
|
-
"
|
|
103
|
+
"4.0.0",
|
|
104
104
|
"esm"
|
|
105
105
|
);
|
|
106
106
|
export {
|
package/dist-esm/lib/file.mjs
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import { fetch } from "./network.mjs";
|
|
2
2
|
class FileHelpers {
|
|
3
|
-
/**
|
|
4
|
-
* @deprecated Use `urlToArrayBuffer` instead.
|
|
5
|
-
*/
|
|
6
|
-
static async dataUrlToArrayBuffer(dataURL) {
|
|
7
|
-
return fetch(dataURL).then(function(result) {
|
|
8
|
-
return result.arrayBuffer();
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
3
|
/**
|
|
12
4
|
* @param url - The url of the file.
|
|
13
5
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/file.ts"],
|
|
4
|
-
"sourcesContent": ["import { fetch } from './network'\n\n/**\n * Helpers for files\n *\n * @public\n */\nexport class FileHelpers {\n\t/**\n\t * @
|
|
5
|
-
"mappings": "AAAA,SAAS,aAAa;AAOf,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA,EAIxB,aAAa,
|
|
4
|
+
"sourcesContent": ["import { fetch } from './network'\n\n/**\n * Helpers for files\n *\n * @public\n */\nexport class FileHelpers {\n\t/**\n\t * @param url - The url of the file.\n\t */\n\tstatic async urlToArrayBuffer(url: string) {\n\t\tconst response = await fetch(url)\n\t\treturn await response.arrayBuffer()\n\t}\n\n\tstatic async urlToBlob(url: string) {\n\t\tconst response = await fetch(url)\n\t\treturn await response.blob()\n\t}\n\n\tstatic async urlToDataUrl(url: string) {\n\t\tif (url.startsWith('data:')) return url\n\t\tconst blob = await FileHelpers.urlToBlob(url)\n\t\treturn await FileHelpers.blobToDataUrl(blob)\n\t}\n\n\t/**\n\t * Convert a file to a base64 encoded data url.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const A = FileHelpers.toDataUrl(myImageFile)\n\t * ```\n\t *\n\t * @param file - The file as a blob.\n\t */\n\tstatic async blobToDataUrl(file: Blob): Promise<string> {\n\t\treturn await new Promise((resolve, reject) => {\n\t\t\tif (file) {\n\t\t\t\tconst reader = new FileReader()\n\t\t\t\treader.onload = () => resolve(reader.result as string)\n\t\t\t\treader.onerror = (error) => reject(error)\n\t\t\t\treader.onabort = (error) => reject(error)\n\t\t\t\treader.readAsDataURL(file)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Convert a file to a unicode text string.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const A = FileHelpers.fileToDataUrl(myTextFile)\n\t * ```\n\t *\n\t * @param file - The file as a blob.\n\t */\n\tstatic async blobToText(file: Blob): Promise<string> {\n\t\treturn await new Promise((resolve, reject) => {\n\t\t\tif (file) {\n\t\t\t\tconst reader = new FileReader()\n\t\t\t\treader.onload = () => resolve(reader.result as string)\n\t\t\t\treader.onerror = (error) => reject(error)\n\t\t\t\treader.onabort = (error) => reject(error)\n\t\t\t\treader.readAsText(file)\n\t\t\t}\n\t\t})\n\t}\n\n\tstatic rewriteMimeType(blob: Blob, newMimeType: string): Blob\n\tstatic rewriteMimeType(blob: File, newMimeType: string): File\n\tstatic rewriteMimeType(blob: Blob | File, newMimeType: string): Blob | File {\n\t\tif (blob.type === newMimeType) return blob\n\t\tif (blob instanceof File) {\n\t\t\treturn new File([blob], blob.name, { type: newMimeType })\n\t\t}\n\t\treturn new Blob([blob], { type: newMimeType })\n\t}\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,aAAa;AAOf,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA,EAIxB,aAAa,iBAAiB,KAAa;AAC1C,UAAM,WAAW,MAAM,MAAM,GAAG;AAChC,WAAO,MAAM,SAAS,YAAY;AAAA,EACnC;AAAA,EAEA,aAAa,UAAU,KAAa;AACnC,UAAM,WAAW,MAAM,MAAM,GAAG;AAChC,WAAO,MAAM,SAAS,KAAK;AAAA,EAC5B;AAAA,EAEA,aAAa,aAAa,KAAa;AACtC,QAAI,IAAI,WAAW,OAAO,EAAG,QAAO;AACpC,UAAM,OAAO,MAAM,YAAY,UAAU,GAAG;AAC5C,WAAO,MAAM,YAAY,cAAc,IAAI;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,aAAa,cAAc,MAA6B;AACvD,WAAO,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC7C,UAAI,MAAM;AACT,cAAM,SAAS,IAAI,WAAW;AAC9B,eAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,cAAc,IAAI;AAAA,MAC1B;AAAA,IACD,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,aAAa,WAAW,MAA6B;AACpD,WAAO,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC7C,UAAI,MAAM;AACT,cAAM,SAAS,IAAI,WAAW;AAC9B,eAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AACxC,eAAO,WAAW,IAAI;AAAA,MACvB;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAIA,OAAO,gBAAgB,MAAmB,aAAkC;AAC3E,QAAI,KAAK,SAAS,YAAa,QAAO;AACtC,QAAI,gBAAgB,MAAM;AACzB,aAAO,IAAI,KAAK,CAAC,IAAI,GAAG,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAAA,IACzD;AACA,WAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,YAAY,CAAC;AAAA,EAC9C;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -158,7 +158,7 @@ class MediaHelpers {
|
|
|
158
158
|
const physChunk = PngHelpers.findChunk(view, "pHYs");
|
|
159
159
|
if (physChunk) {
|
|
160
160
|
const physData = PngHelpers.parsePhys(view, physChunk.dataOffset);
|
|
161
|
-
if (physData.unit ===
|
|
161
|
+
if (physData.unit === 1 && physData.ppux === physData.ppuy) {
|
|
162
162
|
const pixelsPerMeter = 72 / 0.0254;
|
|
163
163
|
const pixelRatio = Math.max(physData.ppux / pixelsPerMeter, 1);
|
|
164
164
|
return {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/media/media.ts"],
|
|
4
|
-
"sourcesContent": ["import { promiseWithResolve } from '../control'\nimport { Image } from '../network'\nimport { isApngAnimated } from './apng'\nimport { isAvifAnimated } from './avif'\nimport { isGifAnimated } from './gif'\nimport { PngHelpers } from './png'\nimport { isWebpAnimated } from './webp'\n\n/** @public */\nexport const DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES = Object.freeze(['image/svg+xml' as const])\n/** @public */\nexport const DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES = Object.freeze([\n\t'image/jpeg' as const,\n\t'image/png' as const,\n\t'image/webp' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES = Object.freeze([\n\t'image/gif' as const,\n\t'image/apng' as const,\n\t'image/avif' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_IMAGE_TYPES = Object.freeze([\n\t...DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES,\n\t...DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES,\n\t...DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES,\n])\n/** @public */\nexport const DEFAULT_SUPPORT_VIDEO_TYPES = Object.freeze([\n\t'video/mp4' as const,\n\t'video/webm' as const,\n\t'video/quicktime' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_MEDIA_TYPES = Object.freeze([\n\t...DEFAULT_SUPPORTED_IMAGE_TYPES,\n\t...DEFAULT_SUPPORT_VIDEO_TYPES,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_MEDIA_TYPE_LIST = DEFAULT_SUPPORTED_MEDIA_TYPES.join(',')\n\n/**\n * Helpers for media\n *\n * @public\n */\nexport class MediaHelpers {\n\t/**\n\t * Load a video from a url.\n\t * @public\n\t */\n\tstatic loadVideo(src: string): Promise<HTMLVideoElement> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst video = document.createElement('video')\n\t\t\tvideo.onloadeddata = () => resolve(video)\n\t\t\tvideo.onerror = (e) => {\n\t\t\t\tconsole.error(e)\n\t\t\t\treject(new Error('Could not load video'))\n\t\t\t}\n\t\t\tvideo.crossOrigin = 'anonymous'\n\t\t\tvideo.src = src\n\t\t})\n\t}\n\n\tstatic async getVideoFrameAsDataUrl(video: HTMLVideoElement, time = 0): Promise<string> {\n\t\tconst promise = promiseWithResolve<string>()\n\t\tlet didSetTime = false\n\n\t\tconst onReadyStateChanged = () => {\n\t\t\tif (!didSetTime) {\n\t\t\t\tif (video.readyState >= video.HAVE_METADATA) {\n\t\t\t\t\tdidSetTime = true\n\t\t\t\t\tvideo.currentTime = time\n\t\t\t\t} else {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (video.readyState >= video.HAVE_CURRENT_DATA) {\n\t\t\t\tconst canvas = document.createElement('canvas')\n\t\t\t\tcanvas.width = video.videoWidth\n\t\t\t\tcanvas.height = video.videoHeight\n\t\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\t\tif (!ctx) {\n\t\t\t\t\tthrow new Error('Could not get 2d context')\n\t\t\t\t}\n\t\t\t\tctx.drawImage(video, 0, 0)\n\t\t\t\tpromise.resolve(canvas.toDataURL())\n\t\t\t}\n\t\t}\n\t\tconst onError = (e: Event) => {\n\t\t\tconsole.error(e)\n\t\t\tpromise.reject(new Error('Could not get video frame'))\n\t\t}\n\n\t\tvideo.addEventListener('loadedmetadata', onReadyStateChanged)\n\t\tvideo.addEventListener('loadeddata', onReadyStateChanged)\n\t\tvideo.addEventListener('canplay', onReadyStateChanged)\n\t\tvideo.addEventListener('seeked', onReadyStateChanged)\n\n\t\tvideo.addEventListener('error', onError)\n\t\tvideo.addEventListener('stalled', onError)\n\n\t\tonReadyStateChanged()\n\n\t\ttry {\n\t\t\treturn await promise\n\t\t} finally {\n\t\t\tvideo.removeEventListener('loadedmetadata', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('loadeddata', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('canplay', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('seeked', onReadyStateChanged)\n\n\t\t\tvideo.removeEventListener('error', onError)\n\t\t\tvideo.removeEventListener('stalled', onError)\n\t\t}\n\t}\n\n\t/**\n\t * Load an image from a url.\n\t * @public\n\t */\n\tstatic getImageAndDimensions(\n\t\tsrc: string\n\t): Promise<{ w: number; h: number; image: HTMLImageElement }> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst img = Image()\n\t\t\timg.onload = () => {\n\t\t\t\tlet dimensions\n\t\t\t\tif (img.naturalWidth) {\n\t\t\t\t\tdimensions = {\n\t\t\t\t\t\tw: img.naturalWidth,\n\t\t\t\t\t\th: img.naturalHeight,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Sigh, Firefox doesn't have naturalWidth or naturalHeight for SVGs. :-/\n\t\t\t\t\t// We have to attach to dom and use clientWidth/clientHeight.\n\t\t\t\t\tdocument.body.appendChild(img)\n\t\t\t\t\tdimensions = {\n\t\t\t\t\t\tw: img.clientWidth,\n\t\t\t\t\t\th: img.clientHeight,\n\t\t\t\t\t}\n\t\t\t\t\tdocument.body.removeChild(img)\n\t\t\t\t}\n\t\t\t\tresolve({ ...dimensions, image: img })\n\t\t\t}\n\t\t\timg.onerror = (e) => {\n\t\t\t\tconsole.error(e)\n\t\t\t\treject(new Error('Could not load image'))\n\t\t\t}\n\t\t\timg.crossOrigin = 'anonymous'\n\t\t\timg.referrerPolicy = 'strict-origin-when-cross-origin'\n\t\t\timg.style.visibility = 'hidden'\n\t\t\timg.style.position = 'absolute'\n\t\t\timg.style.opacity = '0'\n\t\t\timg.style.zIndex = '-9999'\n\t\t\timg.src = src\n\t\t})\n\t}\n\n\t/**\n\t * Get the size of a video blob\n\t *\n\t * @param blob - A SharedBlob containing the video\n\t * @public\n\t */\n\tstatic async getVideoSize(blob: Blob): Promise<{ w: number; h: number }> {\n\t\treturn MediaHelpers.usingObjectURL(blob, async (url) => {\n\t\t\tconst video = await MediaHelpers.loadVideo(url)\n\t\t\treturn { w: video.videoWidth, h: video.videoHeight }\n\t\t})\n\t}\n\n\t/**\n\t * Get the size of an image blob\n\t *\n\t * @param blob - A Blob containing the image.\n\t * @public\n\t */\n\tstatic async getImageSize(blob: Blob): Promise<{ w: number; h: number }> {\n\t\tconst { w, h } = await MediaHelpers.usingObjectURL(blob, MediaHelpers.getImageAndDimensions)\n\n\t\ttry {\n\t\t\tif (blob.type === 'image/png') {\n\t\t\t\tconst view = new DataView(await blob.arrayBuffer())\n\t\t\t\tif (PngHelpers.isPng(view, 0)) {\n\t\t\t\t\tconst physChunk = PngHelpers.findChunk(view, 'pHYs')\n\t\t\t\t\tif (physChunk) {\n\t\t\t\t\t\tconst physData = PngHelpers.parsePhys(view, physChunk.dataOffset)\n\t\t\t\t\t\tif (physData.unit ===
|
|
4
|
+
"sourcesContent": ["import { promiseWithResolve } from '../control'\nimport { Image } from '../network'\nimport { isApngAnimated } from './apng'\nimport { isAvifAnimated } from './avif'\nimport { isGifAnimated } from './gif'\nimport { PngHelpers } from './png'\nimport { isWebpAnimated } from './webp'\n\n/** @public */\nexport const DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES = Object.freeze(['image/svg+xml' as const])\n/** @public */\nexport const DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES = Object.freeze([\n\t'image/jpeg' as const,\n\t'image/png' as const,\n\t'image/webp' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES = Object.freeze([\n\t'image/gif' as const,\n\t'image/apng' as const,\n\t'image/avif' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_IMAGE_TYPES = Object.freeze([\n\t...DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES,\n\t...DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES,\n\t...DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES,\n])\n/** @public */\nexport const DEFAULT_SUPPORT_VIDEO_TYPES = Object.freeze([\n\t'video/mp4' as const,\n\t'video/webm' as const,\n\t'video/quicktime' as const,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_MEDIA_TYPES = Object.freeze([\n\t...DEFAULT_SUPPORTED_IMAGE_TYPES,\n\t...DEFAULT_SUPPORT_VIDEO_TYPES,\n])\n/** @public */\nexport const DEFAULT_SUPPORTED_MEDIA_TYPE_LIST = DEFAULT_SUPPORTED_MEDIA_TYPES.join(',')\n\n/**\n * Helpers for media\n *\n * @public\n */\nexport class MediaHelpers {\n\t/**\n\t * Load a video from a url.\n\t * @public\n\t */\n\tstatic loadVideo(src: string): Promise<HTMLVideoElement> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst video = document.createElement('video')\n\t\t\tvideo.onloadeddata = () => resolve(video)\n\t\t\tvideo.onerror = (e) => {\n\t\t\t\tconsole.error(e)\n\t\t\t\treject(new Error('Could not load video'))\n\t\t\t}\n\t\t\tvideo.crossOrigin = 'anonymous'\n\t\t\tvideo.src = src\n\t\t})\n\t}\n\n\tstatic async getVideoFrameAsDataUrl(video: HTMLVideoElement, time = 0): Promise<string> {\n\t\tconst promise = promiseWithResolve<string>()\n\t\tlet didSetTime = false\n\n\t\tconst onReadyStateChanged = () => {\n\t\t\tif (!didSetTime) {\n\t\t\t\tif (video.readyState >= video.HAVE_METADATA) {\n\t\t\t\t\tdidSetTime = true\n\t\t\t\t\tvideo.currentTime = time\n\t\t\t\t} else {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (video.readyState >= video.HAVE_CURRENT_DATA) {\n\t\t\t\tconst canvas = document.createElement('canvas')\n\t\t\t\tcanvas.width = video.videoWidth\n\t\t\t\tcanvas.height = video.videoHeight\n\t\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\t\tif (!ctx) {\n\t\t\t\t\tthrow new Error('Could not get 2d context')\n\t\t\t\t}\n\t\t\t\tctx.drawImage(video, 0, 0)\n\t\t\t\tpromise.resolve(canvas.toDataURL())\n\t\t\t}\n\t\t}\n\t\tconst onError = (e: Event) => {\n\t\t\tconsole.error(e)\n\t\t\tpromise.reject(new Error('Could not get video frame'))\n\t\t}\n\n\t\tvideo.addEventListener('loadedmetadata', onReadyStateChanged)\n\t\tvideo.addEventListener('loadeddata', onReadyStateChanged)\n\t\tvideo.addEventListener('canplay', onReadyStateChanged)\n\t\tvideo.addEventListener('seeked', onReadyStateChanged)\n\n\t\tvideo.addEventListener('error', onError)\n\t\tvideo.addEventListener('stalled', onError)\n\n\t\tonReadyStateChanged()\n\n\t\ttry {\n\t\t\treturn await promise\n\t\t} finally {\n\t\t\tvideo.removeEventListener('loadedmetadata', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('loadeddata', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('canplay', onReadyStateChanged)\n\t\t\tvideo.removeEventListener('seeked', onReadyStateChanged)\n\n\t\t\tvideo.removeEventListener('error', onError)\n\t\t\tvideo.removeEventListener('stalled', onError)\n\t\t}\n\t}\n\n\t/**\n\t * Load an image from a url.\n\t * @public\n\t */\n\tstatic getImageAndDimensions(\n\t\tsrc: string\n\t): Promise<{ w: number; h: number; image: HTMLImageElement }> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst img = Image()\n\t\t\timg.onload = () => {\n\t\t\t\tlet dimensions\n\t\t\t\tif (img.naturalWidth) {\n\t\t\t\t\tdimensions = {\n\t\t\t\t\t\tw: img.naturalWidth,\n\t\t\t\t\t\th: img.naturalHeight,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Sigh, Firefox doesn't have naturalWidth or naturalHeight for SVGs. :-/\n\t\t\t\t\t// We have to attach to dom and use clientWidth/clientHeight.\n\t\t\t\t\tdocument.body.appendChild(img)\n\t\t\t\t\tdimensions = {\n\t\t\t\t\t\tw: img.clientWidth,\n\t\t\t\t\t\th: img.clientHeight,\n\t\t\t\t\t}\n\t\t\t\t\tdocument.body.removeChild(img)\n\t\t\t\t}\n\t\t\t\tresolve({ ...dimensions, image: img })\n\t\t\t}\n\t\t\timg.onerror = (e) => {\n\t\t\t\tconsole.error(e)\n\t\t\t\treject(new Error('Could not load image'))\n\t\t\t}\n\t\t\timg.crossOrigin = 'anonymous'\n\t\t\timg.referrerPolicy = 'strict-origin-when-cross-origin'\n\t\t\timg.style.visibility = 'hidden'\n\t\t\timg.style.position = 'absolute'\n\t\t\timg.style.opacity = '0'\n\t\t\timg.style.zIndex = '-9999'\n\t\t\timg.src = src\n\t\t})\n\t}\n\n\t/**\n\t * Get the size of a video blob\n\t *\n\t * @param blob - A SharedBlob containing the video\n\t * @public\n\t */\n\tstatic async getVideoSize(blob: Blob): Promise<{ w: number; h: number }> {\n\t\treturn MediaHelpers.usingObjectURL(blob, async (url) => {\n\t\t\tconst video = await MediaHelpers.loadVideo(url)\n\t\t\treturn { w: video.videoWidth, h: video.videoHeight }\n\t\t})\n\t}\n\n\t/**\n\t * Get the size of an image blob\n\t *\n\t * @param blob - A Blob containing the image.\n\t * @public\n\t */\n\tstatic async getImageSize(blob: Blob): Promise<{ w: number; h: number }> {\n\t\tconst { w, h } = await MediaHelpers.usingObjectURL(blob, MediaHelpers.getImageAndDimensions)\n\n\t\ttry {\n\t\t\tif (blob.type === 'image/png') {\n\t\t\t\tconst view = new DataView(await blob.arrayBuffer())\n\t\t\t\tif (PngHelpers.isPng(view, 0)) {\n\t\t\t\t\tconst physChunk = PngHelpers.findChunk(view, 'pHYs')\n\t\t\t\t\tif (physChunk) {\n\t\t\t\t\t\tconst physData = PngHelpers.parsePhys(view, physChunk.dataOffset)\n\t\t\t\t\t\tif (physData.unit === 1 && physData.ppux === physData.ppuy) {\n\t\t\t\t\t\t\t// Calculate pixels per meter:\n\t\t\t\t\t\t\t// - 1 inch = 0.0254 meters\n\t\t\t\t\t\t\t// - 72 DPI is 72 dots per inch\n\t\t\t\t\t\t\t// - pixels per meter = 72 / 0.0254\n\t\t\t\t\t\t\tconst pixelsPerMeter = 72 / 0.0254\n\t\t\t\t\t\t\tconst pixelRatio = Math.max(physData.ppux / pixelsPerMeter, 1)\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tw: Math.round(w / pixelRatio),\n\t\t\t\t\t\t\t\th: Math.round(h / pixelRatio),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(err)\n\t\t\treturn { w, h }\n\t\t}\n\t\treturn { w, h }\n\t}\n\n\tstatic async isAnimated(file: Blob): Promise<boolean> {\n\t\tif (file.type === 'image/gif') {\n\t\t\treturn isGifAnimated(await file.arrayBuffer())\n\t\t}\n\n\t\tif (file.type === 'image/avif') {\n\t\t\treturn isAvifAnimated(await file.arrayBuffer())\n\t\t}\n\n\t\tif (file.type === 'image/webp') {\n\t\t\treturn isWebpAnimated(await file.arrayBuffer())\n\t\t}\n\n\t\tif (file.type === 'image/apng') {\n\t\t\treturn isApngAnimated(await file.arrayBuffer())\n\t\t}\n\n\t\treturn false\n\t}\n\n\tstatic isAnimatedImageType(mimeType: string | null): boolean {\n\t\treturn DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES.includes((mimeType as any) || '')\n\t}\n\n\tstatic isStaticImageType(mimeType: string | null): boolean {\n\t\treturn DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES.includes((mimeType as any) || '')\n\t}\n\n\tstatic isVectorImageType(mimeType: string | null): boolean {\n\t\treturn DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES.includes((mimeType as any) || '')\n\t}\n\n\tstatic isImageType(mimeType: string): boolean {\n\t\treturn DEFAULT_SUPPORTED_IMAGE_TYPES.includes((mimeType as any) || '')\n\t}\n\n\tstatic async usingObjectURL<T>(blob: Blob, fn: (url: string) => Promise<T>): Promise<T> {\n\t\tconst url = URL.createObjectURL(blob)\n\t\ttry {\n\t\t\treturn await fn(url)\n\t\t} finally {\n\t\t\tURL.revokeObjectURL(url)\n\t\t}\n\t}\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -319,7 +319,7 @@ class PngHelpers {
|
|
|
319
319
|
return {
|
|
320
320
|
ppux: view.getUint32(offset),
|
|
321
321
|
ppuy: view.getUint32(offset + 4),
|
|
322
|
-
unit: view.getUint8(offset +
|
|
322
|
+
unit: view.getUint8(offset + 8)
|
|
323
323
|
};
|
|
324
324
|
}
|
|
325
325
|
static findChunk(view, type) {
|
|
@@ -346,9 +346,9 @@ class PngHelpers {
|
|
|
346
346
|
pHYsDataView.setUint8(5, "H".charCodeAt(0));
|
|
347
347
|
pHYsDataView.setUint8(6, "Y".charCodeAt(0));
|
|
348
348
|
pHYsDataView.setUint8(7, "s".charCodeAt(0));
|
|
349
|
-
const
|
|
350
|
-
pHYsDataView.setInt32(8,
|
|
351
|
-
pHYsDataView.setInt32(12,
|
|
349
|
+
const DPI_72 = 2835.5;
|
|
350
|
+
pHYsDataView.setInt32(8, DPI_72 * dpr);
|
|
351
|
+
pHYsDataView.setInt32(12, DPI_72 * dpr);
|
|
352
352
|
pHYsDataView.setInt8(16, 1);
|
|
353
353
|
const crcBit = new Uint8Array(pHYsData.slice(4, 17));
|
|
354
354
|
pHYsDataView.setInt32(17, crc(crcBit));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/media/png.ts"],
|
|
4
|
-
"sourcesContent": ["/*!\n * MIT License: https://github.com/alexgorbatchev/crc/blob/master/LICENSE\n * Copyright: 2014 Alex Gorbatchev\n * Code: crc32, https://github.com/alexgorbatchev/crc/blob/master/src/calculators/crc32.ts\n */\n\ntype BufferInput = string | ArrayBuffer | Buffer\n\ninterface CRCCalculator<T = BufferInput | Uint8Array> {\n\t(value: T, previous?: number): number\n}\n\nlet TABLE: Array<number> | Int32Array = [\n\t0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,\n\t0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,\n\t0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\n\t0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,\n\t0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n\t0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\n\t0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,\n\t0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,\n\t0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\n\t0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n\t0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,\n\t0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\n\t0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,\n\t0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,\n\t0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n\t0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,\n\t0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,\n\t0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\n\t0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,\n\t0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n\t0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\n\t0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,\n\t0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,\n\t0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\n\t0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n\t0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,\n\t0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\n\t0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,\n\t0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,\n\t0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n\t0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,\n\t0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,\n]\n\nif (typeof Int32Array !== 'undefined') {\n\tTABLE = new Int32Array(TABLE)\n}\n\nconst crc: CRCCalculator<Uint8Array> = (current, previous) => {\n\tlet crc = previous === 0 ? 0 : ~~previous! ^ -1\n\n\tfor (let index = 0; index < current.length; index++) {\n\t\tcrc = TABLE[(crc ^ current[index]) & 0xff] ^ (crc >>> 8)\n\t}\n\n\treturn crc ^ -1\n}\n\nconst LEN_SIZE = 4\nconst CRC_SIZE = 4\n\n/** @public */\nexport class PngHelpers {\n\tstatic isPng(view: DataView, offset: number) {\n\t\tif (\n\t\t\tview.getUint8(offset + 0) === 0x89 &&\n\t\t\tview.getUint8(offset + 1) === 0x50 &&\n\t\t\tview.getUint8(offset + 2) === 0x4e &&\n\t\t\tview.getUint8(offset + 3) === 0x47 &&\n\t\t\tview.getUint8(offset + 4) === 0x0d &&\n\t\t\tview.getUint8(offset + 5) === 0x0a &&\n\t\t\tview.getUint8(offset + 6) === 0x1a &&\n\t\t\tview.getUint8(offset + 7) === 0x0a\n\t\t) {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tstatic getChunkType(view: DataView, offset: number) {\n\t\treturn [\n\t\t\tString.fromCharCode(view.getUint8(offset)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 1)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 2)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 3)),\n\t\t].join('')\n\t}\n\n\tstatic readChunks(view: DataView, offset = 0) {\n\t\tconst chunks: Record<string, { dataOffset: number; size: number; start: number }> = {}\n\t\tif (!PngHelpers.isPng(view, offset)) {\n\t\t\tthrow new Error('Not a PNG')\n\t\t}\n\t\toffset += 8\n\n\t\twhile (offset <= view.buffer.byteLength) {\n\t\t\tconst start = offset\n\t\t\tconst len = view.getInt32(offset)\n\t\t\toffset += 4\n\t\t\tconst chunkType = PngHelpers.getChunkType(view, offset)\n\n\t\t\tif (chunkType === 'IDAT' && chunks[chunkType]) {\n\t\t\t\toffset += len + LEN_SIZE + CRC_SIZE\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (chunkType === 'IEND') {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tchunks[chunkType] = {\n\t\t\t\tstart,\n\t\t\t\tdataOffset: offset + 4,\n\t\t\t\tsize: len,\n\t\t\t}\n\t\t\toffset += len + LEN_SIZE + CRC_SIZE\n\t\t}\n\n\t\treturn chunks\n\t}\n\n\tstatic parsePhys(view: DataView, offset: number) {\n\t\treturn {\n\t\t\tppux: view.getUint32(offset),\n\t\t\tppuy: view.getUint32(offset + 4),\n\t\t\tunit: view.getUint8(offset +
|
|
4
|
+
"sourcesContent": ["/*!\n * MIT License: https://github.com/alexgorbatchev/crc/blob/master/LICENSE\n * Copyright: 2014 Alex Gorbatchev\n * Code: crc32, https://github.com/alexgorbatchev/crc/blob/master/src/calculators/crc32.ts\n */\n\ntype BufferInput = string | ArrayBuffer | Buffer\n\ninterface CRCCalculator<T = BufferInput | Uint8Array> {\n\t(value: T, previous?: number): number\n}\n\nlet TABLE: Array<number> | Int32Array = [\n\t0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,\n\t0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,\n\t0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\n\t0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,\n\t0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n\t0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\n\t0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,\n\t0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,\n\t0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\n\t0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n\t0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,\n\t0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\n\t0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,\n\t0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,\n\t0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n\t0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,\n\t0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,\n\t0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\n\t0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,\n\t0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n\t0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\n\t0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,\n\t0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,\n\t0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\n\t0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n\t0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,\n\t0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\n\t0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,\n\t0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,\n\t0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n\t0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,\n\t0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,\n]\n\nif (typeof Int32Array !== 'undefined') {\n\tTABLE = new Int32Array(TABLE)\n}\n\nconst crc: CRCCalculator<Uint8Array> = (current, previous) => {\n\tlet crc = previous === 0 ? 0 : ~~previous! ^ -1\n\n\tfor (let index = 0; index < current.length; index++) {\n\t\tcrc = TABLE[(crc ^ current[index]) & 0xff] ^ (crc >>> 8)\n\t}\n\n\treturn crc ^ -1\n}\n\nconst LEN_SIZE = 4\nconst CRC_SIZE = 4\n\n/** @public */\nexport class PngHelpers {\n\tstatic isPng(view: DataView, offset: number) {\n\t\tif (\n\t\t\tview.getUint8(offset + 0) === 0x89 &&\n\t\t\tview.getUint8(offset + 1) === 0x50 &&\n\t\t\tview.getUint8(offset + 2) === 0x4e &&\n\t\t\tview.getUint8(offset + 3) === 0x47 &&\n\t\t\tview.getUint8(offset + 4) === 0x0d &&\n\t\t\tview.getUint8(offset + 5) === 0x0a &&\n\t\t\tview.getUint8(offset + 6) === 0x1a &&\n\t\t\tview.getUint8(offset + 7) === 0x0a\n\t\t) {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tstatic getChunkType(view: DataView, offset: number) {\n\t\treturn [\n\t\t\tString.fromCharCode(view.getUint8(offset)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 1)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 2)),\n\t\t\tString.fromCharCode(view.getUint8(offset + 3)),\n\t\t].join('')\n\t}\n\n\tstatic readChunks(view: DataView, offset = 0) {\n\t\tconst chunks: Record<string, { dataOffset: number; size: number; start: number }> = {}\n\t\tif (!PngHelpers.isPng(view, offset)) {\n\t\t\tthrow new Error('Not a PNG')\n\t\t}\n\t\toffset += 8\n\n\t\twhile (offset <= view.buffer.byteLength) {\n\t\t\tconst start = offset\n\t\t\tconst len = view.getInt32(offset)\n\t\t\toffset += 4\n\t\t\tconst chunkType = PngHelpers.getChunkType(view, offset)\n\n\t\t\tif (chunkType === 'IDAT' && chunks[chunkType]) {\n\t\t\t\toffset += len + LEN_SIZE + CRC_SIZE\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (chunkType === 'IEND') {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tchunks[chunkType] = {\n\t\t\t\tstart,\n\t\t\t\tdataOffset: offset + 4,\n\t\t\t\tsize: len,\n\t\t\t}\n\t\t\toffset += len + LEN_SIZE + CRC_SIZE\n\t\t}\n\n\t\treturn chunks\n\t}\n\n\tstatic parsePhys(view: DataView, offset: number) {\n\t\treturn {\n\t\t\tppux: view.getUint32(offset),\n\t\t\tppuy: view.getUint32(offset + 4),\n\t\t\tunit: view.getUint8(offset + 8),\n\t\t}\n\t}\n\n\tstatic findChunk(view: DataView, type: string) {\n\t\tconst chunks = PngHelpers.readChunks(view)\n\t\treturn chunks[type]\n\t}\n\n\tstatic setPhysChunk(view: DataView, dpr = 1, options?: BlobPropertyBag) {\n\t\tlet offset = 46\n\t\tlet size = 0\n\t\tconst res1 = PngHelpers.findChunk(view, 'pHYs')\n\t\tif (res1) {\n\t\t\toffset = res1.start\n\t\t\tsize = res1.size\n\t\t}\n\n\t\tconst res2 = PngHelpers.findChunk(view, 'IDAT')\n\t\tif (res2) {\n\t\t\toffset = res2.start\n\t\t\tsize = 0\n\t\t}\n\n\t\tconst pHYsData = new ArrayBuffer(21)\n\t\tconst pHYsDataView = new DataView(pHYsData)\n\n\t\tpHYsDataView.setUint32(0, 9)\n\n\t\tpHYsDataView.setUint8(4, 'p'.charCodeAt(0))\n\t\tpHYsDataView.setUint8(5, 'H'.charCodeAt(0))\n\t\tpHYsDataView.setUint8(6, 'Y'.charCodeAt(0))\n\t\tpHYsDataView.setUint8(7, 's'.charCodeAt(0))\n\n\t\tconst DPI_72 = 2835.5\n\n\t\tpHYsDataView.setInt32(8, DPI_72 * dpr)\n\t\tpHYsDataView.setInt32(12, DPI_72 * dpr)\n\t\tpHYsDataView.setInt8(16, 1)\n\n\t\tconst crcBit = new Uint8Array(pHYsData.slice(4, 17))\n\t\tpHYsDataView.setInt32(17, crc(crcBit))\n\n\t\tconst startBuf = view.buffer.slice(0, offset)\n\t\tconst endBuf = view.buffer.slice(offset + size)\n\n\t\treturn new Blob([startBuf as ArrayBuffer, pHYsData, endBuf as ArrayBuffer], options)\n\t}\n}\n"],
|
|
5
5
|
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,IAAI,QAAoC;AAAA,EACvC;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EACpF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",
|
|
6
6
|
"names": ["crc"]
|
|
7
7
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const generateKeysFn = process.env.NODE_ENV === "test" ? generateNKeysBetween : generateNJitteredKeysBetween;
|
|
1
|
+
import { generateKeyBetween, generateNKeysBetween } from "jittered-fractional-indexing";
|
|
2
|
+
const generateNKeysBetweenWithNoJitter = (a, b, n) => {
|
|
3
|
+
return generateNKeysBetween(a, b, n, { jitterBits: 0 });
|
|
4
|
+
};
|
|
5
|
+
const generateKeysFn = process.env.NODE_ENV === "test" ? generateNKeysBetweenWithNoJitter : generateNKeysBetween;
|
|
7
6
|
const ZERO_INDEX_KEY = "a0";
|
|
8
7
|
function validateIndexKey(index) {
|
|
9
8
|
try {
|
|
10
|
-
|
|
9
|
+
generateKeyBetween(index, null);
|
|
11
10
|
} catch {
|
|
12
11
|
throw new Error("invalid index: " + index);
|
|
13
12
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/reordering.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\
|
|
5
|
-
"mappings": "AAAA
|
|
4
|
+
"sourcesContent": ["import { generateKeyBetween, generateNKeysBetween } from 'jittered-fractional-indexing'\n\nconst generateNKeysBetweenWithNoJitter = (a: string | null, b: string | null, n: number) => {\n\treturn generateNKeysBetween(a, b, n, { jitterBits: 0 })\n}\n\nconst generateKeysFn =\n\tprocess.env.NODE_ENV === 'test' ? generateNKeysBetweenWithNoJitter : generateNKeysBetween\n\n/**\n * A string made up of an integer part followed by a fraction part. The fraction point consists of\n * zero or more digits with no trailing zeros. Based on\n * {@link https://observablehq.com/@dgreensp/implementing-fractional-indexing}.\n *\n * @public\n */\nexport type IndexKey = string & { __brand: 'indexKey' }\n\n/**\n * The index key for the first index - 'a0'.\n * @public\n */\nexport const ZERO_INDEX_KEY = 'a0' as IndexKey\n\n/** @internal */\nexport function validateIndexKey(index: string): asserts index is IndexKey {\n\ttry {\n\t\tgenerateKeyBetween(index, null)\n\t} catch {\n\t\tthrow new Error('invalid index: ' + index)\n\t}\n}\n\n/**\n * Get a number of indices between two indices.\n * @param below - The index below.\n * @param above - The index above.\n * @param n - The number of indices to get.\n * @public\n */\nexport function getIndicesBetween(\n\tbelow: IndexKey | null | undefined,\n\tabove: IndexKey | null | undefined,\n\tn: number\n) {\n\treturn generateKeysFn(below ?? null, above ?? null, n) as IndexKey[]\n}\n\n/**\n * Get a number of indices above an index.\n * @param below - The index below.\n * @param n - The number of indices to get.\n * @public\n */\nexport function getIndicesAbove(below: IndexKey | null | undefined, n: number) {\n\treturn generateKeysFn(below ?? null, null, n) as IndexKey[]\n}\n\n/**\n * Get a number of indices below an index.\n * @param above - The index above.\n * @param n - The number of indices to get.\n * @public\n */\nexport function getIndicesBelow(above: IndexKey | null | undefined, n: number) {\n\treturn generateKeysFn(null, above ?? null, n) as IndexKey[]\n}\n\n/**\n * Get the index between two indices.\n * @param below - The index below.\n * @param above - The index above.\n * @public\n */\nexport function getIndexBetween(\n\tbelow: IndexKey | null | undefined,\n\tabove: IndexKey | null | undefined\n) {\n\treturn generateKeysFn(below ?? null, above ?? null, 1)[0] as IndexKey\n}\n\n/**\n * Get the index above a given index.\n * @param below - The index below.\n * @public\n */\nexport function getIndexAbove(below: IndexKey | null | undefined = null) {\n\treturn generateKeysFn(below, null, 1)[0] as IndexKey\n}\n\n/**\n * Get the index below a given index.\n * @param above - The index above.\n * @public\n */\nexport function getIndexBelow(above: IndexKey | null | undefined = null) {\n\treturn generateKeysFn(null, above, 1)[0] as IndexKey\n}\n\n/**\n * Get n number of indices, starting at an index.\n * @param n - The number of indices to get.\n * @param start - The index to start at.\n * @public\n */\nexport function getIndices(n: number, start = 'a1' as IndexKey) {\n\treturn [start, ...generateKeysFn(start, null, n)] as IndexKey[]\n}\n\n/**\n * Sort by index.\n * @param a - An object with an index property.\n * @param b - An object with an index property.\n * @public */\nexport function sortByIndex<T extends { index: IndexKey }>(a: T, b: T) {\n\tif (a.index < b.index) {\n\t\treturn -1\n\t} else if (a.index > b.index) {\n\t\treturn 1\n\t}\n\treturn 0\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAoB,4BAA4B;AAEzD,MAAM,mCAAmC,CAAC,GAAkB,GAAkB,MAAc;AAC3F,SAAO,qBAAqB,GAAG,GAAG,GAAG,EAAE,YAAY,EAAE,CAAC;AACvD;AAEA,MAAM,iBACL,QAAQ,IAAI,aAAa,SAAS,mCAAmC;AAe/D,MAAM,iBAAiB;AAGvB,SAAS,iBAAiB,OAA0C;AAC1E,MAAI;AACH,uBAAmB,OAAO,IAAI;AAAA,EAC/B,QAAQ;AACP,UAAM,IAAI,MAAM,oBAAoB,KAAK;AAAA,EAC1C;AACD;AASO,SAAS,kBACf,OACA,OACA,GACC;AACD,SAAO,eAAe,SAAS,MAAM,SAAS,MAAM,CAAC;AACtD;AAQO,SAAS,gBAAgB,OAAoC,GAAW;AAC9E,SAAO,eAAe,SAAS,MAAM,MAAM,CAAC;AAC7C;AAQO,SAAS,gBAAgB,OAAoC,GAAW;AAC9E,SAAO,eAAe,MAAM,SAAS,MAAM,CAAC;AAC7C;AAQO,SAAS,gBACf,OACA,OACC;AACD,SAAO,eAAe,SAAS,MAAM,SAAS,MAAM,CAAC,EAAE,CAAC;AACzD;AAOO,SAAS,cAAc,QAAqC,MAAM;AACxE,SAAO,eAAe,OAAO,MAAM,CAAC,EAAE,CAAC;AACxC;AAOO,SAAS,cAAc,QAAqC,MAAM;AACxE,SAAO,eAAe,MAAM,OAAO,CAAC,EAAE,CAAC;AACxC;AAQO,SAAS,WAAW,GAAW,QAAQ,MAAkB;AAC/D,SAAO,CAAC,OAAO,GAAG,eAAe,OAAO,MAAM,CAAC,CAAC;AACjD;AAOO,SAAS,YAA2C,GAAM,GAAM;AACtE,MAAI,EAAE,QAAQ,EAAE,OAAO;AACtB,WAAO;AAAA,EACR,WAAW,EAAE,QAAQ,EAAE,OAAO;AAC7B,WAAO;AAAA,EACR;AACA,SAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/utils",
|
|
3
3
|
"description": "tldraw infinite canvas SDK (private utilities).",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"context": "yarn run -T tsx ../../internal/scripts/context.ts"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"fractional-indexing
|
|
47
|
+
"jittered-fractional-indexing": "^1.0.0",
|
|
48
48
|
"lodash.isequal": "^4.5.0",
|
|
49
49
|
"lodash.isequalwith": "^4.4.0",
|
|
50
50
|
"lodash.throttle": "^4.1.1",
|
package/src/lib/file.ts
CHANGED
|
@@ -6,15 +6,6 @@ import { fetch } from './network'
|
|
|
6
6
|
* @public
|
|
7
7
|
*/
|
|
8
8
|
export class FileHelpers {
|
|
9
|
-
/**
|
|
10
|
-
* @deprecated Use `urlToArrayBuffer` instead.
|
|
11
|
-
*/
|
|
12
|
-
static async dataUrlToArrayBuffer(dataURL: string) {
|
|
13
|
-
return fetch(dataURL).then(function (result) {
|
|
14
|
-
return result.arrayBuffer()
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
|
|
18
9
|
/**
|
|
19
10
|
* @param url - The url of the file.
|
|
20
11
|
*/
|
package/src/lib/media/media.ts
CHANGED
|
@@ -188,7 +188,7 @@ export class MediaHelpers {
|
|
|
188
188
|
const physChunk = PngHelpers.findChunk(view, 'pHYs')
|
|
189
189
|
if (physChunk) {
|
|
190
190
|
const physData = PngHelpers.parsePhys(view, physChunk.dataOffset)
|
|
191
|
-
if (physData.unit ===
|
|
191
|
+
if (physData.unit === 1 && physData.ppux === physData.ppuy) {
|
|
192
192
|
// Calculate pixels per meter:
|
|
193
193
|
// - 1 inch = 0.0254 meters
|
|
194
194
|
// - 72 DPI is 72 dots per inch
|
package/src/lib/media/png.ts
CHANGED
|
@@ -126,7 +126,7 @@ export class PngHelpers {
|
|
|
126
126
|
return {
|
|
127
127
|
ppux: view.getUint32(offset),
|
|
128
128
|
ppuy: view.getUint32(offset + 4),
|
|
129
|
-
unit: view.getUint8(offset +
|
|
129
|
+
unit: view.getUint8(offset + 8),
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -160,10 +160,10 @@ export class PngHelpers {
|
|
|
160
160
|
pHYsDataView.setUint8(6, 'Y'.charCodeAt(0))
|
|
161
161
|
pHYsDataView.setUint8(7, 's'.charCodeAt(0))
|
|
162
162
|
|
|
163
|
-
const
|
|
163
|
+
const DPI_72 = 2835.5
|
|
164
164
|
|
|
165
|
-
pHYsDataView.setInt32(8,
|
|
166
|
-
pHYsDataView.setInt32(12,
|
|
165
|
+
pHYsDataView.setInt32(8, DPI_72 * dpr)
|
|
166
|
+
pHYsDataView.setInt32(12, DPI_72 * dpr)
|
|
167
167
|
pHYsDataView.setInt8(16, 1)
|
|
168
168
|
|
|
169
169
|
const crcBit = new Uint8Array(pHYsData.slice(4, 17))
|
package/src/lib/reordering.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
generateNKeysBetween,
|
|
5
|
-
}
|
|
1
|
+
import { generateKeyBetween, generateNKeysBetween } from 'jittered-fractional-indexing'
|
|
2
|
+
|
|
3
|
+
const generateNKeysBetweenWithNoJitter = (a: string | null, b: string | null, n: number) => {
|
|
4
|
+
return generateNKeysBetween(a, b, n, { jitterBits: 0 })
|
|
5
|
+
}
|
|
6
6
|
|
|
7
7
|
const generateKeysFn =
|
|
8
|
-
process.env.NODE_ENV === 'test' ?
|
|
8
|
+
process.env.NODE_ENV === 'test' ? generateNKeysBetweenWithNoJitter : generateNKeysBetween
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* A string made up of an integer part followed by a fraction part. The fraction point consists of
|
|
@@ -25,7 +25,7 @@ export const ZERO_INDEX_KEY = 'a0' as IndexKey
|
|
|
25
25
|
/** @internal */
|
|
26
26
|
export function validateIndexKey(index: string): asserts index is IndexKey {
|
|
27
27
|
try {
|
|
28
|
-
|
|
28
|
+
generateKeyBetween(index, null)
|
|
29
29
|
} catch {
|
|
30
30
|
throw new Error('invalid index: ' + index)
|
|
31
31
|
}
|