From 8bf9f81283efb215a3ca49c4203f5a9d379c7d90 Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Mon, 29 Apr 2024 08:01:25 +0200 Subject: [PATCH] docs: update pdf example --- examples/pdf.js | 2 - .../out/BrowserWebSocketTransport-D_zAGZMQ.js | 40 + .../out/NodeWebSocketTransport-CMYjMSDi.js | 64 + .../out/ScreenRecorder-MnWKtu-C.js | 214 + .../puppeteer-in-browser/out/bidi-DSmqnPgA.js | 6109 +++++ examples/puppeteer-in-browser/out/main.js | 20297 ++++++++++++++++ 6 files changed, 26724 insertions(+), 2 deletions(-) create mode 100644 examples/puppeteer-in-browser/out/BrowserWebSocketTransport-D_zAGZMQ.js create mode 100644 examples/puppeteer-in-browser/out/NodeWebSocketTransport-CMYjMSDi.js create mode 100644 examples/puppeteer-in-browser/out/ScreenRecorder-MnWKtu-C.js create mode 100644 examples/puppeteer-in-browser/out/bidi-DSmqnPgA.js create mode 100644 examples/puppeteer-in-browser/out/main.js diff --git a/examples/pdf.js b/examples/pdf.js index e97cc53cdb4..d8c697055b0 100644 --- a/examples/pdf.js +++ b/examples/pdf.js @@ -14,8 +14,6 @@ const puppeteer = require('puppeteer'); await page.goto('https://news.ycombinator.com', { waitUntil: 'networkidle2', }); - // page.pdf() is currently supported only in headless mode. - // @see https://bugs.chromium.org/p/chromium/issues/detail?id=753118 await page.pdf({ path: 'hn.pdf', format: 'letter', diff --git a/examples/puppeteer-in-browser/out/BrowserWebSocketTransport-D_zAGZMQ.js b/examples/puppeteer-in-browser/out/BrowserWebSocketTransport-D_zAGZMQ.js new file mode 100644 index 00000000000..da32e61962c --- /dev/null +++ b/examples/puppeteer-in-browser/out/BrowserWebSocketTransport-D_zAGZMQ.js @@ -0,0 +1,40 @@ +/** + * @internal + */ +class BrowserWebSocketTransport { + static create(url) { + return new Promise((resolve, reject) => { + const ws = new WebSocket(url); + ws.addEventListener('open', () => { + return resolve(new BrowserWebSocketTransport(ws)); + }); + ws.addEventListener('error', reject); + }); + } + #ws; + onmessage; + onclose; + constructor(ws) { + this.#ws = ws; + this.#ws.addEventListener('message', event => { + if (this.onmessage) { + this.onmessage.call(null, event.data); + } + }); + this.#ws.addEventListener('close', () => { + if (this.onclose) { + this.onclose.call(null); + } + }); + // Silently ignore all errors - we don't know what to do with them. + this.#ws.addEventListener('error', () => { }); + } + send(message) { + this.#ws.send(message); + } + close() { + this.#ws.close(); + } +} + +export { BrowserWebSocketTransport }; diff --git a/examples/puppeteer-in-browser/out/NodeWebSocketTransport-CMYjMSDi.js b/examples/puppeteer-in-browser/out/NodeWebSocketTransport-CMYjMSDi.js new file mode 100644 index 00000000000..8baf3f35b41 --- /dev/null +++ b/examples/puppeteer-in-browser/out/NodeWebSocketTransport-CMYjMSDi.js @@ -0,0 +1,64 @@ +import NodeWebSocket from 'ws'; + +/** + * @internal + */ +const packageVersion = '22.7.1'; + +/** + * @license + * Copyright 2018 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class NodeWebSocketTransport { + static create(url, headers) { + return new Promise((resolve, reject) => { + const ws = new NodeWebSocket(url, [], { + followRedirects: true, + perMessageDeflate: false, + maxPayload: 256 * 1024 * 1024, // 256Mb + headers: { + 'User-Agent': `Puppeteer ${packageVersion}`, + ...headers, + }, + }); + ws.addEventListener('open', () => { + return resolve(new NodeWebSocketTransport(ws)); + }); + ws.addEventListener('error', reject); + }); + } + #ws; + onmessage; + onclose; + constructor(ws) { + this.#ws = ws; + this.#ws.addEventListener('message', event => { + setImmediate(() => { + if (this.onmessage) { + this.onmessage.call(null, event.data); + } + }); + }); + this.#ws.addEventListener('close', () => { + setImmediate(() => { + if (this.onclose) { + this.onclose.call(null); + } + }); + }); + // Silently ignore all errors - we don't know what to do with them. + this.#ws.addEventListener('error', () => { }); + } + send(message) { + this.#ws.send(message); + } + close() { + this.#ws.close(); + } +} + +export { NodeWebSocketTransport }; diff --git a/examples/puppeteer-in-browser/out/ScreenRecorder-MnWKtu-C.js b/examples/puppeteer-in-browser/out/ScreenRecorder-MnWKtu-C.js new file mode 100644 index 00000000000..e34141514f2 --- /dev/null +++ b/examples/puppeteer-in-browser/out/ScreenRecorder-MnWKtu-C.js @@ -0,0 +1,214 @@ +import { spawnSync, spawn } from 'child_process'; +import { PassThrough } from 'stream'; +import debug from 'debug'; +import { C as CDPSessionEvent, d as debugError, l as lastValueFrom, f as fromEmitterEvent, t as tap, a as filter, m as map, b as bufferCount, c as concatMap, e as takeUntil, g as fromEvent, h as guarded, i as asyncDisposeSymbol, j as from } from './main.js'; + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var __setFunctionName = (undefined && undefined.__setFunctionName) || function (f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); +}; +const CRF_VALUE = 30; +const DEFAULT_FPS = 30; +const debugFfmpeg = debug('puppeteer:ffmpeg'); +/** + * @public + */ +let ScreenRecorder = (() => { + let _classSuper = PassThrough; + let _instanceExtraInitializers = []; + let _private_writeFrame_decorators; + let _private_writeFrame_descriptor; + let _stop_decorators; + return class ScreenRecorder extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + __esDecorate(this, _private_writeFrame_descriptor = { value: __setFunctionName(async function (buffer) { + const error = await new Promise(resolve => { + this.#process.stdin.write(buffer, resolve); + }); + if (error) { + console.log(`ffmpeg failed to write: ${error.message}.`); + } + }, "#writeFrame") }, _private_writeFrame_decorators, { kind: "method", name: "#writeFrame", static: false, private: true, access: { has: obj => #writeFrame in obj, get: obj => obj.#writeFrame }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate(this, null, _stop_decorators, { kind: "method", name: "stop", static: false, private: false, access: { has: obj => "stop" in obj, get: obj => obj.stop }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + #page = (__runInitializers(this, _instanceExtraInitializers), void 0); + #process; + #controller = new AbortController(); + #lastFrame; + /** + * @internal + */ + constructor(page, width, height, { speed, scale, crop, format, path } = {}) { + super({ allowHalfOpen: false }); + path ??= 'ffmpeg'; + // Tests if `ffmpeg` exists. + const { error } = spawnSync(path); + if (error) { + throw error; + } + this.#process = spawn(path, + // See https://trac.ffmpeg.org/wiki/Encode/VP9 for more information on flags. + [ + ['-loglevel', 'error'], + // Reduces general buffering. + ['-avioflags', 'direct'], + // Reduces initial buffering while analyzing input fps and other stats. + [ + '-fpsprobesize', + '0', + '-probesize', + '32', + '-analyzeduration', + '0', + '-fflags', + 'nobuffer', + ], + // Forces input to be read from standard input, and forces png input + // image format. + ['-f', 'image2pipe', '-c:v', 'png', '-i', 'pipe:0'], + // Overwrite output and no audio. + ['-y', '-an'], + // This drastically reduces stalling when cpu is overbooked. By default + // VP9 tries to use all available threads? + ['-threads', '1'], + // Specifies the frame rate we are giving ffmpeg. + ['-framerate', `${DEFAULT_FPS}`], + // Specifies the encoding and format we are using. + this.#getFormatArgs(format ?? 'webm'), + // Disable bitrate. + ['-b:v', '0'], + // Filters to ensure the images are piped correctly. + [ + '-vf', + `${speed ? `setpts=${1 / speed}*PTS,` : ''}crop='min(${width},iw):min(${height},ih):0:0',pad=${width}:${height}:0:0${crop ? `,crop=${crop.width}:${crop.height}:${crop.x}:${crop.y}` : ''}${scale ? `,scale=iw*${scale}:-1` : ''}`, + ], + 'pipe:1', + ].flat(), { stdio: ['pipe', 'pipe', 'pipe'] }); + this.#process.stdout.pipe(this); + this.#process.stderr.on('data', (data) => { + debugFfmpeg(data.toString('utf8')); + }); + this.#page = page; + const { client } = this.#page.mainFrame(); + client.once(CDPSessionEvent.Disconnected, () => { + void this.stop().catch(debugError); + }); + this.#lastFrame = lastValueFrom(fromEmitterEvent(client, 'Page.screencastFrame').pipe(tap(event => { + void client.send('Page.screencastFrameAck', { + sessionId: event.sessionId, + }); + }), filter(event => { + return event.metadata.timestamp !== undefined; + }), map(event => { + return { + buffer: Buffer.from(event.data, 'base64'), + timestamp: event.metadata.timestamp, + }; + }), bufferCount(2, 1), concatMap(([{ timestamp: previousTimestamp, buffer }, { timestamp }]) => { + return from(Array(Math.round(DEFAULT_FPS * Math.max(timestamp - previousTimestamp, 0))).fill(buffer)); + }), map(buffer => { + void this.#writeFrame(buffer); + return [buffer, performance.now()]; + }), takeUntil(fromEvent(this.#controller.signal, 'abort'))), { defaultValue: [Buffer.from([]), performance.now()] }); + } + #getFormatArgs(format) { + switch (format) { + case 'webm': + return [ + // Sets the codec to use. + ['-c:v', 'vp9'], + // Sets the format + ['-f', 'webm'], + // Sets the quality. Lower the better. + ['-crf', `${CRF_VALUE}`], + // Sets the quality and how efficient the compression will be. + ['-deadline', 'realtime', '-cpu-used', '8'], + ].flat(); + case 'gif': + return [ + // Sets the frame rate and uses a custom palette generated from the + // input. + [ + '-vf', + 'fps=5,split[s0][s1];[s0]palettegen=stats_mode=diff[p];[s1][p]paletteuse', + ], + // Sets the format + ['-f', 'gif'], + ].flat(); + } + } + get #writeFrame() { return _private_writeFrame_descriptor.value; } + /** + * Stops the recorder. + * + * @public + */ + async stop() { + if (this.#controller.signal.aborted) { + return; + } + // Stopping the screencast will flush the frames. + await this.#page._stopScreencast().catch(debugError); + this.#controller.abort(); + // Repeat the last frame for the remaining frames. + const [buffer, timestamp] = await this.#lastFrame; + await Promise.all(Array(Math.max(1, Math.round((DEFAULT_FPS * (performance.now() - timestamp)) / 1000))) + .fill(buffer) + .map(this.#writeFrame.bind(this))); + // Close stdin to notify FFmpeg we are done. + this.#process.stdin.end(); + await new Promise(resolve => { + this.#process.once('close', resolve); + }); + } + /** + * @internal + */ + async [(_private_writeFrame_decorators = [guarded()], _stop_decorators = [guarded()], asyncDisposeSymbol)]() { + await this.stop(); + } + }; +})(); + +export { ScreenRecorder }; diff --git a/examples/puppeteer-in-browser/out/bidi-DSmqnPgA.js b/examples/puppeteer-in-browser/out/bidi-DSmqnPgA.js new file mode 100644 index 00000000000..22ed31fb64f --- /dev/null +++ b/examples/puppeteer-in-browser/out/bidi-DSmqnPgA.js @@ -0,0 +1,6109 @@ +import * as BidiMapper from 'chromium-bidi/lib/cjs/bidiMapper/BidiMapper.js'; +import { k as CDPSession, D as Deferred, U as UnsupportedOperation, T as TargetCloseError, E as EventEmitter, n as CallbackRegistry, o as assert, d as debugError, p as debug, q as DisposableStack, r as disposeSymbol, s as inertIfDisposed, u as throwIfDisposed, v as Dialog, J as JSHandle, w as ElementHandle, A as AsyncIterableUtil, x as stringifyFunction, y as interpolateFunction, H as HTTPResponse, z as invokeAtMostOnceForArguments, B as HTTPRequest, F as handleError, S as STATUS_TEXTS, G as isPlainObject, I as isRegExp, K as isDate, P as PuppeteerURL, L as ProtocolError, M as TimeoutError, R as Realm$1, N as scriptInjector, O as getSourceUrlComment, Q as getSourcePuppeteerURLIfAvailable, V as isString, W as LazyArg, X as ARIAQueryHandler, Y as SOURCE_URL_REGEX, Z as WebWorker, _ as of, $ as combineLatest, f as fromEmitterEvent, m as map, a0 as first, a1 as raceWith, a2 as timeout, a3 as ConsoleMessage, a4 as defer, a as filter, a5 as isErrorLike, a6 as firstValueFrom, a7 as switchMap, a8 as delayWhen, a9 as Frame, aa as throwIfDetached, ab as Keyboard, ac as Mouse, ad as MouseButton, ae as Touchscreen, af as EmulationManager, ag as Accessibility, ah as Tracing, ai as Coverage, aj as parsePDFOptions, j as from, ak as evaluationString, al as Page, am as bubble, an as Target, ao as TargetType, ap as WEB_PERMISSION_TO_PROTOCOL_PERMISSION, aq as BrowserContext, ar as Browser$1 } from './main.js'; +import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js'; + +/** + * @internal + */ +class BidiCdpSession extends CDPSession { + static sessions = new Map(); + #detached = false; + #connection; + #sessionId = Deferred.create(); + frame; + constructor(frame, sessionId) { + super(); + this.frame = frame; + if (!this.frame.page().browser().cdpSupported) { + return; + } + const connection = this.frame.page().browser().connection; + this.#connection = connection; + if (sessionId) { + this.#sessionId.resolve(sessionId); + BidiCdpSession.sessions.set(sessionId, this); + } + else { + (async () => { + try { + const { result } = await connection.send('cdp.getSession', { + context: frame._id, + }); + this.#sessionId.resolve(result.session); + BidiCdpSession.sessions.set(result.session, this); + } + catch (error) { + this.#sessionId.reject(error); + } + })(); + } + // SAFETY: We never throw #sessionId. + BidiCdpSession.sessions.set(this.#sessionId.value(), this); + } + connection() { + return undefined; + } + async send(method, params, options) { + if (this.#connection === undefined) { + throw new UnsupportedOperation('CDP support is required for this feature. The current browser does not support CDP.'); + } + if (this.#detached) { + throw new TargetCloseError(`Protocol error (${method}): Session closed. Most likely the page has been closed.`); + } + const session = await this.#sessionId.valueOrThrow(); + const { result } = await this.#connection.send('cdp.sendCommand', { + method: method, + params: params, + session, + }, options?.timeout); + return result.result; + } + async detach() { + if (this.#connection === undefined || + this.#connection.closed || + this.#detached) { + return; + } + try { + await this.frame.client.send('Target.detachFromTarget', { + sessionId: this.id(), + }); + } + finally { + this.onClose(); + } + } + /** + * @internal + */ + onClose = () => { + BidiCdpSession.sessions.delete(this.id()); + this.#detached = true; + }; + id() { + const value = this.#sessionId.value(); + return typeof value === 'string' ? value : ''; + } +} + +/** + * @license + * Copyright 2017 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +const debugProtocolSend = debug('puppeteer:webDriverBiDi:SEND ►'); +const debugProtocolReceive = debug('puppeteer:webDriverBiDi:RECV ◀'); +/** + * @internal + */ +class BidiConnection extends EventEmitter { + #url; + #transport; + #delay; + #timeout = 0; + #closed = false; + #callbacks = new CallbackRegistry(); + #emitters = []; + constructor(url, transport, delay = 0, timeout) { + super(); + this.#url = url; + this.#delay = delay; + this.#timeout = timeout ?? 180000; + this.#transport = transport; + this.#transport.onmessage = this.onMessage.bind(this); + this.#transport.onclose = this.unbind.bind(this); + } + get closed() { + return this.#closed; + } + get url() { + return this.#url; + } + pipeTo(emitter) { + this.#emitters.push(emitter); + } + emit(type, event) { + for (const emitter of this.#emitters) { + emitter.emit(type, event); + } + return super.emit(type, event); + } + send(method, params, timeout) { + assert(!this.#closed, 'Protocol error: Connection closed.'); + return this.#callbacks.create(method, timeout ?? this.#timeout, id => { + const stringifiedMessage = JSON.stringify({ + id, + method, + params, + }); + debugProtocolSend(stringifiedMessage); + this.#transport.send(stringifiedMessage); + }); + } + /** + * @internal + */ + async onMessage(message) { + if (this.#delay) { + await new Promise(f => { + return setTimeout(f, this.#delay); + }); + } + debugProtocolReceive(message); + const object = JSON.parse(message); + if ('type' in object) { + switch (object.type) { + case 'success': + this.#callbacks.resolve(object.id, object); + return; + case 'error': + if (object.id === null) { + break; + } + this.#callbacks.reject(object.id, createProtocolError(object), object.message); + return; + case 'event': + if (isCdpEvent(object)) { + BidiCdpSession.sessions + .get(object.params.session) + ?.emit(object.params.event, object.params.params); + return; + } + // SAFETY: We know the method and parameter still match here. + this.emit(object.method, object.params); + return; + } + } + // Even if the response in not in BiDi protocol format but `id` is provided, reject + // the callback. This can happen if the endpoint supports CDP instead of BiDi. + if ('id' in object) { + this.#callbacks.reject(object.id, `Protocol Error. Message is not in BiDi protocol format: '${message}'`, object.message); + } + debugError(object); + } + /** + * Unbinds the connection, but keeps the transport open. Useful when the transport will + * be reused by other connection e.g. with different protocol. + * @internal + */ + unbind() { + if (this.#closed) { + return; + } + this.#closed = true; + // Both may still be invoked and produce errors + this.#transport.onmessage = () => { }; + this.#transport.onclose = () => { }; + this.#callbacks.clear(); + } + /** + * Unbinds the connection and closes the transport. + */ + dispose() { + this.unbind(); + this.#transport.close(); + } + getPendingProtocolErrors() { + return this.#callbacks.getPendingProtocolErrors(); + } +} +/** + * @internal + */ +function createProtocolError(object) { + let message = `${object.error} ${object.message}`; + if (object.stacktrace) { + message += ` ${object.stacktrace}`; + } + return message; +} +function isCdpEvent(event) { + return event.method.startsWith('cdp.'); +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +const bidiServerLogger = (prefix, ...args) => { + debug(`bidi:${prefix}`)(args); +}; +/** + * @internal + */ +async function connectBidiOverCdp(cdp, options) { + const transportBiDi = new NoOpTransport(); + const cdpConnectionAdapter = new CdpConnectionAdapter(cdp); + const pptrTransport = { + send(message) { + // Forwards a BiDi command sent by Puppeteer to the input of the BidiServer. + transportBiDi.emitMessage(JSON.parse(message)); + }, + close() { + bidiServer.close(); + cdpConnectionAdapter.close(); + cdp.dispose(); + }, + onmessage(_message) { + // The method is overridden by the Connection. + }, + }; + transportBiDi.on('bidiResponse', (message) => { + // Forwards a BiDi event sent by BidiServer to Puppeteer. + pptrTransport.onmessage(JSON.stringify(message)); + }); + const pptrBiDiConnection = new BidiConnection(cdp.url(), pptrTransport); + const bidiServer = await BidiMapper.BidiServer.createAndStart(transportBiDi, cdpConnectionAdapter, + // TODO: most likely need a little bit of refactoring + cdpConnectionAdapter.browserClient(), '', options, undefined, bidiServerLogger); + return pptrBiDiConnection; +} +/** + * Manages CDPSessions for BidiServer. + * @internal + */ +class CdpConnectionAdapter { + #cdp; + #adapters = new Map(); + #browserCdpConnection; + constructor(cdp) { + this.#cdp = cdp; + this.#browserCdpConnection = new CDPClientAdapter(cdp); + } + browserClient() { + return this.#browserCdpConnection; + } + getCdpClient(id) { + const session = this.#cdp.session(id); + if (!session) { + throw new Error(`Unknown CDP session with id ${id}`); + } + if (!this.#adapters.has(session)) { + const adapter = new CDPClientAdapter(session, id, this.#browserCdpConnection); + this.#adapters.set(session, adapter); + return adapter; + } + return this.#adapters.get(session); + } + close() { + this.#browserCdpConnection.close(); + for (const adapter of this.#adapters.values()) { + adapter.close(); + } + } +} +/** + * Wrapper on top of CDPSession/CDPConnection to satisfy CDP interface that + * BidiServer needs. + * + * @internal + */ +class CDPClientAdapter extends BidiMapper.EventEmitter { + #closed = false; + #client; + sessionId = undefined; + #browserClient; + constructor(client, sessionId, browserClient) { + super(); + this.#client = client; + this.sessionId = sessionId; + this.#browserClient = browserClient; + this.#client.on('*', this.#forwardMessage); + } + browserClient() { + return this.#browserClient; + } + #forwardMessage = (method, event) => { + this.emit(method, event); + }; + async sendCommand(method, ...params) { + if (this.#closed) { + return; + } + try { + return await this.#client.send(method, ...params); + } + catch (err) { + if (this.#closed) { + return; + } + throw err; + } + } + close() { + this.#client.off('*', this.#forwardMessage); + this.#closed = true; + } + isCloseError(error) { + return error instanceof TargetCloseError; + } +} +/** + * This transport is given to the BiDi server instance and allows Puppeteer + * to send and receive commands to the BiDiServer. + * @internal + */ +class NoOpTransport extends BidiMapper.EventEmitter { + #onMessage = async (_m) => { + return; + }; + emitMessage(message) { + void this.#onMessage(message); + } + setOnMessage(onMessage) { + this.#onMessage = onMessage; + } + async sendMessage(message) { + this.emit('bidiResponse', message); + } + close() { + this.#onMessage = async (_m) => { + return; + }; + } +} + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$d = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$d = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +/** + * @internal + */ +let Navigation = (() => { + let _classSuper = EventEmitter; + let _instanceExtraInitializers = []; + let _dispose_decorators; + return class Navigation extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + __esDecorate$d(this, null, _dispose_decorators, { kind: "method", name: "dispose", static: false, private: false, access: { has: obj => "dispose" in obj, get: obj => obj.dispose }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static from(context) { + const navigation = new Navigation(context); + navigation.#initialize(); + return navigation; + } + #request = (__runInitializers$d(this, _instanceExtraInitializers), void 0); + #navigation; + #browsingContext; + #disposables = new DisposableStack(); + #id; + constructor(context) { + super(); + this.#browsingContext = context; + } + #initialize() { + const browsingContextEmitter = this.#disposables.use(new EventEmitter(this.#browsingContext)); + browsingContextEmitter.once('closed', () => { + this.emit('failed', { + url: this.#browsingContext.url, + timestamp: new Date(), + }); + this.dispose(); + }); + browsingContextEmitter.on('request', ({ request }) => { + if (request.navigation === undefined || + // If a request with a navigation ID comes in, then the navigation ID is + // for this navigation. + !this.#matches(request.navigation)) { + return; + } + this.#request = request; + this.emit('request', request); + const requestEmitter = this.#disposables.use(new EventEmitter(this.#request)); + requestEmitter.on('redirect', request => { + this.#request = request; + }); + }); + const sessionEmitter = this.#disposables.use(new EventEmitter(this.#session)); + sessionEmitter.on('browsingContext.navigationStarted', info => { + if (info.context !== this.#browsingContext.id || + this.#navigation !== undefined) { + return; + } + this.#navigation = Navigation.from(this.#browsingContext); + }); + for (const eventName of [ + 'browsingContext.domContentLoaded', + 'browsingContext.load', + ]) { + sessionEmitter.on(eventName, info => { + if (info.context !== this.#browsingContext.id || + info.navigation === null || + !this.#matches(info.navigation)) { + return; + } + this.dispose(); + }); + } + for (const [eventName, event] of [ + ['browsingContext.fragmentNavigated', 'fragment'], + ['browsingContext.navigationFailed', 'failed'], + ['browsingContext.navigationAborted', 'aborted'], + ]) { + sessionEmitter.on(eventName, info => { + if (info.context !== this.#browsingContext.id || + // Note we don't check if `navigation` is null since `null` means the + // fragment navigated. + !this.#matches(info.navigation)) { + return; + } + this.emit(event, { + url: info.url, + timestamp: new Date(info.timestamp), + }); + this.dispose(); + }); + } + } + #matches(navigation) { + if (this.#navigation !== undefined && !this.#navigation.disposed) { + return false; + } + if (this.#id === undefined) { + this.#id = navigation; + return true; + } + return this.#id === navigation; + } + get #session() { + return this.#browsingContext.userContext.browser.session; + } + get disposed() { + return this.#disposables.disposed; + } + get request() { + return this.#request; + } + get navigation() { + return this.#navigation; + } + dispose() { + this[disposeSymbol](); + } + [(_dispose_decorators = [inertIfDisposed], disposeSymbol)]() { + this.#disposables.dispose(); + super[disposeSymbol](); + } + }; +})(); + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$c = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$c = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var _a$1; +/** + * @internal + */ +let Realm = (() => { + let _classSuper = EventEmitter; + let _instanceExtraInitializers = []; + let _dispose_decorators; + let _disown_decorators; + let _callFunction_decorators; + let _evaluate_decorators; + let _resolveExecutionContextId_decorators; + return class Realm extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + __esDecorate$c(this, null, _dispose_decorators, { kind: "method", name: "dispose", static: false, private: false, access: { has: obj => "dispose" in obj, get: obj => obj.dispose }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$c(this, null, _disown_decorators, { kind: "method", name: "disown", static: false, private: false, access: { has: obj => "disown" in obj, get: obj => obj.disown }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$c(this, null, _callFunction_decorators, { kind: "method", name: "callFunction", static: false, private: false, access: { has: obj => "callFunction" in obj, get: obj => obj.callFunction }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$c(this, null, _evaluate_decorators, { kind: "method", name: "evaluate", static: false, private: false, access: { has: obj => "evaluate" in obj, get: obj => obj.evaluate }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$c(this, null, _resolveExecutionContextId_decorators, { kind: "method", name: "resolveExecutionContextId", static: false, private: false, access: { has: obj => "resolveExecutionContextId" in obj, get: obj => obj.resolveExecutionContextId }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + #reason = (__runInitializers$c(this, _instanceExtraInitializers), void 0); + disposables = new DisposableStack(); + id; + origin; + executionContextId; + constructor(id, origin) { + super(); + this.id = id; + this.origin = origin; + } + get disposed() { + return this.#reason !== undefined; + } + get target() { + return { realm: this.id }; + } + dispose(reason) { + this.#reason = reason; + this[disposeSymbol](); + } + async disown(handles) { + await this.session.send('script.disown', { + target: this.target, + handles, + }); + } + async callFunction(functionDeclaration, awaitPromise, options = {}) { + const { result } = await this.session.send('script.callFunction', { + functionDeclaration, + awaitPromise, + target: this.target, + ...options, + }); + return result; + } + async evaluate(expression, awaitPromise, options = {}) { + const { result } = await this.session.send('script.evaluate', { + expression, + awaitPromise, + target: this.target, + ...options, + }); + return result; + } + async resolveExecutionContextId() { + if (!this.executionContextId) { + const { result } = await this.session.connection.send('cdp.resolveRealm', { realm: this.id }); + this.executionContextId = result.executionContextId; + } + return this.executionContextId; + } + [(_dispose_decorators = [inertIfDisposed], _disown_decorators = [throwIfDisposed(realm => { + // SAFETY: Disposal implies this exists. + return realm.#reason; + })], _callFunction_decorators = [throwIfDisposed(realm => { + // SAFETY: Disposal implies this exists. + return realm.#reason; + })], _evaluate_decorators = [throwIfDisposed(realm => { + // SAFETY: Disposal implies this exists. + return realm.#reason; + })], _resolveExecutionContextId_decorators = [throwIfDisposed(realm => { + // SAFETY: Disposal implies this exists. + return realm.#reason; + })], disposeSymbol)]() { + this.#reason ??= + 'Realm already destroyed, probably because all associated browsing contexts closed.'; + this.emit('destroyed', { reason: this.#reason }); + this.disposables.dispose(); + super[disposeSymbol](); + } + }; +})(); +/** + * @internal + */ +class WindowRealm extends Realm { + static from(context, sandbox) { + const realm = new WindowRealm(context, sandbox); + realm.#initialize(); + return realm; + } + browsingContext; + sandbox; + #workers = new Map(); + constructor(context, sandbox) { + super('', ''); + this.browsingContext = context; + this.sandbox = sandbox; + } + #initialize() { + const browsingContextEmitter = this.disposables.use(new EventEmitter(this.browsingContext)); + browsingContextEmitter.on('closed', ({ reason }) => { + this.dispose(reason); + }); + const sessionEmitter = this.disposables.use(new EventEmitter(this.session)); + sessionEmitter.on('script.realmCreated', info => { + if (info.type !== 'window' || + info.context !== this.browsingContext.id || + info.sandbox !== this.sandbox) { + return; + } + this.id = info.realm; + this.origin = info.origin; + this.executionContextId = undefined; + this.emit('updated', this); + }); + sessionEmitter.on('script.realmCreated', info => { + if (info.type !== 'dedicated-worker') { + return; + } + if (!info.owners.includes(this.id)) { + return; + } + const realm = DedicatedWorkerRealm.from(this, info.realm, info.origin); + this.#workers.set(realm.id, realm); + const realmEmitter = this.disposables.use(new EventEmitter(realm)); + realmEmitter.once('destroyed', () => { + realmEmitter.removeAllListeners(); + this.#workers.delete(realm.id); + }); + this.emit('worker', realm); + }); + } + get session() { + return this.browsingContext.userContext.browser.session; + } + get target() { + return { context: this.browsingContext.id, sandbox: this.sandbox }; + } +} +/** + * @internal + */ +class DedicatedWorkerRealm extends Realm { + static from(owner, id, origin) { + const realm = new _a$1(owner, id, origin); + realm.#initialize(); + return realm; + } + #workers = new Map(); + owners; + constructor(owner, id, origin) { + super(id, origin); + this.owners = new Set([owner]); + } + #initialize() { + const sessionEmitter = this.disposables.use(new EventEmitter(this.session)); + sessionEmitter.on('script.realmDestroyed', info => { + if (info.realm !== this.id) { + return; + } + this.dispose('Realm already destroyed.'); + }); + sessionEmitter.on('script.realmCreated', info => { + if (info.type !== 'dedicated-worker') { + return; + } + if (!info.owners.includes(this.id)) { + return; + } + const realm = _a$1.from(this, info.realm, info.origin); + this.#workers.set(realm.id, realm); + const realmEmitter = this.disposables.use(new EventEmitter(realm)); + realmEmitter.once('destroyed', () => { + this.#workers.delete(realm.id); + }); + this.emit('worker', realm); + }); + } + get session() { + // SAFETY: At least one owner will exist. + return this.owners.values().next().value.session; + } +} +_a$1 = DedicatedWorkerRealm; +/** + * @internal + */ +class SharedWorkerRealm extends Realm { + static from(browser, id, origin) { + const realm = new SharedWorkerRealm(browser, id, origin); + realm.#initialize(); + return realm; + } + #workers = new Map(); + browser; + constructor(browser, id, origin) { + super(id, origin); + this.browser = browser; + } + #initialize() { + const sessionEmitter = this.disposables.use(new EventEmitter(this.session)); + sessionEmitter.on('script.realmDestroyed', info => { + if (info.realm !== this.id) { + return; + } + this.dispose('Realm already destroyed.'); + }); + sessionEmitter.on('script.realmCreated', info => { + if (info.type !== 'dedicated-worker') { + return; + } + if (!info.owners.includes(this.id)) { + return; + } + const realm = DedicatedWorkerRealm.from(this, info.realm, info.origin); + this.#workers.set(realm.id, realm); + const realmEmitter = this.disposables.use(new EventEmitter(realm)); + realmEmitter.once('destroyed', () => { + this.#workers.delete(realm.id); + }); + this.emit('worker', realm); + }); + } + get session() { + return this.browser.session; + } +} + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$b = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$b = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +/** + * @internal + */ +let Request = (() => { + let _classSuper = EventEmitter; + let _instanceExtraInitializers = []; + let _dispose_decorators; + return class Request extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + __esDecorate$b(this, null, _dispose_decorators, { kind: "method", name: "dispose", static: false, private: false, access: { has: obj => "dispose" in obj, get: obj => obj.dispose }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static from(browsingContext, event) { + const request = new Request(browsingContext, event); + request.#initialize(); + return request; + } + #error = (__runInitializers$b(this, _instanceExtraInitializers), void 0); + #redirect; + #response; + #browsingContext; + #disposables = new DisposableStack(); + #event; + constructor(browsingContext, event) { + super(); + this.#browsingContext = browsingContext; + this.#event = event; + } + #initialize() { + const browsingContextEmitter = this.#disposables.use(new EventEmitter(this.#browsingContext)); + browsingContextEmitter.once('closed', ({ reason }) => { + this.#error = reason; + this.emit('error', this.#error); + this.dispose(); + }); + const sessionEmitter = this.#disposables.use(new EventEmitter(this.#session)); + sessionEmitter.on('network.beforeRequestSent', event => { + if (event.context !== this.#browsingContext.id || + event.request.request !== this.id || + event.redirectCount !== this.#event.redirectCount + 1) { + return; + } + this.#redirect = Request.from(this.#browsingContext, event); + this.emit('redirect', this.#redirect); + this.dispose(); + }); + sessionEmitter.on('network.authRequired', event => { + if (event.context !== this.#browsingContext.id || + event.request.request !== this.id || + // Don't try to authenticate for events that are not blocked + !event.isBlocked) { + return; + } + this.emit('authenticate', undefined); + }); + sessionEmitter.on('network.fetchError', event => { + if (event.context !== this.#browsingContext.id || + event.request.request !== this.id || + this.#event.redirectCount !== event.redirectCount) { + return; + } + this.#error = event.errorText; + this.emit('error', this.#error); + this.dispose(); + }); + sessionEmitter.on('network.responseCompleted', event => { + if (event.context !== this.#browsingContext.id || + event.request.request !== this.id || + this.#event.redirectCount !== event.redirectCount) { + return; + } + this.#response = event.response; + this.emit('success', this.#response); + // In case this is a redirect. + if (this.#response.status >= 300 && this.#response.status < 400) { + return; + } + this.dispose(); + }); + } + get #session() { + return this.#browsingContext.userContext.browser.session; + } + get disposed() { + return this.#disposables.disposed; + } + get error() { + return this.#error; + } + get headers() { + return this.#event.request.headers; + } + get id() { + return this.#event.request.request; + } + get initiator() { + return this.#event.initiator; + } + get method() { + return this.#event.request.method; + } + get navigation() { + return this.#event.navigation ?? undefined; + } + get redirect() { + return this.#redirect; + } + get lastRedirect() { + let redirect = this.#redirect; + while (redirect) { + if (redirect && !redirect.#redirect) { + return redirect; + } + redirect = redirect.#redirect; + } + return redirect; + } + get response() { + return this.#response; + } + get url() { + return this.#event.request.url; + } + get isBlocked() { + return this.#event.isBlocked; + } + async continueRequest({ url, method, headers, cookies, body, }) { + await this.#session.send('network.continueRequest', { + request: this.id, + url, + method, + headers, + body, + cookies, + }); + } + async failRequest() { + await this.#session.send('network.failRequest', { + request: this.id, + }); + } + async provideResponse({ statusCode, reasonPhrase, headers, body, }) { + await this.#session.send('network.provideResponse', { + request: this.id, + statusCode, + reasonPhrase, + headers, + body, + }); + } + async continueWithAuth(parameters) { + if (parameters.action === 'provideCredentials') { + await this.#session.send('network.continueWithAuth', { + request: this.id, + action: parameters.action, + credentials: parameters.credentials, + }); + } + else { + await this.#session.send('network.continueWithAuth', { + request: this.id, + action: parameters.action, + }); + } + } + dispose() { + this[disposeSymbol](); + } + [(_dispose_decorators = [inertIfDisposed], disposeSymbol)]() { + this.#disposables.dispose(); + super[disposeSymbol](); + } + }; +})(); + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$a = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$a = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +/** + * @internal + */ +let UserPrompt = (() => { + let _classSuper = EventEmitter; + let _instanceExtraInitializers = []; + let _dispose_decorators; + let _handle_decorators; + return class UserPrompt extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + __esDecorate$a(this, null, _dispose_decorators, { kind: "method", name: "dispose", static: false, private: false, access: { has: obj => "dispose" in obj, get: obj => obj.dispose }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$a(this, null, _handle_decorators, { kind: "method", name: "handle", static: false, private: false, access: { has: obj => "handle" in obj, get: obj => obj.handle }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static from(browsingContext, info) { + const userPrompt = new UserPrompt(browsingContext, info); + userPrompt.#initialize(); + return userPrompt; + } + #reason = (__runInitializers$a(this, _instanceExtraInitializers), void 0); + #result; + #disposables = new DisposableStack(); + browsingContext; + info; + constructor(context, info) { + super(); + this.browsingContext = context; + this.info = info; + } + #initialize() { + const browserContextEmitter = this.#disposables.use(new EventEmitter(this.browsingContext)); + browserContextEmitter.once('closed', ({ reason }) => { + this.dispose(`User prompt already closed: ${reason}`); + }); + const sessionEmitter = this.#disposables.use(new EventEmitter(this.#session)); + sessionEmitter.on('browsingContext.userPromptClosed', parameters => { + if (parameters.context !== this.browsingContext.id) { + return; + } + this.#result = parameters; + this.emit('handled', parameters); + this.dispose('User prompt already handled.'); + }); + } + get #session() { + return this.browsingContext.userContext.browser.session; + } + get closed() { + return this.#reason !== undefined; + } + get disposed() { + return this.closed; + } + get handled() { + return this.#result !== undefined; + } + get result() { + return this.#result; + } + dispose(reason) { + this.#reason = reason; + this[disposeSymbol](); + } + async handle(options = {}) { + await this.#session.send('browsingContext.handleUserPrompt', { + ...options, + context: this.info.context, + }); + // SAFETY: `handled` is triggered before the above promise resolved. + return this.#result; + } + [(_dispose_decorators = [inertIfDisposed], _handle_decorators = [throwIfDisposed(prompt => { + // SAFETY: Disposal implies this exists. + return prompt.#reason; + })], disposeSymbol)]() { + this.#reason ??= + 'User prompt already closed, probably because the associated browsing context was destroyed.'; + this.emit('closed', { reason: this.#reason }); + this.#disposables.dispose(); + super[disposeSymbol](); + } + }; +})(); + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$9 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$9 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +/** + * @internal + */ +let BrowsingContext = (() => { + let _classSuper = EventEmitter; + let _instanceExtraInitializers = []; + let _dispose_decorators; + let _activate_decorators; + let _captureScreenshot_decorators; + let _close_decorators; + let _traverseHistory_decorators; + let _navigate_decorators; + let _reload_decorators; + let _print_decorators; + let _handleUserPrompt_decorators; + let _setViewport_decorators; + let _performActions_decorators; + let _releaseActions_decorators; + let _createWindowRealm_decorators; + let _addPreloadScript_decorators; + let _addIntercept_decorators; + let _removePreloadScript_decorators; + let _getCookies_decorators; + let _setCookie_decorators; + let _setFiles_decorators; + let _subscribe_decorators; + let _addInterception_decorators; + let _deleteCookie_decorators; + let _locateNodes_decorators; + return class BrowsingContext extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + _deleteCookie_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })]; + _locateNodes_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })]; + __esDecorate$9(this, null, _dispose_decorators, { kind: "method", name: "dispose", static: false, private: false, access: { has: obj => "dispose" in obj, get: obj => obj.dispose }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _activate_decorators, { kind: "method", name: "activate", static: false, private: false, access: { has: obj => "activate" in obj, get: obj => obj.activate }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _captureScreenshot_decorators, { kind: "method", name: "captureScreenshot", static: false, private: false, access: { has: obj => "captureScreenshot" in obj, get: obj => obj.captureScreenshot }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _close_decorators, { kind: "method", name: "close", static: false, private: false, access: { has: obj => "close" in obj, get: obj => obj.close }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _traverseHistory_decorators, { kind: "method", name: "traverseHistory", static: false, private: false, access: { has: obj => "traverseHistory" in obj, get: obj => obj.traverseHistory }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _navigate_decorators, { kind: "method", name: "navigate", static: false, private: false, access: { has: obj => "navigate" in obj, get: obj => obj.navigate }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _reload_decorators, { kind: "method", name: "reload", static: false, private: false, access: { has: obj => "reload" in obj, get: obj => obj.reload }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _print_decorators, { kind: "method", name: "print", static: false, private: false, access: { has: obj => "print" in obj, get: obj => obj.print }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _handleUserPrompt_decorators, { kind: "method", name: "handleUserPrompt", static: false, private: false, access: { has: obj => "handleUserPrompt" in obj, get: obj => obj.handleUserPrompt }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _setViewport_decorators, { kind: "method", name: "setViewport", static: false, private: false, access: { has: obj => "setViewport" in obj, get: obj => obj.setViewport }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _performActions_decorators, { kind: "method", name: "performActions", static: false, private: false, access: { has: obj => "performActions" in obj, get: obj => obj.performActions }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _releaseActions_decorators, { kind: "method", name: "releaseActions", static: false, private: false, access: { has: obj => "releaseActions" in obj, get: obj => obj.releaseActions }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _createWindowRealm_decorators, { kind: "method", name: "createWindowRealm", static: false, private: false, access: { has: obj => "createWindowRealm" in obj, get: obj => obj.createWindowRealm }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _addPreloadScript_decorators, { kind: "method", name: "addPreloadScript", static: false, private: false, access: { has: obj => "addPreloadScript" in obj, get: obj => obj.addPreloadScript }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _addIntercept_decorators, { kind: "method", name: "addIntercept", static: false, private: false, access: { has: obj => "addIntercept" in obj, get: obj => obj.addIntercept }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _removePreloadScript_decorators, { kind: "method", name: "removePreloadScript", static: false, private: false, access: { has: obj => "removePreloadScript" in obj, get: obj => obj.removePreloadScript }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _getCookies_decorators, { kind: "method", name: "getCookies", static: false, private: false, access: { has: obj => "getCookies" in obj, get: obj => obj.getCookies }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _setCookie_decorators, { kind: "method", name: "setCookie", static: false, private: false, access: { has: obj => "setCookie" in obj, get: obj => obj.setCookie }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _setFiles_decorators, { kind: "method", name: "setFiles", static: false, private: false, access: { has: obj => "setFiles" in obj, get: obj => obj.setFiles }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _subscribe_decorators, { kind: "method", name: "subscribe", static: false, private: false, access: { has: obj => "subscribe" in obj, get: obj => obj.subscribe }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _addInterception_decorators, { kind: "method", name: "addInterception", static: false, private: false, access: { has: obj => "addInterception" in obj, get: obj => obj.addInterception }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _deleteCookie_decorators, { kind: "method", name: "deleteCookie", static: false, private: false, access: { has: obj => "deleteCookie" in obj, get: obj => obj.deleteCookie }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$9(this, null, _locateNodes_decorators, { kind: "method", name: "locateNodes", static: false, private: false, access: { has: obj => "locateNodes" in obj, get: obj => obj.locateNodes }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static from(userContext, parent, id, url) { + const browsingContext = new BrowsingContext(userContext, parent, id, url); + browsingContext.#initialize(); + return browsingContext; + } + #navigation = (__runInitializers$9(this, _instanceExtraInitializers), void 0); + #reason; + #url; + #children = new Map(); + #disposables = new DisposableStack(); + #realms = new Map(); + #requests = new Map(); + defaultRealm; + id; + parent; + userContext; + constructor(context, parent, id, url) { + super(); + this.#url = url; + this.id = id; + this.parent = parent; + this.userContext = context; + this.defaultRealm = this.#createWindowRealm(); + } + #initialize() { + const userContextEmitter = this.#disposables.use(new EventEmitter(this.userContext)); + userContextEmitter.once('closed', ({ reason }) => { + this.dispose(`Browsing context already closed: ${reason}`); + }); + const sessionEmitter = this.#disposables.use(new EventEmitter(this.#session)); + sessionEmitter.on('browsingContext.contextCreated', info => { + if (info.parent !== this.id) { + return; + } + const browsingContext = BrowsingContext.from(this.userContext, this, info.context, info.url); + this.#children.set(info.context, browsingContext); + const browsingContextEmitter = this.#disposables.use(new EventEmitter(browsingContext)); + browsingContextEmitter.once('closed', () => { + browsingContextEmitter.removeAllListeners(); + this.#children.delete(browsingContext.id); + }); + this.emit('browsingcontext', { browsingContext }); + }); + sessionEmitter.on('browsingContext.contextDestroyed', info => { + if (info.context !== this.id) { + return; + } + this.dispose('Browsing context already closed.'); + }); + sessionEmitter.on('browsingContext.domContentLoaded', info => { + if (info.context !== this.id) { + return; + } + this.#url = info.url; + this.emit('DOMContentLoaded', undefined); + }); + sessionEmitter.on('browsingContext.load', info => { + if (info.context !== this.id) { + return; + } + this.#url = info.url; + this.emit('load', undefined); + }); + sessionEmitter.on('browsingContext.navigationStarted', info => { + if (info.context !== this.id) { + return; + } + this.#url = info.url; + for (const [id, request] of this.#requests) { + if (request.disposed) { + this.#requests.delete(id); + } + } + // If the navigation hasn't finished, then this is nested navigation. The + // current navigation will handle this. + if (this.#navigation !== undefined && !this.#navigation.disposed) { + return; + } + // Note the navigation ID is null for this event. + this.#navigation = Navigation.from(this); + const navigationEmitter = this.#disposables.use(new EventEmitter(this.#navigation)); + for (const eventName of ['fragment', 'failed', 'aborted']) { + navigationEmitter.once(eventName, ({ url }) => { + navigationEmitter[disposeSymbol](); + this.#url = url; + }); + } + this.emit('navigation', { navigation: this.#navigation }); + }); + sessionEmitter.on('network.beforeRequestSent', event => { + if (event.context !== this.id) { + return; + } + if (event.redirectCount !== 0) { + // Means the request is a redirect. This is handled in Request. + return; + } + const request = Request.from(this, event); + this.#requests.set(request.id, request); + this.emit('request', { request }); + }); + sessionEmitter.on('log.entryAdded', entry => { + if (entry.source.context !== this.id) { + return; + } + this.emit('log', { entry }); + }); + sessionEmitter.on('browsingContext.userPromptOpened', info => { + if (info.context !== this.id) { + return; + } + const userPrompt = UserPrompt.from(this, info); + this.emit('userprompt', { userPrompt }); + }); + } + get #session() { + return this.userContext.browser.session; + } + get children() { + return this.#children.values(); + } + get closed() { + return this.#reason !== undefined; + } + get disposed() { + return this.closed; + } + get realms() { + // eslint-disable-next-line @typescript-eslint/no-this-alias -- Required + const self = this; + return (function* () { + yield self.defaultRealm; + yield* self.#realms.values(); + })(); + } + get top() { + let context = this; + for (let { parent } = context; parent; { parent } = context) { + context = parent; + } + return context; + } + get url() { + return this.#url; + } + #createWindowRealm(sandbox) { + const realm = WindowRealm.from(this, sandbox); + realm.on('worker', realm => { + this.emit('worker', { realm }); + }); + return realm; + } + dispose(reason) { + this.#reason = reason; + this[disposeSymbol](); + } + async activate() { + await this.#session.send('browsingContext.activate', { + context: this.id, + }); + } + async captureScreenshot(options = {}) { + const { result: { data }, } = await this.#session.send('browsingContext.captureScreenshot', { + context: this.id, + ...options, + }); + return data; + } + async close(promptUnload) { + await Promise.all([...this.#children.values()].map(async (child) => { + await child.close(promptUnload); + })); + await this.#session.send('browsingContext.close', { + context: this.id, + promptUnload, + }); + } + async traverseHistory(delta) { + await this.#session.send('browsingContext.traverseHistory', { + context: this.id, + delta, + }); + } + async navigate(url, wait) { + await this.#session.send('browsingContext.navigate', { + context: this.id, + url, + wait, + }); + } + async reload(options = {}) { + await this.#session.send('browsingContext.reload', { + context: this.id, + ...options, + }); + } + async print(options = {}) { + const { result: { data }, } = await this.#session.send('browsingContext.print', { + context: this.id, + ...options, + }); + return data; + } + async handleUserPrompt(options = {}) { + await this.#session.send('browsingContext.handleUserPrompt', { + context: this.id, + ...options, + }); + } + async setViewport(options = {}) { + await this.#session.send('browsingContext.setViewport', { + context: this.id, + ...options, + }); + } + async performActions(actions) { + await this.#session.send('input.performActions', { + context: this.id, + actions, + }); + } + async releaseActions() { + await this.#session.send('input.releaseActions', { + context: this.id, + }); + } + createWindowRealm(sandbox) { + return this.#createWindowRealm(sandbox); + } + async addPreloadScript(functionDeclaration, options = {}) { + return await this.userContext.browser.addPreloadScript(functionDeclaration, { + ...options, + contexts: [this], + }); + } + async addIntercept(options) { + const { result: { intercept }, } = await this.userContext.browser.session.send('network.addIntercept', { + ...options, + contexts: [this.id], + }); + return intercept; + } + async removePreloadScript(script) { + await this.userContext.browser.removePreloadScript(script); + } + async getCookies(options = {}) { + const { result: { cookies }, } = await this.#session.send('storage.getCookies', { + ...options, + partition: { + type: 'context', + context: this.id, + }, + }); + return cookies; + } + async setCookie(cookie) { + await this.#session.send('storage.setCookie', { + cookie, + partition: { + type: 'context', + context: this.id, + }, + }); + } + async setFiles(element, files) { + await this.#session.send('input.setFiles', { + context: this.id, + element, + files, + }); + } + async subscribe(events) { + await this.#session.subscribe(events, [this.id]); + } + async addInterception(events) { + await this.#session.subscribe(events, [this.id]); + } + [(_dispose_decorators = [inertIfDisposed], _activate_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _captureScreenshot_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _close_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _traverseHistory_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _navigate_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _reload_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _print_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _handleUserPrompt_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _setViewport_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _performActions_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _releaseActions_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _createWindowRealm_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _addPreloadScript_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _addIntercept_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _removePreloadScript_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _getCookies_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _setCookie_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _setFiles_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _subscribe_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _addInterception_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], disposeSymbol)]() { + this.#reason ??= + 'Browsing context already closed, probably because the user context closed.'; + this.emit('closed', { reason: this.#reason }); + this.#disposables.dispose(); + super[disposeSymbol](); + } + async deleteCookie(...cookieFilters) { + await Promise.all(cookieFilters.map(async (filter) => { + await this.#session.send('storage.deleteCookies', { + filter: filter, + partition: { + type: 'context', + context: this.id, + }, + }); + })); + } + async locateNodes(locator, startNodes) { + // TODO: add other locateNodes options if needed. + const result = await this.#session.send('browsingContext.locateNodes', { + context: this.id, + locator, + startNodes: startNodes.length ? startNodes : undefined, + }); + return result.result.nodes; + } + }; +})(); + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$8 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$8 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +/** + * @internal + */ +let UserContext = (() => { + let _classSuper = EventEmitter; + let _instanceExtraInitializers = []; + let _dispose_decorators; + let _createBrowsingContext_decorators; + let _remove_decorators; + let _getCookies_decorators; + let _setCookie_decorators; + let _setPermissions_decorators; + return class UserContext extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + __esDecorate$8(this, null, _dispose_decorators, { kind: "method", name: "dispose", static: false, private: false, access: { has: obj => "dispose" in obj, get: obj => obj.dispose }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$8(this, null, _createBrowsingContext_decorators, { kind: "method", name: "createBrowsingContext", static: false, private: false, access: { has: obj => "createBrowsingContext" in obj, get: obj => obj.createBrowsingContext }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$8(this, null, _remove_decorators, { kind: "method", name: "remove", static: false, private: false, access: { has: obj => "remove" in obj, get: obj => obj.remove }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$8(this, null, _getCookies_decorators, { kind: "method", name: "getCookies", static: false, private: false, access: { has: obj => "getCookies" in obj, get: obj => obj.getCookies }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$8(this, null, _setCookie_decorators, { kind: "method", name: "setCookie", static: false, private: false, access: { has: obj => "setCookie" in obj, get: obj => obj.setCookie }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$8(this, null, _setPermissions_decorators, { kind: "method", name: "setPermissions", static: false, private: false, access: { has: obj => "setPermissions" in obj, get: obj => obj.setPermissions }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static DEFAULT = 'default'; + static create(browser, id) { + const context = new UserContext(browser, id); + context.#initialize(); + return context; + } + #reason = (__runInitializers$8(this, _instanceExtraInitializers), void 0); + // Note these are only top-level contexts. + #browsingContexts = new Map(); + #disposables = new DisposableStack(); + #id; + browser; + constructor(browser, id) { + super(); + this.#id = id; + this.browser = browser; + } + #initialize() { + const browserEmitter = this.#disposables.use(new EventEmitter(this.browser)); + browserEmitter.once('closed', ({ reason }) => { + this.dispose(`User context already closed: ${reason}`); + }); + const sessionEmitter = this.#disposables.use(new EventEmitter(this.#session)); + sessionEmitter.on('browsingContext.contextCreated', info => { + if (info.parent) { + return; + } + if (info.userContext !== this.#id) { + return; + } + const browsingContext = BrowsingContext.from(this, undefined, info.context, info.url); + this.#browsingContexts.set(browsingContext.id, browsingContext); + const browsingContextEmitter = this.#disposables.use(new EventEmitter(browsingContext)); + browsingContextEmitter.on('closed', () => { + browsingContextEmitter.removeAllListeners(); + this.#browsingContexts.delete(browsingContext.id); + }); + this.emit('browsingcontext', { browsingContext }); + }); + } + get #session() { + return this.browser.session; + } + get browsingContexts() { + return this.#browsingContexts.values(); + } + get closed() { + return this.#reason !== undefined; + } + get disposed() { + return this.closed; + } + get id() { + return this.#id; + } + dispose(reason) { + this.#reason = reason; + this[disposeSymbol](); + } + async createBrowsingContext(type, options = {}) { + const { result: { context: contextId }, } = await this.#session.send('browsingContext.create', { + type, + ...options, + referenceContext: options.referenceContext?.id, + userContext: this.#id, + }); + const browsingContext = this.#browsingContexts.get(contextId); + assert(browsingContext, 'The WebDriver BiDi implementation is failing to create a browsing context correctly.'); + // We use an array to avoid the promise from being awaited. + return browsingContext; + } + async remove() { + try { + await this.#session.send('browser.removeUserContext', { + userContext: this.#id, + }); + } + finally { + this.dispose('User context already closed.'); + } + } + async getCookies(options = {}, sourceOrigin = undefined) { + const { result: { cookies }, } = await this.#session.send('storage.getCookies', { + ...options, + partition: { + type: 'storageKey', + userContext: this.#id, + sourceOrigin, + }, + }); + return cookies; + } + async setCookie(cookie, sourceOrigin) { + await this.#session.send('storage.setCookie', { + cookie, + partition: { + type: 'storageKey', + sourceOrigin, + userContext: this.id, + }, + }); + } + async setPermissions(origin, descriptor, state) { + await this.#session.send('permissions.setPermission', { + origin, + descriptor, + state, + userContext: this.#id, + }); + } + [(_dispose_decorators = [inertIfDisposed], _createBrowsingContext_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _remove_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _getCookies_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _setCookie_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], _setPermissions_decorators = [throwIfDisposed(context => { + // SAFETY: Disposal implies this exists. + return context.#reason; + })], disposeSymbol)]() { + this.#reason ??= + 'User context already closed, probably because the browser disconnected/closed.'; + this.emit('closed', { reason: this.#reason }); + this.#disposables.dispose(); + super[disposeSymbol](); + } + }; +})(); + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class BidiDeserializer { + static deserialize(result) { + if (!result) { + debugError('Service did not produce a result.'); + return undefined; + } + switch (result.type) { + case 'array': + return result.value?.map(value => { + return this.deserialize(value); + }); + case 'set': + return result.value?.reduce((acc, value) => { + return acc.add(this.deserialize(value)); + }, new Set()); + case 'object': + return result.value?.reduce((acc, tuple) => { + const { key, value } = this.#deserializeTuple(tuple); + acc[key] = value; + return acc; + }, {}); + case 'map': + return result.value?.reduce((acc, tuple) => { + const { key, value } = this.#deserializeTuple(tuple); + return acc.set(key, value); + }, new Map()); + case 'promise': + return {}; + case 'regexp': + return new RegExp(result.value.pattern, result.value.flags); + case 'date': + return new Date(result.value); + case 'undefined': + return undefined; + case 'null': + return null; + case 'number': + return this.#deserializeNumber(result.value); + case 'bigint': + return BigInt(result.value); + case 'boolean': + return Boolean(result.value); + case 'string': + return result.value; + } + debugError(`Deserialization of type ${result.type} not supported.`); + return undefined; + } + static #deserializeNumber(value) { + switch (value) { + case '-0': + return -0; + case 'NaN': + return NaN; + case 'Infinity': + return Infinity; + case '-Infinity': + return -Infinity; + default: + return value; + } + } + static #deserializeTuple([serializedKey, serializedValue]) { + const key = typeof serializedKey === 'string' + ? serializedKey + : this.deserialize(serializedKey); + const value = this.deserialize(serializedValue); + return { key, value }; + } +} + +/** + * @license + * Copyright 2017 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +class BidiDialog extends Dialog { + static from(prompt) { + return new BidiDialog(prompt); + } + #prompt; + constructor(prompt) { + super(prompt.info.type, prompt.info.message, prompt.info.defaultValue); + this.#prompt = prompt; + } + async handle(options) { + await this.#prompt.handle({ + accept: options.accept, + userText: options.text, + }); + } +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class BidiJSHandle extends JSHandle { + static from(value, realm) { + return new BidiJSHandle(value, realm); + } + #remoteValue; + realm; + #disposed = false; + constructor(value, realm) { + super(); + this.#remoteValue = value; + this.realm = realm; + } + get disposed() { + return this.#disposed; + } + async jsonValue() { + return await this.evaluate(value => { + return value; + }); + } + asElement() { + return null; + } + async dispose() { + if (this.#disposed) { + return; + } + this.#disposed = true; + await this.realm.destroyHandles([this]); + } + get isPrimitiveValue() { + switch (this.#remoteValue.type) { + case 'string': + case 'number': + case 'bigint': + case 'boolean': + case 'undefined': + case 'null': + return true; + default: + return false; + } + } + toString() { + if (this.isPrimitiveValue) { + return 'JSHandle:' + BidiDeserializer.deserialize(this.#remoteValue); + } + return 'JSHandle@' + this.#remoteValue.type; + } + get id() { + return 'handle' in this.#remoteValue ? this.#remoteValue.handle : undefined; + } + remoteValue() { + return this.#remoteValue; + } + remoteObject() { + throw new UnsupportedOperation('Not available in WebDriver BiDi'); + } +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$7 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$7 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var __addDisposableResource$4 = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$4 = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +/** + * @internal + */ +let BidiElementHandle = (() => { + var _a; + let _classSuper = ElementHandle; + let _instanceExtraInitializers = []; + let _autofill_decorators; + let _contentFrame_decorators; + return class BidiElementHandle extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + _autofill_decorators = [throwIfDisposed()]; + _contentFrame_decorators = [throwIfDisposed(), (_a = ElementHandle).bindIsolatedHandle.bind(_a)]; + __esDecorate$7(this, null, _autofill_decorators, { kind: "method", name: "autofill", static: false, private: false, access: { has: obj => "autofill" in obj, get: obj => obj.autofill }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$7(this, null, _contentFrame_decorators, { kind: "method", name: "contentFrame", static: false, private: false, access: { has: obj => "contentFrame" in obj, get: obj => obj.contentFrame }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static from(value, realm) { + return new BidiElementHandle(value, realm); + } + constructor(value, realm) { + super(BidiJSHandle.from(value, realm)); + __runInitializers$7(this, _instanceExtraInitializers); + } + get realm() { + // SAFETY: See the super call in the constructor. + return this.handle.realm; + } + get frame() { + return this.realm.environment; + } + remoteValue() { + return this.handle.remoteValue(); + } + async autofill(data) { + const client = this.frame.client; + const nodeInfo = await client.send('DOM.describeNode', { + objectId: this.handle.id, + }); + const fieldId = nodeInfo.node.backendNodeId; + const frameId = this.frame._id; + await client.send('Autofill.trigger', { + fieldId, + frameId, + card: data.creditCard, + }); + } + async contentFrame() { + const env_1 = { stack: [], error: void 0, hasError: false }; + try { + const handle = __addDisposableResource$4(env_1, (await this.evaluateHandle(element => { + if (element instanceof HTMLIFrameElement || + element instanceof HTMLFrameElement) { + return element.contentWindow; + } + return; + })), false); + const value = handle.remoteValue(); + if (value.type === 'window') { + return (this.frame + .page() + .frames() + .find(frame => { + return frame._id === value.value.context; + }) ?? null); + } + return null; + } + catch (e_1) { + env_1.error = e_1; + env_1.hasError = true; + } + finally { + __disposeResources$4(env_1); + } + } + async uploadFile(...files) { + // Locate all files and confirm that they exist. + // eslint-disable-next-line @typescript-eslint/consistent-type-imports + let path; + try { + path = await import('path'); + } + catch (error) { + if (error instanceof TypeError) { + throw new Error(`JSHandle#uploadFile can only be used in Node-like environments.`); + } + throw error; + } + files = files.map(file => { + if (path.win32.isAbsolute(file) || path.posix.isAbsolute(file)) { + return file; + } + else { + return path.resolve(file); + } + }); + await this.frame.setFiles(this, files); + } + async *queryAXTree(name, role) { + const results = await this.frame.locateNodes(this, { + type: 'accessibility', + value: { + role, + name, + }, + }); + return yield* AsyncIterableUtil.map(results, node => { + // TODO: maybe change ownership since the default ownership is probably none. + return Promise.resolve(BidiElementHandle.from(node, this.realm)); + }); + } + }; +})(); + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __addDisposableResource$3 = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$3 = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +/** + * @internal + */ +class ExposeableFunction { + static async from(frame, name, apply, isolate = false) { + const func = new ExposeableFunction(frame, name, apply, isolate); + await func.#initialize(); + return func; + } + #frame; + name; + #apply; + #isolate; + #channel; + #scripts = []; + #disposables = new DisposableStack(); + constructor(frame, name, apply, isolate = false) { + this.#frame = frame; + this.name = name; + this.#apply = apply; + this.#isolate = isolate; + this.#channel = `__puppeteer__${this.#frame._id}_page_exposeFunction_${this.name}`; + } + async #initialize() { + const connection = this.#connection; + const channel = { + type: 'channel', + value: { + channel: this.#channel, + ownership: "root" /* Bidi.Script.ResultOwnership.Root */, + }, + }; + const connectionEmitter = this.#disposables.use(new EventEmitter(connection)); + connectionEmitter.on(Bidi.ChromiumBidi.Script.EventNames.Message, this.#handleMessage); + const functionDeclaration = stringifyFunction(interpolateFunction((callback) => { + Object.assign(globalThis, { + [PLACEHOLDER('name')]: function (...args) { + return new Promise((resolve, reject) => { + callback([resolve, reject, args]); + }); + }, + }); + }, { name: JSON.stringify(this.name) })); + const frames = [this.#frame]; + for (const frame of frames) { + frames.push(...frame.childFrames()); + } + await Promise.all(frames.map(async (frame) => { + const realm = this.#isolate ? frame.isolatedRealm() : frame.mainRealm(); + try { + const [script] = await Promise.all([ + frame.browsingContext.addPreloadScript(functionDeclaration, { + arguments: [channel], + sandbox: realm.sandbox, + }), + realm.realm.callFunction(functionDeclaration, false, { + arguments: [channel], + }), + ]); + this.#scripts.push([frame, script]); + } + catch (error) { + // If it errors, the frame probably doesn't support call function. We + // fail gracefully. + debugError(error); + } + })); + } + get #connection() { + return this.#frame.page().browser().connection; + } + #handleMessage = async (params) => { + const env_1 = { stack: [], error: void 0, hasError: false }; + try { + if (params.channel !== this.#channel) { + return; + } + const realm = this.#getRealm(params.source); + if (!realm) { + // Unrelated message. + return; + } + const dataHandle = __addDisposableResource$3(env_1, BidiJSHandle.from(params.data, realm), false); + const argsHandle = __addDisposableResource$3(env_1, await dataHandle.evaluateHandle(([, , args]) => { + return args; + }), false); + const stack = __addDisposableResource$3(env_1, new DisposableStack(), false); + const args = []; + for (const [index, handle] of await argsHandle.getProperties()) { + stack.use(handle); + // Element handles are passed as is. + if (handle instanceof BidiElementHandle) { + args[+index] = handle; + stack.use(handle); + continue; + } + // Everything else is passed as the JS value. + args[+index] = handle.jsonValue(); + } + let result; + try { + result = await this.#apply(...(await Promise.all(args))); + } + catch (error) { + try { + if (error instanceof Error) { + await dataHandle.evaluate(([, reject], name, message, stack) => { + const error = new Error(message); + error.name = name; + if (stack) { + error.stack = stack; + } + reject(error); + }, error.name, error.message, error.stack); + } + else { + await dataHandle.evaluate(([, reject], error) => { + reject(error); + }, error); + } + } + catch (error) { + debugError(error); + } + return; + } + try { + await dataHandle.evaluate(([resolve], result) => { + resolve(result); + }, result); + } + catch (error) { + debugError(error); + } + } + catch (e_1) { + env_1.error = e_1; + env_1.hasError = true; + } + finally { + __disposeResources$3(env_1); + } + }; + #getRealm(source) { + const frame = this.#findFrame(source.context); + if (!frame) { + // Unrelated message. + return; + } + return frame.realm(source.realm); + } + #findFrame(id) { + const frames = [this.#frame]; + for (const frame of frames) { + if (frame._id === id) { + return frame; + } + frames.push(...frame.childFrames()); + } + return; + } + [Symbol.dispose]() { + void this[Symbol.asyncDispose]().catch(debugError); + } + async [Symbol.asyncDispose]() { + this.#disposables.dispose(); + await Promise.all(this.#scripts.map(async ([frame, script]) => { + const realm = this.#isolate ? frame.isolatedRealm() : frame.mainRealm(); + try { + await Promise.all([ + realm.evaluate(name => { + delete globalThis[name]; + }, this.name), + frame.browsingContext.removePreloadScript(script), + ]); + } + catch (error) { + debugError(error); + } + })); + } +} + +var __runInitializers$6 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$6 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +/** + * @internal + */ +let BidiHTTPResponse = (() => { + let _classSuper = HTTPResponse; + let _instanceExtraInitializers = []; + let _remoteAddress_decorators; + return class BidiHTTPResponse extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + _remoteAddress_decorators = [invokeAtMostOnceForArguments]; + __esDecorate$6(this, null, _remoteAddress_decorators, { kind: "method", name: "remoteAddress", static: false, private: false, access: { has: obj => "remoteAddress" in obj, get: obj => obj.remoteAddress }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static from(data, request) { + const response = new BidiHTTPResponse(data, request); + response.#initialize(); + return response; + } + #data = (__runInitializers$6(this, _instanceExtraInitializers), void 0); + #request; + constructor(data, request) { + super(); + this.#data = data; + this.#request = request; + } + #initialize() { + if (this.#data.fromCache) { + this.#request + .frame() + ?.page() + .trustedEmitter.emit("requestservedfromcache" /* PageEvent.RequestServedFromCache */, this.#request); + } + this.#request.frame()?.page().trustedEmitter.emit("response" /* PageEvent.Response */, this); + } + remoteAddress() { + return { + ip: '', + port: -1, + }; + } + url() { + return this.#data.url; + } + status() { + return this.#data.status; + } + statusText() { + return this.#data.statusText; + } + headers() { + const headers = {}; + // TODO: Remove once the Firefox implementation is compliant with https://w3c.github.io/webdriver-bidi/#get-the-response-data. + for (const header of this.#data.headers || []) { + // TODO: How to handle Binary Headers + // https://w3c.github.io/webdriver-bidi/#type-network-Header + if (header.value.type === 'string') { + headers[header.name.toLowerCase()] = header.value.value; + } + } + return headers; + } + request() { + return this.#request; + } + fromCache() { + return this.#data.fromCache; + } + timing() { + // TODO: File and issue with BiDi spec + throw new UnsupportedOperation(); + } + frame() { + return this.#request.frame(); + } + fromServiceWorker() { + return false; + } + securityDetails() { + throw new UnsupportedOperation(); + } + buffer() { + throw new UnsupportedOperation(); + } + }; +})(); + +var _a; +const requests = new WeakMap(); +/** + * @internal + */ +class BidiHTTPRequest extends HTTPRequest { + static from(bidiRequest, frame, redirect) { + const request = new _a(bidiRequest, frame, redirect); + request.#initialize(); + return request; + } + #redirectBy; + #response = null; + id; + #frame; + #request; + constructor(request, frame, redirectBy) { + super(); + requests.set(request, this); + this.interception.enabled = request.isBlocked; + this.#request = request; + this.#frame = frame; + this.#redirectBy = redirectBy; + this.id = request.id; + } + get client() { + return this.#frame.client; + } + #initialize() { + this.#request.on('redirect', request => { + const httpRequest = _a.from(request, this.#frame, this); + request.once('success', () => { + this.#frame + .page() + .trustedEmitter.emit("requestfinished" /* PageEvent.RequestFinished */, httpRequest); + }); + request.once('error', () => { + this.#frame + .page() + .trustedEmitter.emit("requestfailed" /* PageEvent.RequestFailed */, httpRequest); + }); + void httpRequest.finalizeInterceptions(); + }); + this.#request.once('success', data => { + this.#response = BidiHTTPResponse.from(data, this); + }); + this.#request.on('authenticate', this.#handleAuthentication); + this.#frame.page().trustedEmitter.emit("request" /* PageEvent.Request */, this); + if (this.#hasInternalHeaderOverwrite) { + this.interception.handlers.push(async () => { + await this.continue({ + headers: this.headers(), + }, 0); + }); + } + } + url() { + return this.#request.url; + } + resourceType() { + throw new UnsupportedOperation(); + } + method() { + return this.#request.method; + } + postData() { + throw new UnsupportedOperation(); + } + hasPostData() { + throw new UnsupportedOperation(); + } + async fetchPostData() { + throw new UnsupportedOperation(); + } + get #hasInternalHeaderOverwrite() { + return Boolean(Object.keys(this.#extraHTTPHeaders).length || + Object.keys(this.#userAgentHeaders).length); + } + get #extraHTTPHeaders() { + return this.#frame?.page()._extraHTTPHeaders ?? {}; + } + get #userAgentHeaders() { + return this.#frame?.page()._userAgentHeaders ?? {}; + } + headers() { + const headers = {}; + for (const header of this.#request.headers) { + headers[header.name.toLowerCase()] = header.value.value; + } + return { + ...headers, + ...this.#extraHTTPHeaders, + ...this.#userAgentHeaders, + }; + } + response() { + return this.#response; + } + failure() { + if (this.#request.error === undefined) { + return null; + } + return { errorText: this.#request.error }; + } + isNavigationRequest() { + return this.#request.navigation !== undefined; + } + initiator() { + return this.#request.initiator; + } + redirectChain() { + if (this.#redirectBy === undefined) { + return []; + } + const redirects = [this.#redirectBy]; + for (const redirect of redirects) { + if (redirect.#redirectBy !== undefined) { + redirects.push(redirect.#redirectBy); + } + } + return redirects; + } + frame() { + return this.#frame; + } + async continue(overrides, priority) { + return await super.continue({ + headers: this.#hasInternalHeaderOverwrite ? this.headers() : undefined, + ...overrides, + }, priority); + } + async _continue(overrides = {}) { + const headers = getBidiHeaders(overrides.headers); + this.interception.handled = true; + return await this.#request + .continueRequest({ + url: overrides.url, + method: overrides.method, + body: overrides.postData + ? { + type: 'base64', + value: btoa(overrides.postData), + } + : undefined, + headers: headers.length > 0 ? headers : undefined, + }) + .catch(error => { + this.interception.handled = false; + return handleError(error); + }); + } + async _abort() { + this.interception.handled = true; + return await this.#request.failRequest().catch(error => { + this.interception.handled = false; + throw error; + }); + } + async _respond(response, _priority) { + this.interception.handled = true; + const responseBody = response.body && response.body instanceof Uint8Array + ? response.body.toString('base64') + : response.body + ? btoa(response.body) + : undefined; + const headers = getBidiHeaders(response.headers); + const hasContentLength = headers.some(header => { + return header.name === 'content-length'; + }); + if (response.contentType) { + headers.push({ + name: 'content-type', + value: { + type: 'string', + value: response.contentType, + }, + }); + } + if (responseBody && !hasContentLength) { + const encoder = new TextEncoder(); + headers.push({ + name: 'content-length', + value: { + type: 'string', + value: String(encoder.encode(responseBody).byteLength), + }, + }); + } + const status = response.status || 200; + return await this.#request + .provideResponse({ + statusCode: status, + headers: headers.length > 0 ? headers : undefined, + reasonPhrase: STATUS_TEXTS[status], + body: responseBody + ? { + type: 'base64', + value: responseBody, + } + : undefined, + }) + .catch(error => { + this.interception.handled = false; + throw error; + }); + } + #authenticationHandled = false; + #handleAuthentication = async () => { + if (!this.#frame) { + return; + } + const credentials = this.#frame.page()._credentials; + if (credentials && !this.#authenticationHandled) { + this.#authenticationHandled = true; + void this.#request.continueWithAuth({ + action: 'provideCredentials', + credentials: { + type: 'password', + username: credentials.username, + password: credentials.password, + }, + }); + } + else { + void this.#request.continueWithAuth({ + action: 'cancel', + }); + } + }; +} +_a = BidiHTTPRequest; +function getBidiHeaders(rawHeaders) { + const headers = []; + for (const [name, value] of Object.entries(rawHeaders ?? [])) { + if (!Object.is(value, undefined)) { + const values = Array.isArray(value) ? value : [value]; + for (const value of values) { + headers.push({ + name: name.toLowerCase(), + value: { + type: 'string', + value: String(value), + }, + }); + } + } + } + return headers; +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class UnserializableError extends Error { +} +/** + * @internal + */ +class BidiSerializer { + static serialize(arg) { + switch (typeof arg) { + case 'symbol': + case 'function': + throw new UnserializableError(`Unable to serializable ${typeof arg}`); + case 'object': + return this.#serializeObject(arg); + case 'undefined': + return { + type: 'undefined', + }; + case 'number': + return this.#serializeNumber(arg); + case 'bigint': + return { + type: 'bigint', + value: arg.toString(), + }; + case 'string': + return { + type: 'string', + value: arg, + }; + case 'boolean': + return { + type: 'boolean', + value: arg, + }; + } + } + static #serializeNumber(arg) { + let value; + if (Object.is(arg, -0)) { + value = '-0'; + } + else if (Object.is(arg, Infinity)) { + value = 'Infinity'; + } + else if (Object.is(arg, -Infinity)) { + value = '-Infinity'; + } + else if (Object.is(arg, NaN)) { + value = 'NaN'; + } + else { + value = arg; + } + return { + type: 'number', + value, + }; + } + static #serializeObject(arg) { + if (arg === null) { + return { + type: 'null', + }; + } + else if (Array.isArray(arg)) { + const parsedArray = arg.map(subArg => { + return this.serialize(subArg); + }); + return { + type: 'array', + value: parsedArray, + }; + } + else if (isPlainObject(arg)) { + try { + JSON.stringify(arg); + } + catch (error) { + if (error instanceof TypeError && + error.message.startsWith('Converting circular structure to JSON')) { + error.message += ' Recursive objects are not allowed.'; + } + throw error; + } + const parsedObject = []; + for (const key in arg) { + parsedObject.push([this.serialize(key), this.serialize(arg[key])]); + } + return { + type: 'object', + value: parsedObject, + }; + } + else if (isRegExp(arg)) { + return { + type: 'regexp', + value: { + pattern: arg.source, + flags: arg.flags, + }, + }; + } + else if (isDate(arg)) { + return { + type: 'date', + value: arg.toISOString(), + }; + } + throw new UnserializableError('Custom object sterilization not possible. Use plain objects instead.'); + } +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +function createEvaluationError(details) { + if (details.exception.type !== 'error') { + return BidiDeserializer.deserialize(details.exception); + } + const [name = '', ...parts] = details.text.split(': '); + const message = parts.join(': '); + const error = new Error(message); + error.name = name; + // The first line is this function which we ignore. + const stackLines = []; + if (details.stackTrace && stackLines.length < Error.stackTraceLimit) { + for (const frame of details.stackTrace.callFrames.reverse()) { + if (PuppeteerURL.isPuppeteerURL(frame.url) && + frame.url !== PuppeteerURL.INTERNAL_URL) { + const url = PuppeteerURL.parse(frame.url); + stackLines.unshift(` at ${frame.functionName || url.functionName} (${url.functionName} at ${url.siteString}, :${frame.lineNumber}:${frame.columnNumber})`); + } + else { + stackLines.push(` at ${frame.functionName || ''} (${frame.url}:${frame.lineNumber}:${frame.columnNumber})`); + } + if (stackLines.length >= Error.stackTraceLimit) { + break; + } + } + } + error.stack = [details.text, ...stackLines].join('\n'); + return error; +} +/** + * @internal + */ +function rewriteNavigationError(message, ms) { + return error => { + if (error instanceof ProtocolError) { + error.message += ` at ${message}`; + } + else if (error instanceof TimeoutError) { + error.message = `Navigation timeout of ${ms} ms exceeded`; + } + throw error; + }; +} + +var __addDisposableResource$2 = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$2 = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +/** + * @internal + */ +class BidiRealm extends Realm$1 { + realm; + constructor(realm, timeoutSettings) { + super(timeoutSettings); + this.realm = realm; + } + initialize() { + this.realm.on('destroyed', ({ reason }) => { + this.taskManager.terminateAll(new Error(reason)); + }); + this.realm.on('updated', () => { + this.internalPuppeteerUtil = undefined; + void this.taskManager.rerunAll(); + }); + } + internalPuppeteerUtil; + get puppeteerUtil() { + const promise = Promise.resolve(); + scriptInjector.inject(script => { + if (this.internalPuppeteerUtil) { + void this.internalPuppeteerUtil.then(handle => { + void handle.dispose(); + }); + } + this.internalPuppeteerUtil = promise.then(() => { + return this.evaluateHandle(script); + }); + }, !this.internalPuppeteerUtil); + return this.internalPuppeteerUtil; + } + async evaluateHandle(pageFunction, ...args) { + return await this.#evaluate(false, pageFunction, ...args); + } + async evaluate(pageFunction, ...args) { + return await this.#evaluate(true, pageFunction, ...args); + } + async #evaluate(returnByValue, pageFunction, ...args) { + const sourceUrlComment = getSourceUrlComment(getSourcePuppeteerURLIfAvailable(pageFunction)?.toString() ?? + PuppeteerURL.INTERNAL_URL); + let responsePromise; + const resultOwnership = returnByValue + ? "none" /* Bidi.Script.ResultOwnership.None */ + : "root" /* Bidi.Script.ResultOwnership.Root */; + const serializationOptions = returnByValue + ? {} + : { + maxObjectDepth: 0, + maxDomDepth: 0, + }; + if (isString(pageFunction)) { + const expression = SOURCE_URL_REGEX.test(pageFunction) + ? pageFunction + : `${pageFunction}\n${sourceUrlComment}\n`; + responsePromise = this.realm.evaluate(expression, true, { + resultOwnership, + userActivation: true, + serializationOptions, + }); + } + else { + let functionDeclaration = stringifyFunction(pageFunction); + functionDeclaration = SOURCE_URL_REGEX.test(functionDeclaration) + ? functionDeclaration + : `${functionDeclaration}\n${sourceUrlComment}\n`; + responsePromise = this.realm.callFunction(functionDeclaration, + /* awaitPromise= */ true, { + arguments: args.length + ? await Promise.all(args.map(arg => { + return this.serialize(arg); + })) + : [], + resultOwnership, + userActivation: true, + serializationOptions, + }); + } + const result = await responsePromise; + if ('type' in result && result.type === 'exception') { + throw createEvaluationError(result.exceptionDetails); + } + return returnByValue + ? BidiDeserializer.deserialize(result.result) + : this.createHandle(result.result); + } + createHandle(result) { + if ((result.type === 'node' || result.type === 'window') && + this instanceof BidiFrameRealm) { + return BidiElementHandle.from(result, this); + } + return BidiJSHandle.from(result, this); + } + async serialize(arg) { + if (arg instanceof LazyArg) { + arg = await arg.get(this); + } + if (arg instanceof BidiJSHandle || arg instanceof BidiElementHandle) { + if (arg.realm !== this) { + if (!(arg.realm instanceof BidiFrameRealm) || + !(this instanceof BidiFrameRealm)) { + throw new Error("Trying to evaluate JSHandle from different global types. Usually this means you're using a handle from a worker in a page or vice versa."); + } + if (arg.realm.environment !== this.environment) { + throw new Error("Trying to evaluate JSHandle from different frames. Usually this means you're using a handle from a page on a different page."); + } + } + if (arg.disposed) { + throw new Error('JSHandle is disposed!'); + } + return arg.remoteValue(); + } + return BidiSerializer.serialize(arg); + } + async destroyHandles(handles) { + const handleIds = handles + .map(({ id }) => { + return id; + }) + .filter((id) => { + return id !== undefined; + }); + if (handleIds.length === 0) { + return; + } + await this.realm.disown(handleIds).catch(error => { + // Exceptions might happen in case of a page been navigated or closed. + // Swallow these since they are harmless and we don't leak anything in this case. + debugError(error); + }); + } + async adoptHandle(handle) { + return (await this.evaluateHandle(node => { + return node; + }, handle)); + } + async transferHandle(handle) { + if (handle.realm === this) { + return handle; + } + const transferredHandle = this.adoptHandle(handle); + await handle.dispose(); + return await transferredHandle; + } +} +/** + * @internal + */ +class BidiFrameRealm extends BidiRealm { + static from(realm, frame) { + const frameRealm = new BidiFrameRealm(realm, frame); + frameRealm.#initialize(); + return frameRealm; + } + #frame; + constructor(realm, frame) { + super(realm, frame.timeoutSettings); + this.#frame = frame; + } + #initialize() { + super.initialize(); + // This should run first. + this.realm.on('updated', () => { + this.environment.clearDocumentHandle(); + this.#bindingsInstalled = false; + }); + } + #bindingsInstalled = false; + get puppeteerUtil() { + let promise = Promise.resolve(); + if (!this.#bindingsInstalled) { + promise = Promise.all([ + ExposeableFunction.from(this.environment, '__ariaQuerySelector', ARIAQueryHandler.queryOne, !!this.sandbox), + ExposeableFunction.from(this.environment, '__ariaQuerySelectorAll', async (element, selector) => { + const results = ARIAQueryHandler.queryAll(element, selector); + return await element.realm.evaluateHandle((...elements) => { + return elements; + }, ...(await AsyncIterableUtil.collect(results))); + }, !!this.sandbox), + ]); + this.#bindingsInstalled = true; + } + return promise.then(() => { + return super.puppeteerUtil; + }); + } + get sandbox() { + return this.realm.sandbox; + } + get environment() { + return this.#frame; + } + async adoptBackendNode(backendNodeId) { + const env_1 = { stack: [], error: void 0, hasError: false }; + try { + const { object } = await this.#frame.client.send('DOM.resolveNode', { + backendNodeId, + executionContextId: await this.realm.resolveExecutionContextId(), + }); + const handle = __addDisposableResource$2(env_1, BidiElementHandle.from({ + handle: object.objectId, + type: 'node', + }, this), false); + // We need the sharedId, so we perform the following to obtain it. + return await handle.evaluateHandle(element => { + return element; + }); + } + catch (e_1) { + env_1.error = e_1; + env_1.hasError = true; + } + finally { + __disposeResources$2(env_1); + } + } +} +/** + * @internal + */ +class BidiWorkerRealm extends BidiRealm { + static from(realm, worker) { + const workerRealm = new BidiWorkerRealm(realm, worker); + workerRealm.initialize(); + return workerRealm; + } + #worker; + constructor(realm, frame) { + super(realm, frame.timeoutSettings); + this.#worker = frame; + } + get environment() { + return this.#worker; + } + async adoptBackendNode() { + throw new Error('Cannot adopt DOM nodes into a worker.'); + } +} + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class BidiWebWorker extends WebWorker { + static from(frame, realm) { + const worker = new BidiWebWorker(frame, realm); + return worker; + } + #frame; + #realm; + constructor(frame, realm) { + super(realm.origin); + this.#frame = frame; + this.#realm = BidiWorkerRealm.from(realm, this); + } + get frame() { + return this.#frame; + } + mainRealm() { + return this.#realm; + } + get client() { + throw new UnsupportedOperation(); + } +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$5 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$5 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var __setFunctionName$1 = (undefined && undefined.__setFunctionName) || function (f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); +}; +let BidiFrame = (() => { + let _classSuper = Frame; + let _instanceExtraInitializers = []; + let _goto_decorators; + let _setContent_decorators; + let _waitForNavigation_decorators; + let _private_waitForLoad$_decorators; + let _private_waitForLoad$_descriptor; + let _private_waitForNetworkIdle$_decorators; + let _private_waitForNetworkIdle$_descriptor; + let _setFiles_decorators; + let _locateNodes_decorators; + return class BidiFrame extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + _goto_decorators = [throwIfDetached]; + _setContent_decorators = [throwIfDetached]; + _waitForNavigation_decorators = [throwIfDetached]; + _private_waitForLoad$_decorators = [throwIfDetached]; + _private_waitForNetworkIdle$_decorators = [throwIfDetached]; + _setFiles_decorators = [throwIfDetached]; + _locateNodes_decorators = [throwIfDetached]; + __esDecorate$5(this, null, _goto_decorators, { kind: "method", name: "goto", static: false, private: false, access: { has: obj => "goto" in obj, get: obj => obj.goto }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$5(this, null, _setContent_decorators, { kind: "method", name: "setContent", static: false, private: false, access: { has: obj => "setContent" in obj, get: obj => obj.setContent }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$5(this, null, _waitForNavigation_decorators, { kind: "method", name: "waitForNavigation", static: false, private: false, access: { has: obj => "waitForNavigation" in obj, get: obj => obj.waitForNavigation }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$5(this, _private_waitForLoad$_descriptor = { value: __setFunctionName$1(function (options = {}) { + let { waitUntil = 'load' } = options; + const { timeout: ms = this.timeoutSettings.navigationTimeout() } = options; + if (!Array.isArray(waitUntil)) { + waitUntil = [waitUntil]; + } + const events = new Set(); + for (const lifecycleEvent of waitUntil) { + switch (lifecycleEvent) { + case 'load': { + events.add('load'); + break; + } + case 'domcontentloaded': { + events.add('DOMContentLoaded'); + break; + } + } + } + if (events.size === 0) { + return of(undefined); + } + return combineLatest([...events].map(event => { + return fromEmitterEvent(this.browsingContext, event); + })).pipe(map(() => { }), first(), raceWith(timeout(ms), this.#detached$().pipe(map(() => { + throw new Error('Frame detached.'); + })))); + }, "#waitForLoad$") }, _private_waitForLoad$_decorators, { kind: "method", name: "#waitForLoad$", static: false, private: true, access: { has: obj => #waitForLoad$ in obj, get: obj => obj.#waitForLoad$ }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$5(this, _private_waitForNetworkIdle$_descriptor = { value: __setFunctionName$1(function (options = {}) { + let { waitUntil = 'load' } = options; + if (!Array.isArray(waitUntil)) { + waitUntil = [waitUntil]; + } + let concurrency = Infinity; + for (const event of waitUntil) { + switch (event) { + case 'networkidle0': { + concurrency = Math.min(0, concurrency); + break; + } + case 'networkidle2': { + concurrency = Math.min(2, concurrency); + break; + } + } + } + if (concurrency === Infinity) { + return of(undefined); + } + return this.page().waitForNetworkIdle$({ + idleTime: 500, + timeout: options.timeout ?? this.timeoutSettings.timeout(), + concurrency, + }); + }, "#waitForNetworkIdle$") }, _private_waitForNetworkIdle$_decorators, { kind: "method", name: "#waitForNetworkIdle$", static: false, private: true, access: { has: obj => #waitForNetworkIdle$ in obj, get: obj => obj.#waitForNetworkIdle$ }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$5(this, null, _setFiles_decorators, { kind: "method", name: "setFiles", static: false, private: false, access: { has: obj => "setFiles" in obj, get: obj => obj.setFiles }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$5(this, null, _locateNodes_decorators, { kind: "method", name: "locateNodes", static: false, private: false, access: { has: obj => "locateNodes" in obj, get: obj => obj.locateNodes }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static from(parent, browsingContext) { + const frame = new BidiFrame(parent, browsingContext); + frame.#initialize(); + return frame; + } + #parent = (__runInitializers$5(this, _instanceExtraInitializers), void 0); + browsingContext; + #frames = new WeakMap(); + realms; + _id; + client; + constructor(parent, browsingContext) { + super(); + this.#parent = parent; + this.browsingContext = browsingContext; + this._id = browsingContext.id; + this.client = new BidiCdpSession(this); + this.realms = { + default: BidiFrameRealm.from(this.browsingContext.defaultRealm, this), + internal: BidiFrameRealm.from(this.browsingContext.createWindowRealm(`__puppeteer_internal_${Math.ceil(Math.random() * 10000)}`), this), + }; + } + #initialize() { + for (const browsingContext of this.browsingContext.children) { + this.#createFrameTarget(browsingContext); + } + this.browsingContext.on('browsingcontext', ({ browsingContext }) => { + this.#createFrameTarget(browsingContext); + }); + this.browsingContext.on('closed', () => { + for (const session of BidiCdpSession.sessions.values()) { + if (session.frame === this) { + session.onClose(); + } + } + this.page().trustedEmitter.emit("framedetached" /* PageEvent.FrameDetached */, this); + }); + this.browsingContext.on('request', ({ request }) => { + const httpRequest = BidiHTTPRequest.from(request, this); + request.once('success', () => { + this.page().trustedEmitter.emit("requestfinished" /* PageEvent.RequestFinished */, httpRequest); + }); + request.once('error', () => { + this.page().trustedEmitter.emit("requestfailed" /* PageEvent.RequestFailed */, httpRequest); + }); + void httpRequest.finalizeInterceptions(); + }); + this.browsingContext.on('navigation', ({ navigation }) => { + navigation.once('fragment', () => { + this.page().trustedEmitter.emit("framenavigated" /* PageEvent.FrameNavigated */, this); + }); + }); + this.browsingContext.on('load', () => { + this.page().trustedEmitter.emit("load" /* PageEvent.Load */, undefined); + }); + this.browsingContext.on('DOMContentLoaded', () => { + this._hasStartedLoading = true; + this.page().trustedEmitter.emit("domcontentloaded" /* PageEvent.DOMContentLoaded */, undefined); + this.page().trustedEmitter.emit("framenavigated" /* PageEvent.FrameNavigated */, this); + }); + this.browsingContext.on('userprompt', ({ userPrompt }) => { + this.page().trustedEmitter.emit("dialog" /* PageEvent.Dialog */, BidiDialog.from(userPrompt)); + }); + this.browsingContext.on('log', ({ entry }) => { + if (this._id !== entry.source.context) { + return; + } + if (isConsoleLogEntry(entry)) { + const args = entry.args.map(arg => { + return this.mainRealm().createHandle(arg); + }); + const text = args + .reduce((value, arg) => { + const parsedValue = arg instanceof BidiJSHandle && arg.isPrimitiveValue + ? BidiDeserializer.deserialize(arg.remoteValue()) + : arg.toString(); + return `${value} ${parsedValue}`; + }, '') + .slice(1); + this.page().trustedEmitter.emit("console" /* PageEvent.Console */, new ConsoleMessage(entry.method, text, args, getStackTraceLocations(entry.stackTrace))); + } + else if (isJavaScriptLogEntry(entry)) { + const error = new Error(entry.text ?? ''); + const messageHeight = error.message.split('\n').length; + const messageLines = error.stack.split('\n').splice(0, messageHeight); + const stackLines = []; + if (entry.stackTrace) { + for (const frame of entry.stackTrace.callFrames) { + // Note we need to add `1` because the values are 0-indexed. + stackLines.push(` at ${frame.functionName || ''} (${frame.url}:${frame.lineNumber + 1}:${frame.columnNumber + 1})`); + if (stackLines.length >= Error.stackTraceLimit) { + break; + } + } + } + error.stack = [...messageLines, ...stackLines].join('\n'); + this.page().trustedEmitter.emit("pageerror" /* PageEvent.PageError */, error); + } + else { + debugError(`Unhandled LogEntry with type "${entry.type}", text "${entry.text}" and level "${entry.level}"`); + } + }); + this.browsingContext.on('worker', ({ realm }) => { + const worker = BidiWebWorker.from(this, realm); + realm.on('destroyed', () => { + this.page().trustedEmitter.emit("workerdestroyed" /* PageEvent.WorkerDestroyed */, worker); + }); + this.page().trustedEmitter.emit("workercreated" /* PageEvent.WorkerCreated */, worker); + }); + } + #createFrameTarget(browsingContext) { + const frame = BidiFrame.from(this, browsingContext); + this.#frames.set(browsingContext, frame); + this.page().trustedEmitter.emit("frameattached" /* PageEvent.FrameAttached */, frame); + browsingContext.on('closed', () => { + this.#frames.delete(browsingContext); + }); + return frame; + } + get timeoutSettings() { + return this.page()._timeoutSettings; + } + mainRealm() { + return this.realms.default; + } + isolatedRealm() { + return this.realms.internal; + } + realm(id) { + for (const realm of Object.values(this.realms)) { + if (realm.realm.id === id) { + return realm; + } + } + return; + } + page() { + let parent = this.#parent; + while (parent instanceof BidiFrame) { + parent = parent.#parent; + } + return parent; + } + isOOPFrame() { + throw new UnsupportedOperation(); + } + url() { + return this.browsingContext.url; + } + parentFrame() { + if (this.#parent instanceof BidiFrame) { + return this.#parent; + } + return null; + } + childFrames() { + return [...this.browsingContext.children].map(child => { + return this.#frames.get(child); + }); + } + #detached$() { + return defer(() => { + if (this.detached) { + return of(this); + } + return fromEmitterEvent(this.page().trustedEmitter, "framedetached" /* PageEvent.FrameDetached */).pipe(filter(detachedFrame => { + return detachedFrame === this; + })); + }); + } + async goto(url, options = {}) { + const [response] = await Promise.all([ + this.waitForNavigation(options), + // Some implementations currently only report errors when the + // readiness=interactive. + // + // Related: https://bugzilla.mozilla.org/show_bug.cgi?id=1846601 + this.browsingContext + .navigate(url, "interactive" /* Bidi.BrowsingContext.ReadinessState.Interactive */) + .catch(error => { + if (isErrorLike(error) && + error.message.includes('net::ERR_HTTP_RESPONSE_CODE_FAILURE')) { + return; + } + throw error; + }), + ]).catch(rewriteNavigationError(url, options.timeout ?? this.timeoutSettings.navigationTimeout())); + return response; + } + async setContent(html, options = {}) { + await Promise.all([ + this.setFrameContent(html), + firstValueFrom(combineLatest([ + this.#waitForLoad$(options), + this.#waitForNetworkIdle$(options), + ])), + ]); + } + async waitForNavigation(options = {}) { + const { timeout: ms = this.timeoutSettings.navigationTimeout() } = options; + const frames = this.childFrames().map(frame => { + return frame.#detached$(); + }); + return await firstValueFrom(combineLatest([ + fromEmitterEvent(this.browsingContext, 'navigation').pipe(switchMap(({ navigation }) => { + return this.#waitForLoad$(options).pipe(delayWhen(() => { + if (frames.length === 0) { + return of(undefined); + } + return combineLatest(frames); + }), raceWith(fromEmitterEvent(navigation, 'fragment'), fromEmitterEvent(navigation, 'failed'), fromEmitterEvent(navigation, 'aborted').pipe(map(({ url }) => { + throw new Error(`Navigation aborted: ${url}`); + }))), switchMap(() => { + if (navigation.request) { + function requestFinished$(request) { + // Reduces flakiness if the response events arrive after + // the load event. + // Usually, the response or error is already there at this point. + if (request.response || request.error) { + return of(navigation); + } + if (request.redirect) { + return requestFinished$(request.redirect); + } + return fromEmitterEvent(request, 'success') + .pipe(raceWith(fromEmitterEvent(request, 'error')), raceWith(fromEmitterEvent(request, 'redirect'))) + .pipe(switchMap(() => { + return requestFinished$(request); + })); + } + return requestFinished$(navigation.request); + } + return of(navigation); + })); + })), + this.#waitForNetworkIdle$(options), + ]).pipe(map(([navigation]) => { + const request = navigation.request; + if (!request) { + return null; + } + const lastRequest = request.lastRedirect ?? request; + const httpRequest = requests.get(lastRequest); + return httpRequest.response(); + }), raceWith(timeout(ms), this.#detached$().pipe(map(() => { + throw new TargetCloseError('Frame detached.'); + }))))); + } + waitForDevicePrompt() { + throw new UnsupportedOperation(); + } + get detached() { + return this.browsingContext.closed; + } + #exposedFunctions = new Map(); + async exposeFunction(name, apply) { + if (this.#exposedFunctions.has(name)) { + throw new Error(`Failed to add page binding with name ${name}: globalThis['${name}'] already exists!`); + } + const exposeable = await ExposeableFunction.from(this, name, apply); + this.#exposedFunctions.set(name, exposeable); + } + async removeExposedFunction(name) { + const exposedFunction = this.#exposedFunctions.get(name); + if (!exposedFunction) { + throw new Error(`Failed to remove page binding with name ${name}: window['${name}'] does not exists!`); + } + this.#exposedFunctions.delete(name); + await exposedFunction[Symbol.asyncDispose](); + } + waitForSelector(selector, options) { + if (selector.startsWith('aria') && !this.page().browser().cdpSupported) { + throw new UnsupportedOperation('ARIA selector is not supported for BiDi!'); + } + return super.waitForSelector(selector, options); + } + async createCDPSession() { + const { sessionId } = await this.client.send('Target.attachToTarget', { + targetId: this._id, + flatten: true, + }); + await this.browsingContext.subscribe([Bidi.ChromiumBidi.BiDiModule.Cdp]); + return new BidiCdpSession(this, sessionId); + } + get #waitForLoad$() { return _private_waitForLoad$_descriptor.value; } + get #waitForNetworkIdle$() { return _private_waitForNetworkIdle$_descriptor.value; } + async setFiles(element, files) { + await this.browsingContext.setFiles( + // SAFETY: ElementHandles are always remote references. + element.remoteValue(), files); + } + async locateNodes(element, locator) { + return await this.browsingContext.locateNodes(locator, + // SAFETY: ElementHandles are always remote references. + [element.remoteValue()]); + } + }; +})(); +function isConsoleLogEntry(event) { + return event.type === 'console'; +} +function isJavaScriptLogEntry(event) { + return event.type === 'javascript'; +} +function getStackTraceLocations(stackTrace) { + const stackTraceLocations = []; + if (stackTrace) { + for (const callFrame of stackTrace.callFrames) { + stackTraceLocations.push({ + url: callFrame.url, + lineNumber: callFrame.lineNumber, + columnNumber: callFrame.columnNumber, + }); + } + } + return stackTraceLocations; +} + +/** + * @license + * Copyright 2017 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var SourceActionsType; +(function (SourceActionsType) { + SourceActionsType["None"] = "none"; + SourceActionsType["Key"] = "key"; + SourceActionsType["Pointer"] = "pointer"; + SourceActionsType["Wheel"] = "wheel"; +})(SourceActionsType || (SourceActionsType = {})); +var ActionType; +(function (ActionType) { + ActionType["Pause"] = "pause"; + ActionType["KeyDown"] = "keyDown"; + ActionType["KeyUp"] = "keyUp"; + ActionType["PointerUp"] = "pointerUp"; + ActionType["PointerDown"] = "pointerDown"; + ActionType["PointerMove"] = "pointerMove"; + ActionType["Scroll"] = "scroll"; +})(ActionType || (ActionType = {})); +const getBidiKeyValue = (key) => { + switch (key) { + case '\r': + case '\n': + key = 'Enter'; + break; + } + // Measures the number of code points rather than UTF-16 code units. + if ([...key].length === 1) { + return key; + } + switch (key) { + case 'Cancel': + return '\uE001'; + case 'Help': + return '\uE002'; + case 'Backspace': + return '\uE003'; + case 'Tab': + return '\uE004'; + case 'Clear': + return '\uE005'; + case 'Enter': + return '\uE007'; + case 'Shift': + case 'ShiftLeft': + return '\uE008'; + case 'Control': + case 'ControlLeft': + return '\uE009'; + case 'Alt': + case 'AltLeft': + return '\uE00A'; + case 'Pause': + return '\uE00B'; + case 'Escape': + return '\uE00C'; + case 'PageUp': + return '\uE00E'; + case 'PageDown': + return '\uE00F'; + case 'End': + return '\uE010'; + case 'Home': + return '\uE011'; + case 'ArrowLeft': + return '\uE012'; + case 'ArrowUp': + return '\uE013'; + case 'ArrowRight': + return '\uE014'; + case 'ArrowDown': + return '\uE015'; + case 'Insert': + return '\uE016'; + case 'Delete': + return '\uE017'; + case 'NumpadEqual': + return '\uE019'; + case 'Numpad0': + return '\uE01A'; + case 'Numpad1': + return '\uE01B'; + case 'Numpad2': + return '\uE01C'; + case 'Numpad3': + return '\uE01D'; + case 'Numpad4': + return '\uE01E'; + case 'Numpad5': + return '\uE01F'; + case 'Numpad6': + return '\uE020'; + case 'Numpad7': + return '\uE021'; + case 'Numpad8': + return '\uE022'; + case 'Numpad9': + return '\uE023'; + case 'NumpadMultiply': + return '\uE024'; + case 'NumpadAdd': + return '\uE025'; + case 'NumpadSubtract': + return '\uE027'; + case 'NumpadDecimal': + return '\uE028'; + case 'NumpadDivide': + return '\uE029'; + case 'F1': + return '\uE031'; + case 'F2': + return '\uE032'; + case 'F3': + return '\uE033'; + case 'F4': + return '\uE034'; + case 'F5': + return '\uE035'; + case 'F6': + return '\uE036'; + case 'F7': + return '\uE037'; + case 'F8': + return '\uE038'; + case 'F9': + return '\uE039'; + case 'F10': + return '\uE03A'; + case 'F11': + return '\uE03B'; + case 'F12': + return '\uE03C'; + case 'Meta': + case 'MetaLeft': + return '\uE03D'; + case 'ShiftRight': + return '\uE050'; + case 'ControlRight': + return '\uE051'; + case 'AltRight': + return '\uE052'; + case 'MetaRight': + return '\uE053'; + case 'Digit0': + return '0'; + case 'Digit1': + return '1'; + case 'Digit2': + return '2'; + case 'Digit3': + return '3'; + case 'Digit4': + return '4'; + case 'Digit5': + return '5'; + case 'Digit6': + return '6'; + case 'Digit7': + return '7'; + case 'Digit8': + return '8'; + case 'Digit9': + return '9'; + case 'KeyA': + return 'a'; + case 'KeyB': + return 'b'; + case 'KeyC': + return 'c'; + case 'KeyD': + return 'd'; + case 'KeyE': + return 'e'; + case 'KeyF': + return 'f'; + case 'KeyG': + return 'g'; + case 'KeyH': + return 'h'; + case 'KeyI': + return 'i'; + case 'KeyJ': + return 'j'; + case 'KeyK': + return 'k'; + case 'KeyL': + return 'l'; + case 'KeyM': + return 'm'; + case 'KeyN': + return 'n'; + case 'KeyO': + return 'o'; + case 'KeyP': + return 'p'; + case 'KeyQ': + return 'q'; + case 'KeyR': + return 'r'; + case 'KeyS': + return 's'; + case 'KeyT': + return 't'; + case 'KeyU': + return 'u'; + case 'KeyV': + return 'v'; + case 'KeyW': + return 'w'; + case 'KeyX': + return 'x'; + case 'KeyY': + return 'y'; + case 'KeyZ': + return 'z'; + case 'Semicolon': + return ';'; + case 'Equal': + return '='; + case 'Comma': + return ','; + case 'Minus': + return '-'; + case 'Period': + return '.'; + case 'Slash': + return '/'; + case 'Backquote': + return '`'; + case 'BracketLeft': + return '['; + case 'Backslash': + return '\\'; + case 'BracketRight': + return ']'; + case 'Quote': + return '"'; + default: + throw new Error(`Unknown key: "${key}"`); + } +}; +/** + * @internal + */ +class BidiKeyboard extends Keyboard { + #page; + constructor(page) { + super(); + this.#page = page; + } + async down(key, _options) { + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Key, + id: "__puppeteer_keyboard" /* InputId.Keyboard */, + actions: [ + { + type: ActionType.KeyDown, + value: getBidiKeyValue(key), + }, + ], + }, + ]); + } + async up(key) { + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Key, + id: "__puppeteer_keyboard" /* InputId.Keyboard */, + actions: [ + { + type: ActionType.KeyUp, + value: getBidiKeyValue(key), + }, + ], + }, + ]); + } + async press(key, options = {}) { + const { delay = 0 } = options; + const actions = [ + { + type: ActionType.KeyDown, + value: getBidiKeyValue(key), + }, + ]; + if (delay > 0) { + actions.push({ + type: ActionType.Pause, + duration: delay, + }); + } + actions.push({ + type: ActionType.KeyUp, + value: getBidiKeyValue(key), + }); + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Key, + id: "__puppeteer_keyboard" /* InputId.Keyboard */, + actions, + }, + ]); + } + async type(text, options = {}) { + const { delay = 0 } = options; + // This spread separates the characters into code points rather than UTF-16 + // code units. + const values = [...text].map(getBidiKeyValue); + const actions = []; + if (delay <= 0) { + for (const value of values) { + actions.push({ + type: ActionType.KeyDown, + value, + }, { + type: ActionType.KeyUp, + value, + }); + } + } + else { + for (const value of values) { + actions.push({ + type: ActionType.KeyDown, + value, + }, { + type: ActionType.Pause, + duration: delay, + }, { + type: ActionType.KeyUp, + value, + }); + } + } + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Key, + id: "__puppeteer_keyboard" /* InputId.Keyboard */, + actions, + }, + ]); + } + async sendCharacter(char) { + // Measures the number of code points rather than UTF-16 code units. + if ([...char].length > 1) { + throw new Error('Cannot send more than 1 character.'); + } + const frame = await this.#page.focusedFrame(); + await frame.isolatedRealm().evaluate(async (char) => { + document.execCommand('insertText', false, char); + }, char); + } +} +const getBidiButton = (button) => { + switch (button) { + case MouseButton.Left: + return 0; + case MouseButton.Middle: + return 1; + case MouseButton.Right: + return 2; + case MouseButton.Back: + return 3; + case MouseButton.Forward: + return 4; + } +}; +/** + * @internal + */ +class BidiMouse extends Mouse { + #page; + #lastMovePoint = { x: 0, y: 0 }; + constructor(page) { + super(); + this.#page = page; + } + async reset() { + this.#lastMovePoint = { x: 0, y: 0 }; + await this.#page.mainFrame().browsingContext.releaseActions(); + } + async move(x, y, options = {}) { + const from = this.#lastMovePoint; + const to = { + x: Math.round(x), + y: Math.round(y), + }; + const actions = []; + const steps = options.steps ?? 0; + for (let i = 0; i < steps; ++i) { + actions.push({ + type: ActionType.PointerMove, + x: from.x + (to.x - from.x) * (i / steps), + y: from.y + (to.y - from.y) * (i / steps), + origin: options.origin, + }); + } + actions.push({ + type: ActionType.PointerMove, + ...to, + origin: options.origin, + }); + // https://w3c.github.io/webdriver-bidi/#command-input-performActions:~:text=input.PointerMoveAction%20%3D%20%7B%0A%20%20type%3A%20%22pointerMove%22%2C%0A%20%20x%3A%20js%2Dint%2C + this.#lastMovePoint = to; + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Pointer, + id: "__puppeteer_mouse" /* InputId.Mouse */, + actions, + }, + ]); + } + async down(options = {}) { + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Pointer, + id: "__puppeteer_mouse" /* InputId.Mouse */, + actions: [ + { + type: ActionType.PointerDown, + button: getBidiButton(options.button ?? MouseButton.Left), + }, + ], + }, + ]); + } + async up(options = {}) { + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Pointer, + id: "__puppeteer_mouse" /* InputId.Mouse */, + actions: [ + { + type: ActionType.PointerUp, + button: getBidiButton(options.button ?? MouseButton.Left), + }, + ], + }, + ]); + } + async click(x, y, options = {}) { + const actions = [ + { + type: ActionType.PointerMove, + x: Math.round(x), + y: Math.round(y), + origin: options.origin, + }, + ]; + const pointerDownAction = { + type: ActionType.PointerDown, + button: getBidiButton(options.button ?? MouseButton.Left), + }; + const pointerUpAction = { + type: ActionType.PointerUp, + button: pointerDownAction.button, + }; + for (let i = 1; i < (options.count ?? 1); ++i) { + actions.push(pointerDownAction, pointerUpAction); + } + actions.push(pointerDownAction); + if (options.delay) { + actions.push({ + type: ActionType.Pause, + duration: options.delay, + }); + } + actions.push(pointerUpAction); + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Pointer, + id: "__puppeteer_mouse" /* InputId.Mouse */, + actions, + }, + ]); + } + async wheel(options = {}) { + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Wheel, + id: "__puppeteer_wheel" /* InputId.Wheel */, + actions: [ + { + type: ActionType.Scroll, + ...(this.#lastMovePoint ?? { + x: 0, + y: 0, + }), + deltaX: options.deltaX ?? 0, + deltaY: options.deltaY ?? 0, + }, + ], + }, + ]); + } + drag() { + throw new UnsupportedOperation(); + } + dragOver() { + throw new UnsupportedOperation(); + } + dragEnter() { + throw new UnsupportedOperation(); + } + drop() { + throw new UnsupportedOperation(); + } + dragAndDrop() { + throw new UnsupportedOperation(); + } +} +/** + * @internal + */ +class BidiTouchscreen extends Touchscreen { + #page; + constructor(page) { + super(); + this.#page = page; + } + async touchStart(x, y, options = {}) { + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Pointer, + id: "__puppeteer_finger" /* InputId.Finger */, + parameters: { + pointerType: "touch" /* Bidi.Input.PointerType.Touch */, + }, + actions: [ + { + type: ActionType.PointerMove, + x: Math.round(x), + y: Math.round(y), + origin: options.origin, + }, + { + type: ActionType.PointerDown, + button: 0, + }, + ], + }, + ]); + } + async touchMove(x, y, options = {}) { + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Pointer, + id: "__puppeteer_finger" /* InputId.Finger */, + parameters: { + pointerType: "touch" /* Bidi.Input.PointerType.Touch */, + }, + actions: [ + { + type: ActionType.PointerMove, + x: Math.round(x), + y: Math.round(y), + origin: options.origin, + }, + ], + }, + ]); + } + async touchEnd() { + await this.#page.mainFrame().browsingContext.performActions([ + { + type: SourceActionsType.Pointer, + id: "__puppeteer_finger" /* InputId.Finger */, + parameters: { + pointerType: "touch" /* Bidi.Input.PointerType.Touch */, + }, + actions: [ + { + type: ActionType.PointerUp, + button: 0, + }, + ], + }, + ]); + } +} + +/** + * @license + * Copyright 2022 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __esDecorate$4 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var __runInitializers$4 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __addDisposableResource$1 = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$1 = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +/** + * Implements Page using WebDriver BiDi. + * + * @internal + */ +let BidiPage = (() => { + let _classSuper = Page; + let _instanceExtraInitializers = []; + let _trustedEmitter_decorators; + let _trustedEmitter_initializers = []; + return class BidiPage extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + _trustedEmitter_decorators = [bubble()]; + __esDecorate$4(this, null, _trustedEmitter_decorators, { kind: "accessor", name: "trustedEmitter", static: false, private: false, access: { has: obj => "trustedEmitter" in obj, get: obj => obj.trustedEmitter, set: (obj, value) => { obj.trustedEmitter = value; } }, metadata: _metadata }, _trustedEmitter_initializers, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static from(browserContext, browsingContext) { + const page = new BidiPage(browserContext, browsingContext); + page.#initialize(); + return page; + } + #trustedEmitter_accessor_storage = (__runInitializers$4(this, _instanceExtraInitializers), __runInitializers$4(this, _trustedEmitter_initializers, new EventEmitter())); + get trustedEmitter() { return this.#trustedEmitter_accessor_storage; } + set trustedEmitter(value) { this.#trustedEmitter_accessor_storage = value; } + #browserContext; + #frame; + #viewport = null; + #workers = new Set(); + keyboard; + mouse; + touchscreen; + accessibility; + tracing; + coverage; + #cdpEmulationManager; + _client() { + return this.#frame.client; + } + constructor(browserContext, browsingContext) { + super(); + this.#browserContext = browserContext; + this.#frame = BidiFrame.from(this, browsingContext); + this.#cdpEmulationManager = new EmulationManager(this.#frame.client); + this.accessibility = new Accessibility(this.#frame.client); + this.tracing = new Tracing(this.#frame.client); + this.coverage = new Coverage(this.#frame.client); + this.keyboard = new BidiKeyboard(this); + this.mouse = new BidiMouse(this); + this.touchscreen = new BidiTouchscreen(this); + } + #initialize() { + this.#frame.browsingContext.on('closed', () => { + this.trustedEmitter.emit("close" /* PageEvent.Close */, undefined); + this.trustedEmitter.removeAllListeners(); + }); + this.trustedEmitter.on("workercreated" /* PageEvent.WorkerCreated */, worker => { + this.#workers.add(worker); + }); + this.trustedEmitter.on("workerdestroyed" /* PageEvent.WorkerDestroyed */, worker => { + this.#workers.delete(worker); + }); + } + /** + * @internal + */ + _userAgentHeaders = {}; + #userAgentInterception; + #userAgentPreloadScript; + async setUserAgent(userAgent, userAgentMetadata) { + if (!this.#browserContext.browser().cdpSupported && userAgentMetadata) { + throw new UnsupportedOperation('Current Browser does not support `userAgentMetadata`'); + } + else if (this.#browserContext.browser().cdpSupported && + userAgentMetadata) { + return await this._client().send('Network.setUserAgentOverride', { + userAgent: userAgent, + userAgentMetadata: userAgentMetadata, + }); + } + const enable = userAgent !== ''; + userAgent = userAgent ?? (await this.#browserContext.browser().userAgent()); + this._userAgentHeaders = enable + ? { + 'User-Agent': userAgent, + } + : {}; + this.#userAgentInterception = await this.#toggleInterception(["beforeRequestSent" /* Bidi.Network.InterceptPhase.BeforeRequestSent */], this.#userAgentInterception, enable); + const changeUserAgent = (userAgent) => { + Object.defineProperty(navigator, 'userAgent', { + value: userAgent, + }); + }; + const frames = [this.#frame]; + for (const frame of frames) { + frames.push(...frame.childFrames()); + } + if (this.#userAgentPreloadScript) { + await this.removeScriptToEvaluateOnNewDocument(this.#userAgentPreloadScript); + } + const [evaluateToken] = await Promise.all([ + enable + ? this.evaluateOnNewDocument(changeUserAgent, userAgent) + : undefined, + // When we disable the UserAgent we want to + // evaluate the original value in all Browsing Contexts + frames.map(frame => { + return frame.evaluate(changeUserAgent, userAgent); + }), + ]); + this.#userAgentPreloadScript = evaluateToken?.identifier; + } + async setBypassCSP(enabled) { + // TODO: handle CDP-specific cases such as mprach. + await this._client().send('Page.setBypassCSP', { enabled }); + } + async queryObjects(prototypeHandle) { + assert(!prototypeHandle.disposed, 'Prototype JSHandle is disposed!'); + assert(prototypeHandle.id, 'Prototype JSHandle must not be referencing primitive value'); + const response = await this.#frame.client.send('Runtime.queryObjects', { + prototypeObjectId: prototypeHandle.id, + }); + return this.#frame.mainRealm().createHandle({ + type: 'array', + handle: response.objects.objectId, + }); + } + browser() { + return this.browserContext().browser(); + } + browserContext() { + return this.#browserContext; + } + mainFrame() { + return this.#frame; + } + async focusedFrame() { + const env_1 = { stack: [], error: void 0, hasError: false }; + try { + const handle = __addDisposableResource$1(env_1, (await this.mainFrame() + .isolatedRealm() + .evaluateHandle(() => { + let win = window; + while (win.document.activeElement instanceof win.HTMLIFrameElement || + win.document.activeElement instanceof win.HTMLFrameElement) { + if (win.document.activeElement.contentWindow === null) { + break; + } + win = win.document.activeElement.contentWindow; + } + return win; + })), false); + const value = handle.remoteValue(); + assert(value.type === 'window'); + const frame = this.frames().find(frame => { + return frame._id === value.value.context; + }); + assert(frame); + return frame; + } + catch (e_1) { + env_1.error = e_1; + env_1.hasError = true; + } + finally { + __disposeResources$1(env_1); + } + } + frames() { + const frames = [this.#frame]; + for (const frame of frames) { + frames.push(...frame.childFrames()); + } + return frames; + } + isClosed() { + return this.#frame.detached; + } + async close(options) { + try { + await this.#frame.browsingContext.close(options?.runBeforeUnload); + } + catch { + return; + } + } + async reload(options = {}) { + const [response] = await Promise.all([ + this.#frame.waitForNavigation(options), + this.#frame.browsingContext.reload(), + ]).catch(rewriteNavigationError(this.url(), options.timeout ?? this._timeoutSettings.navigationTimeout())); + return response; + } + setDefaultNavigationTimeout(timeout) { + this._timeoutSettings.setDefaultNavigationTimeout(timeout); + } + setDefaultTimeout(timeout) { + this._timeoutSettings.setDefaultTimeout(timeout); + } + getDefaultTimeout() { + return this._timeoutSettings.timeout(); + } + isJavaScriptEnabled() { + return this.#cdpEmulationManager.javascriptEnabled; + } + async setGeolocation(options) { + return await this.#cdpEmulationManager.setGeolocation(options); + } + async setJavaScriptEnabled(enabled) { + return await this.#cdpEmulationManager.setJavaScriptEnabled(enabled); + } + async emulateMediaType(type) { + return await this.#cdpEmulationManager.emulateMediaType(type); + } + async emulateCPUThrottling(factor) { + return await this.#cdpEmulationManager.emulateCPUThrottling(factor); + } + async emulateMediaFeatures(features) { + return await this.#cdpEmulationManager.emulateMediaFeatures(features); + } + async emulateTimezone(timezoneId) { + return await this.#cdpEmulationManager.emulateTimezone(timezoneId); + } + async emulateIdleState(overrides) { + return await this.#cdpEmulationManager.emulateIdleState(overrides); + } + async emulateVisionDeficiency(type) { + return await this.#cdpEmulationManager.emulateVisionDeficiency(type); + } + async setViewport(viewport) { + if (!this.browser().cdpSupported) { + await this.#frame.browsingContext.setViewport({ + viewport: viewport.width && viewport.height + ? { + width: viewport.width, + height: viewport.height, + } + : null, + devicePixelRatio: viewport.deviceScaleFactor + ? viewport.deviceScaleFactor + : null, + }); + this.#viewport = viewport; + return; + } + const needsReload = await this.#cdpEmulationManager.emulateViewport(viewport); + this.#viewport = viewport; + if (needsReload) { + await this.reload(); + } + } + viewport() { + return this.#viewport; + } + async pdf(options = {}) { + const { timeout: ms = this._timeoutSettings.timeout(), path = undefined } = options; + const { printBackground: background, margin, landscape, width, height, pageRanges: ranges, scale, preferCSSPageSize, } = parsePDFOptions(options, 'cm'); + const pageRanges = ranges ? ranges.split(', ') : []; + await firstValueFrom(from(this.mainFrame() + .isolatedRealm() + .evaluate(() => { + return document.fonts.ready; + })).pipe(raceWith(timeout(ms)))); + const data = await firstValueFrom(from(this.#frame.browsingContext.print({ + background, + margin, + orientation: landscape ? 'landscape' : 'portrait', + page: { + width, + height, + }, + pageRanges, + scale, + shrinkToFit: !preferCSSPageSize, + })).pipe(raceWith(timeout(ms)))); + const buffer = Buffer.from(data, 'base64'); + await this._maybeWriteBufferToFile(path, buffer); + return buffer; + } + async createPDFStream(options) { + const buffer = await this.pdf(options); + return new ReadableStream({ + start(controller) { + controller.enqueue(buffer); + controller.close(); + }, + }); + } + async _screenshot(options) { + const { clip, type, captureBeyondViewport, quality } = options; + if (options.omitBackground !== undefined && options.omitBackground) { + throw new UnsupportedOperation(`BiDi does not support 'omitBackground'.`); + } + if (options.optimizeForSpeed !== undefined && options.optimizeForSpeed) { + throw new UnsupportedOperation(`BiDi does not support 'optimizeForSpeed'.`); + } + if (options.fromSurface !== undefined && !options.fromSurface) { + throw new UnsupportedOperation(`BiDi does not support 'fromSurface'.`); + } + if (clip !== undefined && clip.scale !== undefined && clip.scale !== 1) { + throw new UnsupportedOperation(`BiDi does not support 'scale' in 'clip'.`); + } + let box; + if (clip) { + if (captureBeyondViewport) { + box = clip; + } + else { + // The clip is always with respect to the document coordinates, so we + // need to convert this to viewport coordinates when we aren't capturing + // beyond the viewport. + const [pageLeft, pageTop] = await this.evaluate(() => { + if (!window.visualViewport) { + throw new Error('window.visualViewport is not supported.'); + } + return [ + window.visualViewport.pageLeft, + window.visualViewport.pageTop, + ]; + }); + box = { + ...clip, + x: clip.x - pageLeft, + y: clip.y - pageTop, + }; + } + } + const data = await this.#frame.browsingContext.captureScreenshot({ + origin: captureBeyondViewport ? 'document' : 'viewport', + format: { + type: `image/${type}`, + ...(quality !== undefined ? { quality: quality / 100 } : {}), + }, + ...(box ? { clip: { type: 'box', ...box } } : {}), + }); + return data; + } + async createCDPSession() { + return await this.#frame.createCDPSession(); + } + async bringToFront() { + await this.#frame.browsingContext.activate(); + } + async evaluateOnNewDocument(pageFunction, ...args) { + const expression = evaluationExpression(pageFunction, ...args); + const script = await this.#frame.browsingContext.addPreloadScript(expression); + return { identifier: script }; + } + async removeScriptToEvaluateOnNewDocument(id) { + await this.#frame.browsingContext.removePreloadScript(id); + } + async exposeFunction(name, pptrFunction) { + return await this.mainFrame().exposeFunction(name, 'default' in pptrFunction ? pptrFunction.default : pptrFunction); + } + isDragInterceptionEnabled() { + return false; + } + async setCacheEnabled(enabled) { + // TODO: handle CDP-specific cases such as mprach. + await this._client().send('Network.setCacheDisabled', { + cacheDisabled: !enabled, + }); + } + async cookies(...urls) { + const normalizedUrls = (urls.length ? urls : [this.url()]).map(url => { + return new URL(url); + }); + const cookies = await this.#frame.browsingContext.getCookies(); + return cookies + .map(cookie => { + return bidiToPuppeteerCookie(cookie); + }) + .filter(cookie => { + return normalizedUrls.some(url => { + return testUrlMatchCookie(cookie, url); + }); + }); + } + isServiceWorkerBypassed() { + throw new UnsupportedOperation(); + } + target() { + throw new UnsupportedOperation(); + } + waitForFileChooser() { + throw new UnsupportedOperation(); + } + workers() { + return [...this.#workers]; + } + #userInterception; + async setRequestInterception(enable) { + this.#userInterception = await this.#toggleInterception(["beforeRequestSent" /* Bidi.Network.InterceptPhase.BeforeRequestSent */], this.#userInterception, enable); + } + /** + * @internal + */ + _extraHTTPHeaders = {}; + #extraHeadersInterception; + async setExtraHTTPHeaders(headers) { + const extraHTTPHeaders = {}; + for (const [key, value] of Object.entries(headers)) { + assert(isString(value), `Expected value of header "${key}" to be String, but "${typeof value}" is found.`); + extraHTTPHeaders[key.toLowerCase()] = value; + } + this._extraHTTPHeaders = extraHTTPHeaders; + this.#extraHeadersInterception = await this.#toggleInterception(["beforeRequestSent" /* Bidi.Network.InterceptPhase.BeforeRequestSent */], this.#extraHeadersInterception, Boolean(Object.keys(this._extraHTTPHeaders).length)); + } + /** + * @internal + */ + _credentials = null; + #authInterception; + async authenticate(credentials) { + this.#authInterception = await this.#toggleInterception(["authRequired" /* Bidi.Network.InterceptPhase.AuthRequired */], this.#authInterception, Boolean(credentials)); + this._credentials = credentials; + } + async #toggleInterception(phases, interception, expected) { + if (expected && !interception) { + return await this.#frame.browsingContext.addIntercept({ + phases, + }); + } + else if (!expected && interception) { + await this.#frame.browsingContext.userContext.browser.removeIntercept(interception); + return; + } + return interception; + } + setDragInterception() { + throw new UnsupportedOperation(); + } + setBypassServiceWorker() { + throw new UnsupportedOperation(); + } + setOfflineMode() { + throw new UnsupportedOperation(); + } + emulateNetworkConditions() { + throw new UnsupportedOperation(); + } + async setCookie(...cookies) { + const pageURL = this.url(); + const pageUrlStartsWithHTTP = pageURL.startsWith('http'); + for (const cookie of cookies) { + let cookieUrl = cookie.url || ''; + if (!cookieUrl && pageUrlStartsWithHTTP) { + cookieUrl = pageURL; + } + assert(cookieUrl !== 'about:blank', `Blank page can not have cookie "${cookie.name}"`); + assert(!String.prototype.startsWith.call(cookieUrl || '', 'data:'), `Data URL page can not have cookie "${cookie.name}"`); + const normalizedUrl = URL.canParse(cookieUrl) + ? new URL(cookieUrl) + : undefined; + const domain = cookie.domain ?? normalizedUrl?.hostname; + assert(domain !== undefined, `At least one of the url and domain needs to be specified`); + const bidiCookie = { + domain: domain, + name: cookie.name, + value: { + type: 'string', + value: cookie.value, + }, + ...(cookie.path !== undefined ? { path: cookie.path } : {}), + ...(cookie.httpOnly !== undefined ? { httpOnly: cookie.httpOnly } : {}), + ...(cookie.secure !== undefined ? { secure: cookie.secure } : {}), + ...(cookie.sameSite !== undefined + ? { sameSite: convertCookiesSameSiteCdpToBiDi(cookie.sameSite) } + : {}), + ...(cookie.expires !== undefined ? { expiry: cookie.expires } : {}), + // Chrome-specific properties. + ...cdpSpecificCookiePropertiesFromPuppeteerToBidi(cookie, 'sameParty', 'sourceScheme', 'priority', 'url'), + }; + if (cookie.partitionKey !== undefined) { + await this.browserContext().userContext.setCookie(bidiCookie, cookie.partitionKey); + } + else { + await this.#frame.browsingContext.setCookie(bidiCookie); + } + } + } + async deleteCookie(...cookies) { + await Promise.all(cookies.map(async (deleteCookieRequest) => { + const cookieUrl = deleteCookieRequest.url ?? this.url(); + const normalizedUrl = URL.canParse(cookieUrl) + ? new URL(cookieUrl) + : undefined; + const domain = deleteCookieRequest.domain ?? normalizedUrl?.hostname; + assert(domain !== undefined, `At least one of the url and domain needs to be specified`); + const filter = { + domain: domain, + name: deleteCookieRequest.name, + ...(deleteCookieRequest.path !== undefined + ? { path: deleteCookieRequest.path } + : {}), + }; + await this.#frame.browsingContext.deleteCookie(filter); + })); + } + async removeExposedFunction(name) { + await this.#frame.removeExposedFunction(name); + } + metrics() { + throw new UnsupportedOperation(); + } + async goBack(options = {}) { + return await this.#go(-1, options); + } + async goForward(options = {}) { + return await this.#go(1, options); + } + async #go(delta, options) { + try { + const [response] = await Promise.all([ + this.waitForNavigation(options), + this.#frame.browsingContext.traverseHistory(delta), + ]); + return response; + } + catch (error) { + // TODO: waitForNavigation should be cancelled if an error happens. + if (isErrorLike(error)) { + if (error.message.includes('no such history entry')) { + return null; + } + } + throw error; + } + } + waitForDevicePrompt() { + throw new UnsupportedOperation(); + } + }; +})(); +function evaluationExpression(fun, ...args) { + return `() => {${evaluationString(fun, ...args)}}`; +} +/** + * Check domains match. + * According to cookies spec, this check should match subdomains as well, but CDP + * implementation does not do that, so this method matches only the exact domains, not + * what is written in the spec: + * https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.3 + */ +function testUrlMatchCookieHostname(cookie, normalizedUrl) { + const cookieDomain = cookie.domain.toLowerCase(); + const urlHostname = normalizedUrl.hostname.toLowerCase(); + return cookieDomain === urlHostname; +} +/** + * Check paths match. + * Spec: https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 + */ +function testUrlMatchCookiePath(cookie, normalizedUrl) { + const uriPath = normalizedUrl.pathname; + const cookiePath = cookie.path; + if (uriPath === cookiePath) { + // The cookie-path and the request-path are identical. + return true; + } + if (uriPath.startsWith(cookiePath)) { + // The cookie-path is a prefix of the request-path. + if (cookiePath.endsWith('/')) { + // The last character of the cookie-path is %x2F ("/"). + return true; + } + if (uriPath[cookiePath.length] === '/') { + // The first character of the request-path that is not included in the cookie-path + // is a %x2F ("/") character. + return true; + } + } + return false; +} +/** + * Checks the cookie matches the URL according to the spec: + */ +function testUrlMatchCookie(cookie, url) { + const normalizedUrl = new URL(url); + assert(cookie !== undefined); + if (!testUrlMatchCookieHostname(cookie, normalizedUrl)) { + return false; + } + return testUrlMatchCookiePath(cookie, normalizedUrl); +} +function bidiToPuppeteerCookie(bidiCookie) { + return { + name: bidiCookie.name, + // Presents binary value as base64 string. + value: bidiCookie.value.value, + domain: bidiCookie.domain, + path: bidiCookie.path, + size: bidiCookie.size, + httpOnly: bidiCookie.httpOnly, + secure: bidiCookie.secure, + sameSite: convertCookiesSameSiteBiDiToCdp(bidiCookie.sameSite), + expires: bidiCookie.expiry ?? -1, + session: bidiCookie.expiry === undefined || bidiCookie.expiry <= 0, + // Extending with CDP-specific properties with `goog:` prefix. + ...cdpSpecificCookiePropertiesFromBidiToPuppeteer(bidiCookie, 'sameParty', 'sourceScheme', 'partitionKey', 'partitionKeyOpaque', 'priority'), + }; +} +const CDP_SPECIFIC_PREFIX = 'goog:'; +/** + * Gets CDP-specific properties from the BiDi cookie and returns them as a new object. + */ +function cdpSpecificCookiePropertiesFromBidiToPuppeteer(bidiCookie, ...propertyNames) { + const result = {}; + for (const property of propertyNames) { + if (bidiCookie[CDP_SPECIFIC_PREFIX + property] !== undefined) { + result[property] = bidiCookie[CDP_SPECIFIC_PREFIX + property]; + } + } + return result; +} +/** + * Gets CDP-specific properties from the cookie, adds CDP-specific prefixes and returns + * them as a new object which can be used in BiDi. + */ +function cdpSpecificCookiePropertiesFromPuppeteerToBidi(cookieParam, ...propertyNames) { + const result = {}; + for (const property of propertyNames) { + if (cookieParam[property] !== undefined) { + result[CDP_SPECIFIC_PREFIX + property] = cookieParam[property]; + } + } + return result; +} +function convertCookiesSameSiteBiDiToCdp(sameSite) { + return sameSite === 'strict' ? 'Strict' : sameSite === 'lax' ? 'Lax' : 'None'; +} +function convertCookiesSameSiteCdpToBiDi(sameSite) { + return sameSite === 'Strict' + ? "strict" /* Bidi.Network.SameSite.Strict */ + : sameSite === 'Lax' + ? "lax" /* Bidi.Network.SameSite.Lax */ + : "none" /* Bidi.Network.SameSite.None */; +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class BidiBrowserTarget extends Target { + #browser; + constructor(browser) { + super(); + this.#browser = browser; + } + asPage() { + throw new UnsupportedOperation(); + } + url() { + return ''; + } + createCDPSession() { + throw new UnsupportedOperation(); + } + type() { + return TargetType.BROWSER; + } + browser() { + return this.#browser; + } + browserContext() { + return this.#browser.defaultBrowserContext(); + } + opener() { + throw new UnsupportedOperation(); + } +} +/** + * @internal + */ +class BidiPageTarget extends Target { + #page; + constructor(page) { + super(); + this.#page = page; + } + async page() { + return this.#page; + } + async asPage() { + return BidiPage.from(this.browserContext(), this.#page.mainFrame().browsingContext); + } + url() { + return this.#page.url(); + } + createCDPSession() { + return this.#page.createCDPSession(); + } + type() { + return TargetType.PAGE; + } + browser() { + return this.browserContext().browser(); + } + browserContext() { + return this.#page.browserContext(); + } + opener() { + throw new UnsupportedOperation(); + } +} +/** + * @internal + */ +class BidiFrameTarget extends Target { + #frame; + #page; + constructor(frame) { + super(); + this.#frame = frame; + } + async page() { + if (this.#page === undefined) { + this.#page = BidiPage.from(this.browserContext(), this.#frame.browsingContext); + } + return this.#page; + } + async asPage() { + return BidiPage.from(this.browserContext(), this.#frame.browsingContext); + } + url() { + return this.#frame.url(); + } + createCDPSession() { + return this.#frame.createCDPSession(); + } + type() { + return TargetType.PAGE; + } + browser() { + return this.browserContext().browser(); + } + browserContext() { + return this.#frame.page().browserContext(); + } + opener() { + throw new UnsupportedOperation(); + } +} +/** + * @internal + */ +class BidiWorkerTarget extends Target { + #worker; + constructor(worker) { + super(); + this.#worker = worker; + } + async page() { + throw new UnsupportedOperation(); + } + async asPage() { + throw new UnsupportedOperation(); + } + url() { + return this.#worker.url(); + } + createCDPSession() { + throw new UnsupportedOperation(); + } + type() { + return TargetType.OTHER; + } + browser() { + return this.browserContext().browser(); + } + browserContext() { + return this.#worker.frame.page().browserContext(); + } + opener() { + throw new UnsupportedOperation(); + } +} + +/** + * @license + * Copyright 2022 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __esDecorate$3 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var __runInitializers$3 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +/** + * @internal + */ +let BidiBrowserContext = (() => { + let _classSuper = BrowserContext; + let _instanceExtraInitializers = []; + let _trustedEmitter_decorators; + let _trustedEmitter_initializers = []; + return class BidiBrowserContext extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + _trustedEmitter_decorators = [bubble()]; + __esDecorate$3(this, null, _trustedEmitter_decorators, { kind: "accessor", name: "trustedEmitter", static: false, private: false, access: { has: obj => "trustedEmitter" in obj, get: obj => obj.trustedEmitter, set: (obj, value) => { obj.trustedEmitter = value; } }, metadata: _metadata }, _trustedEmitter_initializers, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static from(browser, userContext, options) { + const context = new BidiBrowserContext(browser, userContext, options); + context.#initialize(); + return context; + } + #trustedEmitter_accessor_storage = (__runInitializers$3(this, _instanceExtraInitializers), __runInitializers$3(this, _trustedEmitter_initializers, new EventEmitter())); + get trustedEmitter() { return this.#trustedEmitter_accessor_storage; } + set trustedEmitter(value) { this.#trustedEmitter_accessor_storage = value; } + #browser; + #defaultViewport; + // This is public because of cookies. + userContext; + #pages = new WeakMap(); + #targets = new Map(); + #overrides = []; + constructor(browser, userContext, options) { + super(); + this.#browser = browser; + this.userContext = userContext; + this.#defaultViewport = options.defaultViewport; + } + #initialize() { + // Create targets for existing browsing contexts. + for (const browsingContext of this.userContext.browsingContexts) { + this.#createPage(browsingContext); + } + this.userContext.on('browsingcontext', ({ browsingContext }) => { + this.#createPage(browsingContext); + }); + this.userContext.on('closed', () => { + this.trustedEmitter.removeAllListeners(); + }); + } + #createPage(browsingContext) { + const page = BidiPage.from(this, browsingContext); + this.#pages.set(browsingContext, page); + page.trustedEmitter.on("close" /* PageEvent.Close */, () => { + this.#pages.delete(browsingContext); + }); + // -- Target stuff starts here -- + const pageTarget = new BidiPageTarget(page); + const pageTargets = new Map(); + this.#targets.set(page, [pageTarget, pageTargets]); + page.trustedEmitter.on("frameattached" /* PageEvent.FrameAttached */, frame => { + const bidiFrame = frame; + const target = new BidiFrameTarget(bidiFrame); + pageTargets.set(bidiFrame, target); + this.trustedEmitter.emit("targetcreated" /* BrowserContextEvent.TargetCreated */, target); + }); + page.trustedEmitter.on("framenavigated" /* PageEvent.FrameNavigated */, frame => { + const bidiFrame = frame; + const target = pageTargets.get(bidiFrame); + // If there is no target, then this is the page's frame. + if (target === undefined) { + this.trustedEmitter.emit("targetchanged" /* BrowserContextEvent.TargetChanged */, pageTarget); + } + else { + this.trustedEmitter.emit("targetchanged" /* BrowserContextEvent.TargetChanged */, target); + } + }); + page.trustedEmitter.on("framedetached" /* PageEvent.FrameDetached */, frame => { + const bidiFrame = frame; + const target = pageTargets.get(bidiFrame); + if (target === undefined) { + return; + } + pageTargets.delete(bidiFrame); + this.trustedEmitter.emit("targetdestroyed" /* BrowserContextEvent.TargetDestroyed */, target); + }); + page.trustedEmitter.on("workercreated" /* PageEvent.WorkerCreated */, worker => { + const bidiWorker = worker; + const target = new BidiWorkerTarget(bidiWorker); + pageTargets.set(bidiWorker, target); + this.trustedEmitter.emit("targetcreated" /* BrowserContextEvent.TargetCreated */, target); + }); + page.trustedEmitter.on("workerdestroyed" /* PageEvent.WorkerDestroyed */, worker => { + const bidiWorker = worker; + const target = pageTargets.get(bidiWorker); + if (target === undefined) { + return; + } + pageTargets.delete(worker); + this.trustedEmitter.emit("targetdestroyed" /* BrowserContextEvent.TargetDestroyed */, target); + }); + page.trustedEmitter.on("close" /* PageEvent.Close */, () => { + this.#targets.delete(page); + this.trustedEmitter.emit("targetdestroyed" /* BrowserContextEvent.TargetDestroyed */, pageTarget); + }); + this.trustedEmitter.emit("targetcreated" /* BrowserContextEvent.TargetCreated */, pageTarget); + // -- Target stuff ends here -- + return page; + } + targets() { + return [...this.#targets.values()].flatMap(([target, frames]) => { + return [target, ...frames.values()]; + }); + } + async newPage() { + const context = await this.userContext.createBrowsingContext("tab" /* Bidi.BrowsingContext.CreateType.Tab */); + const page = this.#pages.get(context); + if (!page) { + throw new Error('Page is not found'); + } + if (this.#defaultViewport) { + try { + await page.setViewport(this.#defaultViewport); + } + catch { + // No support for setViewport in Firefox. + } + } + return page; + } + async close() { + if (!this.isIncognito()) { + throw new Error('Default context cannot be closed!'); + } + try { + await this.userContext.remove(); + } + catch (error) { + debugError(error); + } + } + browser() { + return this.#browser; + } + async pages() { + return [...this.userContext.browsingContexts].map(context => { + return this.#pages.get(context); + }); + } + isIncognito() { + return this.userContext.id !== UserContext.DEFAULT; + } + async overridePermissions(origin, permissions) { + const permissionsSet = new Set(permissions.map(permission => { + const protocolPermission = WEB_PERMISSION_TO_PROTOCOL_PERMISSION.get(permission); + if (!protocolPermission) { + throw new Error('Unknown permission: ' + permission); + } + return permission; + })); + await Promise.all(Array.from(WEB_PERMISSION_TO_PROTOCOL_PERMISSION.keys()).map(permission => { + const result = this.userContext.setPermissions(origin, { + name: permission, + }, permissionsSet.has(permission) + ? "granted" /* Bidi.Permissions.PermissionState.Granted */ + : "denied" /* Bidi.Permissions.PermissionState.Denied */); + this.#overrides.push({ origin, permission }); + // TODO: some permissions are outdated and setting them to denied does + // not work. + if (!permissionsSet.has(permission)) { + return result.catch(debugError); + } + return result; + })); + } + async clearPermissionOverrides() { + const promises = this.#overrides.map(({ permission, origin }) => { + return this.userContext + .setPermissions(origin, { + name: permission, + }, "prompt" /* Bidi.Permissions.PermissionState.Prompt */) + .catch(debugError); + }); + this.#overrides = []; + await Promise.all(promises); + } + get id() { + if (this.userContext.id === UserContext.DEFAULT) { + return undefined; + } + return this.userContext.id; + } + }; +})(); + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$2 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$2 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var __addDisposableResource = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +/** + * @internal + */ +let Browser = (() => { + let _classSuper = EventEmitter; + let _instanceExtraInitializers = []; + let _dispose_decorators; + let _close_decorators; + let _addPreloadScript_decorators; + let _removeIntercept_decorators; + let _removePreloadScript_decorators; + let _createUserContext_decorators; + return class Browser extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + __esDecorate$2(this, null, _dispose_decorators, { kind: "method", name: "dispose", static: false, private: false, access: { has: obj => "dispose" in obj, get: obj => obj.dispose }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$2(this, null, _close_decorators, { kind: "method", name: "close", static: false, private: false, access: { has: obj => "close" in obj, get: obj => obj.close }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$2(this, null, _addPreloadScript_decorators, { kind: "method", name: "addPreloadScript", static: false, private: false, access: { has: obj => "addPreloadScript" in obj, get: obj => obj.addPreloadScript }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$2(this, null, _removeIntercept_decorators, { kind: "method", name: "removeIntercept", static: false, private: false, access: { has: obj => "removeIntercept" in obj, get: obj => obj.removeIntercept }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$2(this, null, _removePreloadScript_decorators, { kind: "method", name: "removePreloadScript", static: false, private: false, access: { has: obj => "removePreloadScript" in obj, get: obj => obj.removePreloadScript }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$2(this, null, _createUserContext_decorators, { kind: "method", name: "createUserContext", static: false, private: false, access: { has: obj => "createUserContext" in obj, get: obj => obj.createUserContext }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static async from(session) { + const browser = new Browser(session); + await browser.#initialize(); + return browser; + } + #closed = (__runInitializers$2(this, _instanceExtraInitializers), false); + #reason; + #disposables = new DisposableStack(); + #userContexts = new Map(); + session; + #sharedWorkers = new Map(); + constructor(session) { + super(); + this.session = session; + } + async #initialize() { + const sessionEmitter = this.#disposables.use(new EventEmitter(this.session)); + sessionEmitter.once('ended', ({ reason }) => { + this.dispose(reason); + }); + sessionEmitter.on('script.realmCreated', info => { + if (info.type !== 'shared-worker') { + return; + } + this.#sharedWorkers.set(info.realm, SharedWorkerRealm.from(this, info.realm, info.origin)); + }); + await this.#syncUserContexts(); + await this.#syncBrowsingContexts(); + } + async #syncUserContexts() { + const { result: { userContexts }, } = await this.session.send('browser.getUserContexts', {}); + for (const context of userContexts) { + this.#createUserContext(context.userContext); + } + } + async #syncBrowsingContexts() { + // In case contexts are created or destroyed during `getTree`, we use this + // set to detect them. + const contextIds = new Set(); + let contexts; + { + const env_1 = { stack: [], error: void 0, hasError: false }; + try { + const sessionEmitter = __addDisposableResource(env_1, new EventEmitter(this.session), false); + sessionEmitter.on('browsingContext.contextCreated', info => { + contextIds.add(info.context); + }); + const { result } = await this.session.send('browsingContext.getTree', {}); + contexts = result.contexts; + } + catch (e_1) { + env_1.error = e_1; + env_1.hasError = true; + } + finally { + __disposeResources(env_1); + } + } + // Simulating events so contexts are created naturally. + for (const info of contexts) { + if (!contextIds.has(info.context)) { + this.session.emit('browsingContext.contextCreated', info); + } + if (info.children) { + contexts.push(...info.children); + } + } + } + #createUserContext(id) { + const userContext = UserContext.create(this, id); + this.#userContexts.set(userContext.id, userContext); + const userContextEmitter = this.#disposables.use(new EventEmitter(userContext)); + userContextEmitter.once('closed', () => { + userContextEmitter.removeAllListeners(); + this.#userContexts.delete(userContext.id); + }); + return userContext; + } + get closed() { + return this.#closed; + } + get defaultUserContext() { + // SAFETY: A UserContext is always created for the default context. + return this.#userContexts.get(UserContext.DEFAULT); + } + get disconnected() { + return this.#reason !== undefined; + } + get disposed() { + return this.disconnected; + } + get userContexts() { + return this.#userContexts.values(); + } + dispose(reason, closed = false) { + this.#closed = closed; + this.#reason = reason; + this[disposeSymbol](); + } + async close() { + try { + await this.session.send('browser.close', {}); + } + finally { + this.dispose('Browser already closed.', true); + } + } + async addPreloadScript(functionDeclaration, options = {}) { + const { result: { script }, } = await this.session.send('script.addPreloadScript', { + functionDeclaration, + ...options, + contexts: options.contexts?.map(context => { + return context.id; + }), + }); + return script; + } + async removeIntercept(intercept) { + await this.session.send('network.removeIntercept', { + intercept, + }); + } + async removePreloadScript(script) { + await this.session.send('script.removePreloadScript', { + script, + }); + } + async createUserContext() { + const { result: { userContext: context }, } = await this.session.send('browser.createUserContext', {}); + return this.#createUserContext(context); + } + [(_dispose_decorators = [inertIfDisposed], _close_decorators = [throwIfDisposed(browser => { + // SAFETY: By definition of `disposed`, `#reason` is defined. + return browser.#reason; + })], _addPreloadScript_decorators = [throwIfDisposed(browser => { + // SAFETY: By definition of `disposed`, `#reason` is defined. + return browser.#reason; + })], _removeIntercept_decorators = [throwIfDisposed(browser => { + // SAFETY: By definition of `disposed`, `#reason` is defined. + return browser.#reason; + })], _removePreloadScript_decorators = [throwIfDisposed(browser => { + // SAFETY: By definition of `disposed`, `#reason` is defined. + return browser.#reason; + })], _createUserContext_decorators = [throwIfDisposed(browser => { + // SAFETY: By definition of `disposed`, `#reason` is defined. + return browser.#reason; + })], disposeSymbol)]() { + this.#reason ??= + 'Browser was disconnected, probably because the session ended.'; + if (this.closed) { + this.emit('closed', { reason: this.#reason }); + } + this.emit('disconnected', { reason: this.#reason }); + this.#disposables.dispose(); + super[disposeSymbol](); + } + }; +})(); + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$1 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$1 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +// TODO: Once Chrome supports session.status properly, uncomment this block. +// const MAX_RETRIES = 5; +/** + * @internal + */ +let Session = (() => { + let _classSuper = EventEmitter; + let _instanceExtraInitializers = []; + let _connection_decorators; + let _connection_initializers = []; + let _dispose_decorators; + let _send_decorators; + let _subscribe_decorators; + let _addIntercepts_decorators; + let _end_decorators; + return class Session extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + __esDecorate$1(this, null, _connection_decorators, { kind: "accessor", name: "connection", static: false, private: false, access: { has: obj => "connection" in obj, get: obj => obj.connection, set: (obj, value) => { obj.connection = value; } }, metadata: _metadata }, _connection_initializers, _instanceExtraInitializers); + __esDecorate$1(this, null, _dispose_decorators, { kind: "method", name: "dispose", static: false, private: false, access: { has: obj => "dispose" in obj, get: obj => obj.dispose }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$1(this, null, _send_decorators, { kind: "method", name: "send", static: false, private: false, access: { has: obj => "send" in obj, get: obj => obj.send }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$1(this, null, _subscribe_decorators, { kind: "method", name: "subscribe", static: false, private: false, access: { has: obj => "subscribe" in obj, get: obj => obj.subscribe }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$1(this, null, _addIntercepts_decorators, { kind: "method", name: "addIntercepts", static: false, private: false, access: { has: obj => "addIntercepts" in obj, get: obj => obj.addIntercepts }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$1(this, null, _end_decorators, { kind: "method", name: "end", static: false, private: false, access: { has: obj => "end" in obj, get: obj => obj.end }, metadata: _metadata }, null, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + static async from(connection, capabilities) { + // Wait until the session is ready. + // + // TODO: Once Chrome supports session.status properly, uncomment this block + // and remove `getBiDiConnection` in BrowserConnector. + // let status = {message: '', ready: false}; + // for (let i = 0; i < MAX_RETRIES; ++i) { + // status = (await connection.send('session.status', {})).result; + // if (status.ready) { + // break; + // } + // // Backoff a little bit each time. + // await new Promise(resolve => { + // return setTimeout(resolve, (1 << i) * 100); + // }); + // } + // if (!status.ready) { + // throw new Error(status.message); + // } + let result; + try { + result = (await connection.send('session.new', { + capabilities, + })).result; + } + catch (err) { + // Chrome does not support session.new. + debugError(err); + result = { + sessionId: '', + capabilities: { + acceptInsecureCerts: false, + browserName: '', + browserVersion: '', + platformName: '', + setWindowRect: false, + webSocketUrl: '', + userAgent: '', + }, + }; + } + const session = new Session(connection, result); + await session.#initialize(); + return session; + } + #reason = (__runInitializers$1(this, _instanceExtraInitializers), void 0); + #disposables = new DisposableStack(); + #info; + browser; + #connection_accessor_storage = __runInitializers$1(this, _connection_initializers, void 0); + get connection() { return this.#connection_accessor_storage; } + set connection(value) { this.#connection_accessor_storage = value; } + constructor(connection, info) { + super(); + this.#info = info; + this.connection = connection; + } + async #initialize() { + // SAFETY: We use `any` to allow assignment of the readonly property. + this.browser = await Browser.from(this); + const browserEmitter = this.#disposables.use(this.browser); + browserEmitter.once('closed', ({ reason }) => { + this.dispose(reason); + }); + // TODO: Currently, some implementations do not emit navigationStarted event + // for fragment navigations (as per spec) and some do. This could emits a + // synthetic navigationStarted to work around this inconsistency. + const seen = new WeakSet(); + this.on('browsingContext.fragmentNavigated', info => { + if (seen.has(info)) { + return; + } + seen.add(info); + this.emit('browsingContext.navigationStarted', info); + this.emit('browsingContext.fragmentNavigated', info); + }); + } + get capabilities() { + return this.#info.capabilities; + } + get disposed() { + return this.ended; + } + get ended() { + return this.#reason !== undefined; + } + get id() { + return this.#info.sessionId; + } + dispose(reason) { + this.#reason = reason; + this[disposeSymbol](); + } + /** + * Currently, there is a 1:1 relationship between the session and the + * session. In the future, we might support multiple sessions and in that + * case we always needs to make sure that the session for the right session + * object is used, so we implement this method here, although it's not defined + * in the spec. + */ + async send(method, params) { + return await this.connection.send(method, params); + } + async subscribe(events, contexts) { + await this.send('session.subscribe', { + events, + contexts, + }); + } + async addIntercepts(events, contexts) { + await this.send('session.subscribe', { + events, + contexts, + }); + } + async end() { + try { + await this.send('session.end', {}); + } + finally { + this.dispose(`Session already ended.`); + } + } + [(_connection_decorators = [bubble()], _dispose_decorators = [inertIfDisposed], _send_decorators = [throwIfDisposed(session => { + // SAFETY: By definition of `disposed`, `#reason` is defined. + return session.#reason; + })], _subscribe_decorators = [throwIfDisposed(session => { + // SAFETY: By definition of `disposed`, `#reason` is defined. + return session.#reason; + })], _addIntercepts_decorators = [throwIfDisposed(session => { + // SAFETY: By definition of `disposed`, `#reason` is defined. + return session.#reason; + })], _end_decorators = [throwIfDisposed(session => { + // SAFETY: By definition of `disposed`, `#reason` is defined. + return session.#reason; + })], disposeSymbol)]() { + this.#reason ??= + 'Session already destroyed, probably because the connection broke.'; + this.emit('ended', { reason: this.#reason }); + this.#disposables.dispose(); + super[disposeSymbol](); + } + }; +})(); + +/** + * @license + * Copyright 2022 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var __setFunctionName = (undefined && undefined.__setFunctionName) || function (f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); +}; +/** + * @internal + */ +let BidiBrowser = (() => { + let _classSuper = Browser$1; + let _instanceExtraInitializers = []; + let _private_trustedEmitter_decorators; + let _private_trustedEmitter_initializers = []; + let _private_trustedEmitter_descriptor; + return class BidiBrowser extends _classSuper { + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + _private_trustedEmitter_decorators = [bubble()]; + __esDecorate(this, _private_trustedEmitter_descriptor = { get: __setFunctionName(function () { return this.#trustedEmitter_accessor_storage; }, "#trustedEmitter", "get"), set: __setFunctionName(function (value) { this.#trustedEmitter_accessor_storage = value; }, "#trustedEmitter", "set") }, _private_trustedEmitter_decorators, { kind: "accessor", name: "#trustedEmitter", static: false, private: true, access: { has: obj => #trustedEmitter in obj, get: obj => obj.#trustedEmitter, set: (obj, value) => { obj.#trustedEmitter = value; } }, metadata: _metadata }, _private_trustedEmitter_initializers, _instanceExtraInitializers); + if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + } + protocol = (__runInitializers(this, _instanceExtraInitializers), 'webDriverBiDi'); + // TODO: Update generator to include fully module + static subscribeModules = [ + 'browsingContext', + 'network', + 'log', + 'script', + ]; + static subscribeCdpEvents = [ + // Coverage + 'cdp.Debugger.scriptParsed', + 'cdp.CSS.styleSheetAdded', + 'cdp.Runtime.executionContextsCleared', + // Tracing + 'cdp.Tracing.tracingComplete', + // TODO: subscribe to all CDP events in the future. + 'cdp.Network.requestWillBeSent', + 'cdp.Debugger.scriptParsed', + 'cdp.Page.screencastFrame', + ]; + static async create(opts) { + const session = await Session.from(opts.connection, { + alwaysMatch: { + acceptInsecureCerts: opts.ignoreHTTPSErrors, + webSocketUrl: true, + }, + }); + await session.subscribe(session.capabilities.browserName.toLocaleLowerCase().includes('firefox') + ? BidiBrowser.subscribeModules + : [...BidiBrowser.subscribeModules, ...BidiBrowser.subscribeCdpEvents]); + const browser = new BidiBrowser(session.browser, opts); + browser.#initialize(); + return browser; + } + #trustedEmitter_accessor_storage = __runInitializers(this, _private_trustedEmitter_initializers, new EventEmitter()); + get #trustedEmitter() { return _private_trustedEmitter_descriptor.get.call(this); } + set #trustedEmitter(value) { return _private_trustedEmitter_descriptor.set.call(this, value); } + #process; + #closeCallback; + #browserCore; + #defaultViewport; + #browserContexts = new WeakMap(); + #target = new BidiBrowserTarget(this); + constructor(browserCore, opts) { + super(); + this.#process = opts.process; + this.#closeCallback = opts.closeCallback; + this.#browserCore = browserCore; + this.#defaultViewport = opts.defaultViewport; + } + #initialize() { + // Initializing existing contexts. + for (const userContext of this.#browserCore.userContexts) { + this.#createBrowserContext(userContext); + } + this.#browserCore.once('disconnected', () => { + this.#trustedEmitter.emit("disconnected" /* BrowserEvent.Disconnected */, undefined); + this.#trustedEmitter.removeAllListeners(); + }); + this.#process?.once('close', () => { + this.#browserCore.dispose('Browser process exited.', true); + this.connection.dispose(); + }); + } + get #browserName() { + return this.#browserCore.session.capabilities.browserName; + } + get #browserVersion() { + return this.#browserCore.session.capabilities.browserVersion; + } + get cdpSupported() { + return !this.#browserName.toLocaleLowerCase().includes('firefox'); + } + async userAgent() { + return this.#browserCore.session.capabilities.userAgent; + } + #createBrowserContext(userContext) { + const browserContext = BidiBrowserContext.from(this, userContext, { + defaultViewport: this.#defaultViewport, + }); + this.#browserContexts.set(userContext, browserContext); + browserContext.trustedEmitter.on("targetcreated" /* BrowserContextEvent.TargetCreated */, target => { + this.#trustedEmitter.emit("targetcreated" /* BrowserEvent.TargetCreated */, target); + }); + browserContext.trustedEmitter.on("targetchanged" /* BrowserContextEvent.TargetChanged */, target => { + this.#trustedEmitter.emit("targetchanged" /* BrowserEvent.TargetChanged */, target); + }); + browserContext.trustedEmitter.on("targetdestroyed" /* BrowserContextEvent.TargetDestroyed */, target => { + this.#trustedEmitter.emit("targetdestroyed" /* BrowserEvent.TargetDestroyed */, target); + }); + return browserContext; + } + get connection() { + // SAFETY: We only have one implementation. + return this.#browserCore.session.connection; + } + wsEndpoint() { + return this.connection.url; + } + async close() { + if (this.connection.closed) { + return; + } + try { + await this.#browserCore.close(); + await this.#closeCallback?.call(null); + } + catch (error) { + // Fail silently. + debugError(error); + } + finally { + this.connection.dispose(); + } + } + get connected() { + return !this.#browserCore.disconnected; + } + process() { + return this.#process ?? null; + } + async createBrowserContext(_options) { + const userContext = await this.#browserCore.createUserContext(); + return this.#createBrowserContext(userContext); + } + async version() { + return `${this.#browserName}/${this.#browserVersion}`; + } + browserContexts() { + return [...this.#browserCore.userContexts].map(context => { + return this.#browserContexts.get(context); + }); + } + defaultBrowserContext() { + return this.#browserContexts.get(this.#browserCore.defaultUserContext); + } + newPage() { + return this.defaultBrowserContext().newPage(); + } + targets() { + return [ + this.#target, + ...this.browserContexts().flatMap(context => { + return context.targets(); + }), + ]; + } + target() { + return this.#target; + } + async disconnect() { + try { + await this.#browserCore.session.end(); + } + catch (error) { + // Fail silently. + debugError(error); + } + finally { + this.connection.dispose(); + } + } + get debugInfo() { + return { + pendingProtocolErrors: this.connection.getPendingProtocolErrors(), + }; + } + }; +})(); + +export { BidiBrowser, BidiBrowserContext, BidiConnection, BidiElementHandle, BidiFrame, BidiFrameRealm, BidiHTTPRequest, BidiHTTPResponse, BidiJSHandle, BidiKeyboard, BidiMouse, BidiPage, BidiRealm, BidiTouchscreen, BidiWorkerRealm, connectBidiOverCdp, requests }; diff --git a/examples/puppeteer-in-browser/out/main.js b/examples/puppeteer-in-browser/out/main.js new file mode 100644 index 00000000000..9a567965d03 --- /dev/null +++ b/examples/puppeteer-in-browser/out/main.js @@ -0,0 +1,20297 @@ +/** + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2015-2018 Google, Inc., Netflix, Inc., Microsoft Corp. and contributors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +*/ +// node_modules/tslib/tslib.es6.mjs +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { + d2.__proto__ = b2; + } || function(d2, b2) { + for (var p in b2) + if (Object.prototype.hasOwnProperty.call(b2, p)) + d2[p] = b2[p]; + }; + return extendStatics(d, b); +}; +function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { + this.constructor = d; + } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { + if (t[0] & 1) + throw t[1]; + return t[1]; + }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { + return this; + }), g; + function verb(n) { + return function(v) { + return step([n, v]); + }; + } + function step(op) { + if (f) + throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) + try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) + return t; + if (y = 0, t) + op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) + _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) + throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } +} +function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) + return m.call(o); + if (o && typeof o.length === "number") + return { + next: function() { + if (o && i >= o.length) + o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) + return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) + ar.push(r.value); + } catch (error) { + e = { error }; + } finally { + try { + if (r && !r.done && (m = i["return"])) + m.call(i); + } finally { + if (e) + throw e.error; + } + } + return ar; +} +function __spreadArray(to, from2, pack) { + if (pack || arguments.length === 2) + for (var i = 0, l = from2.length, ar; i < l; i++) { + if (ar || !(i in from2)) { + if (!ar) + ar = Array.prototype.slice.call(from2, 0, i); + ar[i] = from2[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from2)); +} +function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); +} +function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) + throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i; + function verb(n) { + if (g[n]) + i[n] = function(v) { + return new Promise(function(a, b) { + q.push([n, v, a, b]) > 1 || resume(n, v); + }); + }; + } + function resume(n, v) { + try { + step(g[n](v)); + } catch (e) { + settle(q[0][3], e); + } + } + function step(r) { + r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); + } + function fulfill(value) { + resume("next", value); + } + function reject(value) { + resume("throw", value); + } + function settle(f, v) { + if (f(v), q.shift(), q.length) + resume(q[0][0], q[0][1]); + } +} +function __asyncValues(o) { + if (!Symbol.asyncIterator) + throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i); + function verb(n) { + i[n] = o[n] && function(v) { + return new Promise(function(resolve, reject) { + v = o[n](v), settle(resolve, reject, v.done, v.value); + }); + }; + } + function settle(resolve, reject, d, v) { + Promise.resolve(v).then(function(v2) { + resolve({ value: v2, done: d }); + }, reject); + } +} + +// node_modules/rxjs/dist/esm5/internal/util/isFunction.js +function isFunction(value) { + return typeof value === "function"; +} + +// node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js +function createErrorClass(createImpl) { + var _super = function(instance) { + Error.call(instance); + instance.stack = new Error().stack; + }; + var ctorFunc = createImpl(_super); + ctorFunc.prototype = Object.create(Error.prototype); + ctorFunc.prototype.constructor = ctorFunc; + return ctorFunc; +} + +// node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js +var UnsubscriptionError = createErrorClass(function(_super) { + return function UnsubscriptionErrorImpl(errors) { + _super(this); + this.message = errors ? errors.length + " errors occurred during unsubscription:\n" + errors.map(function(err, i) { + return i + 1 + ") " + err.toString(); + }).join("\n ") : ""; + this.name = "UnsubscriptionError"; + this.errors = errors; + }; +}); + +// node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +function arrRemove(arr, item) { + if (arr) { + var index = arr.indexOf(item); + 0 <= index && arr.splice(index, 1); + } +} + +// node_modules/rxjs/dist/esm5/internal/Subscription.js +var Subscription = function() { + function Subscription2(initialTeardown) { + this.initialTeardown = initialTeardown; + this.closed = false; + this._parentage = null; + this._finalizers = null; + } + Subscription2.prototype.unsubscribe = function() { + var e_1, _a, e_2, _b; + var errors; + if (!this.closed) { + this.closed = true; + var _parentage = this._parentage; + if (_parentage) { + this._parentage = null; + if (Array.isArray(_parentage)) { + try { + for (var _parentage_1 = __values(_parentage), _parentage_1_1 = _parentage_1.next(); !_parentage_1_1.done; _parentage_1_1 = _parentage_1.next()) { + var parent_1 = _parentage_1_1.value; + parent_1.remove(this); + } + } catch (e_1_1) { + e_1 = { error: e_1_1 }; + } finally { + try { + if (_parentage_1_1 && !_parentage_1_1.done && (_a = _parentage_1.return)) + _a.call(_parentage_1); + } finally { + if (e_1) + throw e_1.error; + } + } + } else { + _parentage.remove(this); + } + } + var initialFinalizer = this.initialTeardown; + if (isFunction(initialFinalizer)) { + try { + initialFinalizer(); + } catch (e) { + errors = e instanceof UnsubscriptionError ? e.errors : [e]; + } + } + var _finalizers = this._finalizers; + if (_finalizers) { + this._finalizers = null; + try { + for (var _finalizers_1 = __values(_finalizers), _finalizers_1_1 = _finalizers_1.next(); !_finalizers_1_1.done; _finalizers_1_1 = _finalizers_1.next()) { + var finalizer = _finalizers_1_1.value; + try { + execFinalizer(finalizer); + } catch (err) { + errors = errors !== null && errors !== void 0 ? errors : []; + if (err instanceof UnsubscriptionError) { + errors = __spreadArray(__spreadArray([], __read(errors)), __read(err.errors)); + } else { + errors.push(err); + } + } + } + } catch (e_2_1) { + e_2 = { error: e_2_1 }; + } finally { + try { + if (_finalizers_1_1 && !_finalizers_1_1.done && (_b = _finalizers_1.return)) + _b.call(_finalizers_1); + } finally { + if (e_2) + throw e_2.error; + } + } + } + if (errors) { + throw new UnsubscriptionError(errors); + } + } + }; + Subscription2.prototype.add = function(teardown) { + var _a; + if (teardown && teardown !== this) { + if (this.closed) { + execFinalizer(teardown); + } else { + if (teardown instanceof Subscription2) { + if (teardown.closed || teardown._hasParent(this)) { + return; + } + teardown._addParent(this); + } + (this._finalizers = (_a = this._finalizers) !== null && _a !== void 0 ? _a : []).push(teardown); + } + } + }; + Subscription2.prototype._hasParent = function(parent) { + var _parentage = this._parentage; + return _parentage === parent || Array.isArray(_parentage) && _parentage.includes(parent); + }; + Subscription2.prototype._addParent = function(parent) { + var _parentage = this._parentage; + this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent; + }; + Subscription2.prototype._removeParent = function(parent) { + var _parentage = this._parentage; + if (_parentage === parent) { + this._parentage = null; + } else if (Array.isArray(_parentage)) { + arrRemove(_parentage, parent); + } + }; + Subscription2.prototype.remove = function(teardown) { + var _finalizers = this._finalizers; + _finalizers && arrRemove(_finalizers, teardown); + if (teardown instanceof Subscription2) { + teardown._removeParent(this); + } + }; + Subscription2.EMPTY = function() { + var empty = new Subscription2(); + empty.closed = true; + return empty; + }(); + return Subscription2; +}(); +var EMPTY_SUBSCRIPTION = Subscription.EMPTY; +function isSubscription(value) { + return value instanceof Subscription || value && "closed" in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe); +} +function execFinalizer(finalizer) { + if (isFunction(finalizer)) { + finalizer(); + } else { + finalizer.unsubscribe(); + } +} + +// node_modules/rxjs/dist/esm5/internal/config.js +var config = { + onUnhandledError: null, + onStoppedNotification: null, + Promise: void 0, + useDeprecatedSynchronousErrorHandling: false, + useDeprecatedNextContext: false +}; + +// node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js +var timeoutProvider = { + setTimeout: function(handler, timeout) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + return setTimeout.apply(void 0, __spreadArray([handler, timeout], __read(args))); + }, + clearTimeout: function(handle) { + return (clearTimeout)(handle); + }, + delegate: void 0 +}; + +// node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js +function reportUnhandledError(err) { + timeoutProvider.setTimeout(function() { + { + throw err; + } + }); +} + +// node_modules/rxjs/dist/esm5/internal/util/noop.js +function noop() { +} +function errorContext(cb) { + { + cb(); + } +} + +// node_modules/rxjs/dist/esm5/internal/Subscriber.js +var Subscriber = function(_super) { + __extends(Subscriber2, _super); + function Subscriber2(destination) { + var _this = _super.call(this) || this; + _this.isStopped = false; + if (destination) { + _this.destination = destination; + if (isSubscription(destination)) { + destination.add(_this); + } + } else { + _this.destination = EMPTY_OBSERVER; + } + return _this; + } + Subscriber2.create = function(next, error, complete) { + return new SafeSubscriber(next, error, complete); + }; + Subscriber2.prototype.next = function(value) { + if (this.isStopped) ; else { + this._next(value); + } + }; + Subscriber2.prototype.error = function(err) { + if (this.isStopped) ; else { + this.isStopped = true; + this._error(err); + } + }; + Subscriber2.prototype.complete = function() { + if (this.isStopped) ; else { + this.isStopped = true; + this._complete(); + } + }; + Subscriber2.prototype.unsubscribe = function() { + if (!this.closed) { + this.isStopped = true; + _super.prototype.unsubscribe.call(this); + this.destination = null; + } + }; + Subscriber2.prototype._next = function(value) { + this.destination.next(value); + }; + Subscriber2.prototype._error = function(err) { + try { + this.destination.error(err); + } finally { + this.unsubscribe(); + } + }; + Subscriber2.prototype._complete = function() { + try { + this.destination.complete(); + } finally { + this.unsubscribe(); + } + }; + return Subscriber2; +}(Subscription); +var _bind = Function.prototype.bind; +function bind(fn, thisArg) { + return _bind.call(fn, thisArg); +} +var ConsumerObserver = function() { + function ConsumerObserver2(partialObserver) { + this.partialObserver = partialObserver; + } + ConsumerObserver2.prototype.next = function(value) { + var partialObserver = this.partialObserver; + if (partialObserver.next) { + try { + partialObserver.next(value); + } catch (error) { + handleUnhandledError(error); + } + } + }; + ConsumerObserver2.prototype.error = function(err) { + var partialObserver = this.partialObserver; + if (partialObserver.error) { + try { + partialObserver.error(err); + } catch (error) { + handleUnhandledError(error); + } + } else { + handleUnhandledError(err); + } + }; + ConsumerObserver2.prototype.complete = function() { + var partialObserver = this.partialObserver; + if (partialObserver.complete) { + try { + partialObserver.complete(); + } catch (error) { + handleUnhandledError(error); + } + } + }; + return ConsumerObserver2; +}(); +var SafeSubscriber = function(_super) { + __extends(SafeSubscriber2, _super); + function SafeSubscriber2(observerOrNext, error, complete) { + var _this = _super.call(this) || this; + var partialObserver; + if (isFunction(observerOrNext) || !observerOrNext) { + partialObserver = { + next: observerOrNext !== null && observerOrNext !== void 0 ? observerOrNext : void 0, + error: error !== null && error !== void 0 ? error : void 0, + complete: complete !== null && complete !== void 0 ? complete : void 0 + }; + } else { + var context_1; + if (_this && config.useDeprecatedNextContext) { + context_1 = Object.create(observerOrNext); + context_1.unsubscribe = function() { + return _this.unsubscribe(); + }; + partialObserver = { + next: observerOrNext.next && bind(observerOrNext.next, context_1), + error: observerOrNext.error && bind(observerOrNext.error, context_1), + complete: observerOrNext.complete && bind(observerOrNext.complete, context_1) + }; + } else { + partialObserver = observerOrNext; + } + } + _this.destination = new ConsumerObserver(partialObserver); + return _this; + } + return SafeSubscriber2; +}(Subscriber); +function handleUnhandledError(error) { + { + reportUnhandledError(error); + } +} +function defaultErrorHandler(err) { + throw err; +} +var EMPTY_OBSERVER = { + closed: true, + next: noop, + error: defaultErrorHandler, + complete: noop +}; + +// node_modules/rxjs/dist/esm5/internal/symbol/observable.js +var observable = function() { + return typeof Symbol === "function" && Symbol.observable || "@@observable"; +}(); + +// node_modules/rxjs/dist/esm5/internal/util/identity.js +function identity(x) { + return x; +} + +// node_modules/rxjs/dist/esm5/internal/util/pipe.js +function pipe() { + var fns = []; + for (var _i = 0; _i < arguments.length; _i++) { + fns[_i] = arguments[_i]; + } + return pipeFromArray(fns); +} +function pipeFromArray(fns) { + if (fns.length === 0) { + return identity; + } + if (fns.length === 1) { + return fns[0]; + } + return function piped(input) { + return fns.reduce(function(prev, fn) { + return fn(prev); + }, input); + }; +} + +// node_modules/rxjs/dist/esm5/internal/Observable.js +var Observable = function() { + function Observable2(subscribe) { + if (subscribe) { + this._subscribe = subscribe; + } + } + Observable2.prototype.lift = function(operator) { + var observable2 = new Observable2(); + observable2.source = this; + observable2.operator = operator; + return observable2; + }; + Observable2.prototype.subscribe = function(observerOrNext, error, complete) { + var _this = this; + var subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete); + errorContext(function() { + var _a = _this, operator = _a.operator, source = _a.source; + subscriber.add(operator ? operator.call(subscriber, source) : source ? _this._subscribe(subscriber) : _this._trySubscribe(subscriber)); + }); + return subscriber; + }; + Observable2.prototype._trySubscribe = function(sink) { + try { + return this._subscribe(sink); + } catch (err) { + sink.error(err); + } + }; + Observable2.prototype.forEach = function(next, promiseCtor) { + var _this = this; + promiseCtor = getPromiseCtor(promiseCtor); + return new promiseCtor(function(resolve, reject) { + var subscriber = new SafeSubscriber({ + next: function(value) { + try { + next(value); + } catch (err) { + reject(err); + subscriber.unsubscribe(); + } + }, + error: reject, + complete: resolve + }); + _this.subscribe(subscriber); + }); + }; + Observable2.prototype._subscribe = function(subscriber) { + var _a; + return (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber); + }; + Observable2.prototype[observable] = function() { + return this; + }; + Observable2.prototype.pipe = function() { + var operations = []; + for (var _i = 0; _i < arguments.length; _i++) { + operations[_i] = arguments[_i]; + } + return pipeFromArray(operations)(this); + }; + Observable2.prototype.toPromise = function(promiseCtor) { + var _this = this; + promiseCtor = getPromiseCtor(promiseCtor); + return new promiseCtor(function(resolve, reject) { + var value; + _this.subscribe(function(x) { + return value = x; + }, function(err) { + return reject(err); + }, function() { + return resolve(value); + }); + }); + }; + Observable2.create = function(subscribe) { + return new Observable2(subscribe); + }; + return Observable2; +}(); +function getPromiseCtor(promiseCtor) { + var _a; + return (_a = promiseCtor !== null && promiseCtor !== void 0 ? promiseCtor : config.Promise) !== null && _a !== void 0 ? _a : Promise; +} +function isObserver(value) { + return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete); +} +function isSubscriber(value) { + return value && value instanceof Subscriber || isObserver(value) && isSubscription(value); +} + +// node_modules/rxjs/dist/esm5/internal/util/lift.js +function hasLift(source) { + return isFunction(source === null || source === void 0 ? void 0 : source.lift); +} +function operate(init) { + return function(source) { + if (hasLift(source)) { + return source.lift(function(liftedSource) { + try { + return init(liftedSource, this); + } catch (err) { + this.error(err); + } + }); + } + throw new TypeError("Unable to lift unknown Observable type"); + }; +} + +// node_modules/rxjs/dist/esm5/internal/operators/OperatorSubscriber.js +function createOperatorSubscriber(destination, onNext, onComplete, onError, onFinalize) { + return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize); +} +var OperatorSubscriber = function(_super) { + __extends(OperatorSubscriber2, _super); + function OperatorSubscriber2(destination, onNext, onComplete, onError, onFinalize, shouldUnsubscribe) { + var _this = _super.call(this, destination) || this; + _this.onFinalize = onFinalize; + _this.shouldUnsubscribe = shouldUnsubscribe; + _this._next = onNext ? function(value) { + try { + onNext(value); + } catch (err) { + destination.error(err); + } + } : _super.prototype._next; + _this._error = onError ? function(err) { + try { + onError(err); + } catch (err2) { + destination.error(err2); + } finally { + this.unsubscribe(); + } + } : _super.prototype._error; + _this._complete = onComplete ? function() { + try { + onComplete(); + } catch (err) { + destination.error(err); + } finally { + this.unsubscribe(); + } + } : _super.prototype._complete; + return _this; + } + OperatorSubscriber2.prototype.unsubscribe = function() { + var _a; + if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) { + var closed_1 = this.closed; + _super.prototype.unsubscribe.call(this); + !closed_1 && ((_a = this.onFinalize) === null || _a === void 0 ? void 0 : _a.call(this)); + } + }; + return OperatorSubscriber2; +}(Subscriber); + +// node_modules/rxjs/dist/esm5/internal/util/ObjectUnsubscribedError.js +var ObjectUnsubscribedError = createErrorClass(function(_super) { + return function ObjectUnsubscribedErrorImpl() { + _super(this); + this.name = "ObjectUnsubscribedError"; + this.message = "object unsubscribed"; + }; +}); + +// node_modules/rxjs/dist/esm5/internal/Subject.js +var Subject = function(_super) { + __extends(Subject2, _super); + function Subject2() { + var _this = _super.call(this) || this; + _this.closed = false; + _this.currentObservers = null; + _this.observers = []; + _this.isStopped = false; + _this.hasError = false; + _this.thrownError = null; + return _this; + } + Subject2.prototype.lift = function(operator) { + var subject = new AnonymousSubject(this, this); + subject.operator = operator; + return subject; + }; + Subject2.prototype._throwIfClosed = function() { + if (this.closed) { + throw new ObjectUnsubscribedError(); + } + }; + Subject2.prototype.next = function(value) { + var _this = this; + errorContext(function() { + var e_1, _a; + _this._throwIfClosed(); + if (!_this.isStopped) { + if (!_this.currentObservers) { + _this.currentObservers = Array.from(_this.observers); + } + try { + for (var _b = __values(_this.currentObservers), _c = _b.next(); !_c.done; _c = _b.next()) { + var observer = _c.value; + observer.next(value); + } + } catch (e_1_1) { + e_1 = { error: e_1_1 }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) + _a.call(_b); + } finally { + if (e_1) + throw e_1.error; + } + } + } + }); + }; + Subject2.prototype.error = function(err) { + var _this = this; + errorContext(function() { + _this._throwIfClosed(); + if (!_this.isStopped) { + _this.hasError = _this.isStopped = true; + _this.thrownError = err; + var observers = _this.observers; + while (observers.length) { + observers.shift().error(err); + } + } + }); + }; + Subject2.prototype.complete = function() { + var _this = this; + errorContext(function() { + _this._throwIfClosed(); + if (!_this.isStopped) { + _this.isStopped = true; + var observers = _this.observers; + while (observers.length) { + observers.shift().complete(); + } + } + }); + }; + Subject2.prototype.unsubscribe = function() { + this.isStopped = this.closed = true; + this.observers = this.currentObservers = null; + }; + Object.defineProperty(Subject2.prototype, "observed", { + get: function() { + var _a; + return ((_a = this.observers) === null || _a === void 0 ? void 0 : _a.length) > 0; + }, + enumerable: false, + configurable: true + }); + Subject2.prototype._trySubscribe = function(subscriber) { + this._throwIfClosed(); + return _super.prototype._trySubscribe.call(this, subscriber); + }; + Subject2.prototype._subscribe = function(subscriber) { + this._throwIfClosed(); + this._checkFinalizedStatuses(subscriber); + return this._innerSubscribe(subscriber); + }; + Subject2.prototype._innerSubscribe = function(subscriber) { + var _this = this; + var _a = this, hasError = _a.hasError, isStopped = _a.isStopped, observers = _a.observers; + if (hasError || isStopped) { + return EMPTY_SUBSCRIPTION; + } + this.currentObservers = null; + observers.push(subscriber); + return new Subscription(function() { + _this.currentObservers = null; + arrRemove(observers, subscriber); + }); + }; + Subject2.prototype._checkFinalizedStatuses = function(subscriber) { + var _a = this, hasError = _a.hasError, thrownError = _a.thrownError, isStopped = _a.isStopped; + if (hasError) { + subscriber.error(thrownError); + } else if (isStopped) { + subscriber.complete(); + } + }; + Subject2.prototype.asObservable = function() { + var observable2 = new Observable(); + observable2.source = this; + return observable2; + }; + Subject2.create = function(destination, source) { + return new AnonymousSubject(destination, source); + }; + return Subject2; +}(Observable); +var AnonymousSubject = function(_super) { + __extends(AnonymousSubject2, _super); + function AnonymousSubject2(destination, source) { + var _this = _super.call(this) || this; + _this.destination = destination; + _this.source = source; + return _this; + } + AnonymousSubject2.prototype.next = function(value) { + var _a, _b; + (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value); + }; + AnonymousSubject2.prototype.error = function(err) { + var _a, _b; + (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err); + }; + AnonymousSubject2.prototype.complete = function() { + var _a, _b; + (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a); + }; + AnonymousSubject2.prototype._subscribe = function(subscriber) { + var _a, _b; + return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : EMPTY_SUBSCRIPTION; + }; + return AnonymousSubject2; +}(Subject); + +// node_modules/rxjs/dist/esm5/internal/scheduler/dateTimestampProvider.js +var dateTimestampProvider = { + now: function() { + return (dateTimestampProvider.delegate || Date).now(); + }, + delegate: void 0 +}; + +// node_modules/rxjs/dist/esm5/internal/ReplaySubject.js +var ReplaySubject = function(_super) { + __extends(ReplaySubject2, _super); + function ReplaySubject2(_bufferSize, _windowTime, _timestampProvider) { + if (_bufferSize === void 0) { + _bufferSize = Infinity; + } + if (_windowTime === void 0) { + _windowTime = Infinity; + } + if (_timestampProvider === void 0) { + _timestampProvider = dateTimestampProvider; + } + var _this = _super.call(this) || this; + _this._bufferSize = _bufferSize; + _this._windowTime = _windowTime; + _this._timestampProvider = _timestampProvider; + _this._buffer = []; + _this._infiniteTimeWindow = true; + _this._infiniteTimeWindow = _windowTime === Infinity; + _this._bufferSize = Math.max(1, _bufferSize); + _this._windowTime = Math.max(1, _windowTime); + return _this; + } + ReplaySubject2.prototype.next = function(value) { + var _a = this, isStopped = _a.isStopped, _buffer = _a._buffer, _infiniteTimeWindow = _a._infiniteTimeWindow, _timestampProvider = _a._timestampProvider, _windowTime = _a._windowTime; + if (!isStopped) { + _buffer.push(value); + !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime); + } + this._trimBuffer(); + _super.prototype.next.call(this, value); + }; + ReplaySubject2.prototype._subscribe = function(subscriber) { + this._throwIfClosed(); + this._trimBuffer(); + var subscription = this._innerSubscribe(subscriber); + var _a = this, _infiniteTimeWindow = _a._infiniteTimeWindow, _buffer = _a._buffer; + var copy = _buffer.slice(); + for (var i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) { + subscriber.next(copy[i]); + } + this._checkFinalizedStatuses(subscriber); + return subscription; + }; + ReplaySubject2.prototype._trimBuffer = function() { + var _a = this, _bufferSize = _a._bufferSize, _timestampProvider = _a._timestampProvider, _buffer = _a._buffer, _infiniteTimeWindow = _a._infiniteTimeWindow; + var adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize; + _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize); + if (!_infiniteTimeWindow) { + var now = _timestampProvider.now(); + var last2 = 0; + for (var i = 1; i < _buffer.length && _buffer[i] <= now; i += 2) { + last2 = i; + } + last2 && _buffer.splice(0, last2 + 1); + } + }; + return ReplaySubject2; +}(Subject); + +// node_modules/rxjs/dist/esm5/internal/scheduler/Action.js +var Action = function(_super) { + __extends(Action2, _super); + function Action2(scheduler, work) { + return _super.call(this) || this; + } + Action2.prototype.schedule = function(state, delay2) { + return this; + }; + return Action2; +}(Subscription); + +// node_modules/rxjs/dist/esm5/internal/scheduler/intervalProvider.js +var intervalProvider = { + setInterval: function(handler, timeout) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + return setInterval.apply(void 0, __spreadArray([handler, timeout], __read(args))); + }, + clearInterval: function(handle) { + return (clearInterval)(handle); + }, + delegate: void 0 +}; + +// node_modules/rxjs/dist/esm5/internal/scheduler/AsyncAction.js +var AsyncAction = function(_super) { + __extends(AsyncAction2, _super); + function AsyncAction2(scheduler, work) { + var _this = _super.call(this, scheduler, work) || this; + _this.scheduler = scheduler; + _this.work = work; + _this.pending = false; + return _this; + } + AsyncAction2.prototype.schedule = function(state, delay2) { + var _a; + if (delay2 === void 0) { + delay2 = 0; + } + if (this.closed) { + return this; + } + this.state = state; + var id = this.id; + var scheduler = this.scheduler; + if (id != null) { + this.id = this.recycleAsyncId(scheduler, id, delay2); + } + this.pending = true; + this.delay = delay2; + this.id = (_a = this.id) !== null && _a !== void 0 ? _a : this.requestAsyncId(scheduler, this.id, delay2); + return this; + }; + AsyncAction2.prototype.requestAsyncId = function(scheduler, _id, delay2) { + if (delay2 === void 0) { + delay2 = 0; + } + return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay2); + }; + AsyncAction2.prototype.recycleAsyncId = function(_scheduler, id, delay2) { + if (delay2 === void 0) { + delay2 = 0; + } + if (delay2 != null && this.delay === delay2 && this.pending === false) { + return id; + } + if (id != null) { + intervalProvider.clearInterval(id); + } + return void 0; + }; + AsyncAction2.prototype.execute = function(state, delay2) { + if (this.closed) { + return new Error("executing a cancelled action"); + } + this.pending = false; + var error = this._execute(state, delay2); + if (error) { + return error; + } else if (this.pending === false && this.id != null) { + this.id = this.recycleAsyncId(this.scheduler, this.id, null); + } + }; + AsyncAction2.prototype._execute = function(state, _delay) { + var errored = false; + var errorValue; + try { + this.work(state); + } catch (e) { + errored = true; + errorValue = e ? e : new Error("Scheduled action threw falsy error"); + } + if (errored) { + this.unsubscribe(); + return errorValue; + } + }; + AsyncAction2.prototype.unsubscribe = function() { + if (!this.closed) { + var _a = this, id = _a.id, scheduler = _a.scheduler; + var actions = scheduler.actions; + this.work = this.state = this.scheduler = null; + this.pending = false; + arrRemove(actions, this); + if (id != null) { + this.id = this.recycleAsyncId(scheduler, id, null); + } + this.delay = null; + _super.prototype.unsubscribe.call(this); + } + }; + return AsyncAction2; +}(Action); + +// node_modules/rxjs/dist/esm5/internal/Scheduler.js +var Scheduler = function() { + function Scheduler2(schedulerActionCtor, now) { + if (now === void 0) { + now = Scheduler2.now; + } + this.schedulerActionCtor = schedulerActionCtor; + this.now = now; + } + Scheduler2.prototype.schedule = function(work, delay2, state) { + if (delay2 === void 0) { + delay2 = 0; + } + return new this.schedulerActionCtor(this, work).schedule(state, delay2); + }; + Scheduler2.now = dateTimestampProvider.now; + return Scheduler2; +}(); + +// node_modules/rxjs/dist/esm5/internal/scheduler/AsyncScheduler.js +var AsyncScheduler = function(_super) { + __extends(AsyncScheduler2, _super); + function AsyncScheduler2(SchedulerAction, now) { + if (now === void 0) { + now = Scheduler.now; + } + var _this = _super.call(this, SchedulerAction, now) || this; + _this.actions = []; + _this._active = false; + return _this; + } + AsyncScheduler2.prototype.flush = function(action) { + var actions = this.actions; + if (this._active) { + actions.push(action); + return; + } + var error; + this._active = true; + do { + if (error = action.execute(action.state, action.delay)) { + break; + } + } while (action = actions.shift()); + this._active = false; + if (error) { + while (action = actions.shift()) { + action.unsubscribe(); + } + throw error; + } + }; + return AsyncScheduler2; +}(Scheduler); + +// node_modules/rxjs/dist/esm5/internal/scheduler/async.js +var asyncScheduler = new AsyncScheduler(AsyncAction); +var async = asyncScheduler; + +// node_modules/rxjs/dist/esm5/internal/observable/empty.js +var EMPTY = new Observable(function(subscriber) { + return subscriber.complete(); +}); + +// node_modules/rxjs/dist/esm5/internal/util/isScheduler.js +function isScheduler(value) { + return value && isFunction(value.schedule); +} + +// node_modules/rxjs/dist/esm5/internal/util/args.js +function last(arr) { + return arr[arr.length - 1]; +} +function popResultSelector(args) { + return isFunction(last(args)) ? args.pop() : void 0; +} +function popScheduler(args) { + return isScheduler(last(args)) ? args.pop() : void 0; +} +function popNumber(args, defaultValue) { + return typeof last(args) === "number" ? args.pop() : defaultValue; +} + +// node_modules/rxjs/dist/esm5/internal/util/isArrayLike.js +var isArrayLike = function(x) { + return x && typeof x.length === "number" && typeof x !== "function"; +}; + +// node_modules/rxjs/dist/esm5/internal/util/isPromise.js +function isPromise(value) { + return isFunction(value === null || value === void 0 ? void 0 : value.then); +} + +// node_modules/rxjs/dist/esm5/internal/util/isInteropObservable.js +function isInteropObservable(input) { + return isFunction(input[observable]); +} + +// node_modules/rxjs/dist/esm5/internal/util/isAsyncIterable.js +function isAsyncIterable(obj) { + return Symbol.asyncIterator && isFunction(obj === null || obj === void 0 ? void 0 : obj[Symbol.asyncIterator]); +} + +// node_modules/rxjs/dist/esm5/internal/util/throwUnobservableError.js +function createInvalidObservableTypeError(input) { + return new TypeError("You provided " + (input !== null && typeof input === "object" ? "an invalid object" : "'" + input + "'") + " where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable."); +} + +// node_modules/rxjs/dist/esm5/internal/symbol/iterator.js +function getSymbolIterator() { + if (typeof Symbol !== "function" || !Symbol.iterator) { + return "@@iterator"; + } + return Symbol.iterator; +} +var iterator = getSymbolIterator(); + +// node_modules/rxjs/dist/esm5/internal/util/isIterable.js +function isIterable(input) { + return isFunction(input === null || input === void 0 ? void 0 : input[iterator]); +} + +// node_modules/rxjs/dist/esm5/internal/util/isReadableStreamLike.js +function readableStreamLikeToAsyncGenerator(readableStream) { + return __asyncGenerator(this, arguments, function readableStreamLikeToAsyncGenerator_1() { + var reader, _a, value, done; + return __generator(this, function(_b) { + switch (_b.label) { + case 0: + reader = readableStream.getReader(); + _b.label = 1; + case 1: + _b.trys.push([1, , 9, 10]); + _b.label = 2; + case 2: + return [4, __await(reader.read())]; + case 3: + _a = _b.sent(), value = _a.value, done = _a.done; + if (!done) + return [3, 5]; + return [4, __await(void 0)]; + case 4: + return [2, _b.sent()]; + case 5: + return [4, __await(value)]; + case 6: + return [4, _b.sent()]; + case 7: + _b.sent(); + return [3, 2]; + case 8: + return [3, 10]; + case 9: + reader.releaseLock(); + return [7]; + case 10: + return [2]; + } + }); + }); +} +function isReadableStreamLike(obj) { + return isFunction(obj === null || obj === void 0 ? void 0 : obj.getReader); +} + +// node_modules/rxjs/dist/esm5/internal/observable/innerFrom.js +function innerFrom(input) { + if (input instanceof Observable) { + return input; + } + if (input != null) { + if (isInteropObservable(input)) { + return fromInteropObservable(input); + } + if (isArrayLike(input)) { + return fromArrayLike(input); + } + if (isPromise(input)) { + return fromPromise(input); + } + if (isAsyncIterable(input)) { + return fromAsyncIterable(input); + } + if (isIterable(input)) { + return fromIterable(input); + } + if (isReadableStreamLike(input)) { + return fromReadableStreamLike(input); + } + } + throw createInvalidObservableTypeError(input); +} +function fromInteropObservable(obj) { + return new Observable(function(subscriber) { + var obs = obj[observable](); + if (isFunction(obs.subscribe)) { + return obs.subscribe(subscriber); + } + throw new TypeError("Provided object does not correctly implement Symbol.observable"); + }); +} +function fromArrayLike(array) { + return new Observable(function(subscriber) { + for (var i = 0; i < array.length && !subscriber.closed; i++) { + subscriber.next(array[i]); + } + subscriber.complete(); + }); +} +function fromPromise(promise) { + return new Observable(function(subscriber) { + promise.then(function(value) { + if (!subscriber.closed) { + subscriber.next(value); + subscriber.complete(); + } + }, function(err) { + return subscriber.error(err); + }).then(null, reportUnhandledError); + }); +} +function fromIterable(iterable) { + return new Observable(function(subscriber) { + var e_1, _a; + try { + for (var iterable_1 = __values(iterable), iterable_1_1 = iterable_1.next(); !iterable_1_1.done; iterable_1_1 = iterable_1.next()) { + var value = iterable_1_1.value; + subscriber.next(value); + if (subscriber.closed) { + return; + } + } + } catch (e_1_1) { + e_1 = { error: e_1_1 }; + } finally { + try { + if (iterable_1_1 && !iterable_1_1.done && (_a = iterable_1.return)) + _a.call(iterable_1); + } finally { + if (e_1) + throw e_1.error; + } + } + subscriber.complete(); + }); +} +function fromAsyncIterable(asyncIterable) { + return new Observable(function(subscriber) { + process$1(asyncIterable, subscriber).catch(function(err) { + return subscriber.error(err); + }); + }); +} +function fromReadableStreamLike(readableStream) { + return fromAsyncIterable(readableStreamLikeToAsyncGenerator(readableStream)); +} +function process$1(asyncIterable, subscriber) { + var asyncIterable_1, asyncIterable_1_1; + var e_2, _a; + return __awaiter(this, void 0, void 0, function() { + var value, e_2_1; + return __generator(this, function(_b) { + switch (_b.label) { + case 0: + _b.trys.push([0, 5, 6, 11]); + asyncIterable_1 = __asyncValues(asyncIterable); + _b.label = 1; + case 1: + return [4, asyncIterable_1.next()]; + case 2: + if (!(asyncIterable_1_1 = _b.sent(), !asyncIterable_1_1.done)) + return [3, 4]; + value = asyncIterable_1_1.value; + subscriber.next(value); + if (subscriber.closed) { + return [2]; + } + _b.label = 3; + case 3: + return [3, 1]; + case 4: + return [3, 11]; + case 5: + e_2_1 = _b.sent(); + e_2 = { error: e_2_1 }; + return [3, 11]; + case 6: + _b.trys.push([6, , 9, 10]); + if (!(asyncIterable_1_1 && !asyncIterable_1_1.done && (_a = asyncIterable_1.return))) + return [3, 8]; + return [4, _a.call(asyncIterable_1)]; + case 7: + _b.sent(); + _b.label = 8; + case 8: + return [3, 10]; + case 9: + if (e_2) + throw e_2.error; + return [7]; + case 10: + return [7]; + case 11: + subscriber.complete(); + return [2]; + } + }); + }); +} + +// node_modules/rxjs/dist/esm5/internal/util/executeSchedule.js +function executeSchedule(parentSubscription, scheduler, work, delay2, repeat) { + if (delay2 === void 0) { + delay2 = 0; + } + if (repeat === void 0) { + repeat = false; + } + var scheduleSubscription = scheduler.schedule(function() { + work(); + if (repeat) { + parentSubscription.add(this.schedule(null, delay2)); + } else { + this.unsubscribe(); + } + }, delay2); + parentSubscription.add(scheduleSubscription); + if (!repeat) { + return scheduleSubscription; + } +} + +// node_modules/rxjs/dist/esm5/internal/operators/observeOn.js +function observeOn(scheduler, delay2) { + if (delay2 === void 0) { + delay2 = 0; + } + return operate(function(source, subscriber) { + source.subscribe(createOperatorSubscriber(subscriber, function(value) { + return executeSchedule(subscriber, scheduler, function() { + return subscriber.next(value); + }, delay2); + }, function() { + return executeSchedule(subscriber, scheduler, function() { + return subscriber.complete(); + }, delay2); + }, function(err) { + return executeSchedule(subscriber, scheduler, function() { + return subscriber.error(err); + }, delay2); + })); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/subscribeOn.js +function subscribeOn(scheduler, delay2) { + if (delay2 === void 0) { + delay2 = 0; + } + return operate(function(source, subscriber) { + subscriber.add(scheduler.schedule(function() { + return source.subscribe(subscriber); + }, delay2)); + }); +} + +// node_modules/rxjs/dist/esm5/internal/scheduled/scheduleObservable.js +function scheduleObservable(input, scheduler) { + return innerFrom(input).pipe(subscribeOn(scheduler), observeOn(scheduler)); +} + +// node_modules/rxjs/dist/esm5/internal/scheduled/schedulePromise.js +function schedulePromise(input, scheduler) { + return innerFrom(input).pipe(subscribeOn(scheduler), observeOn(scheduler)); +} + +// node_modules/rxjs/dist/esm5/internal/scheduled/scheduleArray.js +function scheduleArray(input, scheduler) { + return new Observable(function(subscriber) { + var i = 0; + return scheduler.schedule(function() { + if (i === input.length) { + subscriber.complete(); + } else { + subscriber.next(input[i++]); + if (!subscriber.closed) { + this.schedule(); + } + } + }); + }); +} + +// node_modules/rxjs/dist/esm5/internal/scheduled/scheduleIterable.js +function scheduleIterable(input, scheduler) { + return new Observable(function(subscriber) { + var iterator2; + executeSchedule(subscriber, scheduler, function() { + iterator2 = input[iterator](); + executeSchedule(subscriber, scheduler, function() { + var _a; + var value; + var done; + try { + _a = iterator2.next(), value = _a.value, done = _a.done; + } catch (err) { + subscriber.error(err); + return; + } + if (done) { + subscriber.complete(); + } else { + subscriber.next(value); + } + }, 0, true); + }); + return function() { + return isFunction(iterator2 === null || iterator2 === void 0 ? void 0 : iterator2.return) && iterator2.return(); + }; + }); +} + +// node_modules/rxjs/dist/esm5/internal/scheduled/scheduleAsyncIterable.js +function scheduleAsyncIterable(input, scheduler) { + if (!input) { + throw new Error("Iterable cannot be null"); + } + return new Observable(function(subscriber) { + executeSchedule(subscriber, scheduler, function() { + var iterator2 = input[Symbol.asyncIterator](); + executeSchedule(subscriber, scheduler, function() { + iterator2.next().then(function(result) { + if (result.done) { + subscriber.complete(); + } else { + subscriber.next(result.value); + } + }); + }, 0, true); + }); + }); +} + +// node_modules/rxjs/dist/esm5/internal/scheduled/scheduleReadableStreamLike.js +function scheduleReadableStreamLike(input, scheduler) { + return scheduleAsyncIterable(readableStreamLikeToAsyncGenerator(input), scheduler); +} + +// node_modules/rxjs/dist/esm5/internal/scheduled/scheduled.js +function scheduled(input, scheduler) { + if (input != null) { + if (isInteropObservable(input)) { + return scheduleObservable(input, scheduler); + } + if (isArrayLike(input)) { + return scheduleArray(input, scheduler); + } + if (isPromise(input)) { + return schedulePromise(input, scheduler); + } + if (isAsyncIterable(input)) { + return scheduleAsyncIterable(input, scheduler); + } + if (isIterable(input)) { + return scheduleIterable(input, scheduler); + } + if (isReadableStreamLike(input)) { + return scheduleReadableStreamLike(input, scheduler); + } + } + throw createInvalidObservableTypeError(input); +} + +// node_modules/rxjs/dist/esm5/internal/observable/from.js +function from(input, scheduler) { + return scheduler ? scheduled(input, scheduler) : innerFrom(input); +} + +// node_modules/rxjs/dist/esm5/internal/observable/of.js +function of() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var scheduler = popScheduler(args); + return from(args, scheduler); +} + +// node_modules/rxjs/dist/esm5/internal/util/EmptyError.js +var EmptyError = createErrorClass(function(_super) { + return function EmptyErrorImpl() { + _super(this); + this.name = "EmptyError"; + this.message = "no elements in sequence"; + }; +}); + +// node_modules/rxjs/dist/esm5/internal/lastValueFrom.js +function lastValueFrom(source, config2) { + var hasConfig = typeof config2 === "object"; + return new Promise(function(resolve, reject) { + var _hasValue = false; + var _value; + source.subscribe({ + next: function(value) { + _value = value; + _hasValue = true; + }, + error: reject, + complete: function() { + if (_hasValue) { + resolve(_value); + } else if (hasConfig) { + resolve(config2.defaultValue); + } else { + reject(new EmptyError()); + } + } + }); + }); +} + +// node_modules/rxjs/dist/esm5/internal/firstValueFrom.js +function firstValueFrom(source, config2) { + var hasConfig = typeof config2 === "object"; + return new Promise(function(resolve, reject) { + var subscriber = new SafeSubscriber({ + next: function(value) { + resolve(value); + subscriber.unsubscribe(); + }, + error: reject, + complete: function() { + if (hasConfig) { + resolve(config2.defaultValue); + } else { + reject(new EmptyError()); + } + } + }); + source.subscribe(subscriber); + }); +} + +// node_modules/rxjs/dist/esm5/internal/util/isDate.js +function isValidDate(value) { + return value instanceof Date && !isNaN(value); +} + +// node_modules/rxjs/dist/esm5/internal/operators/map.js +function map(project, thisArg) { + return operate(function(source, subscriber) { + var index = 0; + source.subscribe(createOperatorSubscriber(subscriber, function(value) { + subscriber.next(project.call(thisArg, value, index++)); + })); + }); +} + +// node_modules/rxjs/dist/esm5/internal/util/mapOneOrManyArgs.js +var isArray = Array.isArray; +function callOrApply(fn, args) { + return isArray(args) ? fn.apply(void 0, __spreadArray([], __read(args))) : fn(args); +} +function mapOneOrManyArgs(fn) { + return map(function(args) { + return callOrApply(fn, args); + }); +} + +// node_modules/rxjs/dist/esm5/internal/util/argsArgArrayOrObject.js +var isArray2 = Array.isArray; +var getPrototypeOf = Object.getPrototypeOf; +var objectProto = Object.prototype; +var getKeys = Object.keys; +function argsArgArrayOrObject(args) { + if (args.length === 1) { + var first_1 = args[0]; + if (isArray2(first_1)) { + return { args: first_1, keys: null }; + } + if (isPOJO(first_1)) { + var keys = getKeys(first_1); + return { + args: keys.map(function(key) { + return first_1[key]; + }), + keys + }; + } + } + return { args, keys: null }; +} +function isPOJO(obj) { + return obj && typeof obj === "object" && getPrototypeOf(obj) === objectProto; +} + +// node_modules/rxjs/dist/esm5/internal/util/createObject.js +function createObject(keys, values) { + return keys.reduce(function(result, key, i) { + return result[key] = values[i], result; + }, {}); +} + +// node_modules/rxjs/dist/esm5/internal/observable/combineLatest.js +function combineLatest() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var scheduler = popScheduler(args); + var resultSelector = popResultSelector(args); + var _a = argsArgArrayOrObject(args), observables = _a.args, keys = _a.keys; + if (observables.length === 0) { + return from([], scheduler); + } + var result = new Observable(combineLatestInit(observables, scheduler, keys ? function(values) { + return createObject(keys, values); + } : identity)); + return resultSelector ? result.pipe(mapOneOrManyArgs(resultSelector)) : result; +} +function combineLatestInit(observables, scheduler, valueTransform) { + if (valueTransform === void 0) { + valueTransform = identity; + } + return function(subscriber) { + maybeSchedule(scheduler, function() { + var length = observables.length; + var values = new Array(length); + var active = length; + var remainingFirstValues = length; + var _loop_1 = function(i2) { + maybeSchedule(scheduler, function() { + var source = from(observables[i2], scheduler); + var hasFirstValue = false; + source.subscribe(createOperatorSubscriber(subscriber, function(value) { + values[i2] = value; + if (!hasFirstValue) { + hasFirstValue = true; + remainingFirstValues--; + } + if (!remainingFirstValues) { + subscriber.next(valueTransform(values.slice())); + } + }, function() { + if (!--active) { + subscriber.complete(); + } + })); + }, subscriber); + }; + for (var i = 0; i < length; i++) { + _loop_1(i); + } + }, subscriber); + }; +} +function maybeSchedule(scheduler, execute, subscription) { + if (scheduler) { + executeSchedule(subscription, scheduler, execute); + } else { + execute(); + } +} + +// node_modules/rxjs/dist/esm5/internal/operators/mergeInternals.js +function mergeInternals(source, subscriber, project, concurrent, onBeforeNext, expand, innerSubScheduler, additionalFinalizer) { + var buffer = []; + var active = 0; + var index = 0; + var isComplete = false; + var checkComplete = function() { + if (isComplete && !buffer.length && !active) { + subscriber.complete(); + } + }; + var outerNext = function(value) { + return active < concurrent ? doInnerSub(value) : buffer.push(value); + }; + var doInnerSub = function(value) { + expand && subscriber.next(value); + active++; + var innerComplete = false; + innerFrom(project(value, index++)).subscribe(createOperatorSubscriber(subscriber, function(innerValue) { + onBeforeNext === null || onBeforeNext === void 0 ? void 0 : onBeforeNext(innerValue); + if (expand) { + outerNext(innerValue); + } else { + subscriber.next(innerValue); + } + }, function() { + innerComplete = true; + }, void 0, function() { + if (innerComplete) { + try { + active--; + var _loop_1 = function() { + var bufferedValue = buffer.shift(); + if (innerSubScheduler) { + executeSchedule(subscriber, innerSubScheduler, function() { + return doInnerSub(bufferedValue); + }); + } else { + doInnerSub(bufferedValue); + } + }; + while (buffer.length && active < concurrent) { + _loop_1(); + } + checkComplete(); + } catch (err) { + subscriber.error(err); + } + } + })); + }; + source.subscribe(createOperatorSubscriber(subscriber, outerNext, function() { + isComplete = true; + checkComplete(); + })); + return function() { + additionalFinalizer === null || additionalFinalizer === void 0 ? void 0 : additionalFinalizer(); + }; +} + +// node_modules/rxjs/dist/esm5/internal/operators/mergeMap.js +function mergeMap(project, resultSelector, concurrent) { + if (concurrent === void 0) { + concurrent = Infinity; + } + if (isFunction(resultSelector)) { + return mergeMap(function(a, i) { + return map(function(b, ii) { + return resultSelector(a, b, i, ii); + })(innerFrom(project(a, i))); + }, concurrent); + } else if (typeof resultSelector === "number") { + concurrent = resultSelector; + } + return operate(function(source, subscriber) { + return mergeInternals(source, subscriber, project, concurrent); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/mergeAll.js +function mergeAll(concurrent) { + if (concurrent === void 0) { + concurrent = Infinity; + } + return mergeMap(identity, concurrent); +} + +// node_modules/rxjs/dist/esm5/internal/operators/concatAll.js +function concatAll() { + return mergeAll(1); +} + +// node_modules/rxjs/dist/esm5/internal/observable/concat.js +function concat() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return concatAll()(from(args, popScheduler(args))); +} + +// node_modules/rxjs/dist/esm5/internal/observable/defer.js +function defer(observableFactory) { + return new Observable(function(subscriber) { + innerFrom(observableFactory()).subscribe(subscriber); + }); +} + +// node_modules/rxjs/dist/esm5/internal/observable/fromEvent.js +var nodeEventEmitterMethods = ["addListener", "removeListener"]; +var eventTargetMethods = ["addEventListener", "removeEventListener"]; +var jqueryMethods = ["on", "off"]; +function fromEvent(target, eventName, options, resultSelector) { + if (isFunction(options)) { + resultSelector = options; + options = void 0; + } + if (resultSelector) { + return fromEvent(target, eventName, options).pipe(mapOneOrManyArgs(resultSelector)); + } + var _a = __read(isEventTarget(target) ? eventTargetMethods.map(function(methodName) { + return function(handler) { + return target[methodName](eventName, handler, options); + }; + }) : isNodeStyleEventEmitter(target) ? nodeEventEmitterMethods.map(toCommonHandlerRegistry(target, eventName)) : isJQueryStyleEventEmitter(target) ? jqueryMethods.map(toCommonHandlerRegistry(target, eventName)) : [], 2), add = _a[0], remove = _a[1]; + if (!add) { + if (isArrayLike(target)) { + return mergeMap(function(subTarget) { + return fromEvent(subTarget, eventName, options); + })(innerFrom(target)); + } + } + if (!add) { + throw new TypeError("Invalid event target"); + } + return new Observable(function(subscriber) { + var handler = function() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return subscriber.next(1 < args.length ? args : args[0]); + }; + add(handler); + return function() { + return remove(handler); + }; + }); +} +function toCommonHandlerRegistry(target, eventName) { + return function(methodName) { + return function(handler) { + return target[methodName](eventName, handler); + }; + }; +} +function isNodeStyleEventEmitter(target) { + return isFunction(target.addListener) && isFunction(target.removeListener); +} +function isJQueryStyleEventEmitter(target) { + return isFunction(target.on) && isFunction(target.off); +} +function isEventTarget(target) { + return isFunction(target.addEventListener) && isFunction(target.removeEventListener); +} + +// node_modules/rxjs/dist/esm5/internal/observable/timer.js +function timer(dueTime, intervalOrScheduler, scheduler) { + if (dueTime === void 0) { + dueTime = 0; + } + if (scheduler === void 0) { + scheduler = async; + } + var intervalDuration = -1; + if (intervalOrScheduler != null) { + if (isScheduler(intervalOrScheduler)) { + scheduler = intervalOrScheduler; + } else { + intervalDuration = intervalOrScheduler; + } + } + return new Observable(function(subscriber) { + var due = isValidDate(dueTime) ? +dueTime - scheduler.now() : dueTime; + if (due < 0) { + due = 0; + } + var n = 0; + return scheduler.schedule(function() { + if (!subscriber.closed) { + subscriber.next(n++); + if (0 <= intervalDuration) { + this.schedule(void 0, intervalDuration); + } else { + subscriber.complete(); + } + } + }, due); + }); +} + +// node_modules/rxjs/dist/esm5/internal/observable/merge.js +function merge() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var scheduler = popScheduler(args); + var concurrent = popNumber(args, Infinity); + var sources = args; + return !sources.length ? EMPTY : sources.length === 1 ? innerFrom(sources[0]) : mergeAll(concurrent)(from(sources, scheduler)); +} + +// node_modules/rxjs/dist/esm5/internal/observable/never.js +var NEVER = new Observable(noop); + +// node_modules/rxjs/dist/esm5/internal/util/argsOrArgArray.js +var isArray3 = Array.isArray; +function argsOrArgArray(args) { + return args.length === 1 && isArray3(args[0]) ? args[0] : args; +} + +// node_modules/rxjs/dist/esm5/internal/operators/filter.js +function filter(predicate, thisArg) { + return operate(function(source, subscriber) { + var index = 0; + source.subscribe(createOperatorSubscriber(subscriber, function(value) { + return predicate.call(thisArg, value, index++) && subscriber.next(value); + })); + }); +} + +// node_modules/rxjs/dist/esm5/internal/observable/race.js +function race() { + var sources = []; + for (var _i = 0; _i < arguments.length; _i++) { + sources[_i] = arguments[_i]; + } + sources = argsOrArgArray(sources); + return sources.length === 1 ? innerFrom(sources[0]) : new Observable(raceInit(sources)); +} +function raceInit(sources) { + return function(subscriber) { + var subscriptions = []; + var _loop_1 = function(i2) { + subscriptions.push(innerFrom(sources[i2]).subscribe(createOperatorSubscriber(subscriber, function(value) { + if (subscriptions) { + for (var s = 0; s < subscriptions.length; s++) { + s !== i2 && subscriptions[s].unsubscribe(); + } + subscriptions = null; + } + subscriber.next(value); + }))); + }; + for (var i = 0; subscriptions && !subscriber.closed && i < sources.length; i++) { + _loop_1(i); + } + }; +} + +// node_modules/rxjs/dist/esm5/internal/operators/bufferCount.js +function bufferCount(bufferSize, startBufferEvery) { + if (startBufferEvery === void 0) { + startBufferEvery = null; + } + startBufferEvery = startBufferEvery !== null && startBufferEvery !== void 0 ? startBufferEvery : bufferSize; + return operate(function(source, subscriber) { + var buffers = []; + var count = 0; + source.subscribe(createOperatorSubscriber(subscriber, function(value) { + var e_1, _a, e_2, _b; + var toEmit = null; + if (count++ % startBufferEvery === 0) { + buffers.push([]); + } + try { + for (var buffers_1 = __values(buffers), buffers_1_1 = buffers_1.next(); !buffers_1_1.done; buffers_1_1 = buffers_1.next()) { + var buffer = buffers_1_1.value; + buffer.push(value); + if (bufferSize <= buffer.length) { + toEmit = toEmit !== null && toEmit !== void 0 ? toEmit : []; + toEmit.push(buffer); + } + } + } catch (e_1_1) { + e_1 = { error: e_1_1 }; + } finally { + try { + if (buffers_1_1 && !buffers_1_1.done && (_a = buffers_1.return)) + _a.call(buffers_1); + } finally { + if (e_1) + throw e_1.error; + } + } + if (toEmit) { + try { + for (var toEmit_1 = __values(toEmit), toEmit_1_1 = toEmit_1.next(); !toEmit_1_1.done; toEmit_1_1 = toEmit_1.next()) { + var buffer = toEmit_1_1.value; + arrRemove(buffers, buffer); + subscriber.next(buffer); + } + } catch (e_2_1) { + e_2 = { error: e_2_1 }; + } finally { + try { + if (toEmit_1_1 && !toEmit_1_1.done && (_b = toEmit_1.return)) + _b.call(toEmit_1); + } finally { + if (e_2) + throw e_2.error; + } + } + } + }, function() { + var e_3, _a; + try { + for (var buffers_2 = __values(buffers), buffers_2_1 = buffers_2.next(); !buffers_2_1.done; buffers_2_1 = buffers_2.next()) { + var buffer = buffers_2_1.value; + subscriber.next(buffer); + } + } catch (e_3_1) { + e_3 = { error: e_3_1 }; + } finally { + try { + if (buffers_2_1 && !buffers_2_1.done && (_a = buffers_2.return)) + _a.call(buffers_2); + } finally { + if (e_3) + throw e_3.error; + } + } + subscriber.complete(); + }, void 0, function() { + buffers = null; + })); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/catchError.js +function catchError(selector) { + return operate(function(source, subscriber) { + var innerSub = null; + var syncUnsub = false; + var handledResult; + innerSub = source.subscribe(createOperatorSubscriber(subscriber, void 0, void 0, function(err) { + handledResult = innerFrom(selector(err, catchError(selector)(source))); + if (innerSub) { + innerSub.unsubscribe(); + innerSub = null; + handledResult.subscribe(subscriber); + } else { + syncUnsub = true; + } + })); + if (syncUnsub) { + innerSub.unsubscribe(); + innerSub = null; + handledResult.subscribe(subscriber); + } + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/concatMap.js +function concatMap(project, resultSelector) { + return isFunction(resultSelector) ? mergeMap(project, resultSelector, 1) : mergeMap(project, 1); +} + +// node_modules/rxjs/dist/esm5/internal/operators/defaultIfEmpty.js +function defaultIfEmpty(defaultValue) { + return operate(function(source, subscriber) { + var hasValue = false; + source.subscribe(createOperatorSubscriber(subscriber, function(value) { + hasValue = true; + subscriber.next(value); + }, function() { + if (!hasValue) { + subscriber.next(defaultValue); + } + subscriber.complete(); + })); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/take.js +function take(count) { + return count <= 0 ? function() { + return EMPTY; + } : operate(function(source, subscriber) { + var seen = 0; + source.subscribe(createOperatorSubscriber(subscriber, function(value) { + if (++seen <= count) { + subscriber.next(value); + if (count <= seen) { + subscriber.complete(); + } + } + })); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/ignoreElements.js +function ignoreElements() { + return operate(function(source, subscriber) { + source.subscribe(createOperatorSubscriber(subscriber, noop)); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/mapTo.js +function mapTo(value) { + return map(function() { + return value; + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/delayWhen.js +function delayWhen(delayDurationSelector, subscriptionDelay) { + if (subscriptionDelay) { + return function(source) { + return concat(subscriptionDelay.pipe(take(1), ignoreElements()), source.pipe(delayWhen(delayDurationSelector))); + }; + } + return mergeMap(function(value, index) { + return innerFrom(delayDurationSelector(value, index)).pipe(take(1), mapTo(value)); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/throwIfEmpty.js +function throwIfEmpty(errorFactory) { + if (errorFactory === void 0) { + errorFactory = defaultErrorFactory; + } + return operate(function(source, subscriber) { + var hasValue = false; + source.subscribe(createOperatorSubscriber(subscriber, function(value) { + hasValue = true; + subscriber.next(value); + }, function() { + return hasValue ? subscriber.complete() : subscriber.error(errorFactory()); + })); + }); +} +function defaultErrorFactory() { + return new EmptyError(); +} + +// node_modules/rxjs/dist/esm5/internal/operators/first.js +function first(predicate, defaultValue) { + var hasDefaultValue = arguments.length >= 2; + return function(source) { + return source.pipe(predicate ? filter(function(v, i) { + return predicate(v, i, source); + }) : identity, take(1), hasDefaultValue ? defaultIfEmpty(defaultValue) : throwIfEmpty(function() { + return new EmptyError(); + })); + }; +} + +// node_modules/rxjs/dist/esm5/internal/operators/mergeScan.js +function mergeScan(accumulator, seed, concurrent) { + if (concurrent === void 0) { + concurrent = Infinity; + } + return operate(function(source, subscriber) { + var state = seed; + return mergeInternals(source, subscriber, function(value, index) { + return accumulator(state, value, index); + }, concurrent, function(value) { + state = value; + }, false, void 0, function() { + return state = null; + }); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/raceWith.js +function raceWith() { + var otherSources = []; + for (var _i = 0; _i < arguments.length; _i++) { + otherSources[_i] = arguments[_i]; + } + return !otherSources.length ? identity : operate(function(source, subscriber) { + raceInit(__spreadArray([source], __read(otherSources)))(subscriber); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/retry.js +function retry(configOrCount) { + if (configOrCount === void 0) { + configOrCount = Infinity; + } + var config2; + if (configOrCount && typeof configOrCount === "object") { + config2 = configOrCount; + } else { + config2 = { + count: configOrCount + }; + } + var _a = config2.count, count = _a === void 0 ? Infinity : _a, delay2 = config2.delay, _b = config2.resetOnSuccess, resetOnSuccess = _b === void 0 ? false : _b; + return count <= 0 ? identity : operate(function(source, subscriber) { + var soFar = 0; + var innerSub; + var subscribeForRetry = function() { + var syncUnsub = false; + innerSub = source.subscribe(createOperatorSubscriber(subscriber, function(value) { + if (resetOnSuccess) { + soFar = 0; + } + subscriber.next(value); + }, void 0, function(err) { + if (soFar++ < count) { + var resub_1 = function() { + if (innerSub) { + innerSub.unsubscribe(); + innerSub = null; + subscribeForRetry(); + } else { + syncUnsub = true; + } + }; + if (delay2 != null) { + var notifier = typeof delay2 === "number" ? timer(delay2) : innerFrom(delay2(err, soFar)); + var notifierSubscriber_1 = createOperatorSubscriber(subscriber, function() { + notifierSubscriber_1.unsubscribe(); + resub_1(); + }, function() { + subscriber.complete(); + }); + notifier.subscribe(notifierSubscriber_1); + } else { + resub_1(); + } + } else { + subscriber.error(err); + } + })); + if (syncUnsub) { + innerSub.unsubscribe(); + innerSub = null; + subscribeForRetry(); + } + }; + subscribeForRetry(); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/startWith.js +function startWith() { + var values = []; + for (var _i = 0; _i < arguments.length; _i++) { + values[_i] = arguments[_i]; + } + var scheduler = popScheduler(values); + return operate(function(source, subscriber) { + (scheduler ? concat(values, source, scheduler) : concat(values, source)).subscribe(subscriber); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/switchMap.js +function switchMap(project, resultSelector) { + return operate(function(source, subscriber) { + var innerSubscriber = null; + var index = 0; + var isComplete = false; + var checkComplete = function() { + return isComplete && !innerSubscriber && subscriber.complete(); + }; + source.subscribe(createOperatorSubscriber(subscriber, function(value) { + innerSubscriber === null || innerSubscriber === void 0 ? void 0 : innerSubscriber.unsubscribe(); + var innerIndex = 0; + var outerIndex = index++; + innerFrom(project(value, outerIndex)).subscribe(innerSubscriber = createOperatorSubscriber(subscriber, function(innerValue) { + return subscriber.next(resultSelector ? resultSelector(value, innerValue, outerIndex, innerIndex++) : innerValue); + }, function() { + innerSubscriber = null; + checkComplete(); + })); + }, function() { + isComplete = true; + checkComplete(); + })); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/takeUntil.js +function takeUntil(notifier) { + return operate(function(source, subscriber) { + innerFrom(notifier).subscribe(createOperatorSubscriber(subscriber, function() { + return subscriber.complete(); + }, noop)); + !subscriber.closed && source.subscribe(subscriber); + }); +} + +// node_modules/rxjs/dist/esm5/internal/operators/tap.js +function tap(observerOrNext, error, complete) { + var tapObserver = isFunction(observerOrNext) || error || complete ? { next: observerOrNext, error, complete } : observerOrNext; + return tapObserver ? operate(function(source, subscriber) { + var _a; + (_a = tapObserver.subscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver); + var isUnsub = true; + source.subscribe(createOperatorSubscriber(subscriber, function(value) { + var _a2; + (_a2 = tapObserver.next) === null || _a2 === void 0 ? void 0 : _a2.call(tapObserver, value); + subscriber.next(value); + }, function() { + var _a2; + isUnsub = false; + (_a2 = tapObserver.complete) === null || _a2 === void 0 ? void 0 : _a2.call(tapObserver); + subscriber.complete(); + }, function(err) { + var _a2; + isUnsub = false; + (_a2 = tapObserver.error) === null || _a2 === void 0 ? void 0 : _a2.call(tapObserver, err); + subscriber.error(err); + }, function() { + var _a2, _b; + if (isUnsub) { + (_a2 = tapObserver.unsubscribe) === null || _a2 === void 0 ? void 0 : _a2.call(tapObserver); + } + (_b = tapObserver.finalize) === null || _b === void 0 ? void 0 : _b.call(tapObserver); + })); + }) : identity; +} + +/** +MIT License + +Copyright (c) 2021 Jason Miller + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ +// ../../node_modules/mitt/dist/mitt.mjs +function mitt_default(n) { + return { all: n = n || /* @__PURE__ */ new Map(), on: function(t, e) { + var i = n.get(t); + i ? i.push(e) : n.set(t, [e]); + }, off: function(t, e) { + var i = n.get(t); + i && (e ? i.splice(i.indexOf(e) >>> 0, 1) : n.set(t, [])); + }, emit: function(t, e) { + var i = n.get(t); + i && i.slice().map(function(n2) { + n2(e); + }), (i = n.get("*")) && i.slice().map(function(n2) { + n2(t, e); + }); + } }; +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +Symbol.dispose ??= Symbol('dispose'); +Symbol.asyncDispose ??= Symbol('asyncDispose'); +/** + * @internal + */ +const disposeSymbol = Symbol.dispose; +/** + * @internal + */ +const asyncDisposeSymbol = Symbol.asyncDispose; +/** + * @internal + */ +class DisposableStack { + #disposed = false; + #stack = []; + /** + * Returns a value indicating whether this stack has been disposed. + */ + get disposed() { + return this.#disposed; + } + /** + * Disposes each resource in the stack in the reverse order that they were added. + */ + dispose() { + if (this.#disposed) { + return; + } + this.#disposed = true; + for (const resource of this.#stack.reverse()) { + resource[disposeSymbol](); + } + } + /** + * Adds a disposable resource to the stack, returning the resource. + * + * @param value - The resource to add. `null` and `undefined` will not be added, + * but will be returned. + * @returns The provided `value`. + */ + use(value) { + if (value) { + this.#stack.push(value); + } + return value; + } + /** + * Adds a value and associated disposal callback as a resource to the stack. + * + * @param value - The value to add. + * @param onDispose - The callback to use in place of a `[disposeSymbol]()` + * method. Will be invoked with `value` as the first parameter. + * @returns The provided `value`. + */ + adopt(value, onDispose) { + this.#stack.push({ + [disposeSymbol]() { + onDispose(value); + }, + }); + return value; + } + /** + * Adds a callback to be invoked when the stack is disposed. + */ + defer(onDispose) { + this.#stack.push({ + [disposeSymbol]() { + onDispose(); + }, + }); + } + /** + * Move all resources out of this stack and into a new `DisposableStack`, and + * marks this stack as disposed. + * + * @example + * + * ```ts + * class C { + * #res1: Disposable; + * #res2: Disposable; + * #disposables: DisposableStack; + * constructor() { + * // stack will be disposed when exiting constructor for any reason + * using stack = new DisposableStack(); + * + * // get first resource + * this.#res1 = stack.use(getResource1()); + * + * // get second resource. If this fails, both `stack` and `#res1` will be disposed. + * this.#res2 = stack.use(getResource2()); + * + * // all operations succeeded, move resources out of `stack` so that + * // they aren't disposed when constructor exits + * this.#disposables = stack.move(); + * } + * + * [disposeSymbol]() { + * this.#disposables.dispose(); + * } + * } + * ``` + */ + move() { + if (this.#disposed) { + throw new ReferenceError('a disposed stack can not use anything new'); // step 3 + } + const stack = new DisposableStack(); // step 4-5 + stack.#stack = this.#stack; + this.#disposed = true; + return stack; + } + [disposeSymbol] = this.dispose; + [Symbol.toStringTag] = 'DisposableStack'; +} +/** + * @internal + */ +class AsyncDisposableStack { + #disposed = false; + #stack = []; + /** + * Returns a value indicating whether this stack has been disposed. + */ + get disposed() { + return this.#disposed; + } + /** + * Disposes each resource in the stack in the reverse order that they were added. + */ + async dispose() { + if (this.#disposed) { + return; + } + this.#disposed = true; + for (const resource of this.#stack.reverse()) { + await resource[asyncDisposeSymbol](); + } + } + /** + * Adds a disposable resource to the stack, returning the resource. + * + * @param value - The resource to add. `null` and `undefined` will not be added, + * but will be returned. + * @returns The provided `value`. + */ + use(value) { + if (value) { + this.#stack.push(value); + } + return value; + } + /** + * Adds a value and associated disposal callback as a resource to the stack. + * + * @param value - The value to add. + * @param onDispose - The callback to use in place of a `[disposeSymbol]()` + * method. Will be invoked with `value` as the first parameter. + * @returns The provided `value`. + */ + adopt(value, onDispose) { + this.#stack.push({ + [asyncDisposeSymbol]() { + return onDispose(value); + }, + }); + return value; + } + /** + * Adds a callback to be invoked when the stack is disposed. + */ + defer(onDispose) { + this.#stack.push({ + [asyncDisposeSymbol]() { + return onDispose(); + }, + }); + } + /** + * Move all resources out of this stack and into a new `DisposableStack`, and + * marks this stack as disposed. + * + * @example + * + * ```ts + * class C { + * #res1: Disposable; + * #res2: Disposable; + * #disposables: DisposableStack; + * constructor() { + * // stack will be disposed when exiting constructor for any reason + * using stack = new DisposableStack(); + * + * // get first resource + * this.#res1 = stack.use(getResource1()); + * + * // get second resource. If this fails, both `stack` and `#res1` will be disposed. + * this.#res2 = stack.use(getResource2()); + * + * // all operations succeeded, move resources out of `stack` so that + * // they aren't disposed when constructor exits + * this.#disposables = stack.move(); + * } + * + * [disposeSymbol]() { + * this.#disposables.dispose(); + * } + * } + * ``` + */ + move() { + if (this.#disposed) { + throw new ReferenceError('a disposed stack can not use anything new'); // step 3 + } + const stack = new AsyncDisposableStack(); // step 4-5 + stack.#stack = this.#stack; + this.#disposed = true; + return stack; + } + [asyncDisposeSymbol] = this.dispose; + [Symbol.toStringTag] = 'AsyncDisposableStack'; +} + +/** + * @license + * Copyright 2022 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * The EventEmitter class that many Puppeteer classes extend. + * + * @remarks + * + * This allows you to listen to events that Puppeteer classes fire and act + * accordingly. Therefore you'll mostly use {@link EventEmitter.on | on} and + * {@link EventEmitter.off | off} to bind + * and unbind to event listeners. + * + * @public + */ +class EventEmitter { + #emitter; + #handlers = new Map(); + /** + * If you pass an emitter, the returned emitter will wrap the passed emitter. + * + * @internal + */ + constructor(emitter = mitt_default(new Map())) { + this.#emitter = emitter; + } + /** + * Bind an event listener to fire when an event occurs. + * @param type - the event type you'd like to listen to. Can be a string or symbol. + * @param handler - the function to be called when the event occurs. + * @returns `this` to enable you to chain method calls. + */ + on(type, handler) { + const handlers = this.#handlers.get(type); + if (handlers === undefined) { + this.#handlers.set(type, [handler]); + } + else { + handlers.push(handler); + } + this.#emitter.on(type, handler); + return this; + } + /** + * Remove an event listener from firing. + * @param type - the event type you'd like to stop listening to. + * @param handler - the function that should be removed. + * @returns `this` to enable you to chain method calls. + */ + off(type, handler) { + const handlers = this.#handlers.get(type) ?? []; + if (handler === undefined) { + for (const handler of handlers) { + this.#emitter.off(type, handler); + } + this.#handlers.delete(type); + return this; + } + const index = handlers.lastIndexOf(handler); + if (index > -1) { + this.#emitter.off(type, ...handlers.splice(index, 1)); + } + return this; + } + /** + * Emit an event and call any associated listeners. + * + * @param type - the event you'd like to emit + * @param eventData - any data you'd like to emit with the event + * @returns `true` if there are any listeners, `false` if there are not. + */ + emit(type, event) { + this.#emitter.emit(type, event); + return this.listenerCount(type) > 0; + } + /** + * Like `on` but the listener will only be fired once and then it will be removed. + * @param type - the event you'd like to listen to + * @param handler - the handler function to run when the event occurs + * @returns `this` to enable you to chain method calls. + */ + once(type, handler) { + const onceHandler = eventData => { + handler(eventData); + this.off(type, onceHandler); + }; + return this.on(type, onceHandler); + } + /** + * Gets the number of listeners for a given event. + * + * @param type - the event to get the listener count for + * @returns the number of listeners bound to the given event + */ + listenerCount(type) { + return this.#handlers.get(type)?.length || 0; + } + /** + * Removes all listeners. If given an event argument, it will remove only + * listeners for that event. + * + * @param type - the event to remove listeners for. + * @returns `this` to enable you to chain method calls. + */ + removeAllListeners(type) { + if (type !== undefined) { + return this.off(type); + } + this[disposeSymbol](); + return this; + } + /** + * @internal + */ + [disposeSymbol]() { + for (const [type, handlers] of this.#handlers) { + for (const handler of handlers) { + this.#emitter.off(type, handler); + } + } + this.#handlers.clear(); + } +} + +/** + * @license + * Copyright 2020 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * Asserts that the given value is truthy. + * @param value - some conditional statement + * @param message - the error message to throw if the value is not truthy. + * + * @internal + */ +const assert = (value, message) => { + if (!value) { + throw new Error(message); + } +}; + +/** + * @license + * Copyright 2020 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +const isNode = !!(typeof process !== 'undefined' && process.version); + +/** + * @license + * Copyright 2020 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +let debugModule = null; +/** + * @internal + */ +async function importDebug() { + if (!debugModule) { + debugModule = (await import('debug')).default; + } + return debugModule; +} +/** + * A debug function that can be used in any environment. + * + * @remarks + * If used in Node, it falls back to the + * {@link https://www.npmjs.com/package/debug | debug module}. In the browser it + * uses `console.log`. + * + * In Node, use the `DEBUG` environment variable to control logging: + * + * ``` + * DEBUG=* // logs all channels + * DEBUG=foo // logs the `foo` channel + * DEBUG=foo* // logs any channels starting with `foo` + * ``` + * + * In the browser, set `window.__PUPPETEER_DEBUG` to a string: + * + * ``` + * window.__PUPPETEER_DEBUG='*'; // logs all channels + * window.__PUPPETEER_DEBUG='foo'; // logs the `foo` channel + * window.__PUPPETEER_DEBUG='foo*'; // logs any channels starting with `foo` + * ``` + * + * @example + * + * ``` + * const log = debug('Page'); + * + * log('new page created') + * // logs "Page: new page created" + * ``` + * + * @param prefix - this will be prefixed to each log. + * @returns a function that can be called to log to that debug channel. + * + * @internal + */ +const debug = (prefix) => { + if (isNode) { + return async (...logArgs) => { + (await importDebug())(prefix)(logArgs); + }; + } + return (...logArgs) => { + const debugLevel = globalThis.__PUPPETEER_DEBUG; + if (!debugLevel) { + return; + } + const everythingShouldBeLogged = debugLevel === '*'; + const prefixMatchesDebugLevel = everythingShouldBeLogged || + /** + * If the debug level is `foo*`, that means we match any prefix that + * starts with `foo`. If the level is `foo`, we match only the prefix + * `foo`. + */ + (debugLevel.endsWith('*') + ? prefix.startsWith(debugLevel) + : prefix === debugLevel); + if (!prefixMatchesDebugLevel) { + return; + } + // eslint-disable-next-line no-console + console.log(`${prefix}:`, ...logArgs); + }; +}; + +/** + * @license + * Copyright 2018 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * The base class for all Puppeteer-specific errors + * + * @public + */ +class PuppeteerError extends Error { + /** + * @internal + */ + constructor(message, options) { + super(message, options); + this.name = this.constructor.name; + } + /** + * @internal + */ + get [Symbol.toStringTag]() { + return this.constructor.name; + } +} +/** + * TimeoutError is emitted whenever certain operations are terminated due to + * timeout. + * + * @remarks + * Example operations are {@link Page.waitForSelector | page.waitForSelector} or + * {@link PuppeteerNode.launch | puppeteer.launch}. + * + * @public + */ +class TimeoutError extends PuppeteerError { +} +/** + * ProtocolError is emitted whenever there is an error from the protocol. + * + * @public + */ +class ProtocolError extends PuppeteerError { + #code; + #originalMessage = ''; + set code(code) { + this.#code = code; + } + /** + * @readonly + * @public + */ + get code() { + return this.#code; + } + set originalMessage(originalMessage) { + this.#originalMessage = originalMessage; + } + /** + * @readonly + * @public + */ + get originalMessage() { + return this.#originalMessage; + } +} +/** + * Puppeteer will throw this error if a method is not + * supported by the currently used protocol + * + * @public + */ +class UnsupportedOperation extends PuppeteerError { +} +/** + * @internal + */ +class TargetCloseError extends ProtocolError { +} + +/** + * @license + * Copyright 2020 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +const paperFormats = { + letter: { width: 8.5, height: 11 }, + legal: { width: 8.5, height: 14 }, + tabloid: { width: 11, height: 17 }, + ledger: { width: 17, height: 11 }, + a0: { width: 33.1, height: 46.8 }, + a1: { width: 23.4, height: 33.1 }, + a2: { width: 16.54, height: 23.4 }, + a3: { width: 11.7, height: 16.54 }, + a4: { width: 8.27, height: 11.7 }, + a5: { width: 5.83, height: 8.27 }, + a6: { width: 4.13, height: 5.83 }, +}; + +/** + * @license + * Copyright 2017 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +const debugError = debug('puppeteer:error'); +/** + * @internal + */ +const DEFAULT_VIEWPORT = Object.freeze({ width: 800, height: 600 }); +/** + * @internal + */ +const SOURCE_URL = Symbol('Source URL for Puppeteer evaluation scripts'); +/** + * @internal + */ +class PuppeteerURL { + static INTERNAL_URL = 'pptr:internal'; + static fromCallSite(functionName, site) { + const url = new PuppeteerURL(); + url.#functionName = functionName; + url.#siteString = site.toString(); + return url; + } + static parse = (url) => { + url = url.slice('pptr:'.length); + const [functionName = '', siteString = ''] = url.split(';'); + const puppeteerUrl = new PuppeteerURL(); + puppeteerUrl.#functionName = functionName; + puppeteerUrl.#siteString = decodeURIComponent(siteString); + return puppeteerUrl; + }; + static isPuppeteerURL = (url) => { + return url.startsWith('pptr:'); + }; + #functionName; + #siteString; + get functionName() { + return this.#functionName; + } + get siteString() { + return this.#siteString; + } + toString() { + return `pptr:${[ + this.#functionName, + encodeURIComponent(this.#siteString), + ].join(';')}`; + } +} +/** + * @internal + */ +const withSourcePuppeteerURLIfNone = (functionName, object) => { + if (Object.prototype.hasOwnProperty.call(object, SOURCE_URL)) { + return object; + } + const original = Error.prepareStackTrace; + Error.prepareStackTrace = (_, stack) => { + // First element is the function. + // Second element is the caller of this function. + // Third element is the caller of the caller of this function + // which is precisely what we want. + return stack[2]; + }; + const site = new Error().stack; + Error.prepareStackTrace = original; + return Object.assign(object, { + [SOURCE_URL]: PuppeteerURL.fromCallSite(functionName, site), + }); +}; +/** + * @internal + */ +const getSourcePuppeteerURLIfAvailable = (object) => { + if (Object.prototype.hasOwnProperty.call(object, SOURCE_URL)) { + return object[SOURCE_URL]; + } + return undefined; +}; +/** + * @internal + */ +const isString = (obj) => { + return typeof obj === 'string' || obj instanceof String; +}; +/** + * @internal + */ +const isNumber = (obj) => { + return typeof obj === 'number' || obj instanceof Number; +}; +/** + * @internal + */ +const isPlainObject = (obj) => { + return typeof obj === 'object' && obj?.constructor === Object; +}; +/** + * @internal + */ +const isRegExp = (obj) => { + return typeof obj === 'object' && obj?.constructor === RegExp; +}; +/** + * @internal + */ +const isDate = (obj) => { + return typeof obj === 'object' && obj?.constructor === Date; +}; +/** + * @internal + */ +function evaluationString(fun, ...args) { + if (isString(fun)) { + assert(args.length === 0, 'Cannot evaluate a string with arguments'); + return fun; + } + function serializeArgument(arg) { + if (Object.is(arg, undefined)) { + return 'undefined'; + } + return JSON.stringify(arg); + } + return `(${fun})(${args.map(serializeArgument).join(',')})`; +} +/** + * @internal + */ +let fs = null; +/** + * @internal + */ +async function importFSPromises() { + if (!fs) { + try { + fs = await import('fs/promises'); + } + catch (error) { + if (error instanceof TypeError) { + throw new Error('Cannot write to a path outside of a Node-like environment.'); + } + throw error; + } + } + return fs; +} +/** + * @internal + */ +async function getReadableAsBuffer(readable, path) { + const buffers = []; + const reader = readable.getReader(); + if (path) { + const fs = await importFSPromises(); + const fileHandle = await fs.open(path, 'w+'); + try { + while (true) { + const { done, value } = await reader.read(); + if (done) { + break; + } + buffers.push(value); + await fileHandle.writeFile(value); + } + } + finally { + await fileHandle.close(); + } + } + else { + while (true) { + const { done, value } = await reader.read(); + if (done) { + break; + } + buffers.push(value); + } + } + try { + return Buffer.concat(buffers); + } + catch (error) { + debugError(error); + return null; + } +} +/** + * @internal + */ +/** + * @internal + */ +async function getReadableFromProtocolStream(client, handle) { + return new ReadableStream({ + async pull(controller) { + function getUnit8Array(data, isBase64) { + if (isBase64) { + return Uint8Array.from(atob(data), m => { + return m.codePointAt(0); + }); + } + const encoder = new TextEncoder(); + return encoder.encode(data); + } + const { data, base64Encoded, eof } = await client.send('IO.read', { + handle, + }); + controller.enqueue(getUnit8Array(data, base64Encoded ?? false)); + if (eof) { + await client.send('IO.close', { handle }); + controller.close(); + } + }, + }); +} +/** + * @internal + */ +function validateDialogType(type) { + let dialogType = null; + const validDialogTypes = new Set([ + 'alert', + 'confirm', + 'prompt', + 'beforeunload', + ]); + if (validDialogTypes.has(type)) { + dialogType = type; + } + assert(dialogType, `Unknown javascript dialog type: ${type}`); + return dialogType; +} +/** + * @internal + */ +function timeout(ms, cause) { + return ms === 0 + ? NEVER + : timer(ms).pipe(map(() => { + throw new TimeoutError(`Timed out after waiting ${ms}ms`, { cause }); + })); +} +/** + * @internal + */ +const UTILITY_WORLD_NAME = '__puppeteer_utility_world__'; +/** + * @internal + */ +const SOURCE_URL_REGEX = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m; +/** + * @internal + */ +function getSourceUrlComment(url) { + return `//# sourceURL=${url}`; +} +/** + * @internal + */ +const NETWORK_IDLE_TIME = 500; +/** + * @internal + */ +function parsePDFOptions(options = {}, lengthUnit = 'in') { + const defaults = { + scale: 1, + displayHeaderFooter: false, + headerTemplate: '', + footerTemplate: '', + printBackground: false, + landscape: false, + pageRanges: '', + preferCSSPageSize: false, + omitBackground: false, + outline: false, + tagged: true, + }; + let width = 8.5; + let height = 11; + if (options.format) { + const format = paperFormats[options.format.toLowerCase()]; + assert(format, 'Unknown paper format: ' + options.format); + width = format.width; + height = format.height; + } + else { + width = convertPrintParameterToInches(options.width, lengthUnit) ?? width; + height = + convertPrintParameterToInches(options.height, lengthUnit) ?? height; + } + const margin = { + top: convertPrintParameterToInches(options.margin?.top, lengthUnit) || 0, + left: convertPrintParameterToInches(options.margin?.left, lengthUnit) || 0, + bottom: convertPrintParameterToInches(options.margin?.bottom, lengthUnit) || 0, + right: convertPrintParameterToInches(options.margin?.right, lengthUnit) || 0, + }; + // Quirk https://bugs.chromium.org/p/chromium/issues/detail?id=840455#c44 + if (options.outline) { + options.tagged = true; + } + return { + ...defaults, + ...options, + width, + height, + margin, + }; +} +/** + * @internal + */ +const unitToPixels = { + px: 1, + in: 96, + cm: 37.8, + mm: 3.78, +}; +function convertPrintParameterToInches(parameter, lengthUnit = 'in') { + if (typeof parameter === 'undefined') { + return undefined; + } + let pixels; + if (isNumber(parameter)) { + // Treat numbers as pixel values to be aligned with phantom's paperSize. + pixels = parameter; + } + else if (isString(parameter)) { + const text = parameter; + let unit = text.substring(text.length - 2).toLowerCase(); + let valueText = ''; + if (unit in unitToPixels) { + valueText = text.substring(0, text.length - 2); + } + else { + // In case of unknown unit try to parse the whole parameter as number of pixels. + // This is consistent with phantom's paperSize behavior. + unit = 'px'; + valueText = text; + } + const value = Number(valueText); + assert(!isNaN(value), 'Failed to parse parameter value: ' + text); + pixels = value * unitToPixels[unit]; + } + else { + throw new Error('page.pdf() Cannot handle parameter type: ' + typeof parameter); + } + return pixels / unitToPixels[lengthUnit]; +} +/** + * @internal + */ +function fromEmitterEvent(emitter, eventName) { + return new Observable(subscriber => { + const listener = (event) => { + subscriber.next(event); + }; + emitter.on(eventName, listener); + return () => { + emitter.off(eventName, listener); + }; + }); +} +/** + * @internal + */ +function filterAsync(predicate) { + return mergeMap((value) => { + return from(Promise.resolve(predicate(value))).pipe(filter(isMatch => { + return isMatch; + }), map(() => { + return value; + })); + }); +} + +/** + * @license + * Copyright 2017 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +const WEB_PERMISSION_TO_PROTOCOL_PERMISSION = new Map([ + ['geolocation', 'geolocation'], + ['midi', 'midi'], + ['notifications', 'notifications'], + // TODO: push isn't a valid type? + // ['push', 'push'], + ['camera', 'videoCapture'], + ['microphone', 'audioCapture'], + ['background-sync', 'backgroundSync'], + ['ambient-light-sensor', 'sensors'], + ['accelerometer', 'sensors'], + ['gyroscope', 'sensors'], + ['magnetometer', 'sensors'], + ['accessibility-events', 'accessibilityEvents'], + ['clipboard-read', 'clipboardReadWrite'], + ['clipboard-write', 'clipboardReadWrite'], + ['clipboard-sanitized-write', 'clipboardSanitizedWrite'], + ['payment-handler', 'paymentHandler'], + ['persistent-storage', 'durableStorage'], + ['idle-detection', 'idleDetection'], + // chrome-specific permissions we have. + ['midi-sysex', 'midiSysex'], +]); +/** + * {@link Browser} represents a browser instance that is either: + * + * - connected to via {@link Puppeteer.connect} or + * - launched by {@link PuppeteerNode.launch}. + * + * {@link Browser} {@link EventEmitter.emit | emits} various events which are + * documented in the {@link BrowserEvent} enum. + * + * @example Using a {@link Browser} to create a {@link Page}: + * + * ```ts + * import puppeteer from 'puppeteer'; + * + * const browser = await puppeteer.launch(); + * const page = await browser.newPage(); + * await page.goto('https://example.com'); + * await browser.close(); + * ``` + * + * @example Disconnecting from and reconnecting to a {@link Browser}: + * + * ```ts + * import puppeteer from 'puppeteer'; + * + * const browser = await puppeteer.launch(); + * // Store the endpoint to be able to reconnect to the browser. + * const browserWSEndpoint = browser.wsEndpoint(); + * // Disconnect puppeteer from the browser. + * await browser.disconnect(); + * + * // Use the endpoint to reestablish a connection + * const browser2 = await puppeteer.connect({browserWSEndpoint}); + * // Close the browser. + * await browser2.close(); + * ``` + * + * @public + */ +class Browser extends EventEmitter { + /** + * @internal + */ + constructor() { + super(); + } + /** + * Waits until a {@link Target | target} matching the given `predicate` + * appears and returns it. + * + * This will look all open {@link BrowserContext | browser contexts}. + * + * @example Finding a target for a page opened via `window.open`: + * + * ```ts + * await page.evaluate(() => window.open('https://www.example.com/')); + * const newWindowTarget = await browser.waitForTarget( + * target => target.url() === 'https://www.example.com/' + * ); + * ``` + */ + async waitForTarget(predicate, options = {}) { + const { timeout: ms = 30000 } = options; + return await firstValueFrom(merge(fromEmitterEvent(this, "targetcreated" /* BrowserEvent.TargetCreated */), fromEmitterEvent(this, "targetchanged" /* BrowserEvent.TargetChanged */), from(this.targets())).pipe(filterAsync(predicate), raceWith(timeout(ms)))); + } + /** + * Gets a list of all open {@link Page | pages} inside this {@link Browser}. + * + * If there ar multiple {@link BrowserContext | browser contexts}, this + * returns all {@link Page | pages} in all + * {@link BrowserContext | browser contexts}. + * + * @remarks Non-visible {@link Page | pages}, such as `"background_page"`, + * will not be listed here. You can find them using {@link Target.page}. + */ + async pages() { + const contextPages = await Promise.all(this.browserContexts().map(context => { + return context.pages(); + })); + // Flatten array. + return contextPages.reduce((acc, x) => { + return acc.concat(x); + }, []); + } + /** + * Whether Puppeteer is connected to this {@link Browser | browser}. + * + * @deprecated Use {@link Browser | Browser.connected}. + */ + isConnected() { + return this.connected; + } + /** @internal */ + [disposeSymbol]() { + return void this.close().catch(debugError); + } + /** @internal */ + [asyncDisposeSymbol]() { + return this.close(); + } +} + +/** + * @license + * Copyright 2017 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * {@link BrowserContext} represents individual user contexts within a + * {@link Browser | browser}. + * + * When a {@link Browser | browser} is launched, it has a single + * {@link BrowserContext | browser context} by default. Others can be created + * using {@link Browser.createBrowserContext}. Each context has isolated storage + * (cookies/localStorage/etc.) + * + * {@link BrowserContext} {@link EventEmitter | emits} various events which are + * documented in the {@link BrowserContextEvent} enum. + * + * If a {@link Page | page} opens another {@link Page | page}, e.g. using + * `window.open`, the popup will belong to the parent {@link Page.browserContext + * | page's browser context}. + * + * @example Creating a new {@link BrowserContext | browser context}: + * + * ```ts + * // Create a new browser context + * const context = await browser.createBrowserContext(); + * // Create a new page inside context. + * const page = await context.newPage(); + * // ... do stuff with page ... + * await page.goto('https://example.com'); + * // Dispose context once it's no longer needed. + * await context.close(); + * ``` + * + * @public + */ +class BrowserContext extends EventEmitter { + /** + * @internal + */ + constructor() { + super(); + } + /** + * Waits until a {@link Target | target} matching the given `predicate` + * appears and returns it. + * + * This will look all open {@link BrowserContext | browser contexts}. + * + * @example Finding a target for a page opened via `window.open`: + * + * ```ts + * await page.evaluate(() => window.open('https://www.example.com/')); + * const newWindowTarget = await browserContext.waitForTarget( + * target => target.url() === 'https://www.example.com/' + * ); + * ``` + */ + async waitForTarget(predicate, options = {}) { + const { timeout: ms = 30000 } = options; + return await firstValueFrom(merge(fromEmitterEvent(this, "targetcreated" /* BrowserContextEvent.TargetCreated */), fromEmitterEvent(this, "targetchanged" /* BrowserContextEvent.TargetChanged */), from(this.targets())).pipe(filterAsync(predicate), raceWith(timeout(ms)))); + } + /** + * Whether this {@link BrowserContext | browser context} is closed. + */ + get closed() { + return !this.browser().browserContexts().includes(this); + } + /** + * Identifier for this {@link BrowserContext | browser context}. + */ + get id() { + return undefined; + } + /** @internal */ + [disposeSymbol]() { + return void this.close().catch(debugError); + } + /** @internal */ + [asyncDisposeSymbol]() { + return this.close(); + } +} + +/** + * Events that the CDPSession class emits. + * + * @public + */ +// eslint-disable-next-line @typescript-eslint/no-namespace +var CDPSessionEvent; +(function (CDPSessionEvent) { + /** @internal */ + CDPSessionEvent.Disconnected = Symbol('CDPSession.Disconnected'); + /** @internal */ + CDPSessionEvent.Swapped = Symbol('CDPSession.Swapped'); + /** + * Emitted when the session is ready to be configured during the auto-attach + * process. Right after the event is handled, the session will be resumed. + * + * @internal + */ + CDPSessionEvent.Ready = Symbol('CDPSession.Ready'); + CDPSessionEvent.SessionAttached = 'sessionattached'; + CDPSessionEvent.SessionDetached = 'sessiondetached'; +})(CDPSessionEvent || (CDPSessionEvent = {})); +/** + * The `CDPSession` instances are used to talk raw Chrome Devtools Protocol. + * + * @remarks + * + * Protocol methods can be called with {@link CDPSession.send} method and protocol + * events can be subscribed to with `CDPSession.on` method. + * + * Useful links: {@link https://chromedevtools.github.io/devtools-protocol/ | DevTools Protocol Viewer} + * and {@link https://github.com/aslushnikov/getting-started-with-cdp/blob/HEAD/README.md | Getting Started with DevTools Protocol}. + * + * @example + * + * ```ts + * const client = await page.createCDPSession(); + * await client.send('Animation.enable'); + * client.on('Animation.animationCreated', () => + * console.log('Animation created!') + * ); + * const response = await client.send('Animation.getPlaybackRate'); + * console.log('playback rate is ' + response.playbackRate); + * await client.send('Animation.setPlaybackRate', { + * playbackRate: response.playbackRate / 2, + * }); + * ``` + * + * @public + */ +class CDPSession extends EventEmitter { + /** + * @internal + */ + constructor() { + super(); + } + /** + * Parent session in terms of CDP's auto-attach mechanism. + * + * @internal + */ + parentSession() { + return undefined; + } +} + +/** + * @license + * Copyright 2017 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * Dialog instances are dispatched by the {@link Page} via the `dialog` event. + * + * @remarks + * + * @example + * + * ```ts + * import puppeteer from 'puppeteer'; + * + * (async () => { + * const browser = await puppeteer.launch(); + * const page = await browser.newPage(); + * page.on('dialog', async dialog => { + * console.log(dialog.message()); + * await dialog.dismiss(); + * await browser.close(); + * }); + * page.evaluate(() => alert('1')); + * })(); + * ``` + * + * @public + */ +class Dialog { + #type; + #message; + #defaultValue; + #handled = false; + /** + * @internal + */ + constructor(type, message, defaultValue = '') { + this.#type = type; + this.#message = message; + this.#defaultValue = defaultValue; + } + /** + * The type of the dialog. + */ + type() { + return this.#type; + } + /** + * The message displayed in the dialog. + */ + message() { + return this.#message; + } + /** + * The default value of the prompt, or an empty string if the dialog + * is not a `prompt`. + */ + defaultValue() { + return this.#defaultValue; + } + /** + * A promise that resolves when the dialog has been accepted. + * + * @param promptText - optional text that will be entered in the dialog + * prompt. Has no effect if the dialog's type is not `prompt`. + * + */ + async accept(promptText) { + assert(!this.#handled, 'Cannot accept dialog which is already handled!'); + this.#handled = true; + await this.handle({ + accept: true, + text: promptText, + }); + } + /** + * A promise which will resolve once the dialog has been dismissed + */ + async dismiss() { + assert(!this.#handled, 'Cannot dismiss dialog which is already handled!'); + this.#handled = true; + await this.handle({ + accept: false, + }); + } +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +const _isElementHandle = Symbol('_isElementHandle'); + +/** + * @license + * Copyright 2022 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +function isErrorLike(obj) { + return (typeof obj === 'object' && obj !== null && 'name' in obj && 'message' in obj); +} +/** + * @internal + */ +function rewriteError$1(error, message, originalMessage) { + error.message = message; + error.originalMessage = originalMessage ?? error.originalMessage; + return error; +} +/** + * @internal + */ +function createProtocolErrorMessage(object) { + let message = object.error.message; + // TODO: remove the type checks when we stop connecting to BiDi with a CDP + // client. + if (object.error && + typeof object.error === 'object' && + 'data' in object.error) { + message += ` ${object.error.data}`; + } + return message; +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +const createdFunctions = new Map(); +/** + * Creates a function from a string. + * + * @internal + */ +const createFunction = (functionValue) => { + let fn = createdFunctions.get(functionValue); + if (fn) { + return fn; + } + fn = new Function(`return ${functionValue}`)(); + createdFunctions.set(functionValue, fn); + return fn; +}; +/** + * @internal + */ +function stringifyFunction(fn) { + let value = fn.toString(); + try { + new Function(`(${value})`); + } + catch { + // This means we might have a function shorthand (e.g. `test(){}`). Let's + // try prefixing. + let prefix = 'function '; + if (value.startsWith('async ')) { + prefix = `async ${prefix}`; + value = value.substring('async '.length); + } + value = `${prefix}${value}`; + try { + new Function(`(${value})`); + } + catch { + // We tried hard to serialize, but there's a weird beast here. + throw new Error('Passed function cannot be serialized!'); + } + } + return value; +} +/** + * Replaces `PLACEHOLDER`s with the given replacements. + * + * All replacements must be valid JS code. + * + * @example + * + * ```ts + * interpolateFunction(() => PLACEHOLDER('test'), {test: 'void 0'}); + * // Equivalent to () => void 0 + * ``` + * + * @internal + */ +const interpolateFunction = (fn, replacements) => { + let value = stringifyFunction(fn); + for (const [name, jsValue] of Object.entries(replacements)) { + value = value.replace(new RegExp(`PLACEHOLDER\\(\\s*(?:'${name}'|"${name}")\\s*\\)`, 'g'), + // Wrapping this ensures tersers that accidentally inline PLACEHOLDER calls + // are still valid. Without, we may get calls like ()=>{...}() which is + // not valid. + `(${jsValue})`); + } + return createFunction(value); +}; + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __addDisposableResource$a = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$a = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +const DEFAULT_BATCH_SIZE = 20; +/** + * This will transpose an iterator JSHandle into a fast, Puppeteer-side iterator + * of JSHandles. + * + * @param size - The number of elements to transpose. This should be something + * reasonable. + */ +async function* fastTransposeIteratorHandle(iterator, size) { + const env_1 = { stack: [], error: void 0, hasError: false }; + try { + const array = __addDisposableResource$a(env_1, await iterator.evaluateHandle(async (iterator, size) => { + const results = []; + while (results.length < size) { + const result = await iterator.next(); + if (result.done) { + break; + } + results.push(result.value); + } + return results; + }, size), false); + const properties = (await array.getProperties()); + const handles = properties.values(); + const stack = __addDisposableResource$a(env_1, new DisposableStack(), false); + stack.defer(() => { + for (const handle_1 of handles) { + const env_2 = { stack: [], error: void 0, hasError: false }; + try { + const handle = __addDisposableResource$a(env_2, handle_1, false); + handle[disposeSymbol](); + } + catch (e_2) { + env_2.error = e_2; + env_2.hasError = true; + } + finally { + __disposeResources$a(env_2); + } + } + }); + yield* handles; + return properties.size === 0; + } + catch (e_1) { + env_1.error = e_1; + env_1.hasError = true; + } + finally { + __disposeResources$a(env_1); + } +} +/** + * This will transpose an iterator JSHandle in batches based on the default size + * of {@link fastTransposeIteratorHandle}. + */ +async function* transposeIteratorHandle(iterator) { + let size = DEFAULT_BATCH_SIZE; + while (!(yield* fastTransposeIteratorHandle(iterator, size))) { + size <<= 1; + } +} +/** + * @internal + */ +async function* transposeIterableHandle(handle) { + const env_3 = { stack: [], error: void 0, hasError: false }; + try { + const generatorHandle = __addDisposableResource$a(env_3, await handle.evaluateHandle(iterable => { + return (async function* () { + yield* iterable; + })(); + }), false); + yield* transposeIteratorHandle(generatorHandle); + } + catch (e_3) { + env_3.error = e_3; + env_3.hasError = true; + } + finally { + __disposeResources$a(env_3); + } +} + +/** + * @license + * Copyright 2022 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class LazyArg { + static create = (get) => { + // We don't want to introduce LazyArg to the type system, otherwise we would + // have to make it public. + return new LazyArg(get); + }; + #get; + constructor(get) { + this.#get = get; + } + async get(context) { + return await this.#get(context); + } +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __addDisposableResource$9 = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$9 = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +/** + * @internal + */ +class QueryHandler { + // Either one of these may be implemented, but at least one must be. + static querySelectorAll; + static querySelector; + static get _querySelector() { + if (this.querySelector) { + return this.querySelector; + } + if (!this.querySelectorAll) { + throw new Error('Cannot create default `querySelector`.'); + } + return (this.querySelector = interpolateFunction(async (node, selector, PuppeteerUtil) => { + const querySelectorAll = PLACEHOLDER('querySelectorAll'); + const results = querySelectorAll(node, selector, PuppeteerUtil); + for await (const result of results) { + return result; + } + return null; + }, { + querySelectorAll: stringifyFunction(this.querySelectorAll), + })); + } + static get _querySelectorAll() { + if (this.querySelectorAll) { + return this.querySelectorAll; + } + if (!this.querySelector) { + throw new Error('Cannot create default `querySelectorAll`.'); + } + return (this.querySelectorAll = interpolateFunction(async function* (node, selector, PuppeteerUtil) { + const querySelector = PLACEHOLDER('querySelector'); + const result = await querySelector(node, selector, PuppeteerUtil); + if (result) { + yield result; + } + }, { + querySelector: stringifyFunction(this.querySelector), + })); + } + /** + * Queries for multiple nodes given a selector and {@link ElementHandle}. + * + * Akin to {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll | Document.querySelectorAll()}. + */ + static async *queryAll(element, selector) { + const env_1 = { stack: [], error: void 0, hasError: false }; + try { + const handle = __addDisposableResource$9(env_1, await element.evaluateHandle(this._querySelectorAll, selector, LazyArg.create(context => { + return context.puppeteerUtil; + })), false); + yield* transposeIterableHandle(handle); + } + catch (e_1) { + env_1.error = e_1; + env_1.hasError = true; + } + finally { + __disposeResources$9(env_1); + } + } + /** + * Queries for a single node given a selector and {@link ElementHandle}. + * + * Akin to {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector}. + */ + static async queryOne(element, selector) { + const env_2 = { stack: [], error: void 0, hasError: false }; + try { + const result = __addDisposableResource$9(env_2, await element.evaluateHandle(this._querySelector, selector, LazyArg.create(context => { + return context.puppeteerUtil; + })), false); + if (!(_isElementHandle in result)) { + return null; + } + return result.move(); + } + catch (e_2) { + env_2.error = e_2; + env_2.hasError = true; + } + finally { + __disposeResources$9(env_2); + } + } + /** + * Waits until a single node appears for a given selector and + * {@link ElementHandle}. + * + * This will always query the handle in the Puppeteer world and migrate the + * result to the main world. + */ + static async waitFor(elementOrFrame, selector, options) { + const env_3 = { stack: [], error: void 0, hasError: false }; + try { + let frame; + const element = __addDisposableResource$9(env_3, await (async () => { + if (!(_isElementHandle in elementOrFrame)) { + frame = elementOrFrame; + return; + } + frame = elementOrFrame.frame; + return await frame.isolatedRealm().adoptHandle(elementOrFrame); + })(), false); + const { visible = false, hidden = false, timeout, signal } = options; + try { + const env_4 = { stack: [], error: void 0, hasError: false }; + try { + signal?.throwIfAborted(); + const handle = __addDisposableResource$9(env_4, await frame.isolatedRealm().waitForFunction(async (PuppeteerUtil, query, selector, root, visible) => { + const querySelector = PuppeteerUtil.createFunction(query); + const node = await querySelector(root ?? document, selector, PuppeteerUtil); + return PuppeteerUtil.checkVisibility(node, visible); + }, { + polling: visible || hidden ? 'raf' : 'mutation', + root: element, + timeout, + signal, + }, LazyArg.create(context => { + return context.puppeteerUtil; + }), stringifyFunction(this._querySelector), selector, element, visible ? true : hidden ? false : undefined), false); + if (signal?.aborted) { + throw signal.reason; + } + if (!(_isElementHandle in handle)) { + return null; + } + return await frame.mainRealm().transferHandle(handle); + } + catch (e_3) { + env_4.error = e_3; + env_4.hasError = true; + } + finally { + __disposeResources$9(env_4); + } + } + catch (error) { + if (!isErrorLike(error)) { + throw error; + } + if (error.name === 'AbortError') { + throw error; + } + error.message = `Waiting for selector \`${selector}\` failed: ${error.message}`; + throw error; + } + } + catch (e_4) { + env_3.error = e_4; + env_3.hasError = true; + } + finally { + __disposeResources$9(env_3); + } + } +} + +/** + * @internal + */ +class AsyncIterableUtil { + static async *map(iterable, map) { + for await (const value of iterable) { + yield await map(value); + } + } + static async *flatMap(iterable, map) { + for await (const value of iterable) { + yield* map(value); + } + } + static async collect(iterable) { + const result = []; + for await (const value of iterable) { + result.push(value); + } + return result; + } + static async first(iterable) { + for await (const value of iterable) { + return value; + } + return; + } +} + +/** + * @license + * Copyright 2020 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +const isKnownAttribute = (attribute) => { + return ['name', 'role'].includes(attribute); +}; +const normalizeValue = (value) => { + return value.replace(/ +/g, ' ').trim(); +}; +/** + * The selectors consist of an accessible name to query for and optionally + * further aria attributes on the form `[=]`. + * Currently, we only support the `name` and `role` attribute. + * The following examples showcase how the syntax works wrt. querying: + * + * - 'title[role="heading"]' queries for elements with name 'title' and role 'heading'. + * - '[role="image"]' queries for elements with role 'image' and any name. + * - 'label' queries for elements with name 'label' and any role. + * - '[name=""][role="button"]' queries for elements with no name and role 'button'. + */ +const ATTRIBUTE_REGEXP = /\[\s*(?\w+)\s*=\s*(?"|')(?\\.|.*?(?=\k))\k\s*\]/g; +const parseARIASelector = (selector) => { + const queryOptions = {}; + const defaultName = selector.replace(ATTRIBUTE_REGEXP, (_, attribute, __, value) => { + attribute = attribute.trim(); + assert(isKnownAttribute(attribute), `Unknown aria attribute "${attribute}" in selector`); + queryOptions[attribute] = normalizeValue(value); + return ''; + }); + if (defaultName && !queryOptions.name) { + queryOptions.name = normalizeValue(defaultName); + } + return queryOptions; +}; +/** + * @internal + */ +class ARIAQueryHandler extends QueryHandler { + static querySelector = async (node, selector, { ariaQuerySelector }) => { + return await ariaQuerySelector(node, selector); + }; + static async *queryAll(element, selector) { + const { name, role } = parseARIASelector(selector); + yield* element.queryAXTree(name, role); + } + static queryOne = async (element, selector) => { + return ((await AsyncIterableUtil.first(this.queryAll(element, selector))) ?? null); + }; +} + +/** + * JavaScript code that provides the puppeteer utilities. See the + * [README](https://github.com/puppeteer/puppeteer/blob/main/src/injected/README.md) + * for injection for more information. + * + * @internal + */ +const source = "\"use strict\";var v=Object.defineProperty;var re=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var oe=Object.prototype.hasOwnProperty;var u=(t,e)=>{for(var n in e)v(t,n,{get:e[n],enumerable:!0})},se=(t,e,n,r)=>{if(e&&typeof e==\"object\"||typeof e==\"function\")for(let o of ne(e))!oe.call(t,o)&&o!==n&&v(t,o,{get:()=>e[o],enumerable:!(r=re(e,o))||r.enumerable});return t};var ie=t=>se(v({},\"__esModule\",{value:!0}),t);var Re={};u(Re,{default:()=>ke});module.exports=ie(Re);var C=class extends Error{constructor(e,n){super(e,n),this.name=this.constructor.name}get[Symbol.toStringTag](){return this.constructor.name}},b=class extends C{};var f=class t{static create(e){return new t(e)}static async race(e){let n=new Set;try{let r=e.map(o=>o instanceof t?(o.#s&&n.add(o),o.valueOrThrow()):o);return await Promise.race(r)}finally{for(let r of n)r.reject(new Error(\"Timeout cleared\"))}}#e=!1;#r=!1;#n;#t;#o=new Promise(e=>{this.#t=e});#s;#l;constructor(e){e&&e.timeout>0&&(this.#l=new b(e.message),this.#s=setTimeout(()=>{this.reject(this.#l)},e.timeout))}#a(e){clearTimeout(this.#s),this.#n=e,this.#t()}resolve(e){this.#r||this.#e||(this.#e=!0,this.#a(e))}reject(e){this.#r||this.#e||(this.#r=!0,this.#a(e))}resolved(){return this.#e}finished(){return this.#e||this.#r}value(){return this.#n}#i;valueOrThrow(){return this.#i||(this.#i=(async()=>{if(await this.#o,this.#r)throw this.#n;return this.#n})()),this.#i}};var X=new Map,z=t=>{let e=X.get(t);return e||(e=new Function(`return ${t}`)(),X.set(t,e),e)};var k={};u(k,{ariaQuerySelector:()=>le,ariaQuerySelectorAll:()=>I});var le=(t,e)=>window.__ariaQuerySelector(t,e),I=async function*(t,e){yield*await window.__ariaQuerySelectorAll(t,e)};var M={};u(M,{customQuerySelectors:()=>O});var R=class{#e=new Map;register(e,n){if(!n.queryOne&&n.queryAll){let r=n.queryAll;n.queryOne=(o,i)=>{for(let s of r(o,i))return s;return null}}else if(n.queryOne&&!n.queryAll){let r=n.queryOne;n.queryAll=(o,i)=>{let s=r(o,i);return s?[s]:[]}}else if(!n.queryOne||!n.queryAll)throw new Error(\"At least one query method must be defined.\");this.#e.set(e,{querySelector:n.queryOne,querySelectorAll:n.queryAll})}unregister(e){this.#e.delete(e)}get(e){return this.#e.get(e)}clear(){this.#e.clear()}},O=new R;var q={};u(q,{pierceQuerySelector:()=>ae,pierceQuerySelectorAll:()=>ce});var ae=(t,e)=>{let n=null,r=o=>{let i=document.createTreeWalker(o,NodeFilter.SHOW_ELEMENT);do{let s=i.currentNode;s.shadowRoot&&r(s.shadowRoot),!(s instanceof ShadowRoot)&&s!==o&&!n&&s.matches(e)&&(n=s)}while(!n&&i.nextNode())};return t instanceof Document&&(t=t.documentElement),r(t),n},ce=(t,e)=>{let n=[],r=o=>{let i=document.createTreeWalker(o,NodeFilter.SHOW_ELEMENT);do{let s=i.currentNode;s.shadowRoot&&r(s.shadowRoot),!(s instanceof ShadowRoot)&&s!==o&&s.matches(e)&&n.push(s)}while(i.nextNode())};return t instanceof Document&&(t=t.documentElement),r(t),n};var m=(t,e)=>{if(!t)throw new Error(e)};var T=class{#e;#r;#n;#t;constructor(e,n){this.#e=e,this.#r=n}async start(){let e=this.#t=f.create(),n=await this.#e();if(n){e.resolve(n);return}this.#n=new MutationObserver(async()=>{let r=await this.#e();r&&(e.resolve(r),await this.stop())}),this.#n.observe(this.#r,{childList:!0,subtree:!0,attributes:!0})}async stop(){m(this.#t,\"Polling never started.\"),this.#t.finished()||this.#t.reject(new Error(\"Polling stopped\")),this.#n&&(this.#n.disconnect(),this.#n=void 0)}result(){return m(this.#t,\"Polling never started.\"),this.#t.valueOrThrow()}},E=class{#e;#r;constructor(e){this.#e=e}async start(){let e=this.#r=f.create(),n=await this.#e();if(n){e.resolve(n);return}let r=async()=>{if(e.finished())return;let o=await this.#e();if(!o){window.requestAnimationFrame(r);return}e.resolve(o),await this.stop()};window.requestAnimationFrame(r)}async stop(){m(this.#r,\"Polling never started.\"),this.#r.finished()||this.#r.reject(new Error(\"Polling stopped\"))}result(){return m(this.#r,\"Polling never started.\"),this.#r.valueOrThrow()}},P=class{#e;#r;#n;#t;constructor(e,n){this.#e=e,this.#r=n}async start(){let e=this.#t=f.create(),n=await this.#e();if(n){e.resolve(n);return}this.#n=setInterval(async()=>{let r=await this.#e();r&&(e.resolve(r),await this.stop())},this.#r)}async stop(){m(this.#t,\"Polling never started.\"),this.#t.finished()||this.#t.reject(new Error(\"Polling stopped\")),this.#n&&(clearInterval(this.#n),this.#n=void 0)}result(){return m(this.#t,\"Polling never started.\"),this.#t.valueOrThrow()}};var V={};u(V,{pQuerySelector:()=>Ce,pQuerySelectorAll:()=>te});var c=class{static async*map(e,n){for await(let r of e)yield await n(r)}static async*flatMap(e,n){for await(let r of e)yield*n(r)}static async collect(e){let n=[];for await(let r of e)n.push(r);return n}static async first(e){for await(let n of e)return n}};var p={attribute:/\\[\\s*(?:(?\\*|[-\\w\\P{ASCII}]*)\\|)?(?[-\\w\\P{ASCII}]+)\\s*(?:(?\\W?=)\\s*(?.+?)\\s*(\\s(?[iIsS]))?\\s*)?\\]/gu,id:/#(?[-\\w\\P{ASCII}]+)/gu,class:/\\.(?[-\\w\\P{ASCII}]+)/gu,comma:/\\s*,\\s*/g,combinator:/\\s*[\\s>+~]\\s*/g,\"pseudo-element\":/::(?[-\\w\\P{ASCII}]+)(?:\\((?¶*)\\))?/gu,\"pseudo-class\":/:(?[-\\w\\P{ASCII}]+)(?:\\((?¶*)\\))?/gu,universal:/(?:(?\\*|[-\\w\\P{ASCII}]*)\\|)?\\*/gu,type:/(?:(?\\*|[-\\w\\P{ASCII}]*)\\|)?(?[-\\w\\P{ASCII}]+)/gu},ue=new Set([\"combinator\",\"comma\"]);var fe=t=>{switch(t){case\"pseudo-element\":case\"pseudo-class\":return new RegExp(p[t].source.replace(\"(?\\xB6*)\",\"(?.*)\"),\"gu\");default:return p[t]}};function de(t,e){let n=0,r=\"\";for(;e(n.push({value:i,offset:s}),\"\\uE000\".repeat(i.length))),t=t.replace(he,(i,s,l,a)=>(n.push({value:i,offset:a}),`${s}${\"\\uE001\".repeat(l.length)}${s}`));{let i=0,s;for(;(s=t.indexOf(\"(\",i))>-1;){let l=de(t,s);n.push({value:l,offset:s}),t=`${t.substring(0,s)}(${\"\\xB6\".repeat(l.length-2)})${t.substring(s+l.length)}`,i=s+l.length}}let r=me(t,e),o=new Set;for(let i of n.reverse())for(let s of r){let{offset:l,value:a}=i;if(!(s.pos[0]<=l&&l+a.length<=s.pos[1]))continue;let{content:h}=s,d=l-s.pos[0];s.content=h.slice(0,d)+a+h.slice(d+a.length),s.content!==h&&o.add(s)}for(let i of o){let s=fe(i.type);if(!s)throw new Error(`Unknown token type: ${i.type}`);s.lastIndex=0;let l=s.exec(i.content);if(!l)throw new Error(`Unable to parse content for ${i.type}: ${i.content}`);Object.assign(i,l.groups)}return r}function*x(t,e){switch(t.type){case\"list\":for(let n of t.list)yield*x(n,t);break;case\"complex\":yield*x(t.left,t),yield*x(t.right,t);break;case\"compound\":yield*t.list.map(n=>[n,t]);break;default:yield[t,e]}}function y(t){let e;return Array.isArray(t)?e=t:e=[...x(t)].map(([n])=>n),e.map(n=>n.content).join(\"\")}p.combinator=/\\s*(>>>>?|[\\s>+~])\\s*/g;var ye=/\\\\[\\s\\S]/g,ge=t=>t.length<=1?t:((t[0]==='\"'||t[0]===\"'\")&&t.endsWith(t[0])&&(t=t.slice(1,-1)),t.replace(ye,e=>e[1]));function K(t){let e=!0,n=G(t);if(n.length===0)return[[],e];let r=[],o=[r],i=[o],s=[];for(let l of n){switch(l.type){case\"combinator\":switch(l.content){case\">>>\":e=!1,s.length&&(r.push(y(s)),s.splice(0)),r=[],o.push(\">>>\"),o.push(r);continue;case\">>>>\":e=!1,s.length&&(r.push(y(s)),s.splice(0)),r=[],o.push(\">>>>\"),o.push(r);continue}break;case\"pseudo-element\":if(!l.name.startsWith(\"-p-\"))break;e=!1,s.length&&(r.push(y(s)),s.splice(0)),r.push({name:l.name.slice(3),value:ge(l.argument??\"\")});continue;case\"comma\":s.length&&(r.push(y(s)),s.splice(0)),r=[],o=[r],i.push(o);continue}s.push(l)}return s.length&&r.push(y(s)),[i,e]}var _={};u(_,{textQuerySelectorAll:()=>S});var we=new Set([\"checkbox\",\"image\",\"radio\"]),Se=t=>t instanceof HTMLSelectElement||t instanceof HTMLTextAreaElement||t instanceof HTMLInputElement&&!we.has(t.type),be=new Set([\"SCRIPT\",\"STYLE\"]),w=t=>!be.has(t.nodeName)&&!document.head?.contains(t),D=new WeakMap,J=t=>{for(;t;)D.delete(t),t instanceof ShadowRoot?t=t.host:t=t.parentNode},Y=new WeakSet,Te=new MutationObserver(t=>{for(let e of t)J(e.target)}),g=t=>{let e=D.get(t);if(e||(e={full:\"\",immediate:[]},!w(t)))return e;let n=\"\";if(Se(t))e.full=t.value,e.immediate.push(t.value),t.addEventListener(\"input\",r=>{J(r.target)},{once:!0,capture:!0});else{for(let r=t.firstChild;r;r=r.nextSibling){if(r.nodeType===Node.TEXT_NODE){e.full+=r.nodeValue??\"\",n+=r.nodeValue??\"\";continue}n&&e.immediate.push(n),n=\"\",r.nodeType===Node.ELEMENT_NODE&&(e.full+=g(r).full)}n&&e.immediate.push(n),t instanceof Element&&t.shadowRoot&&(e.full+=g(t.shadowRoot).full),Y.has(t)||(Te.observe(t,{childList:!0,characterData:!0,subtree:!0}),Y.add(t))}return D.set(t,e),e};var S=function*(t,e){let n=!1;for(let r of t.childNodes)if(r instanceof Element&&w(r)){let o;r.shadowRoot?o=S(r.shadowRoot,e):o=S(r,e);for(let i of o)yield i,n=!0}n||t instanceof Element&&w(t)&&g(t).full.includes(e)&&(yield t)};var L={};u(L,{checkVisibility:()=>Pe,pierce:()=>N,pierceAll:()=>Q});var Ee=[\"hidden\",\"collapse\"],Pe=(t,e)=>{if(!t)return e===!1;if(e===void 0)return t;let n=t.nodeType===Node.TEXT_NODE?t.parentElement:t,r=window.getComputedStyle(n),o=r&&!Ee.includes(r.visibility)&&!xe(n);return e===o?t:!1};function xe(t){let e=t.getBoundingClientRect();return e.width===0||e.height===0}var Ne=t=>\"shadowRoot\"in t&&t.shadowRoot instanceof ShadowRoot;function*N(t){Ne(t)?yield t.shadowRoot:yield t}function*Q(t){t=N(t).next().value,yield t;let e=[document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT)];for(let n of e){let r;for(;r=n.nextNode();)r.shadowRoot&&(yield r.shadowRoot,e.push(document.createTreeWalker(r.shadowRoot,NodeFilter.SHOW_ELEMENT)))}}var j={};u(j,{xpathQuerySelectorAll:()=>$});var $=function*(t,e,n=-1){let o=(t.ownerDocument||document).evaluate(e,t,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE),i=[],s;for(;(s=o.iterateNext())&&(i.push(s),!(n&&i.length===n)););for(let l=0;l\"querySelectorAll\"in t,A=class extends Error{constructor(e,n){super(`${e} is not a valid selector: ${n}`)}},U=class{#e;#r;#n=[];#t=void 0;elements;constructor(e,n,r){this.elements=[e],this.#e=n,this.#r=r,this.#o()}async run(){if(typeof this.#t==\"string\")switch(this.#t.trimStart()){case\":scope\":this.#o();break}for(;this.#t!==void 0;this.#o()){let e=this.#t,n=this.#e;typeof e==\"string\"?e[0]&&Ae.test(e[0])?this.elements=c.flatMap(this.elements,async function*(r){Z(r)&&(yield*r.querySelectorAll(e))}):this.elements=c.flatMap(this.elements,async function*(r){if(!r.parentElement){if(!Z(r))return;yield*r.querySelectorAll(e);return}let o=0;for(let i of r.parentElement.children)if(++o,i===r)break;yield*r.parentElement.querySelectorAll(`:scope>:nth-child(${o})${e}`)}):this.elements=c.flatMap(this.elements,async function*(r){switch(e.name){case\"text\":yield*S(r,e.value);break;case\"xpath\":yield*$(r,e.value);break;case\"aria\":yield*I(r,e.value);break;default:let o=O.get(e.name);if(!o)throw new A(n,`Unknown selector type: ${e.name}`);yield*o.querySelectorAll(r,e.value)}})}}#o(){if(this.#n.length!==0){this.#t=this.#n.shift();return}if(this.#r.length===0){this.#t=void 0;return}let e=this.#r.shift();switch(e){case\">>>>\":{this.elements=c.flatMap(this.elements,N),this.#o();break}case\">>>\":{this.elements=c.flatMap(this.elements,Q),this.#o();break}default:this.#n=e,this.#o();break}}},F=class{#e=new WeakMap;calculate(e,n=[]){if(e===null)return n;e instanceof ShadowRoot&&(e=e.host);let r=this.#e.get(e);if(r)return[...r,...n];let o=0;for(let s=e.previousSibling;s;s=s.previousSibling)++o;let i=this.calculate(e.parentNode,[o]);return this.#e.set(e,i),[...i,...n]}},ee=(t,e)=>{if(t.length+e.length===0)return 0;let[n=-1,...r]=t,[o=-1,...i]=e;return n===o?ee(r,i):n[r,n.calculate(r)]).sort(([,r],[,o])=>ee(r,o)).map(([r])=>r)},te=function(t,e){let n,r;try{[n,r]=K(e)}catch{return t.querySelectorAll(e)}if(r)return t.querySelectorAll(e);if(n.some(o=>{let i=0;return o.some(s=>(typeof s==\"string\"?++i:i=0,i>1))}))throw new A(e,\"Multiple deep combinators found in sequence.\");return ve(c.flatMap(n,o=>{let i=new U(t,e,o);return i.run(),i.elements}))},Ce=async function(t,e){for await(let n of te(t,e))return n;return null};var Ie=Object.freeze({...k,...M,...q,...V,..._,...L,...j,Deferred:f,createFunction:z,createTextContent:g,IntervalPoller:P,isSuitableNodeForTextMatching:w,MutationPoller:T,RAFPoller:E}),ke=Ie;\n/**\n * @license\n * Copyright 2018 Google Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n/**\n * @license\n * Copyright 2024 Google Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n/**\n * @license\n * Copyright 2023 Google Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n/**\n * @license\n * Copyright 2022 Google Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n/**\n * @license\n * Copyright 2020 Google Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n"; + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class ScriptInjector { + #updated = false; + #amendments = new Set(); + // Appends a statement of the form `(PuppeteerUtil) => {...}`. + append(statement) { + this.#update(() => { + this.#amendments.add(statement); + }); + } + pop(statement) { + this.#update(() => { + this.#amendments.delete(statement); + }); + } + inject(inject, force = false) { + if (this.#updated || force) { + inject(this.#get()); + } + this.#updated = false; + } + #update(callback) { + callback(); + this.#updated = true; + } + #get() { + return `(() => { + const module = {}; + ${source} + ${[...this.#amendments] + .map(statement => { + return `(${statement})(module.exports.default);`; + }) + .join('')} + return module.exports.default; + })()`; + } +} +/** + * @internal + */ +const scriptInjector = new ScriptInjector(); + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * The registry of {@link CustomQueryHandler | custom query handlers}. + * + * @example + * + * ```ts + * Puppeteer.customQueryHandlers.register('lit', { … }); + * const aHandle = await page.$('lit/…'); + * ``` + * + * @internal + */ +class CustomQueryHandlerRegistry { + #handlers = new Map(); + get(name) { + const handler = this.#handlers.get(name); + return handler ? handler[1] : undefined; + } + /** + * Registers a {@link CustomQueryHandler | custom query handler}. + * + * @remarks + * After registration, the handler can be used everywhere where a selector is + * expected by prepending the selection string with `/`. The name is + * only allowed to consist of lower- and upper case latin letters. + * + * @example + * + * ```ts + * Puppeteer.customQueryHandlers.register('lit', { … }); + * const aHandle = await page.$('lit/…'); + * ``` + * + * @param name - Name to register under. + * @param queryHandler - {@link CustomQueryHandler | Custom query handler} to + * register. + */ + register(name, handler) { + assert(!this.#handlers.has(name), `Cannot register over existing handler: ${name}`); + assert(/^[a-zA-Z]+$/.test(name), `Custom query handler names may only contain [a-zA-Z]`); + assert(handler.queryAll || handler.queryOne, `At least one query method must be implemented.`); + const Handler = class extends QueryHandler { + static querySelectorAll = interpolateFunction((node, selector, PuppeteerUtil) => { + return PuppeteerUtil.customQuerySelectors + .get(PLACEHOLDER('name')) + .querySelectorAll(node, selector); + }, { name: JSON.stringify(name) }); + static querySelector = interpolateFunction((node, selector, PuppeteerUtil) => { + return PuppeteerUtil.customQuerySelectors + .get(PLACEHOLDER('name')) + .querySelector(node, selector); + }, { name: JSON.stringify(name) }); + }; + const registerScript = interpolateFunction((PuppeteerUtil) => { + PuppeteerUtil.customQuerySelectors.register(PLACEHOLDER('name'), { + queryAll: PLACEHOLDER('queryAll'), + queryOne: PLACEHOLDER('queryOne'), + }); + }, { + name: JSON.stringify(name), + queryAll: handler.queryAll + ? stringifyFunction(handler.queryAll) + : String(undefined), + queryOne: handler.queryOne + ? stringifyFunction(handler.queryOne) + : String(undefined), + }).toString(); + this.#handlers.set(name, [registerScript, Handler]); + scriptInjector.append(registerScript); + } + /** + * Unregisters the {@link CustomQueryHandler | custom query handler} for the + * given name. + * + * @throws `Error` if there is no handler under the given name. + */ + unregister(name) { + const handler = this.#handlers.get(name); + if (!handler) { + throw new Error(`Cannot unregister unknown handler: ${name}`); + } + scriptInjector.pop(handler[0]); + this.#handlers.delete(name); + } + /** + * Gets the names of all {@link CustomQueryHandler | custom query handlers}. + */ + names() { + return [...this.#handlers.keys()]; + } + /** + * Unregisters all custom query handlers. + */ + clear() { + for (const [registerScript] of this.#handlers) { + scriptInjector.pop(registerScript); + } + this.#handlers.clear(); + } +} +/** + * @internal + */ +const customQueryHandlers = new CustomQueryHandlerRegistry(); + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class PierceQueryHandler extends QueryHandler { + static querySelector = (element, selector, { pierceQuerySelector }) => { + return pierceQuerySelector(element, selector); + }; + static querySelectorAll = (element, selector, { pierceQuerySelectorAll }) => { + return pierceQuerySelectorAll(element, selector); + }; +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class PQueryHandler extends QueryHandler { + static querySelectorAll = (element, selector, { pQuerySelectorAll }) => { + return pQuerySelectorAll(element, selector); + }; + static querySelector = (element, selector, { pQuerySelector }) => { + return pQuerySelector(element, selector); + }; +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class TextQueryHandler extends QueryHandler { + static querySelectorAll = (element, selector, { textQuerySelectorAll }) => { + return textQuerySelectorAll(element, selector); + }; +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class XPathQueryHandler extends QueryHandler { + static querySelectorAll = (element, selector, { xpathQuerySelectorAll }) => { + return xpathQuerySelectorAll(element, selector); + }; + static querySelector = (element, selector, { xpathQuerySelectorAll }) => { + for (const result of xpathQuerySelectorAll(element, selector, 1)) { + return result; + } + return null; + }; +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +const BUILTIN_QUERY_HANDLERS = { + aria: ARIAQueryHandler, + pierce: PierceQueryHandler, + xpath: XPathQueryHandler, + text: TextQueryHandler, +}; +const QUERY_SEPARATORS = ['=', '/']; +/** + * @internal + */ +function getQueryHandlerAndSelector(selector) { + for (const handlerMap of [ + customQueryHandlers.names().map(name => { + return [name, customQueryHandlers.get(name)]; + }), + Object.entries(BUILTIN_QUERY_HANDLERS), + ]) { + for (const [name, QueryHandler] of handlerMap) { + for (const separator of QUERY_SEPARATORS) { + const prefix = `${name}${separator}`; + if (selector.startsWith(prefix)) { + selector = selector.slice(prefix.length); + return { updatedSelector: selector, QueryHandler }; + } + } + } + } + return { updatedSelector: selector, QueryHandler: PQueryHandler }; +} + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * Creates and returns a deferred object along with the resolve/reject functions. + * + * If the deferred has not been resolved/rejected within the `timeout` period, + * the deferred gets resolves with a timeout error. `timeout` has to be greater than 0 or + * it is ignored. + * + * @internal + */ +class Deferred { + static create(opts) { + return new Deferred(opts); + } + static async race(awaitables) { + const deferredWithTimeout = new Set(); + try { + const promises = awaitables.map(value => { + if (value instanceof Deferred) { + if (value.#timeoutId) { + deferredWithTimeout.add(value); + } + return value.valueOrThrow(); + } + return value; + }); + // eslint-disable-next-line no-restricted-syntax + return await Promise.race(promises); + } + finally { + for (const deferred of deferredWithTimeout) { + // We need to stop the timeout else + // Node.JS will keep running the event loop till the + // timer executes + deferred.reject(new Error('Timeout cleared')); + } + } + } + #isResolved = false; + #isRejected = false; + #value; + // SAFETY: This is ensured by #taskPromise. + #resolve; + #taskPromise = new Promise(resolve => { + this.#resolve = resolve; + }); + #timeoutId; + #timeoutError; + constructor(opts) { + if (opts && opts.timeout > 0) { + this.#timeoutError = new TimeoutError(opts.message); + this.#timeoutId = setTimeout(() => { + this.reject(this.#timeoutError); + }, opts.timeout); + } + } + #finish(value) { + clearTimeout(this.#timeoutId); + this.#value = value; + this.#resolve(); + } + resolve(value) { + if (this.#isRejected || this.#isResolved) { + return; + } + this.#isResolved = true; + this.#finish(value); + } + reject(error) { + if (this.#isRejected || this.#isResolved) { + return; + } + this.#isRejected = true; + this.#finish(error); + } + resolved() { + return this.#isResolved; + } + finished() { + return this.#isResolved || this.#isRejected; + } + value() { + return this.#value; + } + #promise; + valueOrThrow() { + if (!this.#promise) { + this.#promise = (async () => { + await this.#taskPromise; + if (this.#isRejected) { + throw this.#value; + } + return this.#value; + })(); + } + return this.#promise; + } +} + +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @internal + */ +class Mutex { + static Guard = class Guard { + #mutex; + constructor(mutex) { + this.#mutex = mutex; + } + [disposeSymbol]() { + return this.#mutex.release(); + } + }; + #locked = false; + #acquirers = []; + // This is FIFO. + async acquire() { + if (!this.#locked) { + this.#locked = true; + return new Mutex.Guard(this); + } + const deferred = Deferred.create(); + this.#acquirers.push(deferred.resolve.bind(deferred)); + await deferred.valueOrThrow(); + return new Mutex.Guard(this); + } + release() { + const resolve = this.#acquirers.shift(); + if (!resolve) { + this.#locked = false; + return; + } + resolve(); + } +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __addDisposableResource$8 = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$8 = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +const instances = new WeakSet(); +function moveable(Class, _) { + let hasDispose = false; + if (Class.prototype[disposeSymbol]) { + const dispose = Class.prototype[disposeSymbol]; + Class.prototype[disposeSymbol] = function () { + if (instances.has(this)) { + instances.delete(this); + return; + } + return dispose.call(this); + }; + hasDispose = true; + } + if (Class.prototype[asyncDisposeSymbol]) { + const asyncDispose = Class.prototype[asyncDisposeSymbol]; + Class.prototype[asyncDisposeSymbol] = function () { + if (instances.has(this)) { + instances.delete(this); + return; + } + return asyncDispose.call(this); + }; + hasDispose = true; + } + if (hasDispose) { + Class.prototype.move = function () { + instances.add(this); + return this; + }; + } + return Class; +} +function throwIfDisposed(message = value => { + return `Attempted to use disposed ${value.constructor.name}.`; +}) { + return (target, _) => { + return function (...args) { + if (this.disposed) { + throw new Error(message(this)); + } + return target.call(this, ...args); + }; + }; +} +function inertIfDisposed(target, _) { + return function (...args) { + if (this.disposed) { + return; + } + return target.call(this, ...args); + }; +} +/** + * The decorator only invokes the target if the target has not been invoked with + * the same arguments before. The decorated method throws an error if it's + * invoked with a different number of elements: if you decorate a method, it + * should have the same number of arguments + * + * @internal + */ +function invokeAtMostOnceForArguments(target, _) { + const cache = new WeakMap(); + let cacheDepth = -1; + return function (...args) { + if (cacheDepth === -1) { + cacheDepth = args.length; + } + if (cacheDepth !== args.length) { + throw new Error('Memoized method was called with the wrong number of arguments'); + } + let freshArguments = false; + let cacheIterator = cache; + for (const arg of args) { + if (cacheIterator.has(arg)) { + cacheIterator = cacheIterator.get(arg); + } + else { + freshArguments = true; + cacheIterator.set(arg, new WeakMap()); + cacheIterator = cacheIterator.get(arg); + } + } + if (!freshArguments) { + return; + } + return target.call(this, ...args); + }; +} +function guarded(getKey = function () { + return this; +}) { + return (target, _) => { + const mutexes = new WeakMap(); + return async function (...args) { + const env_1 = { stack: [], error: void 0, hasError: false }; + try { + const key = getKey.call(this); + let mutex = mutexes.get(key); + if (!mutex) { + mutex = new Mutex(); + mutexes.set(key, mutex); + } + const _ = __addDisposableResource$8(env_1, await mutex.acquire(), true); + return await target.call(this, ...args); + } + catch (e_1) { + env_1.error = e_1; + env_1.hasError = true; + } + finally { + const result_1 = __disposeResources$8(env_1); + if (result_1) + await result_1; + } + }; + }; +} +const bubbleHandlers = new WeakMap(); +/** + * Event emitter fields marked with `bubble` will have their events bubble up + * the field owner. + */ +// The type is too complicated to type. +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +function bubble(events) { + return ({ set, get }, context) => { + context.addInitializer(function () { + const handlers = bubbleHandlers.get(this) ?? new Map(); + if (handlers.has(events)) { + return; + } + const handler = events !== undefined + ? (type, event) => { + if (events.includes(type)) { + this.emit(type, event); + } + } + : (type, event) => { + this.emit(type, event); + }; + handlers.set(events, handler); + bubbleHandlers.set(this, handlers); + }); + return { + set(emitter) { + const handler = bubbleHandlers.get(this).get(events); + // In case we are re-setting. + const oldEmitter = get.call(this); + if (oldEmitter !== undefined) { + oldEmitter.off('*', handler); + } + if (emitter === undefined) { + return; + } + emitter.on('*', handler); + set.call(this, emitter); + }, + // @ts-expect-error -- TypeScript incorrectly types init to require a + // return. + init(emitter) { + if (emitter === undefined) { + return; + } + const handler = bubbleHandlers.get(this).get(events); + emitter.on('*', handler); + return emitter; + }, + }; + }; +} + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$6 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$6 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var __addDisposableResource$7 = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$7 = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +/** + * Represents a reference to a JavaScript object. Instances can be created using + * {@link Page.evaluateHandle}. + * + * Handles prevent the referenced JavaScript object from being garbage-collected + * unless the handle is purposely {@link JSHandle.dispose | disposed}. JSHandles + * are auto-disposed when their associated frame is navigated away or the parent + * context gets destroyed. + * + * Handles can be used as arguments for any evaluation function such as + * {@link Page.$eval}, {@link Page.evaluate}, and {@link Page.evaluateHandle}. + * They are resolved to their referenced object. + * + * @example + * + * ```ts + * const windowHandle = await page.evaluateHandle(() => window); + * ``` + * + * @public + */ +let JSHandle = (() => { + let _classDecorators = [moveable]; + let _classDescriptor; + let _classExtraInitializers = []; + let _classThis; + let _instanceExtraInitializers = []; + let _getProperty_decorators; + let _getProperties_decorators; + (class { + static { _classThis = this; } + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; + __esDecorate$6(this, null, _getProperty_decorators, { kind: "method", name: "getProperty", static: false, private: false, access: { has: obj => "getProperty" in obj, get: obj => obj.getProperty }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$6(this, null, _getProperties_decorators, { kind: "method", name: "getProperties", static: false, private: false, access: { has: obj => "getProperties" in obj, get: obj => obj.getProperties }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate$6(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); + _classThis = _classDescriptor.value; + if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + __runInitializers$6(_classThis, _classExtraInitializers); + } + /** + * @internal + */ + constructor() { + __runInitializers$6(this, _instanceExtraInitializers); + } + /** + * Evaluates the given function with the current handle as its first argument. + */ + async evaluate(pageFunction, ...args) { + pageFunction = withSourcePuppeteerURLIfNone(this.evaluate.name, pageFunction); + return await this.realm.evaluate(pageFunction, this, ...args); + } + /** + * Evaluates the given function with the current handle as its first argument. + * + */ + async evaluateHandle(pageFunction, ...args) { + pageFunction = withSourcePuppeteerURLIfNone(this.evaluateHandle.name, pageFunction); + return await this.realm.evaluateHandle(pageFunction, this, ...args); + } + /** + * @internal + */ + async getProperty(propertyName) { + return await this.evaluateHandle((object, propertyName) => { + return object[propertyName]; + }, propertyName); + } + /** + * Gets a map of handles representing the properties of the current handle. + * + * @example + * + * ```ts + * const listHandle = await page.evaluateHandle(() => document.body.children); + * const properties = await listHandle.getProperties(); + * const children = []; + * for (const property of properties.values()) { + * const element = property.asElement(); + * if (element) { + * children.push(element); + * } + * } + * children; // holds elementHandles to all children of document.body + * ``` + */ + async getProperties() { + const propertyNames = await this.evaluate(object => { + const enumerableProperties = []; + const descriptors = Object.getOwnPropertyDescriptors(object); + for (const propertyName in descriptors) { + if (descriptors[propertyName]?.enumerable) { + enumerableProperties.push(propertyName); + } + } + return enumerableProperties; + }); + const map = new Map(); + const results = await Promise.all(propertyNames.map(key => { + return this.getProperty(key); + })); + for (const [key, value] of Object.entries(propertyNames)) { + const env_1 = { stack: [], error: void 0, hasError: false }; + try { + const handle = __addDisposableResource$7(env_1, results[key], false); + if (handle) { + map.set(value, handle.move()); + } + } + catch (e_1) { + env_1.error = e_1; + env_1.hasError = true; + } + finally { + __disposeResources$7(env_1); + } + } + return map; + } + /** @internal */ + [(_getProperty_decorators = [throwIfDisposed()], _getProperties_decorators = [throwIfDisposed()], disposeSymbol)]() { + return void this.dispose().catch(debugError); + } + /** @internal */ + [asyncDisposeSymbol]() { + return this.dispose(); + } + }); + return _classThis; +})(); + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$5 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$5 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var __addDisposableResource$6 = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$6 = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +/** + * ElementHandle represents an in-page DOM element. + * + * @remarks + * ElementHandles can be created with the {@link Page.$} method. + * + * ```ts + * import puppeteer from 'puppeteer'; + * + * (async () => { + * const browser = await puppeteer.launch(); + * const page = await browser.newPage(); + * await page.goto('https://example.com'); + * const hrefElement = await page.$('a'); + * await hrefElement.click(); + * // ... + * })(); + * ``` + * + * ElementHandle prevents the DOM element from being garbage-collected unless the + * handle is {@link JSHandle.dispose | disposed}. ElementHandles are auto-disposed + * when their origin frame gets navigated. + * + * ElementHandle instances can be used as arguments in {@link Page.$eval} and + * {@link Page.evaluate} methods. + * + * If you're using TypeScript, ElementHandle takes a generic argument that + * denotes the type of element the handle is holding within. For example, if you + * have a handle to a `` element matching `selector`, the method + * throws an error. + * + * @example + * + * ```ts + * handle.select('blue'); // single selection + * handle.select('red', 'green', 'blue'); // multiple selections + * ``` + * + * @param values - Values of options to select. If the ` element.'); + } + const selectedValues = new Set(); + if (!element.multiple) { + for (const option of element.options) { + option.selected = false; + } + for (const option of element.options) { + if (values.has(option.value)) { + option.selected = true; + selectedValues.add(option.value); + break; + } + } + } + else { + for (const option of element.options) { + option.selected = values.has(option.value); + if (option.selected) { + selectedValues.add(option.value); + } + } + } + element.dispatchEvent(new Event('input', { bubbles: true })); + element.dispatchEvent(new Event('change', { bubbles: true })); + return [...selectedValues.values()]; + }, values); + } + /** + * This method scrolls element into view if needed, and then uses + * {@link Touchscreen.tap} to tap in the center of the element. + * If the element is detached from DOM, the method throws an error. + */ + async tap() { + await this.scrollIntoViewIfNeeded(); + const { x, y } = await this.clickablePoint(); + await this.frame.page().touchscreen.tap(x, y); + } + async touchStart() { + await this.scrollIntoViewIfNeeded(); + const { x, y } = await this.clickablePoint(); + await this.frame.page().touchscreen.touchStart(x, y); + } + async touchMove() { + await this.scrollIntoViewIfNeeded(); + const { x, y } = await this.clickablePoint(); + await this.frame.page().touchscreen.touchMove(x, y); + } + async touchEnd() { + await this.scrollIntoViewIfNeeded(); + await this.frame.page().touchscreen.touchEnd(); + } + /** + * Calls {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus | focus} on the element. + */ + async focus() { + await this.evaluate(element => { + if (!(element instanceof HTMLElement)) { + throw new Error('Cannot focus non-HTMLElement'); + } + return element.focus(); + }); + } + /** + * Focuses the element, and then sends a `keydown`, `keypress`/`input`, and + * `keyup` event for each character in the text. + * + * To press a special key, like `Control` or `ArrowDown`, + * use {@link ElementHandle.press}. + * + * @example + * + * ```ts + * await elementHandle.type('Hello'); // Types instantly + * await elementHandle.type('World', {delay: 100}); // Types slower, like a user + * ``` + * + * @example + * An example of typing into a text field and then submitting the form: + * + * ```ts + * const elementHandle = await page.$('input'); + * await elementHandle.type('some text'); + * await elementHandle.press('Enter'); + * ``` + * + * @param options - Delay in milliseconds. Defaults to 0. + */ + async type(text, options) { + await this.focus(); + await this.frame.page().keyboard.type(text, options); + } + /** + * Focuses the element, and then uses {@link Keyboard.down} and {@link Keyboard.up}. + * + * @remarks + * If `key` is a single character and no modifier keys besides `Shift` + * are being held down, a `keypress`/`input` event will also be generated. + * The `text` option can be specified to force an input event to be generated. + * + * **NOTE** Modifier keys DO affect `elementHandle.press`. Holding down `Shift` + * will type the text in upper case. + * + * @param key - Name of key to press, such as `ArrowLeft`. + * See {@link KeyInput} for a list of all key names. + */ + async press(key, options) { + await this.focus(); + await this.frame.page().keyboard.press(key, options); + } + async #clickableBox() { + const boxes = await this.evaluate(element => { + if (!(element instanceof Element)) { + return null; + } + return [...element.getClientRects()].map(rect => { + return { x: rect.x, y: rect.y, width: rect.width, height: rect.height }; + }); + }); + if (!boxes?.length) { + return null; + } + await this.#intersectBoundingBoxesWithFrame(boxes); + let frame = this.frame; + let parentFrame; + while ((parentFrame = frame?.parentFrame())) { + const env_3 = { stack: [], error: void 0, hasError: false }; + try { + const handle = __addDisposableResource$6(env_3, await frame.frameElement(), false); + if (!handle) { + throw new Error('Unsupported frame type'); + } + const parentBox = await handle.evaluate(element => { + // Element is not visible. + if (element.getClientRects().length === 0) { + return null; + } + const rect = element.getBoundingClientRect(); + const style = window.getComputedStyle(element); + return { + left: rect.left + + parseInt(style.paddingLeft, 10) + + parseInt(style.borderLeftWidth, 10), + top: rect.top + + parseInt(style.paddingTop, 10) + + parseInt(style.borderTopWidth, 10), + }; + }); + if (!parentBox) { + return null; + } + for (const box of boxes) { + box.x += parentBox.left; + box.y += parentBox.top; + } + await handle.#intersectBoundingBoxesWithFrame(boxes); + frame = parentFrame; + } + catch (e_3) { + env_3.error = e_3; + env_3.hasError = true; + } + finally { + __disposeResources$6(env_3); + } + } + const box = boxes.find(box => { + return box.width >= 1 && box.height >= 1; + }); + if (!box) { + return null; + } + return { + x: box.x, + y: box.y, + height: box.height, + width: box.width, + }; + } + async #intersectBoundingBoxesWithFrame(boxes) { + const { documentWidth, documentHeight } = await this.frame + .isolatedRealm() + .evaluate(() => { + return { + documentWidth: document.documentElement.clientWidth, + documentHeight: document.documentElement.clientHeight, + }; + }); + for (const box of boxes) { + intersectBoundingBox(box, documentWidth, documentHeight); + } + } + /** + * This method returns the bounding box of the element (relative to the main frame), + * or `null` if the element is {@link https://drafts.csswg.org/css-display-4/#box-generation | not part of the layout} + * (example: `display: none`). + */ + async boundingBox() { + const box = await this.evaluate(element => { + if (!(element instanceof Element)) { + return null; + } + // Element is not visible. + if (element.getClientRects().length === 0) { + return null; + } + const rect = element.getBoundingClientRect(); + return { x: rect.x, y: rect.y, width: rect.width, height: rect.height }; + }); + if (!box) { + return null; + } + const offset = await this.#getTopLeftCornerOfFrame(); + if (!offset) { + return null; + } + return { + x: box.x + offset.x, + y: box.y + offset.y, + height: box.height, + width: box.width, + }; + } + /** + * This method returns boxes of the element, + * or `null` if the element is {@link https://drafts.csswg.org/css-display-4/#box-generation | not part of the layout} + * (example: `display: none`). + * + * @remarks + * + * Boxes are represented as an array of points; + * Each Point is an object `{x, y}`. Box points are sorted clock-wise. + */ + async boxModel() { + const model = await this.evaluate(element => { + if (!(element instanceof Element)) { + return null; + } + // Element is not visible. + if (element.getClientRects().length === 0) { + return null; + } + const rect = element.getBoundingClientRect(); + const style = window.getComputedStyle(element); + const offsets = { + padding: { + left: parseInt(style.paddingLeft, 10), + top: parseInt(style.paddingTop, 10), + right: parseInt(style.paddingRight, 10), + bottom: parseInt(style.paddingBottom, 10), + }, + margin: { + left: -parseInt(style.marginLeft, 10), + top: -parseInt(style.marginTop, 10), + right: -parseInt(style.marginRight, 10), + bottom: -parseInt(style.marginBottom, 10), + }, + border: { + left: parseInt(style.borderLeft, 10), + top: parseInt(style.borderTop, 10), + right: parseInt(style.borderRight, 10), + bottom: parseInt(style.borderBottom, 10), + }, + }; + const border = [ + { x: rect.left, y: rect.top }, + { x: rect.left + rect.width, y: rect.top }, + { x: rect.left + rect.width, y: rect.top + rect.bottom }, + { x: rect.left, y: rect.top + rect.bottom }, + ]; + const padding = transformQuadWithOffsets(border, offsets.border); + const content = transformQuadWithOffsets(padding, offsets.padding); + const margin = transformQuadWithOffsets(border, offsets.margin); + return { + content, + padding, + border, + margin, + width: rect.width, + height: rect.height, + }; + function transformQuadWithOffsets(quad, offsets) { + return [ + { + x: quad[0].x + offsets.left, + y: quad[0].y + offsets.top, + }, + { + x: quad[1].x - offsets.right, + y: quad[1].y + offsets.top, + }, + { + x: quad[2].x - offsets.right, + y: quad[2].y - offsets.bottom, + }, + { + x: quad[3].x + offsets.left, + y: quad[3].y - offsets.bottom, + }, + ]; + } + }); + if (!model) { + return null; + } + const offset = await this.#getTopLeftCornerOfFrame(); + if (!offset) { + return null; + } + for (const attribute of [ + 'content', + 'padding', + 'border', + 'margin', + ]) { + for (const point of model[attribute]) { + point.x += offset.x; + point.y += offset.y; + } + } + return model; + } + async #getTopLeftCornerOfFrame() { + const point = { x: 0, y: 0 }; + let frame = this.frame; + let parentFrame; + while ((parentFrame = frame?.parentFrame())) { + const env_4 = { stack: [], error: void 0, hasError: false }; + try { + const handle = __addDisposableResource$6(env_4, await frame.frameElement(), false); + if (!handle) { + throw new Error('Unsupported frame type'); + } + const parentBox = await handle.evaluate(element => { + // Element is not visible. + if (element.getClientRects().length === 0) { + return null; + } + const rect = element.getBoundingClientRect(); + const style = window.getComputedStyle(element); + return { + left: rect.left + + parseInt(style.paddingLeft, 10) + + parseInt(style.borderLeftWidth, 10), + top: rect.top + + parseInt(style.paddingTop, 10) + + parseInt(style.borderTopWidth, 10), + }; + }); + if (!parentBox) { + return null; + } + point.x += parentBox.left; + point.y += parentBox.top; + frame = parentFrame; + } + catch (e_4) { + env_4.error = e_4; + env_4.hasError = true; + } + finally { + __disposeResources$6(env_4); + } + } + return point; + } + async screenshot(options = {}) { + const { scrollIntoView = true, clip } = options; + const page = this.frame.page(); + // Only scroll the element into view if the user wants it. + if (scrollIntoView) { + await this.scrollIntoViewIfNeeded(); + } + const elementClip = await this.#nonEmptyVisibleBoundingBox(); + const [pageLeft, pageTop] = await this.evaluate(() => { + if (!window.visualViewport) { + throw new Error('window.visualViewport is not supported.'); + } + return [ + window.visualViewport.pageLeft, + window.visualViewport.pageTop, + ]; + }); + elementClip.x += pageLeft; + elementClip.y += pageTop; + if (clip) { + elementClip.x += clip.x; + elementClip.y += clip.y; + elementClip.height = clip.height; + elementClip.width = clip.width; + } + return await page.screenshot({ ...options, clip: elementClip }); + } + async #nonEmptyVisibleBoundingBox() { + const box = await this.boundingBox(); + assert(box, 'Node is either not visible or not an HTMLElement'); + assert(box.width !== 0, 'Node has 0 width.'); + assert(box.height !== 0, 'Node has 0 height.'); + return box; + } + /** + * @internal + */ + async assertConnectedElement() { + const error = await this.evaluate(async (element) => { + if (!element.isConnected) { + return 'Node is detached from document'; + } + if (element.nodeType !== Node.ELEMENT_NODE) { + return 'Node is not of type HTMLElement'; + } + return; + }); + if (error) { + throw new Error(error); + } + } + /** + * @internal + */ + async scrollIntoViewIfNeeded() { + if (await this.isIntersectingViewport({ + threshold: 1, + })) { + return; + } + await this.scrollIntoView(); + } + /** + * Resolves to true if the element is visible in the current viewport. If an + * element is an SVG, we check if the svg owner element is in the viewport + * instead. See https://crbug.com/963246. + * + * @param options - Threshold for the intersection between 0 (no intersection) and 1 + * (full intersection). Defaults to 1. + */ + async isIntersectingViewport(options = {}) { + const env_5 = { stack: [], error: void 0, hasError: false }; + try { + await this.assertConnectedElement(); + // eslint-disable-next-line rulesdir/use-using -- Returns `this`. + const handle = await this.#asSVGElementHandle(); + const target = __addDisposableResource$6(env_5, handle && (await handle.#getOwnerSVGElement()), false); + return await (target ?? this).evaluate(async (element, threshold) => { + const visibleRatio = await new Promise(resolve => { + const observer = new IntersectionObserver(entries => { + resolve(entries[0].intersectionRatio); + observer.disconnect(); + }); + observer.observe(element); + }); + return threshold === 1 ? visibleRatio === 1 : visibleRatio > threshold; + }, options.threshold ?? 0); + } + catch (e_5) { + env_5.error = e_5; + env_5.hasError = true; + } + finally { + __disposeResources$6(env_5); + } + } + /** + * Scrolls the element into view using either the automation protocol client + * or by calling element.scrollIntoView. + */ + async scrollIntoView() { + await this.assertConnectedElement(); + await this.evaluate(async (element) => { + element.scrollIntoView({ + block: 'center', + inline: 'center', + behavior: 'instant', + }); + }); + } + /** + * Returns true if an element is an SVGElement (included svg, path, rect + * etc.). + */ + async #asSVGElementHandle() { + if (await this.evaluate(element => { + return element instanceof SVGElement; + })) { + return this; + } + else { + return null; + } + } + async #getOwnerSVGElement() { + // SVGSVGElement.ownerSVGElement === null. + return await this.evaluateHandle(element => { + if (element instanceof SVGSVGElement) { + return element; + } + return element.ownerSVGElement; + }); + } + }; +})(); +function intersectBoundingBox(box, width, height) { + box.width = Math.max(box.x >= 0 + ? Math.min(width - box.x, box.width) + : Math.min(width, box.width + box.x), 0); + box.height = Math.max(box.y >= 0 + ? Math.min(height - box.y, box.height) + : Math.min(height, box.height + box.y), 0); +} + +var __addDisposableResource$5 = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$5 = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +/** + * All the events that a locator instance may emit. + * + * @public + */ +var LocatorEvent; +(function (LocatorEvent) { + /** + * Emitted every time before the locator performs an action on the located element(s). + */ + LocatorEvent["Action"] = "action"; +})(LocatorEvent || (LocatorEvent = {})); +/** + * Locators describe a strategy of locating objects and performing an action on + * them. If the action fails because the object is not ready for the action, the + * whole operation is retried. Various preconditions for a successful action are + * checked automatically. + * + * @public + */ +class Locator extends EventEmitter { + /** + * Creates a race between multiple locators but ensures that only a single one + * acts. + * + * @public + */ + static race(locators) { + return RaceLocator.create(locators); + } + /** + * @internal + */ + visibility = null; + /** + * @internal + */ + _timeout = 30000; + #ensureElementIsInTheViewport = true; + #waitForEnabled = true; + #waitForStableBoundingBox = true; + /** + * @internal + */ + operators = { + conditions: (conditions, signal) => { + return mergeMap((handle) => { + return merge(...conditions.map(condition => { + return condition(handle, signal); + })).pipe(defaultIfEmpty(handle)); + }); + }, + retryAndRaceWithSignalAndTimer: (signal, cause) => { + const candidates = []; + if (signal) { + candidates.push(fromEvent(signal, 'abort').pipe(map(() => { + if (signal.reason instanceof Error) { + signal.reason.cause = cause; + } + throw signal.reason; + }))); + } + candidates.push(timeout(this._timeout, cause)); + return pipe(retry({ delay: RETRY_DELAY }), raceWith(...candidates)); + }, + }; + // Determines when the locator will timeout for actions. + get timeout() { + return this._timeout; + } + setTimeout(timeout) { + const locator = this._clone(); + locator._timeout = timeout; + return locator; + } + setVisibility(visibility) { + const locator = this._clone(); + locator.visibility = visibility; + return locator; + } + setWaitForEnabled(value) { + const locator = this._clone(); + locator.#waitForEnabled = value; + return locator; + } + setEnsureElementIsInTheViewport(value) { + const locator = this._clone(); + locator.#ensureElementIsInTheViewport = value; + return locator; + } + setWaitForStableBoundingBox(value) { + const locator = this._clone(); + locator.#waitForStableBoundingBox = value; + return locator; + } + /** + * @internal + */ + copyOptions(locator) { + this._timeout = locator._timeout; + this.visibility = locator.visibility; + this.#waitForEnabled = locator.#waitForEnabled; + this.#ensureElementIsInTheViewport = locator.#ensureElementIsInTheViewport; + this.#waitForStableBoundingBox = locator.#waitForStableBoundingBox; + return this; + } + /** + * If the element has a "disabled" property, wait for the element to be + * enabled. + */ + #waitForEnabledIfNeeded = (handle, signal) => { + if (!this.#waitForEnabled) { + return EMPTY; + } + return from(handle.frame.waitForFunction(element => { + if (!(element instanceof HTMLElement)) { + return true; + } + const isNativeFormControl = [ + 'BUTTON', + 'INPUT', + 'SELECT', + 'TEXTAREA', + 'OPTION', + 'OPTGROUP', + ].includes(element.nodeName); + return !isNativeFormControl || !element.hasAttribute('disabled'); + }, { + timeout: this._timeout, + signal, + }, handle)).pipe(ignoreElements()); + }; + /** + * Compares the bounding box of the element for two consecutive animation + * frames and waits till they are the same. + */ + #waitForStableBoundingBoxIfNeeded = (handle) => { + if (!this.#waitForStableBoundingBox) { + return EMPTY; + } + return defer(() => { + // Note we don't use waitForFunction because that relies on RAF. + return from(handle.evaluate(element => { + return new Promise(resolve => { + window.requestAnimationFrame(() => { + const rect1 = element.getBoundingClientRect(); + window.requestAnimationFrame(() => { + const rect2 = element.getBoundingClientRect(); + resolve([ + { + x: rect1.x, + y: rect1.y, + width: rect1.width, + height: rect1.height, + }, + { + x: rect2.x, + y: rect2.y, + width: rect2.width, + height: rect2.height, + }, + ]); + }); + }); + }); + })); + }).pipe(first(([rect1, rect2]) => { + return (rect1.x === rect2.x && + rect1.y === rect2.y && + rect1.width === rect2.width && + rect1.height === rect2.height); + }), retry({ delay: RETRY_DELAY }), ignoreElements()); + }; + /** + * Checks if the element is in the viewport and auto-scrolls it if it is not. + */ + #ensureElementIsInTheViewportIfNeeded = (handle) => { + if (!this.#ensureElementIsInTheViewport) { + return EMPTY; + } + return from(handle.isIntersectingViewport({ threshold: 0 })).pipe(filter(isIntersectingViewport => { + return !isIntersectingViewport; + }), mergeMap(() => { + return from(handle.scrollIntoView()); + }), mergeMap(() => { + return defer(() => { + return from(handle.isIntersectingViewport({ threshold: 0 })); + }).pipe(first(identity), retry({ delay: RETRY_DELAY }), ignoreElements()); + })); + }; + #click(options) { + const signal = options?.signal; + const cause = new Error('Locator.click'); + return this._wait(options).pipe(this.operators.conditions([ + this.#ensureElementIsInTheViewportIfNeeded, + this.#waitForStableBoundingBoxIfNeeded, + this.#waitForEnabledIfNeeded, + ], signal), tap(() => { + return this.emit(LocatorEvent.Action, undefined); + }), mergeMap(handle => { + return from(handle.click(options)).pipe(catchError(err => { + void handle.dispose().catch(debugError); + throw err; + })); + }), this.operators.retryAndRaceWithSignalAndTimer(signal, cause)); + } + #fill(value, options) { + const signal = options?.signal; + const cause = new Error('Locator.fill'); + return this._wait(options).pipe(this.operators.conditions([ + this.#ensureElementIsInTheViewportIfNeeded, + this.#waitForStableBoundingBoxIfNeeded, + this.#waitForEnabledIfNeeded, + ], signal), tap(() => { + return this.emit(LocatorEvent.Action, undefined); + }), mergeMap(handle => { + return from(handle.evaluate(el => { + if (el instanceof HTMLSelectElement) { + return 'select'; + } + if (el instanceof HTMLTextAreaElement) { + return 'typeable-input'; + } + if (el instanceof HTMLInputElement) { + if (new Set([ + 'textarea', + 'text', + 'url', + 'tel', + 'search', + 'password', + 'number', + 'email', + ]).has(el.type)) { + return 'typeable-input'; + } + else { + return 'other-input'; + } + } + if (el.isContentEditable) { + return 'contenteditable'; + } + return 'unknown'; + })) + .pipe(mergeMap(inputType => { + switch (inputType) { + case 'select': + return from(handle.select(value).then(noop)); + case 'contenteditable': + case 'typeable-input': + return from(handle.evaluate((input, newValue) => { + const currentValue = input.isContentEditable + ? input.innerText + : input.value; + // Clear the input if the current value does not match the filled + // out value. + if (newValue.length <= currentValue.length || + !newValue.startsWith(input.value)) { + if (input.isContentEditable) { + input.innerText = ''; + } + else { + input.value = ''; + } + return newValue; + } + const originalValue = input.isContentEditable + ? input.innerText + : input.value; + // If the value is partially filled out, only type the rest. Move + // cursor to the end of the common prefix. + if (input.isContentEditable) { + input.innerText = ''; + input.innerText = originalValue; + } + else { + input.value = ''; + input.value = originalValue; + } + return newValue.substring(originalValue.length); + }, value)).pipe(mergeMap(textToType => { + return from(handle.type(textToType)); + })); + case 'other-input': + return from(handle.focus()).pipe(mergeMap(() => { + return from(handle.evaluate((input, value) => { + input.value = value; + input.dispatchEvent(new Event('input', { bubbles: true })); + input.dispatchEvent(new Event('change', { bubbles: true })); + }, value)); + })); + case 'unknown': + throw new Error(`Element cannot be filled out.`); + } + })) + .pipe(catchError(err => { + void handle.dispose().catch(debugError); + throw err; + })); + }), this.operators.retryAndRaceWithSignalAndTimer(signal, cause)); + } + #hover(options) { + const signal = options?.signal; + const cause = new Error('Locator.hover'); + return this._wait(options).pipe(this.operators.conditions([ + this.#ensureElementIsInTheViewportIfNeeded, + this.#waitForStableBoundingBoxIfNeeded, + ], signal), tap(() => { + return this.emit(LocatorEvent.Action, undefined); + }), mergeMap(handle => { + return from(handle.hover()).pipe(catchError(err => { + void handle.dispose().catch(debugError); + throw err; + })); + }), this.operators.retryAndRaceWithSignalAndTimer(signal, cause)); + } + #scroll(options) { + const signal = options?.signal; + const cause = new Error('Locator.scroll'); + return this._wait(options).pipe(this.operators.conditions([ + this.#ensureElementIsInTheViewportIfNeeded, + this.#waitForStableBoundingBoxIfNeeded, + ], signal), tap(() => { + return this.emit(LocatorEvent.Action, undefined); + }), mergeMap(handle => { + return from(handle.evaluate((el, scrollTop, scrollLeft) => { + if (scrollTop !== undefined) { + el.scrollTop = scrollTop; + } + if (scrollLeft !== undefined) { + el.scrollLeft = scrollLeft; + } + }, options?.scrollTop, options?.scrollLeft)).pipe(catchError(err => { + void handle.dispose().catch(debugError); + throw err; + })); + }), this.operators.retryAndRaceWithSignalAndTimer(signal, cause)); + } + /** + * Clones the locator. + */ + clone() { + return this._clone(); + } + /** + * Waits for the locator to get a handle from the page. + * + * @public + */ + async waitHandle(options) { + const cause = new Error('Locator.waitHandle'); + return await firstValueFrom(this._wait(options).pipe(this.operators.retryAndRaceWithSignalAndTimer(options?.signal, cause))); + } + /** + * Waits for the locator to get the serialized value from the page. + * + * Note this requires the value to be JSON-serializable. + * + * @public + */ + async wait(options) { + const env_1 = { stack: [], error: void 0, hasError: false }; + try { + const handle = __addDisposableResource$5(env_1, await this.waitHandle(options), false); + return await handle.jsonValue(); + } + catch (e_1) { + env_1.error = e_1; + env_1.hasError = true; + } + finally { + __disposeResources$5(env_1); + } + } + /** + * Maps the locator using the provided mapper. + * + * @public + */ + map(mapper) { + return new MappedLocator(this._clone(), handle => { + // SAFETY: TypeScript cannot deduce the type. + return handle.evaluateHandle(mapper); + }); + } + /** + * Creates an expectation that is evaluated against located values. + * + * If the expectations do not match, then the locator will retry. + * + * @public + */ + filter(predicate) { + return new FilteredLocator(this._clone(), async (handle, signal) => { + await handle.frame.waitForFunction(predicate, { signal, timeout: this._timeout }, handle); + return true; + }); + } + /** + * Creates an expectation that is evaluated against located handles. + * + * If the expectations do not match, then the locator will retry. + * + * @internal + */ + filterHandle(predicate) { + return new FilteredLocator(this._clone(), predicate); + } + /** + * Maps the locator using the provided mapper. + * + * @internal + */ + mapHandle(mapper) { + return new MappedLocator(this._clone(), mapper); + } + click(options) { + return firstValueFrom(this.#click(options)); + } + /** + * Fills out the input identified by the locator using the provided value. The + * type of the input is determined at runtime and the appropriate fill-out + * method is chosen based on the type. contenteditable, selector, inputs are + * supported. + */ + fill(value, options) { + return firstValueFrom(this.#fill(value, options)); + } + hover(options) { + return firstValueFrom(this.#hover(options)); + } + scroll(options) { + return firstValueFrom(this.#scroll(options)); + } +} +/** + * @internal + */ +class FunctionLocator extends Locator { + static create(pageOrFrame, func) { + return new FunctionLocator(pageOrFrame, func).setTimeout('getDefaultTimeout' in pageOrFrame + ? pageOrFrame.getDefaultTimeout() + : pageOrFrame.page().getDefaultTimeout()); + } + #pageOrFrame; + #func; + constructor(pageOrFrame, func) { + super(); + this.#pageOrFrame = pageOrFrame; + this.#func = func; + } + _clone() { + return new FunctionLocator(this.#pageOrFrame, this.#func); + } + _wait(options) { + const signal = options?.signal; + return defer(() => { + return from(this.#pageOrFrame.waitForFunction(this.#func, { + timeout: this.timeout, + signal, + })); + }).pipe(throwIfEmpty()); + } +} +/** + * @internal + */ +class DelegatedLocator extends Locator { + #delegate; + constructor(delegate) { + super(); + this.#delegate = delegate; + this.copyOptions(this.#delegate); + } + get delegate() { + return this.#delegate; + } + setTimeout(timeout) { + const locator = super.setTimeout(timeout); + locator.#delegate = this.#delegate.setTimeout(timeout); + return locator; + } + setVisibility(visibility) { + const locator = super.setVisibility(visibility); + locator.#delegate = locator.#delegate.setVisibility(visibility); + return locator; + } + setWaitForEnabled(value) { + const locator = super.setWaitForEnabled(value); + locator.#delegate = this.#delegate.setWaitForEnabled(value); + return locator; + } + setEnsureElementIsInTheViewport(value) { + const locator = super.setEnsureElementIsInTheViewport(value); + locator.#delegate = this.#delegate.setEnsureElementIsInTheViewport(value); + return locator; + } + setWaitForStableBoundingBox(value) { + const locator = super.setWaitForStableBoundingBox(value); + locator.#delegate = this.#delegate.setWaitForStableBoundingBox(value); + return locator; + } +} +/** + * @internal + */ +class FilteredLocator extends DelegatedLocator { + #predicate; + constructor(base, predicate) { + super(base); + this.#predicate = predicate; + } + _clone() { + return new FilteredLocator(this.delegate.clone(), this.#predicate).copyOptions(this); + } + _wait(options) { + return this.delegate._wait(options).pipe(mergeMap(handle => { + return from(Promise.resolve(this.#predicate(handle, options?.signal))).pipe(filter(value => { + return value; + }), map(() => { + // SAFETY: It passed the predicate, so this is correct. + return handle; + })); + }), throwIfEmpty()); + } +} +/** + * @internal + */ +class MappedLocator extends DelegatedLocator { + #mapper; + constructor(base, mapper) { + super(base); + this.#mapper = mapper; + } + _clone() { + return new MappedLocator(this.delegate.clone(), this.#mapper).copyOptions(this); + } + _wait(options) { + return this.delegate._wait(options).pipe(mergeMap(handle => { + return from(Promise.resolve(this.#mapper(handle, options?.signal))); + })); + } +} +/** + * @internal + */ +class NodeLocator extends Locator { + static create(pageOrFrame, selector) { + return new NodeLocator(pageOrFrame, selector).setTimeout('getDefaultTimeout' in pageOrFrame + ? pageOrFrame.getDefaultTimeout() + : pageOrFrame.page().getDefaultTimeout()); + } + #pageOrFrame; + #selector; + constructor(pageOrFrame, selector) { + super(); + this.#pageOrFrame = pageOrFrame; + this.#selector = selector; + } + /** + * Waits for the element to become visible or hidden. visibility === 'visible' + * means that the element has a computed style, the visibility property other + * than 'hidden' or 'collapse' and non-empty bounding box. visibility === + * 'hidden' means the opposite of that. + */ + #waitForVisibilityIfNeeded = (handle) => { + if (!this.visibility) { + return EMPTY; + } + return (() => { + switch (this.visibility) { + case 'hidden': + return defer(() => { + return from(handle.isHidden()); + }); + case 'visible': + return defer(() => { + return from(handle.isVisible()); + }); + } + })().pipe(first(identity), retry({ delay: RETRY_DELAY }), ignoreElements()); + }; + _clone() { + return new NodeLocator(this.#pageOrFrame, this.#selector).copyOptions(this); + } + _wait(options) { + const signal = options?.signal; + return defer(() => { + return from(this.#pageOrFrame.waitForSelector(this.#selector, { + visible: false, + timeout: this._timeout, + signal, + })); + }).pipe(filter((value) => { + return value !== null; + }), throwIfEmpty(), this.operators.conditions([this.#waitForVisibilityIfNeeded], signal)); + } +} +function checkLocatorArray(locators) { + for (const locator of locators) { + if (!(locator instanceof Locator)) { + throw new Error('Unknown locator for race candidate'); + } + } + return locators; +} +/** + * @internal + */ +class RaceLocator extends Locator { + static create(locators) { + const array = checkLocatorArray(locators); + return new RaceLocator(array); + } + #locators; + constructor(locators) { + super(); + this.#locators = locators; + } + _clone() { + return new RaceLocator(this.#locators.map(locator => { + return locator.clone(); + })).copyOptions(this); + } + _wait(options) { + return race(...this.#locators.map(locator => { + return locator._wait(options); + })); + } +} +/** + * For observables coming from promises, a delay is needed, otherwise RxJS will + * never yield in a permanent failure for a promise. + * + * We also don't want RxJS to do promise operations to often, so we bump the + * delay up to 100ms. + * + * @internal + */ +const RETRY_DELAY = 100; + +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +var __runInitializers$4 = (undefined && undefined.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; +var __esDecorate$4 = (undefined && undefined.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +var __addDisposableResource$4 = (undefined && undefined.__addDisposableResource) || function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +}; +var __disposeResources$4 = (undefined && undefined.__disposeResources) || (function (SuppressedError) { + return function (env) { + function fail(e) { + env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + return next(); + }; +})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}); +/** + * We use symbols to prevent external parties listening to these events. + * They are internal to Puppeteer. + * + * @internal + */ +// eslint-disable-next-line @typescript-eslint/no-namespace +var FrameEvent; +(function (FrameEvent) { + FrameEvent.FrameNavigated = Symbol('Frame.FrameNavigated'); + FrameEvent.FrameSwapped = Symbol('Frame.FrameSwapped'); + FrameEvent.LifecycleEvent = Symbol('Frame.LifecycleEvent'); + FrameEvent.FrameNavigatedWithinDocument = Symbol('Frame.FrameNavigatedWithinDocument'); + FrameEvent.FrameDetached = Symbol('Frame.FrameDetached'); + FrameEvent.FrameSwappedByActivation = Symbol('Frame.FrameSwappedByActivation'); +})(FrameEvent || (FrameEvent = {})); +/** + * @internal + */ +const throwIfDetached = throwIfDisposed(frame => { + return `Attempted to use detached Frame '${frame._id}'.`; +}); +/** + * Represents a DOM frame. + * + * To understand frames, you can think of frames as `