image-endpoint_DVs7qPGs.mjs 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953
  1. globalThis.process ??= {}; globalThis.process.env ??= {};
  2. import { j as joinPaths, i as isRemotePath } from './path_CH3auf61.mjs';
  3. import { A as AstroError, E as ExpectedImage, L as LocalImageUsedWrongly, M as MissingImageDimension, U as UnsupportedImageFormat, I as IncompatibleDescriptorOptions, a as UnsupportedImageConversion, t as toStyleString, N as NoImageMetadata, F as FailedToFetchRemoteImageDimensions, b as ExpectedImageOptions, c as ExpectedNotESMImage, d as InvalidImageService, e as createComponent, f as createAstro, g as ImageMissingAlt, m as maybeRenderHead, h as addAttribute, s as spreadAttributes, r as renderTemplate, i as ExperimentalFontsNotEnabled, j as FontFamilyNotFound, u as unescapeHTML } from './astro/server_WO3f6Mge.mjs';
  4. import { i as isRemoteAllowed } from './remote_BC1y8RCW.mjs';
  5. import './_@astro-renderers_DpxbEuk7.mjs';
  6. const VALID_SUPPORTED_FORMATS = [
  7. "jpeg",
  8. "jpg",
  9. "png",
  10. "tiff",
  11. "webp",
  12. "gif",
  13. "svg",
  14. "avif"
  15. ];
  16. const DEFAULT_OUTPUT_FORMAT = "webp";
  17. const DEFAULT_HASH_PROPS = [
  18. "src",
  19. "width",
  20. "height",
  21. "format",
  22. "quality",
  23. "fit",
  24. "position"
  25. ];
  26. const DEFAULT_RESOLUTIONS = [
  27. 640,
  28. // older and lower-end phones
  29. 750,
  30. // iPhone 6-8
  31. 828,
  32. // iPhone XR/11
  33. 960,
  34. // older horizontal phones
  35. 1080,
  36. // iPhone 6-8 Plus
  37. 1280,
  38. // 720p
  39. 1668,
  40. // Various iPads
  41. 1920,
  42. // 1080p
  43. 2048,
  44. // QXGA
  45. 2560,
  46. // WQXGA
  47. 3200,
  48. // QHD+
  49. 3840,
  50. // 4K
  51. 4480,
  52. // 4.5K
  53. 5120,
  54. // 5K
  55. 6016
  56. // 6K
  57. ];
  58. const LIMITED_RESOLUTIONS = [
  59. 640,
  60. // older and lower-end phones
  61. 750,
  62. // iPhone 6-8
  63. 828,
  64. // iPhone XR/11
  65. 1080,
  66. // iPhone 6-8 Plus
  67. 1280,
  68. // 720p
  69. 1668,
  70. // Various iPads
  71. 2048,
  72. // QXGA
  73. 2560
  74. // WQXGA
  75. ];
  76. const getWidths = ({
  77. width,
  78. layout,
  79. breakpoints = DEFAULT_RESOLUTIONS,
  80. originalWidth
  81. }) => {
  82. const smallerThanOriginal = (w) => !originalWidth || w <= originalWidth;
  83. if (layout === "full-width") {
  84. return breakpoints.filter(smallerThanOriginal);
  85. }
  86. if (!width) {
  87. return [];
  88. }
  89. const doubleWidth = width * 2;
  90. const maxSize = originalWidth ? Math.min(doubleWidth, originalWidth) : doubleWidth;
  91. if (layout === "fixed") {
  92. return originalWidth && width > originalWidth ? [originalWidth] : [width, maxSize];
  93. }
  94. if (layout === "constrained") {
  95. return [
  96. // Always include the image at 1x and 2x the specified width
  97. width,
  98. doubleWidth,
  99. ...breakpoints
  100. ].filter((w) => w <= maxSize).sort((a, b) => a - b);
  101. }
  102. return [];
  103. };
  104. const getSizesAttribute = ({
  105. width,
  106. layout
  107. }) => {
  108. if (!width || !layout) {
  109. return void 0;
  110. }
  111. switch (layout) {
  112. // If screen is wider than the max size then image width is the max size,
  113. // otherwise it's the width of the screen
  114. case "constrained":
  115. return `(min-width: ${width}px) ${width}px, 100vw`;
  116. // Image is always the same width, whatever the size of the screen
  117. case "fixed":
  118. return `${width}px`;
  119. // Image is always the width of the screen
  120. case "full-width":
  121. return `100vw`;
  122. case "none":
  123. default:
  124. return void 0;
  125. }
  126. };
  127. function isESMImportedImage(src) {
  128. return typeof src === "object" || typeof src === "function" && "src" in src;
  129. }
  130. function isRemoteImage(src) {
  131. return typeof src === "string";
  132. }
  133. async function resolveSrc(src) {
  134. if (typeof src === "object" && "then" in src) {
  135. const resource = await src;
  136. return resource.default ?? resource;
  137. }
  138. return src;
  139. }
  140. function isLocalService(service) {
  141. if (!service) {
  142. return false;
  143. }
  144. return "transform" in service;
  145. }
  146. function parseQuality(quality) {
  147. let result = parseInt(quality);
  148. if (Number.isNaN(result)) {
  149. return quality;
  150. }
  151. return result;
  152. }
  153. const sortNumeric = (a, b) => a - b;
  154. const baseService = {
  155. validateOptions(options) {
  156. if (!options.src || !isRemoteImage(options.src) && !isESMImportedImage(options.src)) {
  157. throw new AstroError({
  158. ...ExpectedImage,
  159. message: ExpectedImage.message(
  160. JSON.stringify(options.src),
  161. typeof options.src,
  162. JSON.stringify(options, (_, v) => v === void 0 ? null : v)
  163. )
  164. });
  165. }
  166. if (!isESMImportedImage(options.src)) {
  167. if (options.src.startsWith("/@fs/") || !isRemotePath(options.src) && !options.src.startsWith("/")) {
  168. throw new AstroError({
  169. ...LocalImageUsedWrongly,
  170. message: LocalImageUsedWrongly.message(options.src)
  171. });
  172. }
  173. let missingDimension;
  174. if (!options.width && !options.height) {
  175. missingDimension = "both";
  176. } else if (!options.width && options.height) {
  177. missingDimension = "width";
  178. } else if (options.width && !options.height) {
  179. missingDimension = "height";
  180. }
  181. if (missingDimension) {
  182. throw new AstroError({
  183. ...MissingImageDimension,
  184. message: MissingImageDimension.message(missingDimension, options.src)
  185. });
  186. }
  187. } else {
  188. if (!VALID_SUPPORTED_FORMATS.includes(options.src.format)) {
  189. throw new AstroError({
  190. ...UnsupportedImageFormat,
  191. message: UnsupportedImageFormat.message(
  192. options.src.format,
  193. options.src.src,
  194. VALID_SUPPORTED_FORMATS
  195. )
  196. });
  197. }
  198. if (options.widths && options.densities) {
  199. throw new AstroError(IncompatibleDescriptorOptions);
  200. }
  201. if (options.src.format === "svg") {
  202. options.format = "svg";
  203. }
  204. if (options.src.format === "svg" && options.format !== "svg" || options.src.format !== "svg" && options.format === "svg") {
  205. throw new AstroError(UnsupportedImageConversion);
  206. }
  207. }
  208. if (!options.format) {
  209. options.format = DEFAULT_OUTPUT_FORMAT;
  210. }
  211. if (options.width) options.width = Math.round(options.width);
  212. if (options.height) options.height = Math.round(options.height);
  213. if (options.layout && options.width && options.height) {
  214. options.fit ??= "cover";
  215. delete options.layout;
  216. }
  217. if (options.fit === "none") {
  218. delete options.fit;
  219. }
  220. return options;
  221. },
  222. getHTMLAttributes(options) {
  223. const { targetWidth, targetHeight } = getTargetDimensions(options);
  224. const {
  225. src,
  226. width,
  227. height,
  228. format,
  229. quality,
  230. densities,
  231. widths,
  232. formats,
  233. layout,
  234. priority,
  235. fit,
  236. position,
  237. ...attributes
  238. } = options;
  239. return {
  240. ...attributes,
  241. width: targetWidth,
  242. height: targetHeight,
  243. loading: attributes.loading ?? "lazy",
  244. decoding: attributes.decoding ?? "async"
  245. };
  246. },
  247. getSrcSet(options) {
  248. const { targetWidth, targetHeight } = getTargetDimensions(options);
  249. const aspectRatio = targetWidth / targetHeight;
  250. const { widths, densities } = options;
  251. const targetFormat = options.format ?? DEFAULT_OUTPUT_FORMAT;
  252. let transformedWidths = (widths ?? []).sort(sortNumeric);
  253. let imageWidth = options.width;
  254. let maxWidth = Infinity;
  255. if (isESMImportedImage(options.src)) {
  256. imageWidth = options.src.width;
  257. maxWidth = imageWidth;
  258. if (transformedWidths.length > 0 && transformedWidths.at(-1) > maxWidth) {
  259. transformedWidths = transformedWidths.filter((width) => width <= maxWidth);
  260. transformedWidths.push(maxWidth);
  261. }
  262. }
  263. transformedWidths = Array.from(new Set(transformedWidths));
  264. const {
  265. width: transformWidth,
  266. height: transformHeight,
  267. ...transformWithoutDimensions
  268. } = options;
  269. let allWidths = [];
  270. if (densities) {
  271. const densityValues = densities.map((density) => {
  272. if (typeof density === "number") {
  273. return density;
  274. } else {
  275. return parseFloat(density);
  276. }
  277. });
  278. const densityWidths = densityValues.sort(sortNumeric).map((density) => Math.round(targetWidth * density));
  279. allWidths = densityWidths.map((width, index) => ({
  280. width,
  281. descriptor: `${densityValues[index]}x`
  282. }));
  283. } else if (transformedWidths.length > 0) {
  284. allWidths = transformedWidths.map((width) => ({
  285. width,
  286. descriptor: `${width}w`
  287. }));
  288. }
  289. return allWidths.map(({ width, descriptor }) => {
  290. const height = Math.round(width / aspectRatio);
  291. const transform = { ...transformWithoutDimensions, width, height };
  292. return {
  293. transform,
  294. descriptor,
  295. attributes: {
  296. type: `image/${targetFormat}`
  297. }
  298. };
  299. });
  300. },
  301. getURL(options, imageConfig) {
  302. const searchParams = new URLSearchParams();
  303. if (isESMImportedImage(options.src)) {
  304. searchParams.append("href", options.src.src);
  305. } else if (isRemoteAllowed(options.src, imageConfig)) {
  306. searchParams.append("href", options.src);
  307. } else {
  308. return options.src;
  309. }
  310. const params = {
  311. w: "width",
  312. h: "height",
  313. q: "quality",
  314. f: "format",
  315. fit: "fit",
  316. position: "position"
  317. };
  318. Object.entries(params).forEach(([param, key]) => {
  319. options[key] && searchParams.append(param, options[key].toString());
  320. });
  321. const imageEndpoint = joinPaths("/", imageConfig.endpoint.route);
  322. return `${imageEndpoint}?${searchParams}`;
  323. },
  324. parseURL(url) {
  325. const params = url.searchParams;
  326. if (!params.has("href")) {
  327. return void 0;
  328. }
  329. const transform = {
  330. src: params.get("href"),
  331. width: params.has("w") ? parseInt(params.get("w")) : void 0,
  332. height: params.has("h") ? parseInt(params.get("h")) : void 0,
  333. format: params.get("f"),
  334. quality: params.get("q"),
  335. fit: params.get("fit"),
  336. position: params.get("position") ?? void 0
  337. };
  338. return transform;
  339. }
  340. };
  341. function getTargetDimensions(options) {
  342. let targetWidth = options.width;
  343. let targetHeight = options.height;
  344. if (isESMImportedImage(options.src)) {
  345. const aspectRatio = options.src.width / options.src.height;
  346. if (targetHeight && !targetWidth) {
  347. targetWidth = Math.round(targetHeight * aspectRatio);
  348. } else if (targetWidth && !targetHeight) {
  349. targetHeight = Math.round(targetWidth / aspectRatio);
  350. } else if (!targetWidth && !targetHeight) {
  351. targetWidth = options.src.width;
  352. targetHeight = options.src.height;
  353. }
  354. }
  355. return {
  356. targetWidth,
  357. targetHeight
  358. };
  359. }
  360. function isImageMetadata(src) {
  361. return src.fsPath && !("fsPath" in src);
  362. }
  363. const cssFitValues = ["fill", "contain", "cover", "scale-down"];
  364. function addCSSVarsToStyle(vars, styles) {
  365. const cssVars = Object.entries(vars).filter(([_, value]) => value !== void 0 && value !== false).map(([key, value]) => `--${key}: ${value};`).join(" ");
  366. if (!styles) {
  367. return cssVars;
  368. }
  369. const style = typeof styles === "string" ? styles : toStyleString(styles);
  370. return `${cssVars} ${style}`;
  371. }
  372. const decoder = new TextDecoder();
  373. const toUTF8String = (input, start = 0, end = input.length) => decoder.decode(input.slice(start, end));
  374. const toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo + ("0" + i.toString(16)).slice(-2), "");
  375. const readInt16LE = (input, offset = 0) => {
  376. const val = input[offset] + input[offset + 1] * 2 ** 8;
  377. return val | (val & 2 ** 15) * 131070;
  378. };
  379. const readUInt16BE = (input, offset = 0) => input[offset] * 2 ** 8 + input[offset + 1];
  380. const readUInt16LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8;
  381. const readUInt24LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8 + input[offset + 2] * 2 ** 16;
  382. const readInt32LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8 + input[offset + 2] * 2 ** 16 + (input[offset + 3] << 24);
  383. const readUInt32BE = (input, offset = 0) => input[offset] * 2 ** 24 + input[offset + 1] * 2 ** 16 + input[offset + 2] * 2 ** 8 + input[offset + 3];
  384. const readUInt32LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8 + input[offset + 2] * 2 ** 16 + input[offset + 3] * 2 ** 24;
  385. const methods = {
  386. readUInt16BE,
  387. readUInt16LE,
  388. readUInt32BE,
  389. readUInt32LE
  390. };
  391. function readUInt(input, bits, offset, isBigEndian) {
  392. offset = offset || 0;
  393. const endian = isBigEndian ? "BE" : "LE";
  394. const methodName = "readUInt" + bits + endian;
  395. return methods[methodName](input, offset);
  396. }
  397. function readBox(buffer, offset) {
  398. if (buffer.length - offset < 4) return;
  399. const boxSize = readUInt32BE(buffer, offset);
  400. if (buffer.length - offset < boxSize) return;
  401. return {
  402. name: toUTF8String(buffer, 4 + offset, 8 + offset),
  403. offset,
  404. size: boxSize
  405. };
  406. }
  407. function findBox(buffer, boxName, offset) {
  408. while (offset < buffer.length) {
  409. const box = readBox(buffer, offset);
  410. if (!box) break;
  411. if (box.name === boxName) return box;
  412. offset += box.size;
  413. }
  414. }
  415. const BMP = {
  416. validate: (input) => toUTF8String(input, 0, 2) === "BM",
  417. calculate: (input) => ({
  418. height: Math.abs(readInt32LE(input, 22)),
  419. width: readUInt32LE(input, 18)
  420. })
  421. };
  422. const TYPE_ICON = 1;
  423. const SIZE_HEADER$1 = 2 + 2 + 2;
  424. const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4;
  425. function getSizeFromOffset(input, offset) {
  426. const value = input[offset];
  427. return value === 0 ? 256 : value;
  428. }
  429. function getImageSize$1(input, imageIndex) {
  430. const offset = SIZE_HEADER$1 + imageIndex * SIZE_IMAGE_ENTRY;
  431. return {
  432. height: getSizeFromOffset(input, offset + 1),
  433. width: getSizeFromOffset(input, offset)
  434. };
  435. }
  436. const ICO = {
  437. validate(input) {
  438. const reserved = readUInt16LE(input, 0);
  439. const imageCount = readUInt16LE(input, 4);
  440. if (reserved !== 0 || imageCount === 0) return false;
  441. const imageType = readUInt16LE(input, 2);
  442. return imageType === TYPE_ICON;
  443. },
  444. calculate(input) {
  445. const nbImages = readUInt16LE(input, 4);
  446. const imageSize = getImageSize$1(input, 0);
  447. if (nbImages === 1) return imageSize;
  448. const imgs = [imageSize];
  449. for (let imageIndex = 1; imageIndex < nbImages; imageIndex += 1) {
  450. imgs.push(getImageSize$1(input, imageIndex));
  451. }
  452. return {
  453. height: imageSize.height,
  454. images: imgs,
  455. width: imageSize.width
  456. };
  457. }
  458. };
  459. const TYPE_CURSOR = 2;
  460. const CUR = {
  461. validate(input) {
  462. const reserved = readUInt16LE(input, 0);
  463. const imageCount = readUInt16LE(input, 4);
  464. if (reserved !== 0 || imageCount === 0) return false;
  465. const imageType = readUInt16LE(input, 2);
  466. return imageType === TYPE_CURSOR;
  467. },
  468. calculate: (input) => ICO.calculate(input)
  469. };
  470. const DDS = {
  471. validate: (input) => readUInt32LE(input, 0) === 542327876,
  472. calculate: (input) => ({
  473. height: readUInt32LE(input, 12),
  474. width: readUInt32LE(input, 16)
  475. })
  476. };
  477. const gifRegexp = /^GIF8[79]a/;
  478. const GIF = {
  479. validate: (input) => gifRegexp.test(toUTF8String(input, 0, 6)),
  480. calculate: (input) => ({
  481. height: readUInt16LE(input, 8),
  482. width: readUInt16LE(input, 6)
  483. })
  484. };
  485. const brandMap = {
  486. avif: "avif",
  487. avis: "avif",
  488. // avif-sequence
  489. mif1: "heif",
  490. msf1: "heif",
  491. // heif-sequence
  492. heic: "heic",
  493. heix: "heic",
  494. hevc: "heic",
  495. // heic-sequence
  496. hevx: "heic"
  497. // heic-sequence
  498. };
  499. function detectBrands(buffer, start, end) {
  500. let brandsDetected = {};
  501. for (let i = start; i <= end; i += 4) {
  502. const brand = toUTF8String(buffer, i, i + 4);
  503. if (brand in brandMap) {
  504. brandsDetected[brand] = 1;
  505. }
  506. }
  507. if ("avif" in brandsDetected || "avis" in brandsDetected) {
  508. return "avif";
  509. } else if ("heic" in brandsDetected || "heix" in brandsDetected || "hevc" in brandsDetected || "hevx" in brandsDetected) {
  510. return "heic";
  511. } else if ("mif1" in brandsDetected || "msf1" in brandsDetected) {
  512. return "heif";
  513. }
  514. }
  515. const HEIF = {
  516. validate(buffer) {
  517. const ftype = toUTF8String(buffer, 4, 8);
  518. const brand = toUTF8String(buffer, 8, 12);
  519. return "ftyp" === ftype && brand in brandMap;
  520. },
  521. calculate(buffer) {
  522. const metaBox = findBox(buffer, "meta", 0);
  523. const iprpBox = metaBox && findBox(buffer, "iprp", metaBox.offset + 12);
  524. const ipcoBox = iprpBox && findBox(buffer, "ipco", iprpBox.offset + 8);
  525. const ispeBox = ipcoBox && findBox(buffer, "ispe", ipcoBox.offset + 8);
  526. if (ispeBox) {
  527. return {
  528. height: readUInt32BE(buffer, ispeBox.offset + 16),
  529. width: readUInt32BE(buffer, ispeBox.offset + 12),
  530. type: detectBrands(buffer, 8, metaBox.offset)
  531. };
  532. }
  533. throw new TypeError("Invalid HEIF, no size found");
  534. }
  535. };
  536. const SIZE_HEADER = 4 + 4;
  537. const FILE_LENGTH_OFFSET = 4;
  538. const ENTRY_LENGTH_OFFSET = 4;
  539. const ICON_TYPE_SIZE = {
  540. ICON: 32,
  541. "ICN#": 32,
  542. // m => 16 x 16
  543. "icm#": 16,
  544. icm4: 16,
  545. icm8: 16,
  546. // s => 16 x 16
  547. "ics#": 16,
  548. ics4: 16,
  549. ics8: 16,
  550. is32: 16,
  551. s8mk: 16,
  552. icp4: 16,
  553. // l => 32 x 32
  554. icl4: 32,
  555. icl8: 32,
  556. il32: 32,
  557. l8mk: 32,
  558. icp5: 32,
  559. ic11: 32,
  560. // h => 48 x 48
  561. ich4: 48,
  562. ich8: 48,
  563. ih32: 48,
  564. h8mk: 48,
  565. // . => 64 x 64
  566. icp6: 64,
  567. ic12: 32,
  568. // t => 128 x 128
  569. it32: 128,
  570. t8mk: 128,
  571. ic07: 128,
  572. // . => 256 x 256
  573. ic08: 256,
  574. ic13: 256,
  575. // . => 512 x 512
  576. ic09: 512,
  577. ic14: 512,
  578. // . => 1024 x 1024
  579. ic10: 1024
  580. };
  581. function readImageHeader(input, imageOffset) {
  582. const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET;
  583. return [
  584. toUTF8String(input, imageOffset, imageLengthOffset),
  585. readUInt32BE(input, imageLengthOffset)
  586. ];
  587. }
  588. function getImageSize(type) {
  589. const size = ICON_TYPE_SIZE[type];
  590. return { width: size, height: size, type };
  591. }
  592. const ICNS = {
  593. validate: (input) => toUTF8String(input, 0, 4) === "icns",
  594. calculate(input) {
  595. const inputLength = input.length;
  596. const fileLength = readUInt32BE(input, FILE_LENGTH_OFFSET);
  597. let imageOffset = SIZE_HEADER;
  598. let imageHeader = readImageHeader(input, imageOffset);
  599. let imageSize = getImageSize(imageHeader[0]);
  600. imageOffset += imageHeader[1];
  601. if (imageOffset === fileLength) return imageSize;
  602. const result = {
  603. height: imageSize.height,
  604. images: [imageSize],
  605. width: imageSize.width
  606. };
  607. while (imageOffset < fileLength && imageOffset < inputLength) {
  608. imageHeader = readImageHeader(input, imageOffset);
  609. imageSize = getImageSize(imageHeader[0]);
  610. imageOffset += imageHeader[1];
  611. result.images.push(imageSize);
  612. }
  613. return result;
  614. }
  615. };
  616. const J2C = {
  617. // TODO: this doesn't seem right. SIZ marker doesn't have to be right after the SOC
  618. validate: (input) => toHexString(input, 0, 4) === "ff4fff51",
  619. calculate: (input) => ({
  620. height: readUInt32BE(input, 12),
  621. width: readUInt32BE(input, 8)
  622. })
  623. };
  624. const JP2 = {
  625. validate(input) {
  626. if (readUInt32BE(input, 4) !== 1783636e3 || readUInt32BE(input, 0) < 1) return false;
  627. const ftypBox = findBox(input, "ftyp", 0);
  628. if (!ftypBox) return false;
  629. return readUInt32BE(input, ftypBox.offset + 4) === 1718909296;
  630. },
  631. calculate(input) {
  632. const jp2hBox = findBox(input, "jp2h", 0);
  633. const ihdrBox = jp2hBox && findBox(input, "ihdr", jp2hBox.offset + 8);
  634. if (ihdrBox) {
  635. return {
  636. height: readUInt32BE(input, ihdrBox.offset + 8),
  637. width: readUInt32BE(input, ihdrBox.offset + 12)
  638. };
  639. }
  640. throw new TypeError("Unsupported JPEG 2000 format");
  641. }
  642. };
  643. const EXIF_MARKER = "45786966";
  644. const APP1_DATA_SIZE_BYTES = 2;
  645. const EXIF_HEADER_BYTES = 6;
  646. const TIFF_BYTE_ALIGN_BYTES = 2;
  647. const BIG_ENDIAN_BYTE_ALIGN = "4d4d";
  648. const LITTLE_ENDIAN_BYTE_ALIGN = "4949";
  649. const IDF_ENTRY_BYTES = 12;
  650. const NUM_DIRECTORY_ENTRIES_BYTES = 2;
  651. function isEXIF(input) {
  652. return toHexString(input, 2, 6) === EXIF_MARKER;
  653. }
  654. function extractSize(input, index) {
  655. return {
  656. height: readUInt16BE(input, index),
  657. width: readUInt16BE(input, index + 2)
  658. };
  659. }
  660. function extractOrientation(exifBlock, isBigEndian) {
  661. const idfOffset = 8;
  662. const offset = EXIF_HEADER_BYTES + idfOffset;
  663. const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian);
  664. for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) {
  665. const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + directoryEntryNumber * IDF_ENTRY_BYTES;
  666. const end = start + IDF_ENTRY_BYTES;
  667. if (start > exifBlock.length) {
  668. return;
  669. }
  670. const block = exifBlock.slice(start, end);
  671. const tagNumber = readUInt(block, 16, 0, isBigEndian);
  672. if (tagNumber === 274) {
  673. const dataFormat = readUInt(block, 16, 2, isBigEndian);
  674. if (dataFormat !== 3) {
  675. return;
  676. }
  677. const numberOfComponents = readUInt(block, 32, 4, isBigEndian);
  678. if (numberOfComponents !== 1) {
  679. return;
  680. }
  681. return readUInt(block, 16, 8, isBigEndian);
  682. }
  683. }
  684. }
  685. function validateExifBlock(input, index) {
  686. const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index);
  687. const byteAlign = toHexString(
  688. exifBlock,
  689. EXIF_HEADER_BYTES,
  690. EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES
  691. );
  692. const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN;
  693. const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN;
  694. if (isBigEndian || isLittleEndian) {
  695. return extractOrientation(exifBlock, isBigEndian);
  696. }
  697. }
  698. function validateInput(input, index) {
  699. if (index > input.length) {
  700. throw new TypeError("Corrupt JPG, exceeded buffer limits");
  701. }
  702. }
  703. const JPG = {
  704. validate: (input) => toHexString(input, 0, 2) === "ffd8",
  705. calculate(input) {
  706. input = input.slice(4);
  707. let orientation;
  708. let next;
  709. while (input.length) {
  710. const i = readUInt16BE(input, 0);
  711. if (input[i] !== 255) {
  712. input = input.slice(i);
  713. continue;
  714. }
  715. if (isEXIF(input)) {
  716. orientation = validateExifBlock(input, i);
  717. }
  718. validateInput(input, i);
  719. next = input[i + 1];
  720. if (next === 192 || next === 193 || next === 194) {
  721. const size = extractSize(input, i + 5);
  722. if (!orientation) {
  723. return size;
  724. }
  725. return {
  726. height: size.height,
  727. orientation,
  728. width: size.width
  729. };
  730. }
  731. input = input.slice(i + 2);
  732. }
  733. throw new TypeError("Invalid JPG, no size found");
  734. }
  735. };
  736. const KTX = {
  737. validate: (input) => {
  738. const signature = toUTF8String(input, 1, 7);
  739. return ["KTX 11", "KTX 20"].includes(signature);
  740. },
  741. calculate: (input) => {
  742. const type = input[5] === 49 ? "ktx" : "ktx2";
  743. const offset = type === "ktx" ? 36 : 20;
  744. return {
  745. height: readUInt32LE(input, offset + 4),
  746. width: readUInt32LE(input, offset),
  747. type
  748. };
  749. }
  750. };
  751. const pngSignature = "PNG\r\n\n";
  752. const pngImageHeaderChunkName = "IHDR";
  753. const pngFriedChunkName = "CgBI";
  754. const PNG = {
  755. validate(input) {
  756. if (pngSignature === toUTF8String(input, 1, 8)) {
  757. let chunkName = toUTF8String(input, 12, 16);
  758. if (chunkName === pngFriedChunkName) {
  759. chunkName = toUTF8String(input, 28, 32);
  760. }
  761. if (chunkName !== pngImageHeaderChunkName) {
  762. throw new TypeError("Invalid PNG");
  763. }
  764. return true;
  765. }
  766. return false;
  767. },
  768. calculate(input) {
  769. if (toUTF8String(input, 12, 16) === pngFriedChunkName) {
  770. return {
  771. height: readUInt32BE(input, 36),
  772. width: readUInt32BE(input, 32)
  773. };
  774. }
  775. return {
  776. height: readUInt32BE(input, 20),
  777. width: readUInt32BE(input, 16)
  778. };
  779. }
  780. };
  781. const PNMTypes = {
  782. P1: "pbm/ascii",
  783. P2: "pgm/ascii",
  784. P3: "ppm/ascii",
  785. P4: "pbm",
  786. P5: "pgm",
  787. P6: "ppm",
  788. P7: "pam",
  789. PF: "pfm"
  790. };
  791. const handlers = {
  792. default: (lines) => {
  793. let dimensions = [];
  794. while (lines.length > 0) {
  795. const line = lines.shift();
  796. if (line[0] === "#") {
  797. continue;
  798. }
  799. dimensions = line.split(" ");
  800. break;
  801. }
  802. if (dimensions.length === 2) {
  803. return {
  804. height: parseInt(dimensions[1], 10),
  805. width: parseInt(dimensions[0], 10)
  806. };
  807. } else {
  808. throw new TypeError("Invalid PNM");
  809. }
  810. },
  811. pam: (lines) => {
  812. const size = {};
  813. while (lines.length > 0) {
  814. const line = lines.shift();
  815. if (line.length > 16 || line.charCodeAt(0) > 128) {
  816. continue;
  817. }
  818. const [key, value] = line.split(" ");
  819. if (key && value) {
  820. size[key.toLowerCase()] = parseInt(value, 10);
  821. }
  822. if (size.height && size.width) {
  823. break;
  824. }
  825. }
  826. if (size.height && size.width) {
  827. return {
  828. height: size.height,
  829. width: size.width
  830. };
  831. } else {
  832. throw new TypeError("Invalid PAM");
  833. }
  834. }
  835. };
  836. const PNM = {
  837. validate: (input) => toUTF8String(input, 0, 2) in PNMTypes,
  838. calculate(input) {
  839. const signature = toUTF8String(input, 0, 2);
  840. const type = PNMTypes[signature];
  841. const lines = toUTF8String(input, 3).split(/[\r\n]+/);
  842. const handler = handlers[type] || handlers.default;
  843. return handler(lines);
  844. }
  845. };
  846. const PSD = {
  847. validate: (input) => toUTF8String(input, 0, 4) === "8BPS",
  848. calculate: (input) => ({
  849. height: readUInt32BE(input, 14),
  850. width: readUInt32BE(input, 18)
  851. })
  852. };
  853. const svgReg = /<svg\s([^>"']|"[^"]*"|'[^']*')*>/;
  854. const extractorRegExps = {
  855. height: /\sheight=(['"])([^%]+?)\1/,
  856. root: svgReg,
  857. viewbox: /\sviewBox=(['"])(.+?)\1/i,
  858. width: /\swidth=(['"])([^%]+?)\1/
  859. };
  860. const INCH_CM = 2.54;
  861. const units = {
  862. in: 96,
  863. cm: 96 / INCH_CM,
  864. em: 16,
  865. ex: 8,
  866. m: 96 / INCH_CM * 100,
  867. mm: 96 / INCH_CM / 10,
  868. pc: 96 / 72 / 12,
  869. pt: 96 / 72,
  870. px: 1
  871. };
  872. const unitsReg = new RegExp(
  873. `^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join("|")})?$`
  874. );
  875. function parseLength(len) {
  876. const m = unitsReg.exec(len);
  877. if (!m) {
  878. return void 0;
  879. }
  880. return Math.round(Number(m[1]) * (units[m[2]] || 1));
  881. }
  882. function parseViewbox(viewbox) {
  883. const bounds = viewbox.split(" ");
  884. return {
  885. height: parseLength(bounds[3]),
  886. width: parseLength(bounds[2])
  887. };
  888. }
  889. function parseAttributes(root) {
  890. const width = extractorRegExps.width.exec(root);
  891. const height = extractorRegExps.height.exec(root);
  892. const viewbox = extractorRegExps.viewbox.exec(root);
  893. return {
  894. height: height && parseLength(height[2]),
  895. viewbox: viewbox && parseViewbox(viewbox[2]),
  896. width: width && parseLength(width[2])
  897. };
  898. }
  899. function calculateByDimensions(attrs) {
  900. return {
  901. height: attrs.height,
  902. width: attrs.width
  903. };
  904. }
  905. function calculateByViewbox(attrs, viewbox) {
  906. const ratio = viewbox.width / viewbox.height;
  907. if (attrs.width) {
  908. return {
  909. height: Math.floor(attrs.width / ratio),
  910. width: attrs.width
  911. };
  912. }
  913. if (attrs.height) {
  914. return {
  915. height: attrs.height,
  916. width: Math.floor(attrs.height * ratio)
  917. };
  918. }
  919. return {
  920. height: viewbox.height,
  921. width: viewbox.width
  922. };
  923. }
  924. const SVG = {
  925. // Scan only the first kilo-byte to speed up the check on larger files
  926. validate: (input) => svgReg.test(toUTF8String(input, 0, 1e3)),
  927. calculate(input) {
  928. const root = extractorRegExps.root.exec(toUTF8String(input));
  929. if (root) {
  930. const attrs = parseAttributes(root[0]);
  931. if (attrs.width && attrs.height) {
  932. return calculateByDimensions(attrs);
  933. }
  934. if (attrs.viewbox) {
  935. return calculateByViewbox(attrs, attrs.viewbox);
  936. }
  937. }
  938. throw new TypeError("Invalid SVG");
  939. }
  940. };
  941. const TGA = {
  942. validate(input) {
  943. return readUInt16LE(input, 0) === 0 && readUInt16LE(input, 4) === 0;
  944. },
  945. calculate(input) {
  946. return {
  947. height: readUInt16LE(input, 14),
  948. width: readUInt16LE(input, 12)
  949. };
  950. }
  951. };
  952. function readIFD(input, isBigEndian) {
  953. const ifdOffset = readUInt(input, 32, 4, isBigEndian);
  954. return input.slice(ifdOffset + 2);
  955. }
  956. function readValue(input, isBigEndian) {
  957. const low = readUInt(input, 16, 8, isBigEndian);
  958. const high = readUInt(input, 16, 10, isBigEndian);
  959. return (high << 16) + low;
  960. }
  961. function nextTag(input) {
  962. if (input.length > 24) {
  963. return input.slice(12);
  964. }
  965. }
  966. function extractTags(input, isBigEndian) {
  967. const tags = {};
  968. let temp = input;
  969. while (temp && temp.length) {
  970. const code = readUInt(temp, 16, 0, isBigEndian);
  971. const type = readUInt(temp, 16, 2, isBigEndian);
  972. const length = readUInt(temp, 32, 4, isBigEndian);
  973. if (code === 0) {
  974. break;
  975. } else {
  976. if (length === 1 && (type === 3 || type === 4)) {
  977. tags[code] = readValue(temp, isBigEndian);
  978. }
  979. temp = nextTag(temp);
  980. }
  981. }
  982. return tags;
  983. }
  984. function determineEndianness(input) {
  985. const signature = toUTF8String(input, 0, 2);
  986. if ("II" === signature) {
  987. return "LE";
  988. } else if ("MM" === signature) {
  989. return "BE";
  990. }
  991. }
  992. const signatures = [
  993. // '492049', // currently not supported
  994. "49492a00",
  995. // Little endian
  996. "4d4d002a"
  997. // Big Endian
  998. // '4d4d002a', // BigTIFF > 4GB. currently not supported
  999. ];
  1000. const TIFF = {
  1001. validate: (input) => signatures.includes(toHexString(input, 0, 4)),
  1002. calculate(input) {
  1003. const isBigEndian = determineEndianness(input) === "BE";
  1004. const ifdBuffer = readIFD(input, isBigEndian);
  1005. const tags = extractTags(ifdBuffer, isBigEndian);
  1006. const width = tags[256];
  1007. const height = tags[257];
  1008. if (!width || !height) {
  1009. throw new TypeError("Invalid Tiff. Missing tags");
  1010. }
  1011. return { height, width };
  1012. }
  1013. };
  1014. function calculateExtended(input) {
  1015. return {
  1016. height: 1 + readUInt24LE(input, 7),
  1017. width: 1 + readUInt24LE(input, 4)
  1018. };
  1019. }
  1020. function calculateLossless(input) {
  1021. return {
  1022. height: 1 + ((input[4] & 15) << 10 | input[3] << 2 | (input[2] & 192) >> 6),
  1023. width: 1 + ((input[2] & 63) << 8 | input[1])
  1024. };
  1025. }
  1026. function calculateLossy(input) {
  1027. return {
  1028. height: readInt16LE(input, 8) & 16383,
  1029. width: readInt16LE(input, 6) & 16383
  1030. };
  1031. }
  1032. const WEBP = {
  1033. validate(input) {
  1034. const riffHeader = "RIFF" === toUTF8String(input, 0, 4);
  1035. const webpHeader = "WEBP" === toUTF8String(input, 8, 12);
  1036. const vp8Header = "VP8" === toUTF8String(input, 12, 15);
  1037. return riffHeader && webpHeader && vp8Header;
  1038. },
  1039. calculate(input) {
  1040. const chunkHeader = toUTF8String(input, 12, 16);
  1041. input = input.slice(20, 30);
  1042. if (chunkHeader === "VP8X") {
  1043. const extendedHeader = input[0];
  1044. const validStart = (extendedHeader & 192) === 0;
  1045. const validEnd = (extendedHeader & 1) === 0;
  1046. if (validStart && validEnd) {
  1047. return calculateExtended(input);
  1048. } else {
  1049. throw new TypeError("Invalid WebP");
  1050. }
  1051. }
  1052. if (chunkHeader === "VP8 " && input[0] !== 47) {
  1053. return calculateLossy(input);
  1054. }
  1055. const signature = toHexString(input, 3, 6);
  1056. if (chunkHeader === "VP8L" && signature !== "9d012a") {
  1057. return calculateLossless(input);
  1058. }
  1059. throw new TypeError("Invalid WebP");
  1060. }
  1061. };
  1062. const typeHandlers = /* @__PURE__ */ new Map([
  1063. ["bmp", BMP],
  1064. ["cur", CUR],
  1065. ["dds", DDS],
  1066. ["gif", GIF],
  1067. ["heif", HEIF],
  1068. ["icns", ICNS],
  1069. ["ico", ICO],
  1070. ["j2c", J2C],
  1071. ["jp2", JP2],
  1072. ["jpg", JPG],
  1073. ["ktx", KTX],
  1074. ["png", PNG],
  1075. ["pnm", PNM],
  1076. ["psd", PSD],
  1077. ["svg", SVG],
  1078. ["tga", TGA],
  1079. ["tiff", TIFF],
  1080. ["webp", WEBP]
  1081. ]);
  1082. const types = Array.from(typeHandlers.keys());
  1083. const firstBytes = /* @__PURE__ */ new Map([
  1084. [56, "psd"],
  1085. [66, "bmp"],
  1086. [68, "dds"],
  1087. [71, "gif"],
  1088. [73, "tiff"],
  1089. [77, "tiff"],
  1090. [82, "webp"],
  1091. [105, "icns"],
  1092. [137, "png"],
  1093. [255, "jpg"]
  1094. ]);
  1095. function detector(input) {
  1096. const byte = input[0];
  1097. const type = firstBytes.get(byte);
  1098. if (type && typeHandlers.get(type).validate(input)) {
  1099. return type;
  1100. }
  1101. return types.find((fileType) => typeHandlers.get(fileType).validate(input));
  1102. }
  1103. function lookup$1(input) {
  1104. const type = detector(input);
  1105. if (typeof type !== "undefined") {
  1106. const size = typeHandlers.get(type).calculate(input);
  1107. if (size !== void 0) {
  1108. size.type = size.type ?? type;
  1109. return size;
  1110. }
  1111. }
  1112. throw new TypeError("unsupported file type: " + type);
  1113. }
  1114. async function imageMetadata(data, src) {
  1115. let result;
  1116. try {
  1117. result = lookup$1(data);
  1118. } catch {
  1119. throw new AstroError({
  1120. ...NoImageMetadata,
  1121. message: NoImageMetadata.message(src)
  1122. });
  1123. }
  1124. if (!result.height || !result.width || !result.type) {
  1125. throw new AstroError({
  1126. ...NoImageMetadata,
  1127. message: NoImageMetadata.message(src)
  1128. });
  1129. }
  1130. const { width, height, type, orientation } = result;
  1131. const isPortrait = (orientation || 0) >= 5;
  1132. return {
  1133. width: isPortrait ? height : width,
  1134. height: isPortrait ? width : height,
  1135. format: type,
  1136. orientation
  1137. };
  1138. }
  1139. async function inferRemoteSize(url) {
  1140. const response = await fetch(url);
  1141. if (!response.body || !response.ok) {
  1142. throw new AstroError({
  1143. ...FailedToFetchRemoteImageDimensions,
  1144. message: FailedToFetchRemoteImageDimensions.message(url)
  1145. });
  1146. }
  1147. const reader = response.body.getReader();
  1148. let done, value;
  1149. let accumulatedChunks = new Uint8Array();
  1150. while (!done) {
  1151. const readResult = await reader.read();
  1152. done = readResult.done;
  1153. if (done) break;
  1154. if (readResult.value) {
  1155. value = readResult.value;
  1156. let tmp = new Uint8Array(accumulatedChunks.length + value.length);
  1157. tmp.set(accumulatedChunks, 0);
  1158. tmp.set(value, accumulatedChunks.length);
  1159. accumulatedChunks = tmp;
  1160. try {
  1161. const dimensions = await imageMetadata(accumulatedChunks, url);
  1162. if (dimensions) {
  1163. await reader.cancel();
  1164. return dimensions;
  1165. }
  1166. } catch {
  1167. }
  1168. }
  1169. }
  1170. throw new AstroError({
  1171. ...NoImageMetadata,
  1172. message: NoImageMetadata.message(url)
  1173. });
  1174. }
  1175. async function getConfiguredImageService() {
  1176. if (!globalThis?.astroAsset?.imageService) {
  1177. const { default: service } = await import(
  1178. // @ts-expect-error
  1179. './sharp_CG4EIo5e.mjs'
  1180. ).catch((e) => {
  1181. const error = new AstroError(InvalidImageService);
  1182. error.cause = e;
  1183. throw error;
  1184. });
  1185. if (!globalThis.astroAsset) globalThis.astroAsset = {};
  1186. globalThis.astroAsset.imageService = service;
  1187. return service;
  1188. }
  1189. return globalThis.astroAsset.imageService;
  1190. }
  1191. async function getImage$1(options, imageConfig) {
  1192. if (!options || typeof options !== "object") {
  1193. throw new AstroError({
  1194. ...ExpectedImageOptions,
  1195. message: ExpectedImageOptions.message(JSON.stringify(options))
  1196. });
  1197. }
  1198. if (typeof options.src === "undefined") {
  1199. throw new AstroError({
  1200. ...ExpectedImage,
  1201. message: ExpectedImage.message(
  1202. options.src,
  1203. "undefined",
  1204. JSON.stringify(options)
  1205. )
  1206. });
  1207. }
  1208. if (isImageMetadata(options)) {
  1209. throw new AstroError(ExpectedNotESMImage);
  1210. }
  1211. const service = await getConfiguredImageService();
  1212. const resolvedOptions = {
  1213. ...options,
  1214. src: await resolveSrc(options.src)
  1215. };
  1216. let originalWidth;
  1217. let originalHeight;
  1218. if (options.inferSize && isRemoteImage(resolvedOptions.src) && isRemotePath(resolvedOptions.src)) {
  1219. const result = await inferRemoteSize(resolvedOptions.src);
  1220. resolvedOptions.width ??= result.width;
  1221. resolvedOptions.height ??= result.height;
  1222. originalWidth = result.width;
  1223. originalHeight = result.height;
  1224. delete resolvedOptions.inferSize;
  1225. }
  1226. const originalFilePath = isESMImportedImage(resolvedOptions.src) ? resolvedOptions.src.fsPath : void 0;
  1227. const clonedSrc = isESMImportedImage(resolvedOptions.src) ? (
  1228. // @ts-expect-error - clone is a private, hidden prop
  1229. resolvedOptions.src.clone ?? resolvedOptions.src
  1230. ) : resolvedOptions.src;
  1231. if (isESMImportedImage(clonedSrc)) {
  1232. originalWidth = clonedSrc.width;
  1233. originalHeight = clonedSrc.height;
  1234. }
  1235. if (originalWidth && originalHeight) {
  1236. const aspectRatio = originalWidth / originalHeight;
  1237. if (resolvedOptions.height && !resolvedOptions.width) {
  1238. resolvedOptions.width = Math.round(resolvedOptions.height * aspectRatio);
  1239. } else if (resolvedOptions.width && !resolvedOptions.height) {
  1240. resolvedOptions.height = Math.round(resolvedOptions.width / aspectRatio);
  1241. } else if (!resolvedOptions.width && !resolvedOptions.height) {
  1242. resolvedOptions.width = originalWidth;
  1243. resolvedOptions.height = originalHeight;
  1244. }
  1245. }
  1246. resolvedOptions.src = clonedSrc;
  1247. const layout = options.layout ?? imageConfig.layout ?? "none";
  1248. if (resolvedOptions.priority) {
  1249. resolvedOptions.loading ??= "eager";
  1250. resolvedOptions.decoding ??= "sync";
  1251. resolvedOptions.fetchpriority ??= "high";
  1252. delete resolvedOptions.priority;
  1253. } else {
  1254. resolvedOptions.loading ??= "lazy";
  1255. resolvedOptions.decoding ??= "async";
  1256. resolvedOptions.fetchpriority ??= "auto";
  1257. }
  1258. if (layout !== "none") {
  1259. resolvedOptions.widths ||= getWidths({
  1260. width: resolvedOptions.width,
  1261. layout,
  1262. originalWidth,
  1263. breakpoints: imageConfig.breakpoints?.length ? imageConfig.breakpoints : isLocalService(service) ? LIMITED_RESOLUTIONS : DEFAULT_RESOLUTIONS
  1264. });
  1265. resolvedOptions.sizes ||= getSizesAttribute({ width: resolvedOptions.width, layout });
  1266. delete resolvedOptions.densities;
  1267. resolvedOptions.style = addCSSVarsToStyle(
  1268. {
  1269. fit: cssFitValues.includes(resolvedOptions.fit ?? "") && resolvedOptions.fit,
  1270. pos: resolvedOptions.position
  1271. },
  1272. resolvedOptions.style
  1273. );
  1274. resolvedOptions["data-astro-image"] = layout;
  1275. }
  1276. const validatedOptions = service.validateOptions ? await service.validateOptions(resolvedOptions, imageConfig) : resolvedOptions;
  1277. const srcSetTransforms = service.getSrcSet ? await service.getSrcSet(validatedOptions, imageConfig) : [];
  1278. let imageURL = await service.getURL(validatedOptions, imageConfig);
  1279. const matchesValidatedTransform = (transform) => transform.width === validatedOptions.width && transform.height === validatedOptions.height && transform.format === validatedOptions.format;
  1280. let srcSets = await Promise.all(
  1281. srcSetTransforms.map(async (srcSet) => {
  1282. return {
  1283. transform: srcSet.transform,
  1284. url: matchesValidatedTransform(srcSet.transform) ? imageURL : await service.getURL(srcSet.transform, imageConfig),
  1285. descriptor: srcSet.descriptor,
  1286. attributes: srcSet.attributes
  1287. };
  1288. })
  1289. );
  1290. if (isLocalService(service) && globalThis.astroAsset.addStaticImage && !(isRemoteImage(validatedOptions.src) && imageURL === validatedOptions.src)) {
  1291. const propsToHash = service.propertiesToHash ?? DEFAULT_HASH_PROPS;
  1292. imageURL = globalThis.astroAsset.addStaticImage(
  1293. validatedOptions,
  1294. propsToHash,
  1295. originalFilePath
  1296. );
  1297. srcSets = srcSetTransforms.map((srcSet) => {
  1298. return {
  1299. transform: srcSet.transform,
  1300. url: matchesValidatedTransform(srcSet.transform) ? imageURL : globalThis.astroAsset.addStaticImage(srcSet.transform, propsToHash, originalFilePath),
  1301. descriptor: srcSet.descriptor,
  1302. attributes: srcSet.attributes
  1303. };
  1304. });
  1305. }
  1306. return {
  1307. rawOptions: resolvedOptions,
  1308. options: validatedOptions,
  1309. src: imageURL,
  1310. srcSet: {
  1311. values: srcSets,
  1312. attribute: srcSets.map((srcSet) => `${srcSet.url} ${srcSet.descriptor}`).join(", ")
  1313. },
  1314. attributes: service.getHTMLAttributes !== void 0 ? await service.getHTMLAttributes(validatedOptions, imageConfig) : {}
  1315. };
  1316. }
  1317. const $$Astro$2 = createAstro();
  1318. const $$Image = createComponent(async ($$result, $$props, $$slots) => {
  1319. const Astro2 = $$result.createAstro($$Astro$2, $$props, $$slots);
  1320. Astro2.self = $$Image;
  1321. const props = Astro2.props;
  1322. if (props.alt === void 0 || props.alt === null) {
  1323. throw new AstroError(ImageMissingAlt);
  1324. }
  1325. if (typeof props.width === "string") {
  1326. props.width = parseInt(props.width);
  1327. }
  1328. if (typeof props.height === "string") {
  1329. props.height = parseInt(props.height);
  1330. }
  1331. const layout = props.layout ?? imageConfig.layout ?? "none";
  1332. if (layout !== "none") {
  1333. props.layout ??= imageConfig.layout;
  1334. props.fit ??= imageConfig.objectFit ?? "cover";
  1335. props.position ??= imageConfig.objectPosition ?? "center";
  1336. }
  1337. const image = await getImage(props);
  1338. const additionalAttributes = {};
  1339. if (image.srcSet.values.length > 0) {
  1340. additionalAttributes.srcset = image.srcSet.attribute;
  1341. }
  1342. const { class: className, ...attributes } = { ...additionalAttributes, ...image.attributes };
  1343. return renderTemplate`${maybeRenderHead()}<img${addAttribute(image.src, "src")}${spreadAttributes(attributes)}${addAttribute(className, "class")}>`;
  1344. }, "/home/fc/Projects/glance/node_modules/astro/components/Image.astro", void 0);
  1345. const mimes = {
  1346. "3g2": "video/3gpp2",
  1347. "3gp": "video/3gpp",
  1348. "3gpp": "video/3gpp",
  1349. "3mf": "model/3mf",
  1350. "aac": "audio/aac",
  1351. "ac": "application/pkix-attr-cert",
  1352. "adp": "audio/adpcm",
  1353. "adts": "audio/aac",
  1354. "ai": "application/postscript",
  1355. "aml": "application/automationml-aml+xml",
  1356. "amlx": "application/automationml-amlx+zip",
  1357. "amr": "audio/amr",
  1358. "apng": "image/apng",
  1359. "appcache": "text/cache-manifest",
  1360. "appinstaller": "application/appinstaller",
  1361. "appx": "application/appx",
  1362. "appxbundle": "application/appxbundle",
  1363. "asc": "application/pgp-keys",
  1364. "atom": "application/atom+xml",
  1365. "atomcat": "application/atomcat+xml",
  1366. "atomdeleted": "application/atomdeleted+xml",
  1367. "atomsvc": "application/atomsvc+xml",
  1368. "au": "audio/basic",
  1369. "avci": "image/avci",
  1370. "avcs": "image/avcs",
  1371. "avif": "image/avif",
  1372. "aw": "application/applixware",
  1373. "bdoc": "application/bdoc",
  1374. "bin": "application/octet-stream",
  1375. "bmp": "image/bmp",
  1376. "bpk": "application/octet-stream",
  1377. "btf": "image/prs.btif",
  1378. "btif": "image/prs.btif",
  1379. "buffer": "application/octet-stream",
  1380. "ccxml": "application/ccxml+xml",
  1381. "cdfx": "application/cdfx+xml",
  1382. "cdmia": "application/cdmi-capability",
  1383. "cdmic": "application/cdmi-container",
  1384. "cdmid": "application/cdmi-domain",
  1385. "cdmio": "application/cdmi-object",
  1386. "cdmiq": "application/cdmi-queue",
  1387. "cer": "application/pkix-cert",
  1388. "cgm": "image/cgm",
  1389. "cjs": "application/node",
  1390. "class": "application/java-vm",
  1391. "coffee": "text/coffeescript",
  1392. "conf": "text/plain",
  1393. "cpl": "application/cpl+xml",
  1394. "cpt": "application/mac-compactpro",
  1395. "crl": "application/pkix-crl",
  1396. "css": "text/css",
  1397. "csv": "text/csv",
  1398. "cu": "application/cu-seeme",
  1399. "cwl": "application/cwl",
  1400. "cww": "application/prs.cww",
  1401. "davmount": "application/davmount+xml",
  1402. "dbk": "application/docbook+xml",
  1403. "deb": "application/octet-stream",
  1404. "def": "text/plain",
  1405. "deploy": "application/octet-stream",
  1406. "dib": "image/bmp",
  1407. "disposition-notification": "message/disposition-notification",
  1408. "dist": "application/octet-stream",
  1409. "distz": "application/octet-stream",
  1410. "dll": "application/octet-stream",
  1411. "dmg": "application/octet-stream",
  1412. "dms": "application/octet-stream",
  1413. "doc": "application/msword",
  1414. "dot": "application/msword",
  1415. "dpx": "image/dpx",
  1416. "drle": "image/dicom-rle",
  1417. "dsc": "text/prs.lines.tag",
  1418. "dssc": "application/dssc+der",
  1419. "dtd": "application/xml-dtd",
  1420. "dump": "application/octet-stream",
  1421. "dwd": "application/atsc-dwd+xml",
  1422. "ear": "application/java-archive",
  1423. "ecma": "application/ecmascript",
  1424. "elc": "application/octet-stream",
  1425. "emf": "image/emf",
  1426. "eml": "message/rfc822",
  1427. "emma": "application/emma+xml",
  1428. "emotionml": "application/emotionml+xml",
  1429. "eps": "application/postscript",
  1430. "epub": "application/epub+zip",
  1431. "exe": "application/octet-stream",
  1432. "exi": "application/exi",
  1433. "exp": "application/express",
  1434. "exr": "image/aces",
  1435. "ez": "application/andrew-inset",
  1436. "fdf": "application/fdf",
  1437. "fdt": "application/fdt+xml",
  1438. "fits": "image/fits",
  1439. "g3": "image/g3fax",
  1440. "gbr": "application/rpki-ghostbusters",
  1441. "geojson": "application/geo+json",
  1442. "gif": "image/gif",
  1443. "glb": "model/gltf-binary",
  1444. "gltf": "model/gltf+json",
  1445. "gml": "application/gml+xml",
  1446. "gpx": "application/gpx+xml",
  1447. "gram": "application/srgs",
  1448. "grxml": "application/srgs+xml",
  1449. "gxf": "application/gxf",
  1450. "gz": "application/gzip",
  1451. "h261": "video/h261",
  1452. "h263": "video/h263",
  1453. "h264": "video/h264",
  1454. "heic": "image/heic",
  1455. "heics": "image/heic-sequence",
  1456. "heif": "image/heif",
  1457. "heifs": "image/heif-sequence",
  1458. "hej2": "image/hej2k",
  1459. "held": "application/atsc-held+xml",
  1460. "hjson": "application/hjson",
  1461. "hlp": "application/winhlp",
  1462. "hqx": "application/mac-binhex40",
  1463. "hsj2": "image/hsj2",
  1464. "htm": "text/html",
  1465. "html": "text/html",
  1466. "ics": "text/calendar",
  1467. "ief": "image/ief",
  1468. "ifb": "text/calendar",
  1469. "iges": "model/iges",
  1470. "igs": "model/iges",
  1471. "img": "application/octet-stream",
  1472. "in": "text/plain",
  1473. "ini": "text/plain",
  1474. "ink": "application/inkml+xml",
  1475. "inkml": "application/inkml+xml",
  1476. "ipfix": "application/ipfix",
  1477. "iso": "application/octet-stream",
  1478. "its": "application/its+xml",
  1479. "jade": "text/jade",
  1480. "jar": "application/java-archive",
  1481. "jhc": "image/jphc",
  1482. "jls": "image/jls",
  1483. "jp2": "image/jp2",
  1484. "jpe": "image/jpeg",
  1485. "jpeg": "image/jpeg",
  1486. "jpf": "image/jpx",
  1487. "jpg": "image/jpeg",
  1488. "jpg2": "image/jp2",
  1489. "jpgm": "image/jpm",
  1490. "jpgv": "video/jpeg",
  1491. "jph": "image/jph",
  1492. "jpm": "image/jpm",
  1493. "jpx": "image/jpx",
  1494. "js": "text/javascript",
  1495. "json": "application/json",
  1496. "json5": "application/json5",
  1497. "jsonld": "application/ld+json",
  1498. "jsonml": "application/jsonml+json",
  1499. "jsx": "text/jsx",
  1500. "jt": "model/jt",
  1501. "jxl": "image/jxl",
  1502. "jxr": "image/jxr",
  1503. "jxra": "image/jxra",
  1504. "jxrs": "image/jxrs",
  1505. "jxs": "image/jxs",
  1506. "jxsc": "image/jxsc",
  1507. "jxsi": "image/jxsi",
  1508. "jxss": "image/jxss",
  1509. "kar": "audio/midi",
  1510. "ktx": "image/ktx",
  1511. "ktx2": "image/ktx2",
  1512. "less": "text/less",
  1513. "lgr": "application/lgr+xml",
  1514. "list": "text/plain",
  1515. "litcoffee": "text/coffeescript",
  1516. "log": "text/plain",
  1517. "lostxml": "application/lost+xml",
  1518. "lrf": "application/octet-stream",
  1519. "m1v": "video/mpeg",
  1520. "m21": "application/mp21",
  1521. "m2a": "audio/mpeg",
  1522. "m2t": "video/mp2t",
  1523. "m2ts": "video/mp2t",
  1524. "m2v": "video/mpeg",
  1525. "m3a": "audio/mpeg",
  1526. "m4a": "audio/mp4",
  1527. "m4p": "application/mp4",
  1528. "m4s": "video/iso.segment",
  1529. "ma": "application/mathematica",
  1530. "mads": "application/mads+xml",
  1531. "maei": "application/mmt-aei+xml",
  1532. "man": "text/troff",
  1533. "manifest": "text/cache-manifest",
  1534. "map": "application/json",
  1535. "mar": "application/octet-stream",
  1536. "markdown": "text/markdown",
  1537. "mathml": "application/mathml+xml",
  1538. "mb": "application/mathematica",
  1539. "mbox": "application/mbox",
  1540. "md": "text/markdown",
  1541. "mdx": "text/mdx",
  1542. "me": "text/troff",
  1543. "mesh": "model/mesh",
  1544. "meta4": "application/metalink4+xml",
  1545. "metalink": "application/metalink+xml",
  1546. "mets": "application/mets+xml",
  1547. "mft": "application/rpki-manifest",
  1548. "mid": "audio/midi",
  1549. "midi": "audio/midi",
  1550. "mime": "message/rfc822",
  1551. "mj2": "video/mj2",
  1552. "mjp2": "video/mj2",
  1553. "mjs": "text/javascript",
  1554. "mml": "text/mathml",
  1555. "mods": "application/mods+xml",
  1556. "mov": "video/quicktime",
  1557. "mp2": "audio/mpeg",
  1558. "mp21": "application/mp21",
  1559. "mp2a": "audio/mpeg",
  1560. "mp3": "audio/mpeg",
  1561. "mp4": "video/mp4",
  1562. "mp4a": "audio/mp4",
  1563. "mp4s": "application/mp4",
  1564. "mp4v": "video/mp4",
  1565. "mpd": "application/dash+xml",
  1566. "mpe": "video/mpeg",
  1567. "mpeg": "video/mpeg",
  1568. "mpf": "application/media-policy-dataset+xml",
  1569. "mpg": "video/mpeg",
  1570. "mpg4": "video/mp4",
  1571. "mpga": "audio/mpeg",
  1572. "mpp": "application/dash-patch+xml",
  1573. "mrc": "application/marc",
  1574. "mrcx": "application/marcxml+xml",
  1575. "ms": "text/troff",
  1576. "mscml": "application/mediaservercontrol+xml",
  1577. "msh": "model/mesh",
  1578. "msi": "application/octet-stream",
  1579. "msix": "application/msix",
  1580. "msixbundle": "application/msixbundle",
  1581. "msm": "application/octet-stream",
  1582. "msp": "application/octet-stream",
  1583. "mtl": "model/mtl",
  1584. "mts": "video/mp2t",
  1585. "musd": "application/mmt-usd+xml",
  1586. "mxf": "application/mxf",
  1587. "mxmf": "audio/mobile-xmf",
  1588. "mxml": "application/xv+xml",
  1589. "n3": "text/n3",
  1590. "nb": "application/mathematica",
  1591. "nq": "application/n-quads",
  1592. "nt": "application/n-triples",
  1593. "obj": "model/obj",
  1594. "oda": "application/oda",
  1595. "oga": "audio/ogg",
  1596. "ogg": "audio/ogg",
  1597. "ogv": "video/ogg",
  1598. "ogx": "application/ogg",
  1599. "omdoc": "application/omdoc+xml",
  1600. "onepkg": "application/onenote",
  1601. "onetmp": "application/onenote",
  1602. "onetoc": "application/onenote",
  1603. "onetoc2": "application/onenote",
  1604. "opf": "application/oebps-package+xml",
  1605. "opus": "audio/ogg",
  1606. "otf": "font/otf",
  1607. "owl": "application/rdf+xml",
  1608. "oxps": "application/oxps",
  1609. "p10": "application/pkcs10",
  1610. "p7c": "application/pkcs7-mime",
  1611. "p7m": "application/pkcs7-mime",
  1612. "p7s": "application/pkcs7-signature",
  1613. "p8": "application/pkcs8",
  1614. "pdf": "application/pdf",
  1615. "pfr": "application/font-tdpfr",
  1616. "pgp": "application/pgp-encrypted",
  1617. "pkg": "application/octet-stream",
  1618. "pki": "application/pkixcmp",
  1619. "pkipath": "application/pkix-pkipath",
  1620. "pls": "application/pls+xml",
  1621. "png": "image/png",
  1622. "prc": "model/prc",
  1623. "prf": "application/pics-rules",
  1624. "provx": "application/provenance+xml",
  1625. "ps": "application/postscript",
  1626. "pskcxml": "application/pskc+xml",
  1627. "pti": "image/prs.pti",
  1628. "qt": "video/quicktime",
  1629. "raml": "application/raml+yaml",
  1630. "rapd": "application/route-apd+xml",
  1631. "rdf": "application/rdf+xml",
  1632. "relo": "application/p2p-overlay+xml",
  1633. "rif": "application/reginfo+xml",
  1634. "rl": "application/resource-lists+xml",
  1635. "rld": "application/resource-lists-diff+xml",
  1636. "rmi": "audio/midi",
  1637. "rnc": "application/relax-ng-compact-syntax",
  1638. "rng": "application/xml",
  1639. "roa": "application/rpki-roa",
  1640. "roff": "text/troff",
  1641. "rq": "application/sparql-query",
  1642. "rs": "application/rls-services+xml",
  1643. "rsat": "application/atsc-rsat+xml",
  1644. "rsd": "application/rsd+xml",
  1645. "rsheet": "application/urc-ressheet+xml",
  1646. "rss": "application/rss+xml",
  1647. "rtf": "text/rtf",
  1648. "rtx": "text/richtext",
  1649. "rusd": "application/route-usd+xml",
  1650. "s3m": "audio/s3m",
  1651. "sbml": "application/sbml+xml",
  1652. "scq": "application/scvp-cv-request",
  1653. "scs": "application/scvp-cv-response",
  1654. "sdp": "application/sdp",
  1655. "senmlx": "application/senml+xml",
  1656. "sensmlx": "application/sensml+xml",
  1657. "ser": "application/java-serialized-object",
  1658. "setpay": "application/set-payment-initiation",
  1659. "setreg": "application/set-registration-initiation",
  1660. "sgi": "image/sgi",
  1661. "sgm": "text/sgml",
  1662. "sgml": "text/sgml",
  1663. "shex": "text/shex",
  1664. "shf": "application/shf+xml",
  1665. "shtml": "text/html",
  1666. "sieve": "application/sieve",
  1667. "sig": "application/pgp-signature",
  1668. "sil": "audio/silk",
  1669. "silo": "model/mesh",
  1670. "siv": "application/sieve",
  1671. "slim": "text/slim",
  1672. "slm": "text/slim",
  1673. "sls": "application/route-s-tsid+xml",
  1674. "smi": "application/smil+xml",
  1675. "smil": "application/smil+xml",
  1676. "snd": "audio/basic",
  1677. "so": "application/octet-stream",
  1678. "spdx": "text/spdx",
  1679. "spp": "application/scvp-vp-response",
  1680. "spq": "application/scvp-vp-request",
  1681. "spx": "audio/ogg",
  1682. "sql": "application/sql",
  1683. "sru": "application/sru+xml",
  1684. "srx": "application/sparql-results+xml",
  1685. "ssdl": "application/ssdl+xml",
  1686. "ssml": "application/ssml+xml",
  1687. "stk": "application/hyperstudio",
  1688. "stl": "model/stl",
  1689. "stpx": "model/step+xml",
  1690. "stpxz": "model/step-xml+zip",
  1691. "stpz": "model/step+zip",
  1692. "styl": "text/stylus",
  1693. "stylus": "text/stylus",
  1694. "svg": "image/svg+xml",
  1695. "svgz": "image/svg+xml",
  1696. "swidtag": "application/swid+xml",
  1697. "t": "text/troff",
  1698. "t38": "image/t38",
  1699. "td": "application/urc-targetdesc+xml",
  1700. "tei": "application/tei+xml",
  1701. "teicorpus": "application/tei+xml",
  1702. "text": "text/plain",
  1703. "tfi": "application/thraud+xml",
  1704. "tfx": "image/tiff-fx",
  1705. "tif": "image/tiff",
  1706. "tiff": "image/tiff",
  1707. "toml": "application/toml",
  1708. "tr": "text/troff",
  1709. "trig": "application/trig",
  1710. "ts": "video/mp2t",
  1711. "tsd": "application/timestamped-data",
  1712. "tsv": "text/tab-separated-values",
  1713. "ttc": "font/collection",
  1714. "ttf": "font/ttf",
  1715. "ttl": "text/turtle",
  1716. "ttml": "application/ttml+xml",
  1717. "txt": "text/plain",
  1718. "u3d": "model/u3d",
  1719. "u8dsn": "message/global-delivery-status",
  1720. "u8hdr": "message/global-headers",
  1721. "u8mdn": "message/global-disposition-notification",
  1722. "u8msg": "message/global",
  1723. "ubj": "application/ubjson",
  1724. "uri": "text/uri-list",
  1725. "uris": "text/uri-list",
  1726. "urls": "text/uri-list",
  1727. "vcard": "text/vcard",
  1728. "vrml": "model/vrml",
  1729. "vtt": "text/vtt",
  1730. "vxml": "application/voicexml+xml",
  1731. "war": "application/java-archive",
  1732. "wasm": "application/wasm",
  1733. "wav": "audio/wav",
  1734. "weba": "audio/webm",
  1735. "webm": "video/webm",
  1736. "webmanifest": "application/manifest+json",
  1737. "webp": "image/webp",
  1738. "wgsl": "text/wgsl",
  1739. "wgt": "application/widget",
  1740. "wif": "application/watcherinfo+xml",
  1741. "wmf": "image/wmf",
  1742. "woff": "font/woff",
  1743. "woff2": "font/woff2",
  1744. "wrl": "model/vrml",
  1745. "wsdl": "application/wsdl+xml",
  1746. "wspolicy": "application/wspolicy+xml",
  1747. "x3d": "model/x3d+xml",
  1748. "x3db": "model/x3d+fastinfoset",
  1749. "x3dbz": "model/x3d+binary",
  1750. "x3dv": "model/x3d-vrml",
  1751. "x3dvz": "model/x3d+vrml",
  1752. "x3dz": "model/x3d+xml",
  1753. "xaml": "application/xaml+xml",
  1754. "xav": "application/xcap-att+xml",
  1755. "xca": "application/xcap-caps+xml",
  1756. "xcs": "application/calendar+xml",
  1757. "xdf": "application/xcap-diff+xml",
  1758. "xdssc": "application/dssc+xml",
  1759. "xel": "application/xcap-el+xml",
  1760. "xenc": "application/xenc+xml",
  1761. "xer": "application/patch-ops-error+xml",
  1762. "xfdf": "application/xfdf",
  1763. "xht": "application/xhtml+xml",
  1764. "xhtml": "application/xhtml+xml",
  1765. "xhvml": "application/xv+xml",
  1766. "xlf": "application/xliff+xml",
  1767. "xm": "audio/xm",
  1768. "xml": "text/xml",
  1769. "xns": "application/xcap-ns+xml",
  1770. "xop": "application/xop+xml",
  1771. "xpl": "application/xproc+xml",
  1772. "xsd": "application/xml",
  1773. "xsf": "application/prs.xsf+xml",
  1774. "xsl": "application/xml",
  1775. "xslt": "application/xml",
  1776. "xspf": "application/xspf+xml",
  1777. "xvm": "application/xv+xml",
  1778. "xvml": "application/xv+xml",
  1779. "yaml": "text/yaml",
  1780. "yang": "application/yang",
  1781. "yin": "application/yin+xml",
  1782. "yml": "text/yaml",
  1783. "zip": "application/zip"
  1784. };
  1785. function lookup(extn) {
  1786. let tmp = ('' + extn).trim().toLowerCase();
  1787. let idx = tmp.lastIndexOf('.');
  1788. return mimes[!~idx ? tmp : tmp.substring(++idx)];
  1789. }
  1790. const $$Astro$1 = createAstro();
  1791. const $$Picture = createComponent(async ($$result, $$props, $$slots) => {
  1792. const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots);
  1793. Astro2.self = $$Picture;
  1794. const defaultFormats = ["webp"];
  1795. const defaultFallbackFormat = "png";
  1796. const specialFormatsFallback = ["gif", "svg", "jpg", "jpeg"];
  1797. const { formats = defaultFormats, pictureAttributes = {}, fallbackFormat, ...props } = Astro2.props;
  1798. if (props.alt === void 0 || props.alt === null) {
  1799. throw new AstroError(ImageMissingAlt);
  1800. }
  1801. const scopedStyleClass = props.class?.match(/\bastro-\w{8}\b/)?.[0];
  1802. if (scopedStyleClass) {
  1803. if (pictureAttributes.class) {
  1804. pictureAttributes.class = `${pictureAttributes.class} ${scopedStyleClass}`;
  1805. } else {
  1806. pictureAttributes.class = scopedStyleClass;
  1807. }
  1808. }
  1809. const layout = props.layout ?? imageConfig.layout ?? "none";
  1810. const useResponsive = layout !== "none";
  1811. if (useResponsive) {
  1812. props.layout ??= imageConfig.layout;
  1813. props.fit ??= imageConfig.objectFit ?? "cover";
  1814. props.position ??= imageConfig.objectPosition ?? "center";
  1815. }
  1816. for (const key in props) {
  1817. if (key.startsWith("data-astro-cid")) {
  1818. pictureAttributes[key] = props[key];
  1819. }
  1820. }
  1821. const originalSrc = await resolveSrc(props.src);
  1822. const optimizedImages = await Promise.all(
  1823. formats.map(
  1824. async (format) => await getImage({
  1825. ...props,
  1826. src: originalSrc,
  1827. format,
  1828. widths: props.widths,
  1829. densities: props.densities
  1830. })
  1831. )
  1832. );
  1833. let resultFallbackFormat = fallbackFormat ?? defaultFallbackFormat;
  1834. if (!fallbackFormat && isESMImportedImage(originalSrc) && specialFormatsFallback.includes(originalSrc.format)) {
  1835. resultFallbackFormat = originalSrc.format;
  1836. }
  1837. const fallbackImage = await getImage({
  1838. ...props,
  1839. format: resultFallbackFormat,
  1840. widths: props.widths,
  1841. densities: props.densities
  1842. });
  1843. const imgAdditionalAttributes = {};
  1844. const sourceAdditionalAttributes = {};
  1845. if (props.sizes) {
  1846. sourceAdditionalAttributes.sizes = props.sizes;
  1847. }
  1848. if (fallbackImage.srcSet.values.length > 0) {
  1849. imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute;
  1850. }
  1851. const { class: className, ...attributes } = {
  1852. ...imgAdditionalAttributes,
  1853. ...fallbackImage.attributes
  1854. };
  1855. return renderTemplate`${maybeRenderHead()}<picture${spreadAttributes(pictureAttributes)}> ${Object.entries(optimizedImages).map(([_, image]) => {
  1856. const srcsetAttribute = props.densities || !props.densities && !props.widths && !useResponsive ? `${image.src}${image.srcSet.values.length > 0 ? ", " + image.srcSet.attribute : ""}` : image.srcSet.attribute;
  1857. return renderTemplate`<source${addAttribute(srcsetAttribute, "srcset")}${addAttribute(lookup(image.options.format ?? image.src) ?? `image/${image.options.format}`, "type")}${spreadAttributes(sourceAdditionalAttributes)}>`;
  1858. })} <img${addAttribute(fallbackImage.src, "src")}${spreadAttributes(attributes)}${addAttribute(className, "class")}> </picture>`;
  1859. }, "/home/fc/Projects/glance/node_modules/astro/components/Picture.astro", void 0);
  1860. const fontsMod = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
  1861. __proto__: null
  1862. }, Symbol.toStringTag, { value: 'Module' }));
  1863. const $$Astro = createAstro();
  1864. const $$Font = createComponent(($$result, $$props, $$slots) => {
  1865. const Astro2 = $$result.createAstro($$Astro, $$props, $$slots);
  1866. Astro2.self = $$Font;
  1867. const { internalConsumableMap } = fontsMod;
  1868. if (!internalConsumableMap) {
  1869. throw new AstroError(ExperimentalFontsNotEnabled);
  1870. }
  1871. const { cssVariable, preload = false } = Astro2.props;
  1872. const data = internalConsumableMap.get(cssVariable);
  1873. if (!data) {
  1874. throw new AstroError({
  1875. ...FontFamilyNotFound,
  1876. message: FontFamilyNotFound.message(cssVariable)
  1877. });
  1878. }
  1879. return renderTemplate`${preload && data.preloadData.map(({ url, type }) => renderTemplate`<link rel="preload"${addAttribute(url, "href")} as="font"${addAttribute(`font/${type}`, "type")} crossorigin>`)}<style>${unescapeHTML(data.css)}</style>`;
  1880. }, "/home/fc/Projects/glance/node_modules/astro/components/Font.astro", void 0);
  1881. const imageConfig = {"endpoint":{"route":"/_image","entrypoint":"@astrojs/cloudflare/image-endpoint"},"service":{"entrypoint":"astro/assets/services/sharp","config":{}},"domains":[],"remotePatterns":[],"responsiveStyles":false};
  1882. const getImage = async (options) => await getImage$1(options, imageConfig);
  1883. const prerender = false;
  1884. const GET = (ctx) => {
  1885. const href = ctx.url.searchParams.get("href");
  1886. if (!href) {
  1887. return new Response("Missing 'href' query parameter", {
  1888. status: 400,
  1889. statusText: "Missing 'href' query parameter"
  1890. });
  1891. }
  1892. if (isRemotePath(href)) {
  1893. if (isRemoteAllowed(href, imageConfig) === false) {
  1894. return new Response("Forbidden", { status: 403 });
  1895. } else {
  1896. return Response.redirect(href, 302);
  1897. }
  1898. }
  1899. const proxied = new URL(href, ctx.url.origin);
  1900. if (proxied.origin !== ctx.url.origin) {
  1901. return new Response("Forbidden", { status: 403 });
  1902. }
  1903. return fetch(proxied);
  1904. };
  1905. const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
  1906. __proto__: null,
  1907. GET,
  1908. prerender
  1909. }, Symbol.toStringTag, { value: 'Module' }));
  1910. const page = () => _page;
  1911. export { page as a, baseService as b, parseQuality as p };