"use strict";
((window) => {
const core = window.Deno.core;
const webidl = window.__bootstrap.webidl;
const isWindows = false;
function collectCodepointsNotCRLF(input, position) {
const start = position;
for (
let c = input.charAt(position);
position < input.length && !(c === "\r" || c === "\n");
c = input.charAt(++position)
);
return { result: input.slice(start, position), position };
}
function convertLineEndingsToNative(s) {
const nativeLineEnding = isWindows ? "\r\n" : "\n";
let { result, position } = collectCodepointsNotCRLF(s, 0);
while (position < s.length) {
const codePoint = s.charAt(position);
if (codePoint === "\r") {
result += nativeLineEnding;
position++;
if (position < s.length && s.charAt(position) === "\n") {
position++;
}
} else if (codePoint === "\n") {
position++;
result += nativeLineEnding;
}
const { result: token, position: newPosition } = collectCodepointsNotCRLF(
s,
position,
);
position = newPosition;
result += token;
}
return result;
}
function concatUint8Arrays(...bytesArrays) {
let byteLength = 0;
for (const bytes of bytesArrays) {
byteLength += bytes.byteLength;
}
const finalBytes = new Uint8Array(byteLength);
let current = 0;
for (const bytes of bytesArrays) {
finalBytes.set(bytes, current);
current += bytes.byteLength;
}
return finalBytes;
}
function processBlobParts(parts, endings) {
const bytesArrays = [];
for (const element of parts) {
if (element instanceof ArrayBuffer) {
bytesArrays.push(new Uint8Array(element.slice(0)));
} else if (ArrayBuffer.isView(element)) {
const buffer = element.buffer.slice(
element.byteOffset,
element.byteOffset + element.byteLength,
);
bytesArrays.push(new Uint8Array(buffer));
} else if (element instanceof Blob) {
bytesArrays.push(
new Uint8Array(element[_byteSequence].buffer.slice(0)),
);
} else if (typeof element === "string") {
let s = element;
if (endings == "native") {
s = convertLineEndingsToNative(s);
}
bytesArrays.push(core.encode(s));
} else {
throw new TypeError("Unreachable code (invalild element type)");
}
}
return concatUint8Arrays(...bytesArrays);
}
function normalizeType(str) {
let normalizedType = str;
if (!/^[\x20-\x7E]*$/.test(str)) {
normalizedType = "";
}
return normalizedType.toLowerCase();
}
const _byteSequence = Symbol("[[ByteSequence]]");
class Blob {
get [Symbol.toStringTag]() {
return "Blob";
}
#type;
[_byteSequence];
constructor(blobParts = [], options = {}) {
const prefix = "Failed to construct 'Blob'";
blobParts = webidl.converters["sequence<BlobPart>"](blobParts, {
context: "Argument 1",
prefix,
});
options = webidl.converters["BlobPropertyBag"](options, {
context: "Argument 2",
prefix,
});
this[webidl.brand] = webidl.brand;
this[_byteSequence] = processBlobParts(
blobParts,
options.endings,
);
this.#type = normalizeType(options.type);
}
get size() {
webidl.assertBranded(this, Blob);
return this[_byteSequence].byteLength;
}
get type() {
webidl.assertBranded(this, Blob);
return this.#type;
}
slice(start, end, contentType) {
webidl.assertBranded(this, Blob);
const prefix = "Failed to execute 'slice' on 'Blob'";
if (start !== undefined) {
start = webidl.converters["long long"](start, {
clamp: true,
context: "Argument 1",
prefix,
});
}
if (end !== undefined) {
end = webidl.converters["long long"](end, {
clamp: true,
context: "Argument 2",
prefix,
});
}
if (contentType !== undefined) {
contentType = webidl.converters["DOMString"](contentType, {
context: "Argument 3",
prefix,
});
}
const O = this;
let relativeStart;
if (start === undefined) {
relativeStart = 0;
} else {
if (start < 0) {
relativeStart = Math.max(O.size + start, 0);
} else {
relativeStart = Math.min(start, O.size);
}
}
let relativeEnd;
if (end === undefined) {
relativeEnd = O.size;
} else {
if (end < 0) {
relativeEnd = Math.max(O.size + end, 0);
} else {
relativeEnd = Math.min(end, O.size);
}
}
let relativeContentType;
if (contentType === undefined) {
relativeContentType = "";
} else {
relativeContentType = normalizeType(contentType);
}
return new Blob([
O[_byteSequence].buffer.slice(relativeStart, relativeEnd),
], { type: relativeContentType });
}
stream() {
webidl.assertBranded(this, Blob);
const bytes = this[_byteSequence];
const stream = new ReadableStream({
type: "bytes",
start(controller) {
const chunk = new Uint8Array(bytes.buffer.slice(0));
if (chunk.byteLength > 0) controller.enqueue(chunk);
controller.close();
},
});
return stream;
}
async text() {
webidl.assertBranded(this, Blob);
const buffer = await this.arrayBuffer();
return core.decode(new Uint8Array(buffer));
}
async arrayBuffer() {
webidl.assertBranded(this, Blob);
const stream = this.stream();
let bytes = new Uint8Array();
for await (const chunk of stream) {
bytes = concatUint8Arrays(bytes, chunk);
}
return bytes.buffer;
}
}
webidl.configurePrototype(Blob);
webidl.converters["Blob"] = webidl.createInterfaceConverter("Blob", Blob);
webidl.converters["BlobPart"] = (V, opts) => {
if (typeof V == "object") {
if (V instanceof Blob) {
return webidl.converters["Blob"](V, opts);
}
if (V instanceof ArrayBuffer || V instanceof SharedArrayBuffer) {
return webidl.converters["ArrayBuffer"](V, opts);
}
if (ArrayBuffer.isView(V)) {
return webidl.converters["ArrayBufferView"](V, opts);
}
}
return webidl.converters["USVString"](V, opts);
};
webidl.converters["sequence<BlobPart>"] = webidl.createSequenceConverter(
webidl.converters["BlobPart"],
);
webidl.converters["EndingType"] = webidl.createEnumConverter("EndingType", [
"transparent",
"native",
]);
const blobPropertyBagDictionary = [
{
key: "type",
converter: webidl.converters["DOMString"],
defaultValue: "",
},
{
key: "endings",
converter: webidl.converters["EndingType"],
defaultValue: "transparent",
},
];
webidl.converters["BlobPropertyBag"] = webidl.createDictionaryConverter(
"BlobPropertyBag",
blobPropertyBagDictionary,
);
const _Name = Symbol("[[Name]]");
const _LastModfied = Symbol("[[LastModified]]");
class File extends Blob {
get [Symbol.toStringTag]() {
return "File";
}
[_Name];
[_LastModfied];
constructor(fileBits, fileName, options = {}) {
const prefix = "Failed to construct 'File'";
webidl.requiredArguments(arguments.length, 2, { prefix });
fileBits = webidl.converters["sequence<BlobPart>"](fileBits, {
context: "Argument 1",
prefix,
});
fileName = webidl.converters["USVString"](fileName, {
context: "Argument 2",
prefix,
});
options = webidl.converters["FilePropertyBag"](options, {
context: "Argument 3",
prefix,
});
super(fileBits, options);
this[_Name] = fileName;
if (options.lastModified === undefined) {
this[_LastModfied] = new Date().getTime();
} else {
this[_LastModfied] = options.lastModified;
}
}
get name() {
webidl.assertBranded(this, File);
return this[_Name];
}
get lastModified() {
webidl.assertBranded(this, File);
return this[_LastModfied];
}
}
webidl.configurePrototype(File);
webidl.converters["FilePropertyBag"] = webidl.createDictionaryConverter(
"FilePropertyBag",
blobPropertyBagDictionary,
[
{
key: "lastModified",
converter: webidl.converters["long long"],
},
],
);
window.__bootstrap.file = {
Blob,
_byteSequence,
File,
};
})(this);