1184 lines
37 KiB
JavaScript
1184 lines
37 KiB
JavaScript
import { H as RemoteImageNotAllowed, N as NoImageMetadata, Z as AstroError, u as FailedToFetchRemoteImageDimensions } from "./errors-data_zYnyWRO_.mjs";
|
||
//#region node_modules/@astrojs/internal-helpers/dist/remote.js
|
||
function matchPattern(url, remotePattern) {
|
||
return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true);
|
||
}
|
||
function matchPort(url, port) {
|
||
return !port || port === url.port;
|
||
}
|
||
function matchProtocol(url, protocol) {
|
||
return !protocol || protocol === url.protocol.slice(0, -1);
|
||
}
|
||
function matchHostname(url, hostname, allowWildcard = false) {
|
||
if (!hostname) return true;
|
||
else if (!allowWildcard || !hostname.startsWith("*")) return hostname === url.hostname;
|
||
else if (hostname.startsWith("**.")) {
|
||
const slicedHostname = hostname.slice(2);
|
||
return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname);
|
||
} else if (hostname.startsWith("*.")) {
|
||
const slicedHostname = hostname.slice(1);
|
||
if (!url.hostname.endsWith(slicedHostname)) return false;
|
||
const subdomainWithDot = url.hostname.slice(0, -(slicedHostname.length - 1));
|
||
return subdomainWithDot.endsWith(".") && !subdomainWithDot.slice(0, -1).includes(".");
|
||
}
|
||
return false;
|
||
}
|
||
function matchPathname(url, pathname, allowWildcard = false) {
|
||
if (!pathname) return true;
|
||
else if (!allowWildcard || !pathname.endsWith("*")) return pathname === url.pathname;
|
||
else if (pathname.endsWith("/**")) {
|
||
const slicedPathname = pathname.slice(0, -2);
|
||
return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname);
|
||
} else if (pathname.endsWith("/*")) {
|
||
const slicedPathname = pathname.slice(0, -1);
|
||
if (!url.pathname.startsWith(slicedPathname)) return false;
|
||
return url.pathname.slice(slicedPathname.length).split("/").filter(Boolean).length === 1;
|
||
}
|
||
return false;
|
||
}
|
||
function isRemoteAllowed(src, { domains, remotePatterns }) {
|
||
if (!URL.canParse(src)) return false;
|
||
const url = new URL(src);
|
||
if (![
|
||
"http:",
|
||
"https:",
|
||
"data:"
|
||
].includes(url.protocol)) return false;
|
||
return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern));
|
||
}
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/utils.js
|
||
var decoder = new TextDecoder();
|
||
var toUTF8String = (input, start = 0, end = input.length) => decoder.decode(input.slice(start, end));
|
||
var toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo + `0${i.toString(16)}`.slice(-2), "");
|
||
var getView = (input, offset) => new DataView(input.buffer, input.byteOffset + offset);
|
||
var readInt16LE = (input, offset = 0) => getView(input, offset).getInt16(0, true);
|
||
var readUInt16BE = (input, offset = 0) => getView(input, offset).getUint16(0, false);
|
||
var readUInt16LE = (input, offset = 0) => getView(input, offset).getUint16(0, true);
|
||
var readUInt24LE = (input, offset = 0) => {
|
||
const view = getView(input, offset);
|
||
return view.getUint16(0, true) + (view.getUint8(2) << 16);
|
||
};
|
||
var readInt32LE = (input, offset = 0) => getView(input, offset).getInt32(0, true);
|
||
var readUInt32BE = (input, offset = 0) => getView(input, offset).getUint32(0, false);
|
||
var readUInt32LE = (input, offset = 0) => getView(input, offset).getUint32(0, true);
|
||
var readUInt64 = (input, offset, isBigEndian) => getView(input, offset).getBigUint64(0, !isBigEndian);
|
||
var methods = {
|
||
readUInt16BE,
|
||
readUInt16LE,
|
||
readUInt32BE,
|
||
readUInt32LE
|
||
};
|
||
function readUInt(input, bits, offset = 0, isBigEndian = false) {
|
||
return methods[`readUInt${bits}${isBigEndian ? "BE" : "LE"}`](input, offset);
|
||
}
|
||
var MIN_BOX_HEADER = 8;
|
||
function readBox(input, offset) {
|
||
if (input.length - offset < MIN_BOX_HEADER) return;
|
||
const boxSize = readUInt32BE(input, offset);
|
||
if (boxSize === 0) return {
|
||
name: toUTF8String(input, offset + 4, offset + 8),
|
||
offset,
|
||
size: input.length - offset
|
||
};
|
||
if (boxSize === 1) return;
|
||
if (boxSize < MIN_BOX_HEADER) return;
|
||
if (input.length - offset < boxSize) return;
|
||
return {
|
||
name: toUTF8String(input, offset + 4, offset + 8),
|
||
offset,
|
||
size: boxSize
|
||
};
|
||
}
|
||
function findBox(input, boxName, startOffset) {
|
||
let offset = startOffset;
|
||
while (offset < input.length) {
|
||
const box = readBox(input, offset);
|
||
if (!box) break;
|
||
if (box.name === boxName) return box;
|
||
if (box.size < MIN_BOX_HEADER) break;
|
||
const nextOffset = offset + box.size;
|
||
if (nextOffset <= offset) break;
|
||
offset = nextOffset;
|
||
}
|
||
}
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/bmp.js
|
||
var BMP = {
|
||
validate: (input) => toUTF8String(input, 0, 2) === "BM",
|
||
calculate: (input) => ({
|
||
height: Math.abs(readInt32LE(input, 22)),
|
||
width: readUInt32LE(input, 18)
|
||
})
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/ico.js
|
||
var TYPE_ICON = 1;
|
||
var SIZE_HEADER$1 = 6;
|
||
var SIZE_IMAGE_ENTRY = 16;
|
||
function getSizeFromOffset(input, offset) {
|
||
const value = input[offset];
|
||
return value === 0 ? 256 : value;
|
||
}
|
||
function getImageSize$1(input, imageIndex) {
|
||
const offset = SIZE_HEADER$1 + imageIndex * SIZE_IMAGE_ENTRY;
|
||
return {
|
||
height: getSizeFromOffset(input, offset + 1),
|
||
width: getSizeFromOffset(input, offset)
|
||
};
|
||
}
|
||
var ICO = {
|
||
validate(input) {
|
||
const reserved = readUInt16LE(input, 0);
|
||
const imageCount = readUInt16LE(input, 4);
|
||
if (reserved !== 0 || imageCount === 0) return false;
|
||
return readUInt16LE(input, 2) === TYPE_ICON;
|
||
},
|
||
calculate(input) {
|
||
const nbImages = readUInt16LE(input, 4);
|
||
const imageSize = getImageSize$1(input, 0);
|
||
if (nbImages === 1) return imageSize;
|
||
const images = [];
|
||
for (let imageIndex = 0; imageIndex < nbImages; imageIndex += 1) images.push(getImageSize$1(input, imageIndex));
|
||
return {
|
||
width: imageSize.width,
|
||
height: imageSize.height,
|
||
images
|
||
};
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/cur.js
|
||
var TYPE_CURSOR = 2;
|
||
var CUR = {
|
||
validate(input) {
|
||
const reserved = readUInt16LE(input, 0);
|
||
const imageCount = readUInt16LE(input, 4);
|
||
if (reserved !== 0 || imageCount === 0) return false;
|
||
return readUInt16LE(input, 2) === TYPE_CURSOR;
|
||
},
|
||
calculate: (input) => ICO.calculate(input)
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/dds.js
|
||
var DDS = {
|
||
validate: (input) => readUInt32LE(input, 0) === 542327876,
|
||
calculate: (input) => ({
|
||
height: readUInt32LE(input, 12),
|
||
width: readUInt32LE(input, 16)
|
||
})
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/gif.js
|
||
var gifRegexp = /^GIF8[79]a/;
|
||
var GIF = {
|
||
validate: (input) => gifRegexp.test(toUTF8String(input, 0, 6)),
|
||
calculate: (input) => ({
|
||
height: readUInt16LE(input, 8),
|
||
width: readUInt16LE(input, 6)
|
||
})
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/heif.js
|
||
var brandMap = {
|
||
avif: "avif",
|
||
avis: "avif",
|
||
mif1: "heif",
|
||
msf1: "heif",
|
||
heic: "heic",
|
||
heix: "heic",
|
||
hevc: "heic",
|
||
hevx: "heic"
|
||
};
|
||
function detectType(input, start, end) {
|
||
let hasAvif = false;
|
||
let hasHeic = false;
|
||
let hasHeif = false;
|
||
for (let i = start; i <= end; i += 4) {
|
||
const brand = toUTF8String(input, i, i + 4);
|
||
if (brand === "avif" || brand === "avis") hasAvif = true;
|
||
else if (brand === "heic" || brand === "heix" || brand === "hevc" || brand === "hevx") hasHeic = true;
|
||
else if (brand === "mif1" || brand === "msf1") hasHeif = true;
|
||
}
|
||
if (hasAvif) return "avif";
|
||
if (hasHeic) return "heic";
|
||
if (hasHeif) return "heif";
|
||
}
|
||
var HEIF = {
|
||
validate(input) {
|
||
if (toUTF8String(input, 4, 8) !== "ftyp") return false;
|
||
const ftypBox = findBox(input, "ftyp", 0);
|
||
if (!ftypBox) return false;
|
||
return toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12) in brandMap;
|
||
},
|
||
calculate(input) {
|
||
const metaBox = findBox(input, "meta", 0);
|
||
const iprpBox = metaBox && findBox(input, "iprp", metaBox.offset + 12);
|
||
const ipcoBox = iprpBox && findBox(input, "ipco", iprpBox.offset + 8);
|
||
if (!ipcoBox) throw new TypeError("Invalid HEIF, no ipco box found");
|
||
const type = detectType(input, 8, metaBox.offset);
|
||
const images = [];
|
||
let currentOffset = ipcoBox.offset + 8;
|
||
const ipcoEnd = ipcoBox.offset + ipcoBox.size;
|
||
while (currentOffset < ipcoEnd) {
|
||
const ispeBox = findBox(input, "ispe", currentOffset);
|
||
if (!ispeBox) break;
|
||
if (ispeBox.size < 8) break;
|
||
if (ispeBox.offset + ispeBox.size > ipcoEnd) break;
|
||
const rawWidth = readUInt32BE(input, ispeBox.offset + 12);
|
||
const rawHeight = readUInt32BE(input, ispeBox.offset + 16);
|
||
const clapBox = findBox(input, "clap", currentOffset);
|
||
let width = rawWidth;
|
||
let height = rawHeight;
|
||
if (clapBox && clapBox.offset < ipcoEnd && clapBox.size >= 8) width = rawWidth - readUInt32BE(input, clapBox.offset + 12);
|
||
images.push({
|
||
height,
|
||
width
|
||
});
|
||
const nextOffset = ispeBox.offset + ispeBox.size;
|
||
if (nextOffset <= currentOffset) break;
|
||
currentOffset = nextOffset;
|
||
}
|
||
if (images.length === 0) throw new TypeError("Invalid HEIF, no sizes found");
|
||
return {
|
||
width: images[0].width,
|
||
height: images[0].height,
|
||
type,
|
||
...images.length > 1 ? { images } : {}
|
||
};
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/icns.js
|
||
var SIZE_HEADER = 8;
|
||
var FILE_LENGTH_OFFSET = 4;
|
||
var MIN_ENTRY_LENGTH = 8;
|
||
var ENTRY_LENGTH_OFFSET = 4;
|
||
var ICON_TYPE_SIZE = {
|
||
ICON: 32,
|
||
"ICN#": 32,
|
||
"icm#": 16,
|
||
icm4: 16,
|
||
icm8: 16,
|
||
"ics#": 16,
|
||
ics4: 16,
|
||
ics8: 16,
|
||
is32: 16,
|
||
s8mk: 16,
|
||
icp4: 16,
|
||
icl4: 32,
|
||
icl8: 32,
|
||
il32: 32,
|
||
l8mk: 32,
|
||
icp5: 32,
|
||
ic11: 32,
|
||
ich4: 48,
|
||
ich8: 48,
|
||
ih32: 48,
|
||
h8mk: 48,
|
||
icp6: 64,
|
||
ic12: 32,
|
||
it32: 128,
|
||
t8mk: 128,
|
||
ic07: 128,
|
||
ic08: 256,
|
||
ic13: 256,
|
||
ic09: 512,
|
||
ic14: 512,
|
||
ic10: 1024
|
||
};
|
||
function readImageHeader(input, imageOffset) {
|
||
const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET;
|
||
return [toUTF8String(input, imageOffset, imageLengthOffset), readUInt32BE(input, imageLengthOffset)];
|
||
}
|
||
function getImageSize(type) {
|
||
const size = ICON_TYPE_SIZE[type];
|
||
return {
|
||
width: size,
|
||
height: size,
|
||
type
|
||
};
|
||
}
|
||
var ICNS = {
|
||
validate: (input) => toUTF8String(input, 0, 4) === "icns",
|
||
calculate(input) {
|
||
const inputLength = input.length;
|
||
const fileLength = readUInt32BE(input, FILE_LENGTH_OFFSET);
|
||
let imageOffset = SIZE_HEADER;
|
||
const images = [];
|
||
while (imageOffset < fileLength && imageOffset < inputLength) {
|
||
if (inputLength - imageOffset < MIN_ENTRY_LENGTH) break;
|
||
const imageHeader = readImageHeader(input, imageOffset);
|
||
const entryLength = imageHeader[1];
|
||
if (entryLength < MIN_ENTRY_LENGTH) break;
|
||
const imageSize = getImageSize(imageHeader[0]);
|
||
if (imageSize.width && imageSize.height) images.push(imageSize);
|
||
const nextOffset = imageOffset + entryLength;
|
||
if (nextOffset <= imageOffset) break;
|
||
imageOffset = nextOffset;
|
||
}
|
||
if (images.length === 0) throw new TypeError("Invalid ICNS, no sizes found");
|
||
return {
|
||
width: images[0].width,
|
||
height: images[0].height,
|
||
...images.length > 1 ? { images } : {}
|
||
};
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/j2c.js
|
||
var J2C = {
|
||
validate: (input) => readUInt32BE(input, 0) === 4283432785,
|
||
calculate: (input) => ({
|
||
height: readUInt32BE(input, 12),
|
||
width: readUInt32BE(input, 8)
|
||
})
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/jp2.js
|
||
var JP2 = {
|
||
validate(input) {
|
||
if (toUTF8String(input, 4, 8) !== "jP ") return false;
|
||
const ftypBox = findBox(input, "ftyp", 0);
|
||
if (!ftypBox) return false;
|
||
return toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12) === "jp2 ";
|
||
},
|
||
calculate(input) {
|
||
const jp2hBox = findBox(input, "jp2h", 0);
|
||
const ihdrBox = jp2hBox && jp2hBox.size >= 8 && findBox(input, "ihdr", jp2hBox.offset + 8);
|
||
if (ihdrBox && ihdrBox.size >= 8) return {
|
||
height: readUInt32BE(input, ihdrBox.offset + 8),
|
||
width: readUInt32BE(input, ihdrBox.offset + 12)
|
||
};
|
||
throw new TypeError("Unsupported JPEG 2000 format");
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/jpg.js
|
||
var EXIF_MARKER = "45786966";
|
||
var APP1_DATA_SIZE_BYTES = 2;
|
||
var EXIF_HEADER_BYTES = 6;
|
||
var BIG_ENDIAN_BYTE_ALIGN = "4d4d";
|
||
var LITTLE_ENDIAN_BYTE_ALIGN = "4949";
|
||
var IDF_ENTRY_BYTES = 12;
|
||
function isEXIF(input) {
|
||
return toHexString(input, 2, 6) === EXIF_MARKER;
|
||
}
|
||
function extractSize(input, index) {
|
||
return {
|
||
height: readUInt16BE(input, index),
|
||
width: readUInt16BE(input, index + 2)
|
||
};
|
||
}
|
||
function extractOrientation(exifBlock, isBigEndian) {
|
||
const idfDirectoryEntries = readUInt(exifBlock, 16, 14, isBigEndian);
|
||
for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) {
|
||
const start = 16 + directoryEntryNumber * IDF_ENTRY_BYTES;
|
||
const end = start + IDF_ENTRY_BYTES;
|
||
if (start > exifBlock.length) return;
|
||
const block = exifBlock.slice(start, end);
|
||
if (readUInt(block, 16, 0, isBigEndian) === 274) {
|
||
if (readUInt(block, 16, 2, isBigEndian) !== 3) return;
|
||
if (readUInt(block, 32, 4, isBigEndian) !== 1) return;
|
||
return readUInt(block, 16, 8, isBigEndian);
|
||
}
|
||
}
|
||
}
|
||
function validateExifBlock(input, index) {
|
||
const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index);
|
||
const byteAlign = toHexString(exifBlock, EXIF_HEADER_BYTES, 8);
|
||
const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN;
|
||
if (isBigEndian || byteAlign === LITTLE_ENDIAN_BYTE_ALIGN) return extractOrientation(exifBlock, isBigEndian);
|
||
}
|
||
function validateInput(input, index) {
|
||
if (index > input.length) throw new TypeError("Corrupt JPG, exceeded buffer limits");
|
||
}
|
||
var JPG = {
|
||
validate: (input) => toHexString(input, 0, 2) === "ffd8",
|
||
calculate(_input) {
|
||
let input = _input.slice(4);
|
||
let orientation;
|
||
let next;
|
||
while (input.length) {
|
||
const i = readUInt16BE(input, 0);
|
||
validateInput(input, i);
|
||
if (input[i] !== 255) {
|
||
input = input.slice(1);
|
||
continue;
|
||
}
|
||
if (isEXIF(input)) orientation = validateExifBlock(input, i);
|
||
next = input[i + 1];
|
||
if (next === 192 || next === 193 || next === 194) {
|
||
const size = extractSize(input, i + 5);
|
||
if (!orientation) return size;
|
||
return {
|
||
height: size.height,
|
||
orientation,
|
||
width: size.width
|
||
};
|
||
}
|
||
input = input.slice(i + 2);
|
||
}
|
||
throw new TypeError("Invalid JPG, no size found");
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/utils/bit-reader.js
|
||
var BitReader = class {
|
||
byteOffset = 2;
|
||
bitOffset = 0;
|
||
input;
|
||
endianness;
|
||
constructor(input, endianness) {
|
||
this.input = input;
|
||
this.endianness = endianness;
|
||
}
|
||
/** Reads a specified number of bits, and move the offset */
|
||
getBits(length = 1) {
|
||
let result = 0;
|
||
let bitsRead = 0;
|
||
while (bitsRead < length) {
|
||
if (this.byteOffset >= this.input.length) throw new Error("Reached end of input");
|
||
const currentByte = this.input[this.byteOffset];
|
||
const bitsLeft = 8 - this.bitOffset;
|
||
const bitsToRead = Math.min(length - bitsRead, bitsLeft);
|
||
if (this.endianness === "little-endian") {
|
||
const mask = (1 << bitsToRead) - 1;
|
||
const bits = currentByte >> this.bitOffset & mask;
|
||
result |= bits << bitsRead;
|
||
} else {
|
||
const bits = (currentByte & (1 << bitsToRead) - 1 << 8 - this.bitOffset - bitsToRead) >> 8 - this.bitOffset - bitsToRead;
|
||
result = result << bitsToRead | bits;
|
||
}
|
||
bitsRead += bitsToRead;
|
||
this.bitOffset += bitsToRead;
|
||
if (this.bitOffset === 8) {
|
||
this.byteOffset++;
|
||
this.bitOffset = 0;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/jxl-stream.js
|
||
function calculateImageDimension(reader, isSmallImage) {
|
||
if (isSmallImage) return 8 * (1 + reader.getBits(5));
|
||
const extraBits = [
|
||
9,
|
||
13,
|
||
18,
|
||
30
|
||
][reader.getBits(2)];
|
||
return 1 + reader.getBits(extraBits);
|
||
}
|
||
function calculateImageWidth(reader, isSmallImage, widthMode, height) {
|
||
if (isSmallImage && widthMode === 0) return 8 * (1 + reader.getBits(5));
|
||
if (widthMode === 0) return calculateImageDimension(reader, false);
|
||
return Math.floor(height * [
|
||
1,
|
||
1.2,
|
||
4 / 3,
|
||
1.5,
|
||
16 / 9,
|
||
5 / 4,
|
||
2
|
||
][widthMode - 1]);
|
||
}
|
||
var JXLStream = {
|
||
validate: (input) => {
|
||
return toHexString(input, 0, 2) === "ff0a";
|
||
},
|
||
calculate(input) {
|
||
const reader = new BitReader(input, "little-endian");
|
||
const isSmallImage = reader.getBits(1) === 1;
|
||
const height = calculateImageDimension(reader, isSmallImage);
|
||
return {
|
||
width: calculateImageWidth(reader, isSmallImage, reader.getBits(3), height),
|
||
height
|
||
};
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/jxl.js
|
||
function extractCodestream(input) {
|
||
const jxlcBox = findBox(input, "jxlc", 0);
|
||
if (jxlcBox && jxlcBox.size >= 8) return input.slice(jxlcBox.offset + 8, jxlcBox.offset + jxlcBox.size);
|
||
const partialStreams = extractPartialStreams(input);
|
||
if (partialStreams.length > 0) return concatenateCodestreams(partialStreams);
|
||
}
|
||
function extractPartialStreams(input) {
|
||
const partialStreams = [];
|
||
let offset = 0;
|
||
while (offset < input.length) {
|
||
const jxlpBox = findBox(input, "jxlp", offset);
|
||
if (!jxlpBox) break;
|
||
if (jxlpBox.size < 12) break;
|
||
partialStreams.push(input.slice(jxlpBox.offset + 12, jxlpBox.offset + jxlpBox.size));
|
||
const nextOffset = jxlpBox.offset + jxlpBox.size;
|
||
if (nextOffset <= offset) break;
|
||
offset = nextOffset;
|
||
}
|
||
return partialStreams;
|
||
}
|
||
function concatenateCodestreams(partialCodestreams) {
|
||
const totalLength = partialCodestreams.reduce((acc, curr) => acc + curr.length, 0);
|
||
const codestream = new Uint8Array(totalLength);
|
||
let position = 0;
|
||
for (const partial of partialCodestreams) {
|
||
codestream.set(partial, position);
|
||
position += partial.length;
|
||
}
|
||
return codestream;
|
||
}
|
||
var JXL = {
|
||
validate: (input) => {
|
||
if (toUTF8String(input, 4, 8) !== "JXL ") return false;
|
||
const ftypBox = findBox(input, "ftyp", 0);
|
||
if (!ftypBox) return false;
|
||
return toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12) === "jxl ";
|
||
},
|
||
calculate(input) {
|
||
const codestream = extractCodestream(input);
|
||
if (codestream) return JXLStream.calculate(codestream);
|
||
throw new Error("No codestream found in JXL container");
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/ktx.js
|
||
var KTX = {
|
||
validate: (input) => {
|
||
const signature = toUTF8String(input, 1, 7);
|
||
return ["KTX 11", "KTX 20"].includes(signature);
|
||
},
|
||
calculate: (input) => {
|
||
const type = input[5] === 49 ? "ktx" : "ktx2";
|
||
const offset = type === "ktx" ? 36 : 20;
|
||
return {
|
||
height: readUInt32LE(input, offset + 4),
|
||
width: readUInt32LE(input, offset),
|
||
type
|
||
};
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/png.js
|
||
var pngSignature = "PNG\r\n\n";
|
||
var pngImageHeaderChunkName = "IHDR";
|
||
var pngFriedChunkName = "CgBI";
|
||
var PNG = {
|
||
validate(input) {
|
||
if (pngSignature === toUTF8String(input, 1, 8)) {
|
||
let chunkName = toUTF8String(input, 12, 16);
|
||
if (chunkName === pngFriedChunkName) chunkName = toUTF8String(input, 28, 32);
|
||
if (chunkName !== pngImageHeaderChunkName) throw new TypeError("Invalid PNG");
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
calculate(input) {
|
||
if (toUTF8String(input, 12, 16) === pngFriedChunkName) return {
|
||
height: readUInt32BE(input, 36),
|
||
width: readUInt32BE(input, 32)
|
||
};
|
||
return {
|
||
height: readUInt32BE(input, 20),
|
||
width: readUInt32BE(input, 16)
|
||
};
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/pnm.js
|
||
var PNMTypes = {
|
||
P1: "pbm/ascii",
|
||
P2: "pgm/ascii",
|
||
P3: "ppm/ascii",
|
||
P4: "pbm",
|
||
P5: "pgm",
|
||
P6: "ppm",
|
||
P7: "pam",
|
||
PF: "pfm"
|
||
};
|
||
var handlers = {
|
||
default: (lines) => {
|
||
let dimensions = [];
|
||
while (lines.length > 0) {
|
||
const line = lines.shift();
|
||
if (line[0] === "#") continue;
|
||
dimensions = line.split(" ");
|
||
break;
|
||
}
|
||
if (dimensions.length === 2) return {
|
||
height: Number.parseInt(dimensions[1], 10),
|
||
width: Number.parseInt(dimensions[0], 10)
|
||
};
|
||
throw new TypeError("Invalid PNM");
|
||
},
|
||
pam: (lines) => {
|
||
const size = {};
|
||
while (lines.length > 0) {
|
||
const line = lines.shift();
|
||
if (line.length > 16 || line.charCodeAt(0) > 128) continue;
|
||
const [key, value] = line.split(" ");
|
||
if (key && value) size[key.toLowerCase()] = Number.parseInt(value, 10);
|
||
if (size.height && size.width) break;
|
||
}
|
||
if (size.height && size.width) return {
|
||
height: size.height,
|
||
width: size.width
|
||
};
|
||
throw new TypeError("Invalid PAM");
|
||
}
|
||
};
|
||
var PNM = {
|
||
validate: (input) => toUTF8String(input, 0, 2) in PNMTypes,
|
||
calculate(input) {
|
||
const type = PNMTypes[toUTF8String(input, 0, 2)];
|
||
const lines = toUTF8String(input, 3).split(/[\r\n]+/);
|
||
return (handlers[type] || handlers.default)(lines);
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/psd.js
|
||
var PSD = {
|
||
validate: (input) => toUTF8String(input, 0, 4) === "8BPS",
|
||
calculate: (input) => ({
|
||
height: readUInt32BE(input, 14),
|
||
width: readUInt32BE(input, 18)
|
||
})
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/svg.js
|
||
var svgReg = /<svg\s([^>"']|"[^"]*"|'[^']*')*>/;
|
||
var extractorRegExps = {
|
||
height: /\sheight=(['"])([^%]+?)\1/,
|
||
root: svgReg,
|
||
viewbox: /\sviewBox=(['"])(.+?)\1/i,
|
||
width: /\swidth=(['"])([^%]+?)\1/
|
||
};
|
||
var INCH_CM = 2.54;
|
||
var units = {
|
||
in: 96,
|
||
cm: 96 / INCH_CM,
|
||
em: 16,
|
||
ex: 8,
|
||
m: 96 / INCH_CM * 100,
|
||
mm: 96 / INCH_CM / 10,
|
||
pc: 96 / 72 / 12,
|
||
pt: 96 / 72,
|
||
px: 1
|
||
};
|
||
var unitsReg = new RegExp(`^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join("|")})?$`);
|
||
function parseLength(len) {
|
||
const m = unitsReg.exec(len);
|
||
if (!m) return;
|
||
return Math.round(Number(m[1]) * (units[m[2]] || 1));
|
||
}
|
||
function parseViewbox(viewbox) {
|
||
const bounds = viewbox.split(" ");
|
||
return {
|
||
height: parseLength(bounds[3]),
|
||
width: parseLength(bounds[2])
|
||
};
|
||
}
|
||
function parseAttributes(root) {
|
||
const width = extractorRegExps.width.exec(root);
|
||
const height = extractorRegExps.height.exec(root);
|
||
const viewbox = extractorRegExps.viewbox.exec(root);
|
||
return {
|
||
height: height && parseLength(height[2]),
|
||
viewbox: viewbox && parseViewbox(viewbox[2]),
|
||
width: width && parseLength(width[2])
|
||
};
|
||
}
|
||
function calculateByDimensions(attrs) {
|
||
return {
|
||
height: attrs.height,
|
||
width: attrs.width
|
||
};
|
||
}
|
||
function calculateByViewbox(attrs, viewbox) {
|
||
const ratio = viewbox.width / viewbox.height;
|
||
if (attrs.width) return {
|
||
height: Math.floor(attrs.width / ratio),
|
||
width: attrs.width
|
||
};
|
||
if (attrs.height) return {
|
||
height: attrs.height,
|
||
width: Math.floor(attrs.height * ratio)
|
||
};
|
||
return {
|
||
height: viewbox.height,
|
||
width: viewbox.width
|
||
};
|
||
}
|
||
var SVG = {
|
||
validate: (input) => svgReg.test(toUTF8String(input, 0, 1e3)),
|
||
calculate(input) {
|
||
const root = extractorRegExps.root.exec(toUTF8String(input));
|
||
if (root) {
|
||
const attrs = parseAttributes(root[0]);
|
||
if (attrs.width != null && attrs.height != null) return calculateByDimensions(attrs);
|
||
if (attrs.viewbox) return calculateByViewbox(attrs, attrs.viewbox);
|
||
}
|
||
throw new TypeError("Invalid SVG");
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/tga.js
|
||
var TGA = {
|
||
validate(input) {
|
||
return readUInt16LE(input, 0) === 0 && readUInt16LE(input, 4) === 0;
|
||
},
|
||
calculate(input) {
|
||
return {
|
||
height: readUInt16LE(input, 14),
|
||
width: readUInt16LE(input, 12)
|
||
};
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/tiff.js
|
||
var CONSTANTS = {
|
||
TAG: {
|
||
WIDTH: 256,
|
||
HEIGHT: 257,
|
||
COMPRESSION: 259
|
||
},
|
||
TYPE: {
|
||
SHORT: 3,
|
||
LONG: 4,
|
||
LONG8: 16
|
||
},
|
||
ENTRY_SIZE: {
|
||
STANDARD: 12,
|
||
BIG: 20
|
||
},
|
||
COUNT_SIZE: {
|
||
STANDARD: 2,
|
||
BIG: 8
|
||
}
|
||
};
|
||
function readIFD(input, { isBigEndian, isBigTiff }) {
|
||
const ifdOffset = isBigTiff ? Number(readUInt64(input, 8, isBigEndian)) : readUInt(input, 32, 4, isBigEndian);
|
||
const entryCountSize = isBigTiff ? CONSTANTS.COUNT_SIZE.BIG : CONSTANTS.COUNT_SIZE.STANDARD;
|
||
return input.slice(ifdOffset + entryCountSize);
|
||
}
|
||
function readTagValue(input, type, offset, isBigEndian) {
|
||
switch (type) {
|
||
case CONSTANTS.TYPE.SHORT: return readUInt(input, 16, offset, isBigEndian);
|
||
case CONSTANTS.TYPE.LONG: return readUInt(input, 32, offset, isBigEndian);
|
||
case CONSTANTS.TYPE.LONG8: {
|
||
const value = Number(readUInt64(input, offset, isBigEndian));
|
||
if (value > Number.MAX_SAFE_INTEGER) throw new TypeError("Value too large");
|
||
return value;
|
||
}
|
||
default: return 0;
|
||
}
|
||
}
|
||
function nextTag(input, isBigTiff) {
|
||
const entrySize = isBigTiff ? CONSTANTS.ENTRY_SIZE.BIG : CONSTANTS.ENTRY_SIZE.STANDARD;
|
||
if (input.length > entrySize) return input.slice(entrySize);
|
||
}
|
||
function extractTags(input, { isBigEndian, isBigTiff }) {
|
||
const tags = {};
|
||
let temp = input;
|
||
while (temp?.length) {
|
||
const code = readUInt(temp, 16, 0, isBigEndian);
|
||
const type = readUInt(temp, 16, 2, isBigEndian);
|
||
const length = isBigTiff ? Number(readUInt64(temp, 4, isBigEndian)) : readUInt(temp, 32, 4, isBigEndian);
|
||
if (code === 0) break;
|
||
if (length === 1 && (type === CONSTANTS.TYPE.SHORT || type === CONSTANTS.TYPE.LONG || isBigTiff && type === CONSTANTS.TYPE.LONG8)) tags[code] = readTagValue(temp, type, isBigTiff ? 12 : 8, isBigEndian);
|
||
temp = nextTag(temp, isBigTiff);
|
||
}
|
||
return tags;
|
||
}
|
||
function determineFormat(input) {
|
||
const signature = toUTF8String(input, 0, 2);
|
||
const version = readUInt(input, 16, 2, signature === "MM");
|
||
return {
|
||
isBigEndian: signature === "MM",
|
||
isBigTiff: version === 43
|
||
};
|
||
}
|
||
function validateBigTIFFHeader(input, isBigEndian) {
|
||
const byteSize = readUInt(input, 16, 4, isBigEndian);
|
||
const reserved = readUInt(input, 16, 6, isBigEndian);
|
||
if (byteSize !== 8 || reserved !== 0) throw new TypeError("Invalid BigTIFF header");
|
||
}
|
||
var signatures = /* @__PURE__ */ new Set([
|
||
"49492a00",
|
||
"4d4d002a",
|
||
"49492b00",
|
||
"4d4d002b"
|
||
]);
|
||
var TIFF = {
|
||
validate: (input) => {
|
||
const signature = toHexString(input, 0, 4);
|
||
return signatures.has(signature);
|
||
},
|
||
calculate(input) {
|
||
const format = determineFormat(input);
|
||
if (format.isBigTiff) validateBigTIFFHeader(input, format.isBigEndian);
|
||
const tags = extractTags(readIFD(input, format), format);
|
||
const info = {
|
||
height: tags[CONSTANTS.TAG.HEIGHT],
|
||
width: tags[CONSTANTS.TAG.WIDTH],
|
||
type: format.isBigTiff ? "bigtiff" : "tiff"
|
||
};
|
||
if (tags[CONSTANTS.TAG.COMPRESSION]) info.compression = tags[CONSTANTS.TAG.COMPRESSION];
|
||
if (!info.width || !info.height) throw new TypeError("Invalid Tiff. Missing tags");
|
||
return info;
|
||
}
|
||
};
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/webp.js
|
||
function calculateExtended(input) {
|
||
return {
|
||
height: 1 + readUInt24LE(input, 7),
|
||
width: 1 + readUInt24LE(input, 4)
|
||
};
|
||
}
|
||
function calculateLossless(input) {
|
||
return {
|
||
height: 1 + ((input[4] & 15) << 10 | input[3] << 2 | (input[2] & 192) >> 6),
|
||
width: 1 + ((input[2] & 63) << 8 | input[1])
|
||
};
|
||
}
|
||
function calculateLossy(input) {
|
||
return {
|
||
height: readInt16LE(input, 8) & 16383,
|
||
width: readInt16LE(input, 6) & 16383
|
||
};
|
||
}
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/types/index.js
|
||
var typeHandlers = /* @__PURE__ */ new Map([
|
||
["bmp", BMP],
|
||
["cur", CUR],
|
||
["dds", DDS],
|
||
["gif", GIF],
|
||
["heif", HEIF],
|
||
["icns", ICNS],
|
||
["ico", ICO],
|
||
["j2c", J2C],
|
||
["jp2", JP2],
|
||
["jpg", JPG],
|
||
["jxl", JXL],
|
||
["jxl-stream", JXLStream],
|
||
["ktx", KTX],
|
||
["png", PNG],
|
||
["pnm", PNM],
|
||
["psd", PSD],
|
||
["svg", SVG],
|
||
["tga", TGA],
|
||
["tiff", TIFF],
|
||
["webp", {
|
||
validate(input) {
|
||
const riffHeader = "RIFF" === toUTF8String(input, 0, 4);
|
||
const webpHeader = "WEBP" === toUTF8String(input, 8, 12);
|
||
const vp8Header = "VP8" === toUTF8String(input, 12, 15);
|
||
return riffHeader && webpHeader && vp8Header;
|
||
},
|
||
calculate(_input) {
|
||
const chunkHeader = toUTF8String(_input, 12, 16);
|
||
const input = _input.slice(20, 30);
|
||
if (chunkHeader === "VP8X") {
|
||
const extendedHeader = input[0];
|
||
const validStart = (extendedHeader & 192) === 0;
|
||
const validEnd = (extendedHeader & 1) === 0;
|
||
if (validStart && validEnd) return calculateExtended(input);
|
||
throw new TypeError("Invalid WebP");
|
||
}
|
||
if (chunkHeader === "VP8 " && input[0] !== 47) return calculateLossy(input);
|
||
const signature = toHexString(input, 3, 6);
|
||
if (chunkHeader === "VP8L" && signature !== "9d012a") return calculateLossless(input);
|
||
throw new TypeError("Invalid WebP");
|
||
}
|
||
}]
|
||
]);
|
||
var types = Array.from(typeHandlers.keys());
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/detector.js
|
||
var firstBytes = /* @__PURE__ */ new Map([
|
||
[0, "heif"],
|
||
[56, "psd"],
|
||
[66, "bmp"],
|
||
[68, "dds"],
|
||
[71, "gif"],
|
||
[73, "tiff"],
|
||
[77, "tiff"],
|
||
[82, "webp"],
|
||
[105, "icns"],
|
||
[137, "png"],
|
||
[255, "jpg"]
|
||
]);
|
||
function detector(input) {
|
||
const byte = input[0];
|
||
const type = firstBytes.get(byte);
|
||
if (type && typeHandlers.get(type).validate(input)) return type;
|
||
return types.find((imageType) => typeHandlers.get(imageType).validate(input));
|
||
}
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/vendor/image-size/lookup.js
|
||
function lookup(input) {
|
||
const type = detector(input);
|
||
if (typeof type !== "undefined") {
|
||
const size = typeHandlers.get(type).calculate(input);
|
||
if (size !== void 0) {
|
||
size.type = size.type ?? type;
|
||
return size;
|
||
}
|
||
}
|
||
throw new TypeError("unsupported file type: " + type);
|
||
}
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/metadata.js
|
||
async function imageMetadata(data, src) {
|
||
let result;
|
||
try {
|
||
result = lookup(data);
|
||
} catch {
|
||
throw new AstroError({
|
||
...NoImageMetadata,
|
||
message: NoImageMetadata.message(src)
|
||
});
|
||
}
|
||
if (result.height == null || result.width == null || !result.type) throw new AstroError({
|
||
...NoImageMetadata,
|
||
message: NoImageMetadata.message(src)
|
||
});
|
||
const { width, height, type, orientation } = result;
|
||
const isPortrait = (orientation || 0) >= 5;
|
||
return {
|
||
width: isPortrait ? height : width,
|
||
height: isPortrait ? width : height,
|
||
format: type,
|
||
orientation
|
||
};
|
||
}
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/redirectValidation.js
|
||
async function fetchWithRedirects(options) {
|
||
const { url, headers, imageConfig, fetchFn = globalThis.fetch, redirectLimit = 10, onMaxRedirectsExceeded = (_u) => /* @__PURE__ */ new Error("Maximum redirect depth exceeded"), onMissingLocationHeader = (_s, _u) => /* @__PURE__ */ new Error(`Redirect response ${_s} missing Location header`), onDisallowedRedirect = (_current, _target) => /* @__PURE__ */ new Error(`The image at ${_current} redirected to ${_target}, which is not an allowed remote location.`) } = options;
|
||
if (redirectLimit <= 0) throw onMaxRedirectsExceeded(typeof url === "string" ? url : url.toString());
|
||
const urlString = typeof url === "string" ? url : url.toString();
|
||
const res = await fetchFn(new Request(url, { headers }), { redirect: "manual" });
|
||
if ([
|
||
301,
|
||
302,
|
||
303,
|
||
307,
|
||
308
|
||
].includes(res.status)) {
|
||
const location = res.headers.get("Location");
|
||
if (!location) throw onMissingLocationHeader(res.status, urlString);
|
||
const redirectUrl = new URL(location, urlString).toString();
|
||
if (!isRemoteAllowed(redirectUrl, {
|
||
domains: imageConfig.domains ?? [],
|
||
remotePatterns: imageConfig.remotePatterns ?? []
|
||
})) throw onDisallowedRedirect(urlString, redirectUrl);
|
||
return fetchWithRedirects({
|
||
url: redirectUrl,
|
||
headers,
|
||
imageConfig,
|
||
fetchFn,
|
||
redirectLimit: redirectLimit - 1,
|
||
onMaxRedirectsExceeded,
|
||
onMissingLocationHeader,
|
||
onDisallowedRedirect
|
||
});
|
||
}
|
||
return res;
|
||
}
|
||
//#endregion
|
||
//#region node_modules/astro/dist/assets/utils/remoteProbe.js
|
||
async function inferRemoteSize(url, imageConfig) {
|
||
if (!URL.canParse(url)) throw new AstroError({
|
||
...FailedToFetchRemoteImageDimensions,
|
||
message: FailedToFetchRemoteImageDimensions.message(url)
|
||
});
|
||
const allowlistConfig = imageConfig ? {
|
||
domains: imageConfig.domains ?? [],
|
||
remotePatterns: imageConfig.remotePatterns ?? []
|
||
} : void 0;
|
||
if (!allowlistConfig) {
|
||
const parsedUrl = new URL(url);
|
||
if (!["http:", "https:"].includes(parsedUrl.protocol)) throw new AstroError({
|
||
...FailedToFetchRemoteImageDimensions,
|
||
message: FailedToFetchRemoteImageDimensions.message(url)
|
||
});
|
||
}
|
||
if (allowlistConfig && !isRemoteAllowed(url, allowlistConfig)) throw new AstroError({
|
||
...RemoteImageNotAllowed,
|
||
message: RemoteImageNotAllowed.message(url)
|
||
});
|
||
let response;
|
||
try {
|
||
response = await fetchWithRedirects({
|
||
url,
|
||
onMaxRedirectsExceeded: (u) => new AstroError({
|
||
...FailedToFetchRemoteImageDimensions,
|
||
message: FailedToFetchRemoteImageDimensions.message(u)
|
||
}),
|
||
onMissingLocationHeader: (_status, u) => new AstroError({
|
||
...FailedToFetchRemoteImageDimensions,
|
||
message: FailedToFetchRemoteImageDimensions.message(u)
|
||
}),
|
||
imageConfig: imageConfig ?? {
|
||
remotePatterns: [],
|
||
domains: []
|
||
}
|
||
});
|
||
} catch (_err) {
|
||
throw new AstroError({
|
||
...FailedToFetchRemoteImageDimensions,
|
||
message: FailedToFetchRemoteImageDimensions.message(url)
|
||
});
|
||
}
|
||
if (allowlistConfig && !isRemoteAllowed(response.url, allowlistConfig)) throw new AstroError({
|
||
...RemoteImageNotAllowed,
|
||
message: RemoteImageNotAllowed.message(url)
|
||
});
|
||
if (!response.body || !response.ok) throw new AstroError({
|
||
...FailedToFetchRemoteImageDimensions,
|
||
message: FailedToFetchRemoteImageDimensions.message(url)
|
||
});
|
||
const reader = response.body.getReader();
|
||
let done, value;
|
||
let accumulatedChunks = /* @__PURE__ */ new Uint8Array();
|
||
while (!done) {
|
||
const readResult = await reader.read();
|
||
done = readResult.done;
|
||
if (done) break;
|
||
if (readResult.value) {
|
||
value = readResult.value;
|
||
let tmp = new Uint8Array(accumulatedChunks.length + value.length);
|
||
tmp.set(accumulatedChunks, 0);
|
||
tmp.set(value, accumulatedChunks.length);
|
||
accumulatedChunks = tmp;
|
||
try {
|
||
const dimensions = await imageMetadata(accumulatedChunks, url);
|
||
if (dimensions) {
|
||
await reader.cancel();
|
||
return dimensions;
|
||
}
|
||
} catch {}
|
||
}
|
||
}
|
||
throw new AstroError({
|
||
...NoImageMetadata,
|
||
message: NoImageMetadata.message(url)
|
||
});
|
||
}
|
||
//#endregion
|
||
//#region node_modules/@astrojs/internal-helpers/dist/path.js
|
||
function appendForwardSlash(path) {
|
||
return path.endsWith("/") ? path : path + "/";
|
||
}
|
||
function prependForwardSlash(path) {
|
||
return path[0] === "/" ? path : "/" + path;
|
||
}
|
||
var MANY_LEADING_SLASHES = /^\/{2,}/;
|
||
function collapseDuplicateLeadingSlashes(path) {
|
||
if (!path) return path;
|
||
return path.replace(MANY_LEADING_SLASHES, "/");
|
||
}
|
||
var MANY_SLASHES = /\/{2,}/g;
|
||
function collapseDuplicateSlashes(path) {
|
||
if (!path) return path;
|
||
return path.replace(MANY_SLASHES, "/");
|
||
}
|
||
var MANY_TRAILING_SLASHES = /\/{2,}$/g;
|
||
function collapseDuplicateTrailingSlashes(path, trailingSlash) {
|
||
if (!path) return path;
|
||
return path.replace(MANY_TRAILING_SLASHES, trailingSlash ? "/" : "") || "/";
|
||
}
|
||
function removeTrailingForwardSlash(path) {
|
||
return path.endsWith("/") ? path.slice(0, path.length - 1) : path;
|
||
}
|
||
function removeLeadingForwardSlash(path) {
|
||
return path.startsWith("/") ? path.substring(1) : path;
|
||
}
|
||
function trimSlashes(path) {
|
||
return path.replace(/^\/|\/$/g, "");
|
||
}
|
||
function isString(path) {
|
||
return typeof path === "string" || path instanceof String;
|
||
}
|
||
var INTERNAL_PREFIXES = /* @__PURE__ */ new Set([
|
||
"/_",
|
||
"/@",
|
||
"/.",
|
||
"//"
|
||
]);
|
||
var JUST_SLASHES = /^\/{2,}$/;
|
||
function isInternalPath(path) {
|
||
const prefix = path.slice(0, 2).replace(/\\/g, "/");
|
||
return INTERNAL_PREFIXES.has(prefix) && !JUST_SLASHES.test(path);
|
||
}
|
||
function joinPaths(...paths) {
|
||
return paths.filter(isString).map((path, i) => {
|
||
if (i === 0) return removeTrailingForwardSlash(path);
|
||
else if (i === paths.length - 1) return removeLeadingForwardSlash(path);
|
||
else return trimSlashes(path);
|
||
}).join("/");
|
||
}
|
||
function removeQueryString(path) {
|
||
const index = path.lastIndexOf("?");
|
||
return index > 0 ? path.substring(0, index) : path;
|
||
}
|
||
function isRemotePath(src) {
|
||
if (!src) return false;
|
||
const trimmed = src.trim();
|
||
if (!trimmed) return false;
|
||
let decoded = trimmed;
|
||
let previousDecoded = "";
|
||
let maxIterations = 10;
|
||
while (decoded !== previousDecoded && maxIterations > 0) {
|
||
previousDecoded = decoded;
|
||
try {
|
||
decoded = decodeURIComponent(decoded);
|
||
} catch {
|
||
break;
|
||
}
|
||
maxIterations--;
|
||
}
|
||
if (/^[a-zA-Z]:/.test(decoded)) return false;
|
||
if (decoded[0] === "/" && /^\/[\w.@-]/.test(decoded)) return false;
|
||
if (decoded[0] === "\\") return true;
|
||
if (decoded.startsWith("//")) return true;
|
||
try {
|
||
const url = new URL(decoded, "http://n");
|
||
if (url.username || url.password) return true;
|
||
if (decoded.includes("@") && !url.pathname.includes("@") && !url.search.includes("@")) return true;
|
||
if (url.origin !== "http://n") {
|
||
if (url.protocol.toLowerCase() === "file:") return false;
|
||
return true;
|
||
}
|
||
if (URL.canParse(decoded)) return true;
|
||
return false;
|
||
} catch {
|
||
return true;
|
||
}
|
||
}
|
||
function slash(path) {
|
||
return path.replace(/\\/g, "/");
|
||
}
|
||
function fileExtension(path) {
|
||
const ext = path.split(".").pop();
|
||
return ext !== path ? `.${ext}` : "";
|
||
}
|
||
function stripRequestBase(pathname, base) {
|
||
pathname = collapseDuplicateLeadingSlashes(pathname);
|
||
const baseWithoutTrailingSlash = removeTrailingForwardSlash(base);
|
||
if (pathname === baseWithoutTrailingSlash) return "/";
|
||
if (pathname.startsWith(baseWithoutTrailingSlash + "/")) return pathname.slice(baseWithoutTrailingSlash.length);
|
||
return pathname;
|
||
}
|
||
var WITH_FILE_EXT = /\/[^/]+\.\w+$/;
|
||
function hasFileExtension(path) {
|
||
return WITH_FILE_EXT.test(path);
|
||
}
|
||
//#endregion
|
||
export { inferRemoteSize as _, fileExtension as a, isRemoteAllowed as b, isRemotePath as c, removeLeadingForwardSlash as d, removeQueryString as f, trimSlashes as g, stripRequestBase as h, collapseDuplicateTrailingSlashes as i, joinPaths as l, slash as m, collapseDuplicateLeadingSlashes as n, hasFileExtension as o, removeTrailingForwardSlash as p, collapseDuplicateSlashes as r, isInternalPath as s, appendForwardSlash as t, prependForwardSlash as u, fetchWithRedirects as v, matchPattern as x, detector as y };
|