diff --git a/dist/index.js b/dist/index.js index ad2de20..2c5681a 100644 --- a/dist/index.js +++ b/dist/index.js @@ -5932,7 +5932,7 @@ async function deleteAuthorization(options) { /***/ }), -/***/ 53653: +/***/ 76034: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; @@ -10432,7 +10432,7 @@ config.VERSION = VERSION; /***/ }), -/***/ 5187: +/***/ 67180: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { module.exports = { getTransformStream }; @@ -10440,7 +10440,7 @@ module.exports = { getTransformStream }; const { Transform } = __nccwpck_require__(16754); const prettyFactory = __nccwpck_require__(34996); -const Sentry = __nccwpck_require__(99931); +const Sentry = __nccwpck_require__(72454); const LEVEL_MAP = { 10: "trace", @@ -10513,8 +10513,7 @@ function getTransformStream(options = {}) { } Sentry.withScope(function (scope) { - const sentryLevelName = - data.level === 50 ? Sentry.Severity.Error : Sentry.Severity.Fatal; + const sentryLevelName = data.level === 50 ? "error" : "fatal"; scope.setLevel(sentryLevelName); for (const extra of ["event", "headers", "request", "status"]) { @@ -10585,293 +10584,142 @@ function toSentryError(data) { /***/ }), -/***/ 86277: +/***/ 91458: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var utils_1 = __nccwpck_require__(6785); -var SENTRY_API_VERSION = '7'; -/** - * Helper class to provide urls, headers and metadata that can be used to form - * different types of requests to Sentry endpoints. - * Supports both envelopes and regular event requests. - * - * @deprecated Please use APIDetails - **/ -var API = /** @class */ (function () { - /** Create a new instance of API */ - function API(dsn, metadata, tunnel) { - if (metadata === void 0) { metadata = {}; } - this.dsn = dsn; - this._dsnObject = utils_1.makeDsn(dsn); - this.metadata = metadata; - this._tunnel = tunnel; - } - /** Returns the Dsn object. */ - API.prototype.getDsn = function () { - return this._dsnObject; - }; - /** Does this transport force envelopes? */ - API.prototype.forceEnvelope = function () { - return !!this._tunnel; - }; - /** Returns the prefix to construct Sentry ingestion API endpoints. */ - API.prototype.getBaseApiEndpoint = function () { - return getBaseApiEndpoint(this._dsnObject); - }; - /** Returns the store endpoint URL. */ - API.prototype.getStoreEndpoint = function () { - return getStoreEndpoint(this._dsnObject); - }; - /** - * Returns the store endpoint URL with auth in the query string. - * - * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests. - */ - API.prototype.getStoreEndpointWithUrlEncodedAuth = function () { - return getStoreEndpointWithUrlEncodedAuth(this._dsnObject); - }; - /** - * Returns the envelope endpoint URL with auth in the query string. - * - * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests. - */ - API.prototype.getEnvelopeEndpointWithUrlEncodedAuth = function () { - return getEnvelopeEndpointWithUrlEncodedAuth(this._dsnObject, this._tunnel); - }; - return API; -}()); -exports.API = API; -/** Initializes API Details */ -function initAPIDetails(dsn, metadata, tunnel) { - return { - initDsn: dsn, - metadata: metadata || {}, - dsn: utils_1.makeDsn(dsn), - tunnel: tunnel, - }; -} -exports.initAPIDetails = initAPIDetails; + +const utils = __nccwpck_require__(57540); + +const SENTRY_API_VERSION = '7'; + /** Returns the prefix to construct Sentry ingestion API endpoints. */ function getBaseApiEndpoint(dsn) { - var protocol = dsn.protocol ? dsn.protocol + ":" : ''; - var port = dsn.port ? ":" + dsn.port : ''; - return protocol + "//" + dsn.host + port + (dsn.path ? "/" + dsn.path : '') + "/api/"; + const protocol = dsn.protocol ? `${dsn.protocol}:` : ''; + const port = dsn.port ? `:${dsn.port}` : ''; + return `${protocol}//${dsn.host}${port}${dsn.path ? `/${dsn.path}` : ''}/api/`; } + /** Returns the ingest API endpoint for target. */ -function _getIngestEndpoint(dsn, target) { - return "" + getBaseApiEndpoint(dsn) + dsn.projectId + "/" + target + "/"; +function _getIngestEndpoint(dsn) { + return `${getBaseApiEndpoint(dsn)}${dsn.projectId}/envelope/`; } + /** Returns a URL-encoded string with auth config suitable for a query string. */ -function _encodedAuth(dsn) { - return utils_1.urlEncode({ - // We send only the minimum set of required information. See - // https://github.com/getsentry/sentry-javascript/issues/2572. - sentry_key: dsn.publicKey, - sentry_version: SENTRY_API_VERSION, - }); -} -/** Returns the store endpoint URL. */ -function getStoreEndpoint(dsn) { - return _getIngestEndpoint(dsn, 'store'); -} -/** - * Returns the store endpoint URL with auth in the query string. - * - * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests. - */ -function getStoreEndpointWithUrlEncodedAuth(dsn) { - return getStoreEndpoint(dsn) + "?" + _encodedAuth(dsn); -} -exports.getStoreEndpointWithUrlEncodedAuth = getStoreEndpointWithUrlEncodedAuth; -/** Returns the envelope endpoint URL. */ -function _getEnvelopeEndpoint(dsn) { - return _getIngestEndpoint(dsn, 'envelope'); +function _encodedAuth(dsn, sdkInfo) { + return utils.urlEncode({ + // We send only the minimum set of required information. See + // https://github.com/getsentry/sentry-javascript/issues/2572. + sentry_key: dsn.publicKey, + sentry_version: SENTRY_API_VERSION, + ...(sdkInfo && { sentry_client: `${sdkInfo.name}/${sdkInfo.version}` }), + }); } + /** * Returns the envelope endpoint URL with auth in the query string. * * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests. */ -function getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel) { - return tunnel ? tunnel : _getEnvelopeEndpoint(dsn) + "?" + _encodedAuth(dsn); -} -exports.getEnvelopeEndpointWithUrlEncodedAuth = getEnvelopeEndpointWithUrlEncodedAuth; -/** - * Returns an object that can be used in request headers. - * This is needed for node and the old /store endpoint in sentry - */ -function getRequestHeaders(dsn, clientName, clientVersion) { - // CHANGE THIS to use metadata but keep clientName and clientVersion compatible - var header = ["Sentry sentry_version=" + SENTRY_API_VERSION]; - header.push("sentry_client=" + clientName + "/" + clientVersion); - header.push("sentry_key=" + dsn.publicKey); - if (dsn.pass) { - header.push("sentry_secret=" + dsn.pass); - } - return { - 'Content-Type': 'application/json', - 'X-Sentry-Auth': header.join(', '), - }; +function getEnvelopeEndpointWithUrlEncodedAuth( + dsn, + // TODO (v8): Remove `tunnelOrOptions` in favor of `options`, and use the substitute code below + // options: ClientOptions = {} as ClientOptions, + tunnelOrOptions = {} , +) { + // TODO (v8): Use this code instead + // const { tunnel, _metadata = {} } = options; + // return tunnel ? tunnel : `${_getIngestEndpoint(dsn)}?${_encodedAuth(dsn, _metadata.sdk)}`; + + const tunnel = typeof tunnelOrOptions === 'string' ? tunnelOrOptions : tunnelOrOptions.tunnel; + const sdkInfo = + typeof tunnelOrOptions === 'string' || !tunnelOrOptions._metadata ? undefined : tunnelOrOptions._metadata.sdk; + + return tunnel ? tunnel : `${_getIngestEndpoint(dsn)}?${_encodedAuth(dsn, sdkInfo)}`; } -exports.getRequestHeaders = getRequestHeaders; + /** Returns the url to the report dialog endpoint. */ -function getReportDialogEndpoint(dsnLike, dialogOptions) { - var dsn = utils_1.makeDsn(dsnLike); - var endpoint = getBaseApiEndpoint(dsn) + "embed/error-page/"; - var encodedOptions = "dsn=" + utils_1.dsnToString(dsn); - for (var key in dialogOptions) { - if (key === 'dsn') { - continue; - } - if (key === 'user') { - if (!dialogOptions.user) { - continue; - } - if (dialogOptions.user.name) { - encodedOptions += "&name=" + encodeURIComponent(dialogOptions.user.name); - } - if (dialogOptions.user.email) { - encodedOptions += "&email=" + encodeURIComponent(dialogOptions.user.email); - } - } - else { - encodedOptions += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(dialogOptions[key]); - } +function getReportDialogEndpoint( + dsnLike, + dialogOptions + +, +) { + const dsn = utils.makeDsn(dsnLike); + if (!dsn) { + return ''; + } + + const endpoint = `${getBaseApiEndpoint(dsn)}embed/error-page/`; + + let encodedOptions = `dsn=${utils.dsnToString(dsn)}`; + for (const key in dialogOptions) { + if (key === 'dsn') { + continue; + } + + if (key === 'onClose') { + continue; + } + + if (key === 'user') { + const user = dialogOptions.user; + if (!user) { + continue; + } + if (user.name) { + encodedOptions += `&name=${encodeURIComponent(user.name)}`; + } + if (user.email) { + encodedOptions += `&email=${encodeURIComponent(user.email)}`; + } + } else { + encodedOptions += `&${encodeURIComponent(key)}=${encodeURIComponent(dialogOptions[key] )}`; } - return endpoint + "?" + encodedOptions; + } + + return `${endpoint}?${encodedOptions}`; } + +exports.getEnvelopeEndpointWithUrlEncodedAuth = getEnvelopeEndpointWithUrlEncodedAuth; exports.getReportDialogEndpoint = getReportDialogEndpoint; //# sourceMappingURL=api.js.map + /***/ }), -/***/ 18082: +/***/ 36950: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var utils_1 = __nccwpck_require__(6785); -var api_1 = __nccwpck_require__(86277); -var flags_1 = __nccwpck_require__(15314); -var request_1 = __nccwpck_require__(92688); -var noop_1 = __nccwpck_require__(74534); -/** - * This is the base implemention of a Backend. - * @hidden - */ -var BaseBackend = /** @class */ (function () { - /** Creates a new backend instance. */ - function BaseBackend(options) { - this._options = options; - if (!this._options.dsn) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn('No DSN provided, backend will not do anything.'); - } - this._transport = this._setupTransport(); - } - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types - BaseBackend.prototype.eventFromException = function (_exception, _hint) { - throw new utils_1.SentryError('Backend has to implement `eventFromException` method'); - }; - /** - * @inheritDoc - */ - BaseBackend.prototype.eventFromMessage = function (_message, _level, _hint) { - throw new utils_1.SentryError('Backend has to implement `eventFromMessage` method'); - }; - /** - * @inheritDoc - */ - BaseBackend.prototype.sendEvent = function (event) { - // TODO(v7): Remove the if-else - if (this._newTransport && - this._options.dsn && - this._options._experiments && - this._options._experiments.newTransport) { - var api = api_1.initAPIDetails(this._options.dsn, this._options._metadata, this._options.tunnel); - var env = request_1.createEventEnvelope(event, api); - void this._newTransport.send(env).then(null, function (reason) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.error('Error while sending event:', reason); - }); - } - else { - void this._transport.sendEvent(event).then(null, function (reason) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.error('Error while sending event:', reason); - }); - } - }; - /** - * @inheritDoc - */ - BaseBackend.prototype.sendSession = function (session) { - if (!this._transport.sendSession) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn("Dropping session because custom transport doesn't implement sendSession"); - return; - } - // TODO(v7): Remove the if-else - if (this._newTransport && - this._options.dsn && - this._options._experiments && - this._options._experiments.newTransport) { - var api = api_1.initAPIDetails(this._options.dsn, this._options._metadata, this._options.tunnel); - var _a = tslib_1.__read(request_1.createSessionEnvelope(session, api), 1), env = _a[0]; - void this._newTransport.send(env).then(null, function (reason) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.error('Error while sending session:', reason); - }); - } - else { - void this._transport.sendSession(session).then(null, function (reason) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.error('Error while sending session:', reason); - }); - } - }; - /** - * @inheritDoc - */ - BaseBackend.prototype.getTransport = function () { - return this._transport; - }; - /** - * Sets up the transport so it can be used later to send requests. - */ - BaseBackend.prototype._setupTransport = function () { - return new noop_1.NoopTransport(); - }; - return BaseBackend; -}()); -exports.BaseBackend = BaseBackend; -//# sourceMappingURL=basebackend.js.map -/***/ }), +const utils = __nccwpck_require__(57540); +const api = __nccwpck_require__(91458); +const debugBuild = __nccwpck_require__(93376); +const envelope = __nccwpck_require__(90820); +const exports$1 = __nccwpck_require__(74313); +const hub = __nccwpck_require__(18205); +const integration = __nccwpck_require__(11000); +const envelope$1 = __nccwpck_require__(67258); +const session = __nccwpck_require__(14638); +const dynamicSamplingContext = __nccwpck_require__(76248); +const prepareEvent = __nccwpck_require__(57847); -/***/ 40195: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured."; -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -/* eslint-disable max-lines */ -var hub_1 = __nccwpck_require__(17237); -var utils_1 = __nccwpck_require__(6785); -var flags_1 = __nccwpck_require__(15314); -var integration_1 = __nccwpck_require__(1071); -var ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured."; /** * Base implementation for all JavaScript SDK clients. * - * Call the constructor with the corresponding backend constructor and options + * Call the constructor with the corresponding options * specific to the client subclass. To access these options later, use - * {@link Client.getOptions}. Also, the Backend instance is available via - * {@link Client.getBackend}. + * {@link Client.getOptions}. * * If a Dsn is specified in the options, it will be parsed and stored. Use * {@link Client.getDsn} to retrieve the Dsn at any moment. In case the Dsn is * invalid, the constructor will throw a {@link SentryException}. Note that * without a valid Dsn, the SDK will not send any events to Sentry. * - * Before sending an event via the backend, it is passed through + * Before sending an event, it is passed through * {@link BaseClient._prepareEvent} to add SDK information and scope data * (breadcrumbs and context). To add more custom information, override this * method and extend the resulting prepared event. @@ -10882,2540 +10730,1114 @@ var ALREADY_SEEN_ERROR = "Not capturing exception because it's already been capt * {@link Client.addBreadcrumb}. * * @example - * class NodeClient extends BaseClient { + * class NodeClient extends BaseClient { * public constructor(options: NodeOptions) { - * super(NodeBackend, options); + * super(options); * } * * // ... * } */ -var BaseClient = /** @class */ (function () { - /** - * Initializes this client instance. - * - * @param backendClass A constructor function to create the backend. - * @param options Options for the client. - */ - function BaseClient(backendClass, options) { - /** Array of used integrations. */ - this._integrations = {}; - /** Number of calls being processed */ - this._numProcessing = 0; - this._backend = new backendClass(options); - this._options = options; - if (options.dsn) { - this._dsn = utils_1.makeDsn(options.dsn); - } +class BaseClient { + /** + * A reference to a metrics aggregator + * + * @experimental Note this is alpha API. It may experience breaking changes in the future. + */ + + /** Options passed to the SDK. */ + + /** The client Dsn, if specified in options. Without this Dsn, the SDK will be disabled. */ + + /** Array of set up integrations. */ + + /** Indicates whether this client's integrations have been set up. */ + + /** Number of calls being processed */ + + /** Holds flushable */ + + // eslint-disable-next-line @typescript-eslint/ban-types + + /** + * Initializes this client instance. + * + * @param options Options for the client. + */ + constructor(options) { + this._options = options; + this._integrations = {}; + this._integrationsInitialized = false; + this._numProcessing = 0; + this._outcomes = {}; + this._hooks = {}; + this._eventProcessors = []; + + if (options.dsn) { + this._dsn = utils.makeDsn(options.dsn); + } else { + debugBuild.DEBUG_BUILD && utils.logger.warn('No DSN provided, client will not send events.'); } - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types - BaseClient.prototype.captureException = function (exception, hint, scope) { - var _this = this; - // ensure we haven't captured this very object before - if (utils_1.checkOrSetAlreadyCaught(exception)) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.log(ALREADY_SEEN_ERROR); - return; - } - var eventId = hint && hint.event_id; - this._process(this._getBackend() - .eventFromException(exception, hint) - .then(function (event) { return _this._captureEvent(event, hint, scope); }) - .then(function (result) { - eventId = result; - })); - return eventId; - }; - /** - * @inheritDoc - */ - BaseClient.prototype.captureMessage = function (message, level, hint, scope) { - var _this = this; - var eventId = hint && hint.event_id; - var promisedEvent = utils_1.isPrimitive(message) - ? this._getBackend().eventFromMessage(String(message), level, hint) - : this._getBackend().eventFromException(message, hint); - this._process(promisedEvent - .then(function (event) { return _this._captureEvent(event, hint, scope); }) - .then(function (result) { - eventId = result; - })); - return eventId; - }; - /** - * @inheritDoc - */ - BaseClient.prototype.captureEvent = function (event, hint, scope) { - // ensure we haven't captured this very object before - if (hint && hint.originalException && utils_1.checkOrSetAlreadyCaught(hint.originalException)) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.log(ALREADY_SEEN_ERROR); - return; - } - var eventId = hint && hint.event_id; - this._process(this._captureEvent(event, hint, scope).then(function (result) { - eventId = result; - })); - return eventId; - }; - /** - * @inheritDoc - */ - BaseClient.prototype.captureSession = function (session) { - if (!this._isEnabled()) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn('SDK not enabled, will not capture session.'); - return; - } - if (!(typeof session.release === 'string')) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn('Discarded session because of missing or non-string release'); - } - else { - this._sendSession(session); - // After sending, we set init false to indicate it's not the first occurrence - session.update({ init: false }); - } - }; - /** - * @inheritDoc - */ - BaseClient.prototype.getDsn = function () { - return this._dsn; - }; - /** - * @inheritDoc - */ - BaseClient.prototype.getOptions = function () { - return this._options; - }; - /** - * @inheritDoc - */ - BaseClient.prototype.getTransport = function () { - return this._getBackend().getTransport(); - }; - /** - * @inheritDoc - */ - BaseClient.prototype.flush = function (timeout) { - var _this = this; - return this._isClientDoneProcessing(timeout).then(function (clientFinished) { - return _this.getTransport() - .close(timeout) - .then(function (transportFlushed) { return clientFinished && transportFlushed; }); - }); - }; - /** - * @inheritDoc - */ - BaseClient.prototype.close = function (timeout) { - var _this = this; - return this.flush(timeout).then(function (result) { - _this.getOptions().enabled = false; - return result; - }); - }; - /** - * Sets up the integrations - */ - BaseClient.prototype.setupIntegrations = function () { - if (this._isEnabled() && !this._integrations.initialized) { - this._integrations = integration_1.setupIntegrations(this._options); - } - }; - /** - * @inheritDoc - */ - BaseClient.prototype.getIntegration = function (integration) { - try { - return this._integrations[integration.id] || null; - } - catch (_oO) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn("Cannot retrieve integration " + integration.id + " from the current Client"); - return null; - } - }; - /** Updates existing session based on the provided event */ - BaseClient.prototype._updateSessionFromEvent = function (session, event) { - var e_1, _a; - var crashed = false; - var errored = false; - var exceptions = event.exception && event.exception.values; - if (exceptions) { - errored = true; - try { - for (var exceptions_1 = tslib_1.__values(exceptions), exceptions_1_1 = exceptions_1.next(); !exceptions_1_1.done; exceptions_1_1 = exceptions_1.next()) { - var ex = exceptions_1_1.value; - var mechanism = ex.mechanism; - if (mechanism && mechanism.handled === false) { - crashed = true; - break; - } - } - } - catch (e_1_1) { e_1 = { error: e_1_1 }; } - finally { - try { - if (exceptions_1_1 && !exceptions_1_1.done && (_a = exceptions_1.return)) _a.call(exceptions_1); - } - finally { if (e_1) throw e_1.error; } - } - } - // A session is updated and that session update is sent in only one of the two following scenarios: - // 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update - // 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update - var sessionNonTerminal = session.status === 'ok'; - var shouldUpdateAndSend = (sessionNonTerminal && session.errors === 0) || (sessionNonTerminal && crashed); - if (shouldUpdateAndSend) { - session.update(tslib_1.__assign(tslib_1.__assign({}, (crashed && { status: 'crashed' })), { errors: session.errors || Number(errored || crashed) })); - this.captureSession(session); - } - }; - /** Deliver captured session to Sentry */ - BaseClient.prototype._sendSession = function (session) { - this._getBackend().sendSession(session); - }; - /** - * Determine if the client is finished processing. Returns a promise because it will wait `timeout` ms before saying - * "no" (resolving to `false`) in order to give the client a chance to potentially finish first. - * - * @param timeout The time, in ms, after which to resolve to `false` if the client is still busy. Passing `0` (or not - * passing anything) will make the promise wait as long as it takes for processing to finish before resolving to - * `true`. - * @returns A promise which will resolve to `true` if processing is already done or finishes before the timeout, and - * `false` otherwise - */ - BaseClient.prototype._isClientDoneProcessing = function (timeout) { - var _this = this; - return new utils_1.SyncPromise(function (resolve) { - var ticked = 0; - var tick = 1; - var interval = setInterval(function () { - if (_this._numProcessing == 0) { - clearInterval(interval); - resolve(true); - } - else { - ticked += tick; - if (timeout && ticked >= timeout) { - clearInterval(interval); - resolve(false); - } - } - }, tick); - }); - }; - /** Returns the current backend. */ - BaseClient.prototype._getBackend = function () { - return this._backend; - }; - /** Determines whether this SDK is enabled and a valid Dsn is present. */ - BaseClient.prototype._isEnabled = function () { - return this.getOptions().enabled !== false && this._dsn !== undefined; - }; - /** - * Adds common information to events. - * - * The information includes release and environment from `options`, - * breadcrumbs and context (extra, tags and user) from the scope. - * - * Information that is already present in the event is never overwritten. For - * nested objects, such as the context, keys are merged. - * - * @param event The original event. - * @param hint May contain additional information about the original exception. - * @param scope A scope containing event metadata. - * @returns A new event with more information. - */ - BaseClient.prototype._prepareEvent = function (event, scope, hint) { - var _this = this; - var _a = this.getOptions(), _b = _a.normalizeDepth, normalizeDepth = _b === void 0 ? 3 : _b, _c = _a.normalizeMaxBreadth, normalizeMaxBreadth = _c === void 0 ? 1000 : _c; - var prepared = tslib_1.__assign(tslib_1.__assign({}, event), { event_id: event.event_id || (hint && hint.event_id ? hint.event_id : utils_1.uuid4()), timestamp: event.timestamp || utils_1.dateTimestampInSeconds() }); - this._applyClientOptions(prepared); - this._applyIntegrationsMetadata(prepared); - // If we have scope given to us, use it as the base for further modifications. - // This allows us to prevent unnecessary copying of data if `captureContext` is not provided. - var finalScope = scope; - if (hint && hint.captureContext) { - finalScope = hub_1.Scope.clone(finalScope).update(hint.captureContext); - } - // We prepare the result here with a resolved Event. - var result = utils_1.resolvedSyncPromise(prepared); - // This should be the last thing called, since we want that - // {@link Hub.addEventProcessor} gets the finished prepared event. - if (finalScope) { - // In case we have a hub we reassign it. - result = finalScope.applyToEvent(prepared, hint); - } - return result.then(function (evt) { - if (evt) { - // TODO this is more of the hack trying to solve https://github.com/getsentry/sentry-javascript/issues/2809 - // it is only attached as extra data to the event if the event somehow skips being normalized - evt.sdkProcessingMetadata = tslib_1.__assign(tslib_1.__assign({}, evt.sdkProcessingMetadata), { normalizeDepth: utils_1.normalize(normalizeDepth) + " (" + typeof normalizeDepth + ")" }); - } - if (typeof normalizeDepth === 'number' && normalizeDepth > 0) { - return _this._normalizeEvent(evt, normalizeDepth, normalizeMaxBreadth); - } - return evt; - }); - }; - /** - * Applies `normalize` function on necessary `Event` attributes to make them safe for serialization. - * Normalized keys: - * - `breadcrumbs.data` - * - `user` - * - `contexts` - * - `extra` - * @param event Event - * @returns Normalized event - */ - BaseClient.prototype._normalizeEvent = function (event, depth, maxBreadth) { - if (!event) { - return null; - } - var normalized = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, event), (event.breadcrumbs && { - breadcrumbs: event.breadcrumbs.map(function (b) { return (tslib_1.__assign(tslib_1.__assign({}, b), (b.data && { - data: utils_1.normalize(b.data, depth, maxBreadth), - }))); }), - })), (event.user && { - user: utils_1.normalize(event.user, depth, maxBreadth), - })), (event.contexts && { - contexts: utils_1.normalize(event.contexts, depth, maxBreadth), - })), (event.extra && { - extra: utils_1.normalize(event.extra, depth, maxBreadth), - })); - // event.contexts.trace stores information about a Transaction. Similarly, - // event.spans[] stores information about child Spans. Given that a - // Transaction is conceptually a Span, normalization should apply to both - // Transactions and Spans consistently. - // For now the decision is to skip normalization of Transactions and Spans, - // so this block overwrites the normalized event to add back the original - // Transaction information prior to normalization. - if (event.contexts && event.contexts.trace) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - normalized.contexts.trace = event.contexts.trace; - } - normalized.sdkProcessingMetadata = tslib_1.__assign(tslib_1.__assign({}, normalized.sdkProcessingMetadata), { baseClientNormalized: true }); - return normalized; - }; - /** - * Enhances event using the client configuration. - * It takes care of all "static" values like environment, release and `dist`, - * as well as truncating overly long values. - * @param event event instance to be enhanced - */ - BaseClient.prototype._applyClientOptions = function (event) { - var options = this.getOptions(); - var environment = options.environment, release = options.release, dist = options.dist, _a = options.maxValueLength, maxValueLength = _a === void 0 ? 250 : _a; - if (!('environment' in event)) { - event.environment = 'environment' in options ? environment : 'production'; - } - if (event.release === undefined && release !== undefined) { - event.release = release; - } - if (event.dist === undefined && dist !== undefined) { - event.dist = dist; - } - if (event.message) { - event.message = utils_1.truncate(event.message, maxValueLength); - } - var exception = event.exception && event.exception.values && event.exception.values[0]; - if (exception && exception.value) { - exception.value = utils_1.truncate(exception.value, maxValueLength); - } - var request = event.request; - if (request && request.url) { - request.url = utils_1.truncate(request.url, maxValueLength); - } - }; - /** - * This function adds all used integrations to the SDK info in the event. - * @param event The event that will be filled with all integrations. - */ - BaseClient.prototype._applyIntegrationsMetadata = function (event) { - var integrationsArray = Object.keys(this._integrations); - if (integrationsArray.length > 0) { - event.sdk = event.sdk || {}; - event.sdk.integrations = tslib_1.__spread((event.sdk.integrations || []), integrationsArray); - } - }; - /** - * Tells the backend to send this event - * @param event The Sentry event to send - */ - BaseClient.prototype._sendEvent = function (event) { - this._getBackend().sendEvent(event); - }; - /** - * Processes the event and logs an error in case of rejection - * @param event - * @param hint - * @param scope - */ - BaseClient.prototype._captureEvent = function (event, hint, scope) { - return this._processEvent(event, hint, scope).then(function (finalEvent) { - return finalEvent.event_id; - }, function (reason) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.error(reason); - return undefined; - }); - }; - /** - * Processes an event (either error or message) and sends it to Sentry. - * - * This also adds breadcrumbs and context information to the event. However, - * platform specific meta data (such as the User's IP address) must be added - * by the SDK implementor. - * - * - * @param event The event to send to Sentry. - * @param hint May contain additional information about the original exception. - * @param scope A scope containing event metadata. - * @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send. - */ - BaseClient.prototype._processEvent = function (event, hint, scope) { - var _this = this; - // eslint-disable-next-line @typescript-eslint/unbound-method - var _a = this.getOptions(), beforeSend = _a.beforeSend, sampleRate = _a.sampleRate; - var transport = this.getTransport(); - function recordLostEvent(outcome, category) { - if (transport.recordLostEvent) { - transport.recordLostEvent(outcome, category); - } - } - if (!this._isEnabled()) { - return utils_1.rejectedSyncPromise(new utils_1.SentryError('SDK not enabled, will not capture event.')); - } - var isTransaction = event.type === 'transaction'; - // 1.0 === 100% events are sent - // 0.0 === 0% events are sent - // Sampling for transaction happens somewhere else - if (!isTransaction && typeof sampleRate === 'number' && Math.random() > sampleRate) { - recordLostEvent('sample_rate', 'event'); - return utils_1.rejectedSyncPromise(new utils_1.SentryError("Discarding event because it's not included in the random sample (sampling rate = " + sampleRate + ")")); - } - return this._prepareEvent(event, scope, hint) - .then(function (prepared) { - if (prepared === null) { - recordLostEvent('event_processor', event.type || 'event'); - throw new utils_1.SentryError('An event processor returned null, will not send event.'); - } - var isInternalException = hint && hint.data && hint.data.__sentry__ === true; - if (isInternalException || isTransaction || !beforeSend) { - return prepared; - } - var beforeSendResult = beforeSend(prepared, hint); - return _ensureBeforeSendRv(beforeSendResult); - }) - .then(function (processedEvent) { - if (processedEvent === null) { - recordLostEvent('before_send', event.type || 'event'); - throw new utils_1.SentryError('`beforeSend` returned `null`, will not send event.'); - } - var session = scope && scope.getSession && scope.getSession(); - if (!isTransaction && session) { - _this._updateSessionFromEvent(session, processedEvent); - } - _this._sendEvent(processedEvent); - return processedEvent; - }) - .then(null, function (reason) { - if (reason instanceof utils_1.SentryError) { - throw reason; - } - _this.captureException(reason, { - data: { - __sentry__: true, - }, - originalException: reason, - }); - throw new utils_1.SentryError("Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\nReason: " + reason); - }); - }; - /** - * Occupies the client with processing and event - */ - BaseClient.prototype._process = function (promise) { - var _this = this; - this._numProcessing += 1; - void promise.then(function (value) { - _this._numProcessing -= 1; - return value; - }, function (reason) { - _this._numProcessing -= 1; - return reason; - }); - }; - return BaseClient; -}()); -exports.BaseClient = BaseClient; -/** - * Verifies that return value of configured `beforeSend` is of expected type. - */ -function _ensureBeforeSendRv(rv) { - var nullErr = '`beforeSend` method has to return `null` or a valid event.'; - if (utils_1.isThenable(rv)) { - return rv.then(function (event) { - if (!(utils_1.isPlainObject(event) || event === null)) { - throw new utils_1.SentryError(nullErr); - } - return event; - }, function (e) { - throw new utils_1.SentryError("beforeSend rejected with " + e); - }); + + if (this._dsn) { + const url = api.getEnvelopeEndpointWithUrlEncodedAuth(this._dsn, options); + this._transport = options.transport({ + tunnel: this._options.tunnel, + recordDroppedEvent: this.recordDroppedEvent.bind(this), + ...options.transportOptions, + url, + }); } - else if (!(utils_1.isPlainObject(rv) || rv === null)) { - throw new utils_1.SentryError(nullErr); + } + + /** + * @inheritDoc + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types + captureException(exception, hint, scope) { + // ensure we haven't captured this very object before + if (utils.checkOrSetAlreadyCaught(exception)) { + debugBuild.DEBUG_BUILD && utils.logger.log(ALREADY_SEEN_ERROR); + return; } - return rv; -} -//# sourceMappingURL=baseclient.js.map -/***/ }), + let eventId = hint && hint.event_id; -/***/ 15314: -/***/ ((__unused_webpack_module, exports) => { + this._process( + this.eventFromException(exception, hint) + .then(event => this._captureEvent(event, hint, scope)) + .then(result => { + eventId = result; + }), + ); -/* - * This file defines flags and constants that can be modified during compile time in order to facilitate tree shaking - * for users. - * - * Debug flags need to be declared in each package individually and must not be imported across package boundaries, - * because some build tools have trouble tree-shaking imported guards. - * - * As a convention, we define debug flags in a `flags.ts` file in the root of a package's `src` folder. - * - * Debug flag files will contain "magic strings" like `__SENTRY_DEBUG__` that may get replaced with actual values during - * our, or the user's build process. Take care when introducing new flags - they must not throw if they are not - * replaced. - */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -/** Flag that is true for debug builds, false otherwise. */ -exports.IS_DEBUG_BUILD = typeof __SENTRY_DEBUG__ === 'undefined' ? true : __SENTRY_DEBUG__; -//# sourceMappingURL=flags.js.map + return eventId; + } -/***/ }), + /** + * @inheritDoc + */ + captureMessage( + message, + // eslint-disable-next-line deprecation/deprecation + level, + hint, + scope, + ) { + let eventId = hint && hint.event_id; -/***/ 41429: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + const eventMessage = utils.isParameterizedString(message) ? message : String(message); -Object.defineProperty(exports, "__esModule", ({ value: true })); -var minimal_1 = __nccwpck_require__(85509); -exports.addBreadcrumb = minimal_1.addBreadcrumb; -exports.captureException = minimal_1.captureException; -exports.captureEvent = minimal_1.captureEvent; -exports.captureMessage = minimal_1.captureMessage; -exports.configureScope = minimal_1.configureScope; -exports.startTransaction = minimal_1.startTransaction; -exports.setContext = minimal_1.setContext; -exports.setExtra = minimal_1.setExtra; -exports.setExtras = minimal_1.setExtras; -exports.setTag = minimal_1.setTag; -exports.setTags = minimal_1.setTags; -exports.setUser = minimal_1.setUser; -exports.withScope = minimal_1.withScope; -var hub_1 = __nccwpck_require__(17237); -exports.addGlobalEventProcessor = hub_1.addGlobalEventProcessor; -exports.getCurrentHub = hub_1.getCurrentHub; -exports.getHubFromCarrier = hub_1.getHubFromCarrier; -exports.Hub = hub_1.Hub; -exports.makeMain = hub_1.makeMain; -exports.Scope = hub_1.Scope; -exports.Session = hub_1.Session; -var api_1 = __nccwpck_require__(86277); -// eslint-disable-next-line deprecation/deprecation -exports.API = api_1.API; -exports.getEnvelopeEndpointWithUrlEncodedAuth = api_1.getEnvelopeEndpointWithUrlEncodedAuth; -exports.getStoreEndpointWithUrlEncodedAuth = api_1.getStoreEndpointWithUrlEncodedAuth; -exports.getRequestHeaders = api_1.getRequestHeaders; -exports.initAPIDetails = api_1.initAPIDetails; -exports.getReportDialogEndpoint = api_1.getReportDialogEndpoint; -var baseclient_1 = __nccwpck_require__(40195); -exports.BaseClient = baseclient_1.BaseClient; -var basebackend_1 = __nccwpck_require__(18082); -exports.BaseBackend = basebackend_1.BaseBackend; -var request_1 = __nccwpck_require__(92688); -exports.eventToSentryRequest = request_1.eventToSentryRequest; -exports.sessionToSentryRequest = request_1.sessionToSentryRequest; -var sdk_1 = __nccwpck_require__(82817); -exports.initAndBind = sdk_1.initAndBind; -var noop_1 = __nccwpck_require__(74534); -exports.NoopTransport = noop_1.NoopTransport; -var base_1 = __nccwpck_require__(62575); -exports.createTransport = base_1.createTransport; -var version_1 = __nccwpck_require__(3693); -exports.SDK_VERSION = version_1.SDK_VERSION; -var Integrations = __nccwpck_require__(82633); -exports.Integrations = Integrations; -//# sourceMappingURL=index.js.map + const promisedEvent = utils.isPrimitive(message) + ? this.eventFromMessage(eventMessage, level, hint) + : this.eventFromException(message, hint); -/***/ }), + this._process( + promisedEvent + .then(event => this._captureEvent(event, hint, scope)) + .then(result => { + eventId = result; + }), + ); -/***/ 1071: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + return eventId; + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var hub_1 = __nccwpck_require__(17237); -var utils_1 = __nccwpck_require__(6785); -var flags_1 = __nccwpck_require__(15314); -exports.installedIntegrations = []; -/** - * @private - */ -function filterDuplicates(integrations) { - return integrations.reduce(function (acc, integrations) { - if (acc.every(function (accIntegration) { return integrations.name !== accIntegration.name; })) { - acc.push(integrations); - } - return acc; - }, []); -} -/** Gets integration to install */ -function getIntegrationsToSetup(options) { - var defaultIntegrations = (options.defaultIntegrations && tslib_1.__spread(options.defaultIntegrations)) || []; - var userIntegrations = options.integrations; - var integrations = tslib_1.__spread(filterDuplicates(defaultIntegrations)); - if (Array.isArray(userIntegrations)) { - // Filter out integrations that are also included in user options - integrations = tslib_1.__spread(integrations.filter(function (integrations) { - return userIntegrations.every(function (userIntegration) { return userIntegration.name !== integrations.name; }); - }), filterDuplicates(userIntegrations)); - } - else if (typeof userIntegrations === 'function') { - integrations = userIntegrations(integrations); - integrations = Array.isArray(integrations) ? integrations : [integrations]; - } - // Make sure that if present, `Debug` integration will always run last - var integrationsNames = integrations.map(function (i) { return i.name; }); - var alwaysLastToRun = 'Debug'; - if (integrationsNames.indexOf(alwaysLastToRun) !== -1) { - integrations.push.apply(integrations, tslib_1.__spread(integrations.splice(integrationsNames.indexOf(alwaysLastToRun), 1))); - } - return integrations; -} -exports.getIntegrationsToSetup = getIntegrationsToSetup; -/** Setup given integration */ -function setupIntegration(integration) { - if (exports.installedIntegrations.indexOf(integration.name) !== -1) { - return; + /** + * @inheritDoc + */ + captureEvent(event, hint, scope) { + // ensure we haven't captured this very object before + if (hint && hint.originalException && utils.checkOrSetAlreadyCaught(hint.originalException)) { + debugBuild.DEBUG_BUILD && utils.logger.log(ALREADY_SEEN_ERROR); + return; } - integration.setupOnce(hub_1.addGlobalEventProcessor, hub_1.getCurrentHub); - exports.installedIntegrations.push(integration.name); - flags_1.IS_DEBUG_BUILD && utils_1.logger.log("Integration installed: " + integration.name); -} -exports.setupIntegration = setupIntegration; -/** - * Given a list of integration instances this installs them all. When `withDefaults` is set to `true` then all default - * integrations are added unless they were already provided before. - * @param integrations array of integration instances - * @param withDefault should enable default integrations - */ -function setupIntegrations(options) { - var integrations = {}; - getIntegrationsToSetup(options).forEach(function (integration) { - integrations[integration.name] = integration; - setupIntegration(integration); - }); - // set the `initialized` flag so we don't run through the process again unecessarily; use `Object.defineProperty` - // because by default it creates a property which is nonenumerable, which we want since `initialized` shouldn't be - // considered a member of the index the way the actual integrations are - utils_1.addNonEnumerableProperty(integrations, 'initialized', true); - return integrations; -} -exports.setupIntegrations = setupIntegrations; -//# sourceMappingURL=integration.js.map -/***/ }), + let eventId = hint && hint.event_id; -/***/ 9801: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + const sdkProcessingMetadata = event.sdkProcessingMetadata || {}; + const capturedSpanScope = sdkProcessingMetadata.capturedSpanScope; -Object.defineProperty(exports, "__esModule", ({ value: true })); -var utils_1 = __nccwpck_require__(6785); -var originalFunctionToString; -/** Patch toString calls to return proper name for wrapped functions */ -var FunctionToString = /** @class */ (function () { - function FunctionToString() { - /** - * @inheritDoc - */ - this.name = FunctionToString.id; + this._process( + this._captureEvent(event, hint, capturedSpanScope || scope).then(result => { + eventId = result; + }), + ); + + return eventId; + } + + /** + * @inheritDoc + */ + captureSession(session$1) { + if (!(typeof session$1.release === 'string')) { + debugBuild.DEBUG_BUILD && utils.logger.warn('Discarded session because of missing or non-string release'); + } else { + this.sendSession(session$1); + // After sending, we set init false to indicate it's not the first occurrence + session.updateSession(session$1, { init: false }); } - /** - * @inheritDoc - */ - FunctionToString.prototype.setupOnce = function () { - // eslint-disable-next-line @typescript-eslint/unbound-method - originalFunctionToString = Function.prototype.toString; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - Function.prototype.toString = function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var context = utils_1.getOriginalFunction(this) || this; - return originalFunctionToString.apply(context, args); - }; - }; - /** - * @inheritDoc - */ - FunctionToString.id = 'FunctionToString'; - return FunctionToString; -}()); -exports.FunctionToString = FunctionToString; -//# sourceMappingURL=functiontostring.js.map + } -/***/ }), + /** + * @inheritDoc + */ + getDsn() { + return this._dsn; + } -/***/ 71405: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + /** + * @inheritDoc + */ + getOptions() { + return this._options; + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var utils_1 = __nccwpck_require__(6785); -var flags_1 = __nccwpck_require__(15314); -// "Script error." is hard coded into browsers for errors that it can't read. -// this is the result of a script being pulled in from an external domain and CORS. -var DEFAULT_IGNORE_ERRORS = [/^Script error\.?$/, /^Javascript error: Script error\.? on line 0$/]; -/** Inbound filters configurable by the user */ -var InboundFilters = /** @class */ (function () { - function InboundFilters(_options) { - if (_options === void 0) { _options = {}; } - this._options = _options; - /** - * @inheritDoc - */ - this.name = InboundFilters.id; - } - /** - * @inheritDoc - */ - InboundFilters.prototype.setupOnce = function (addGlobalEventProcessor, getCurrentHub) { - addGlobalEventProcessor(function (event) { - var hub = getCurrentHub(); - if (hub) { - var self_1 = hub.getIntegration(InboundFilters); - if (self_1) { - var client = hub.getClient(); - var clientOptions = client ? client.getOptions() : {}; - var options = _mergeOptions(self_1._options, clientOptions); - return _shouldDropEvent(event, options) ? null : event; - } - } - return event; - }); - }; - /** - * @inheritDoc - */ - InboundFilters.id = 'InboundFilters'; - return InboundFilters; -}()); -exports.InboundFilters = InboundFilters; -/** JSDoc */ -function _mergeOptions(internalOptions, clientOptions) { - if (internalOptions === void 0) { internalOptions = {}; } - if (clientOptions === void 0) { clientOptions = {}; } - return { - allowUrls: tslib_1.__spread((internalOptions.whitelistUrls || []), (internalOptions.allowUrls || []), (clientOptions.whitelistUrls || []), (clientOptions.allowUrls || [])), - denyUrls: tslib_1.__spread((internalOptions.blacklistUrls || []), (internalOptions.denyUrls || []), (clientOptions.blacklistUrls || []), (clientOptions.denyUrls || [])), - ignoreErrors: tslib_1.__spread((internalOptions.ignoreErrors || []), (clientOptions.ignoreErrors || []), DEFAULT_IGNORE_ERRORS), - ignoreInternal: internalOptions.ignoreInternal !== undefined ? internalOptions.ignoreInternal : true, - }; -} -exports._mergeOptions = _mergeOptions; -/** JSDoc */ -function _shouldDropEvent(event, options) { - if (options.ignoreInternal && _isSentryError(event)) { - flags_1.IS_DEBUG_BUILD && - utils_1.logger.warn("Event dropped due to being internal Sentry Error.\nEvent: " + utils_1.getEventDescription(event)); - return true; - } - if (_isIgnoredError(event, options.ignoreErrors)) { - flags_1.IS_DEBUG_BUILD && - utils_1.logger.warn("Event dropped due to being matched by `ignoreErrors` option.\nEvent: " + utils_1.getEventDescription(event)); - return true; - } - if (_isDeniedUrl(event, options.denyUrls)) { - flags_1.IS_DEBUG_BUILD && - utils_1.logger.warn("Event dropped due to being matched by `denyUrls` option.\nEvent: " + utils_1.getEventDescription(event) + ".\nUrl: " + _getEventFilterUrl(event)); - return true; - } - if (!_isAllowedUrl(event, options.allowUrls)) { - flags_1.IS_DEBUG_BUILD && - utils_1.logger.warn("Event dropped due to not being matched by `allowUrls` option.\nEvent: " + utils_1.getEventDescription(event) + ".\nUrl: " + _getEventFilterUrl(event)); - return true; - } - return false; -} -exports._shouldDropEvent = _shouldDropEvent; -function _isIgnoredError(event, ignoreErrors) { - if (!ignoreErrors || !ignoreErrors.length) { - return false; + /** + * @see SdkMetadata in @sentry/types + * + * @return The metadata of the SDK + */ + getSdkMetadata() { + return this._options._metadata; + } + + /** + * @inheritDoc + */ + getTransport() { + return this._transport; + } + + /** + * @inheritDoc + */ + flush(timeout) { + const transport = this._transport; + if (transport) { + if (this.metricsAggregator) { + this.metricsAggregator.flush(); + } + return this._isClientDoneProcessing(timeout).then(clientFinished => { + return transport.flush(timeout).then(transportFlushed => clientFinished && transportFlushed); + }); + } else { + return utils.resolvedSyncPromise(true); } - return _getPossibleEventMessages(event).some(function (message) { - return ignoreErrors.some(function (pattern) { return utils_1.isMatchingPattern(message, pattern); }); + } + + /** + * @inheritDoc + */ + close(timeout) { + return this.flush(timeout).then(result => { + this.getOptions().enabled = false; + if (this.metricsAggregator) { + this.metricsAggregator.close(); + } + return result; }); -} -function _isDeniedUrl(event, denyUrls) { - // TODO: Use Glob instead? - if (!denyUrls || !denyUrls.length) { - return false; - } - var url = _getEventFilterUrl(event); - return !url ? false : denyUrls.some(function (pattern) { return utils_1.isMatchingPattern(url, pattern); }); -} -function _isAllowedUrl(event, allowUrls) { - // TODO: Use Glob instead? - if (!allowUrls || !allowUrls.length) { - return true; - } - var url = _getEventFilterUrl(event); - return !url ? true : allowUrls.some(function (pattern) { return utils_1.isMatchingPattern(url, pattern); }); -} -function _getPossibleEventMessages(event) { - if (event.message) { - return [event.message]; - } - if (event.exception) { - try { - var _a = (event.exception.values && event.exception.values[0]) || {}, _b = _a.type, type = _b === void 0 ? '' : _b, _c = _a.value, value = _c === void 0 ? '' : _c; - return ["" + value, type + ": " + value]; - } - catch (oO) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.error("Cannot extract message for event " + utils_1.getEventDescription(event)); - return []; - } - } - return []; -} -function _isSentryError(event) { - try { - // @ts-ignore can't be a sentry error if undefined - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - return event.exception.values[0].type === 'SentryError'; - } - catch (e) { - // ignore + } + + /** Get all installed event processors. */ + getEventProcessors() { + return this._eventProcessors; + } + + /** @inheritDoc */ + addEventProcessor(eventProcessor) { + this._eventProcessors.push(eventProcessor); + } + + /** + * This is an internal function to setup all integrations that should run on the client. + * @deprecated Use `client.init()` instead. + */ + setupIntegrations(forceInitialize) { + if ((forceInitialize && !this._integrationsInitialized) || (this._isEnabled() && !this._integrationsInitialized)) { + this._setupIntegrations(); } - return false; -} -function _getLastValidUrl(frames) { - if (frames === void 0) { frames = []; } - for (var i = frames.length - 1; i >= 0; i--) { - var frame = frames[i]; - if (frame && frame.filename !== '' && frame.filename !== '[native code]') { - return frame.filename || null; - } + } + + /** @inheritdoc */ + init() { + if (this._isEnabled()) { + this._setupIntegrations(); } - return null; -} -function _getEventFilterUrl(event) { + } + + /** + * Gets an installed integration by its `id`. + * + * @returns The installed integration or `undefined` if no integration with that `id` was installed. + * @deprecated Use `getIntegrationByName()` instead. + */ + getIntegrationById(integrationId) { + return this.getIntegrationByName(integrationId); + } + + /** + * Gets an installed integration by its name. + * + * @returns The installed integration or `undefined` if no integration with that `name` was installed. + */ + getIntegrationByName(integrationName) { + return this._integrations[integrationName] ; + } + + /** + * Returns the client's instance of the given integration class, it any. + * @deprecated Use `getIntegrationByName()` instead. + */ + getIntegration(integration) { try { - if (event.stacktrace) { - return _getLastValidUrl(event.stacktrace.frames); - } - var frames_1; - try { - // @ts-ignore we only care about frames if the whole thing here is defined - frames_1 = event.exception.values[0].stacktrace.frames; - } - catch (e) { - // ignore - } - return frames_1 ? _getLastValidUrl(frames_1) : null; - } - catch (oO) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.error("Cannot extract url for event " + utils_1.getEventDescription(event)); - return null; + return (this._integrations[integration.id] ) || null; + } catch (_oO) { + debugBuild.DEBUG_BUILD && utils.logger.warn(`Cannot retrieve integration ${integration.id} from the current Client`); + return null; } -} -//# sourceMappingURL=inboundfilters.js.map + } -/***/ }), + /** + * @inheritDoc + */ + addIntegration(integration$1) { + const isAlreadyInstalled = this._integrations[integration$1.name]; -/***/ 82633: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + // This hook takes care of only installing if not already installed + integration.setupIntegration(this, integration$1, this._integrations); + // Here we need to check manually to make sure to not run this multiple times + if (!isAlreadyInstalled) { + integration.afterSetupIntegrations(this, [integration$1]); + } + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var functiontostring_1 = __nccwpck_require__(9801); -exports.FunctionToString = functiontostring_1.FunctionToString; -var inboundfilters_1 = __nccwpck_require__(71405); -exports.InboundFilters = inboundfilters_1.InboundFilters; -//# sourceMappingURL=index.js.map + /** + * @inheritDoc + */ + sendEvent(event, hint = {}) { + this.emit('beforeSendEvent', event, hint); -/***/ }), + let env = envelope.createEventEnvelope(event, this._dsn, this._options._metadata, this._options.tunnel); -/***/ 92688: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + for (const attachment of hint.attachments || []) { + env = utils.addItemToEnvelope( + env, + utils.createAttachmentEnvelopeItem( + attachment, + this._options.transportOptions && this._options.transportOptions.textEncoder, + ), + ); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var utils_1 = __nccwpck_require__(6785); -var api_1 = __nccwpck_require__(86277); -/** Extract sdk info from from the API metadata */ -function getSdkMetadataForEnvelopeHeader(api) { - if (!api.metadata || !api.metadata.sdk) { - return; - } - var _a = api.metadata.sdk, name = _a.name, version = _a.version; - return { name: name, version: version }; -} -/** - * Apply SdkInfo (name, version, packages, integrations) to the corresponding event key. - * Merge with existing data if any. - **/ -function enhanceEventWithSdkInfo(event, sdkInfo) { - if (!sdkInfo) { - return event; - } - event.sdk = event.sdk || {}; - event.sdk.name = event.sdk.name || sdkInfo.name; - event.sdk.version = event.sdk.version || sdkInfo.version; - event.sdk.integrations = tslib_1.__spread((event.sdk.integrations || []), (sdkInfo.integrations || [])); - event.sdk.packages = tslib_1.__spread((event.sdk.packages || []), (sdkInfo.packages || [])); - return event; -} -/** Creates an envelope from a Session */ -function createSessionEnvelope(session, api) { - var sdkInfo = getSdkMetadataForEnvelopeHeader(api); - var envelopeHeaders = tslib_1.__assign(tslib_1.__assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: utils_1.dsnToString(api.dsn) })); - // I know this is hacky but we don't want to add `sessions` to request type since it's never rate limited - var type = 'aggregates' in session ? 'sessions' : 'session'; - // TODO (v7) Have to cast type because envelope items do not accept a `SentryRequestType` - var envelopeItem = [{ type: type }, session]; - var envelope = utils_1.createEnvelope(envelopeHeaders, [envelopeItem]); - return [envelope, type]; -} -exports.createSessionEnvelope = createSessionEnvelope; -/** Creates a SentryRequest from a Session. */ -function sessionToSentryRequest(session, api) { - var _a = tslib_1.__read(createSessionEnvelope(session, api), 2), envelope = _a[0], type = _a[1]; - return { - body: utils_1.serializeEnvelope(envelope), - type: type, - url: api_1.getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel), - }; -} -exports.sessionToSentryRequest = sessionToSentryRequest; -/** - * Create an Envelope from an event. Note that this is duplicated from below, - * but on purpose as this will be refactored in v7. - */ -function createEventEnvelope(event, api) { - var sdkInfo = getSdkMetadataForEnvelopeHeader(api); - var eventType = event.type || 'event'; - var transactionSampling = (event.sdkProcessingMetadata || {}).transactionSampling; - var _a = transactionSampling || {}, samplingMethod = _a.method, sampleRate = _a.rate; - // TODO: Below is a temporary hack in order to debug a serialization error - see - // https://github.com/getsentry/sentry-javascript/issues/2809, - // https://github.com/getsentry/sentry-javascript/pull/4425, and - // https://github.com/getsentry/sentry-javascript/pull/4574. - // - // TL; DR: even though we normalize all events (which should prevent this), something is causing `JSON.stringify` to - // throw a circular reference error. - // - // When it's time to remove it: - // 1. Delete everything between here and where the request object `req` is created, EXCEPT the line deleting - // `sdkProcessingMetadata` - // 2. Restore the original version of the request body, which is commented out - // 3. Search for either of the PR URLs above and pull out the companion hacks in the browser playwright tests and the - // baseClient tests in this package - enhanceEventWithSdkInfo(event, api.metadata.sdk); - event.tags = event.tags || {}; - event.extra = event.extra || {}; - // In theory, all events should be marked as having gone through normalization and so - // we should never set this tag/extra data - if (!(event.sdkProcessingMetadata && event.sdkProcessingMetadata.baseClientNormalized)) { - event.tags.skippedNormalization = true; - event.extra.normalizeDepth = event.sdkProcessingMetadata ? event.sdkProcessingMetadata.normalizeDepth : 'unset'; - } - // prevent this data from being sent to sentry - // TODO: This is NOT part of the hack - DO NOT DELETE - delete event.sdkProcessingMetadata; - var envelopeHeaders = tslib_1.__assign(tslib_1.__assign({ event_id: event.event_id, sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: utils_1.dsnToString(api.dsn) })); - var eventItem = [ - { - type: eventType, - sample_rates: [{ id: samplingMethod, rate: sampleRate }], - }, - event, - ]; - return utils_1.createEnvelope(envelopeHeaders, [eventItem]); -} -exports.createEventEnvelope = createEventEnvelope; -/** Creates a SentryRequest from an event. */ -function eventToSentryRequest(event, api) { - var sdkInfo = getSdkMetadataForEnvelopeHeader(api); - var eventType = event.type || 'event'; - var useEnvelope = eventType === 'transaction' || !!api.tunnel; - var transactionSampling = (event.sdkProcessingMetadata || {}).transactionSampling; - var _a = transactionSampling || {}, samplingMethod = _a.method, sampleRate = _a.rate; - // TODO: Below is a temporary hack in order to debug a serialization error - see - // https://github.com/getsentry/sentry-javascript/issues/2809, - // https://github.com/getsentry/sentry-javascript/pull/4425, and - // https://github.com/getsentry/sentry-javascript/pull/4574. - // - // TL; DR: even though we normalize all events (which should prevent this), something is causing `JSON.stringify` to - // throw a circular reference error. - // - // When it's time to remove it: - // 1. Delete everything between here and where the request object `req` is created, EXCEPT the line deleting - // `sdkProcessingMetadata` - // 2. Restore the original version of the request body, which is commented out - // 3. Search for either of the PR URLs above and pull out the companion hacks in the browser playwright tests and the - // baseClient tests in this package - enhanceEventWithSdkInfo(event, api.metadata.sdk); - event.tags = event.tags || {}; - event.extra = event.extra || {}; - // In theory, all events should be marked as having gone through normalization and so - // we should never set this tag/extra data - if (!(event.sdkProcessingMetadata && event.sdkProcessingMetadata.baseClientNormalized)) { - event.tags.skippedNormalization = true; - event.extra.normalizeDepth = event.sdkProcessingMetadata ? event.sdkProcessingMetadata.normalizeDepth : 'unset'; - } - // prevent this data from being sent to sentry - // TODO: This is NOT part of the hack - DO NOT DELETE - delete event.sdkProcessingMetadata; - var body; - try { - // 99.9% of events should get through just fine - no change in behavior for them - body = JSON.stringify(event); + const promise = this._sendEnvelope(env); + if (promise) { + promise.then(sendResponse => this.emit('afterSendEvent', event, sendResponse), null); } - catch (err) { - // Record data about the error without replacing original event data, then force renormalization - event.tags.JSONStringifyError = true; - event.extra.JSONStringifyError = err; - try { - body = JSON.stringify(utils_1.normalize(event)); - } - catch (newErr) { - // At this point even renormalization hasn't worked, meaning something about the event data has gone very wrong. - // Time to cut our losses and record only the new error. With luck, even in the problematic cases we're trying to - // debug with this hack, we won't ever land here. - var innerErr = newErr; - body = JSON.stringify({ - message: 'JSON.stringify error after renormalization', - // setting `extra: { innerErr }` here for some reason results in an empty object, so unpack manually - extra: { message: innerErr.message, stack: innerErr.stack }, - }); - } - } - var req = { - // this is the relevant line of code before the hack was added, to make it easy to undo said hack once we've solved - // the mystery - // body: JSON.stringify(sdkInfo ? enhanceEventWithSdkInfo(event, api.metadata.sdk) : event), - body: body, - type: eventType, - url: useEnvelope - ? api_1.getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel) - : api_1.getStoreEndpointWithUrlEncodedAuth(api.dsn), - }; - // https://develop.sentry.dev/sdk/envelopes/ - // Since we don't need to manipulate envelopes nor store them, there is no - // exported concept of an Envelope with operations including serialization and - // deserialization. Instead, we only implement a minimal subset of the spec to - // serialize events inline here. - if (useEnvelope) { - var envelopeHeaders = tslib_1.__assign(tslib_1.__assign({ event_id: event.event_id, sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (!!api.tunnel && { dsn: utils_1.dsnToString(api.dsn) })); - var eventItem = [ - { - type: eventType, - sample_rates: [{ id: samplingMethod, rate: sampleRate }], - }, - req.body, - ]; - var envelope = utils_1.createEnvelope(envelopeHeaders, [eventItem]); - req.body = utils_1.serializeEnvelope(envelope); + } + + /** + * @inheritDoc + */ + sendSession(session) { + const env = envelope.createSessionEnvelope(session, this._dsn, this._options._metadata, this._options.tunnel); + + // _sendEnvelope should not throw + // eslint-disable-next-line @typescript-eslint/no-floating-promises + this._sendEnvelope(env); + } + + /** + * @inheritDoc + */ + recordDroppedEvent(reason, category, eventOrCount) { + if (this._options.sendClientReports) { + // TODO v9: We do not need the `event` passed as third argument anymore, and can possibly remove this overload + // If event is passed as third argument, we assume this is a count of 1 + const count = typeof eventOrCount === 'number' ? eventOrCount : 1; + + // We want to track each category (error, transaction, session, replay_event) separately + // but still keep the distinction between different type of outcomes. + // We could use nested maps, but it's much easier to read and type this way. + // A correct type for map-based implementation if we want to go that route + // would be `Partial>>>` + // With typescript 4.1 we could even use template literal types + const key = `${reason}:${category}`; + debugBuild.DEBUG_BUILD && utils.logger.log(`Recording outcome: "${key}"${count > 1 ? ` (${count} times)` : ''}`); + this._outcomes[key] = (this._outcomes[key] || 0) + count; } - return req; -} -exports.eventToSentryRequest = eventToSentryRequest; -//# sourceMappingURL=request.js.map + } -/***/ }), + /** + * @inheritDoc + */ + captureAggregateMetrics(metricBucketItems) { + debugBuild.DEBUG_BUILD && utils.logger.log(`Flushing aggregated metrics, number of metrics: ${metricBucketItems.length}`); + const metricsEnvelope = envelope$1.createMetricEnvelope( + metricBucketItems, + this._dsn, + this._options._metadata, + this._options.tunnel, + ); -/***/ 82817: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + // _sendEnvelope should not throw + // eslint-disable-next-line @typescript-eslint/no-floating-promises + this._sendEnvelope(metricsEnvelope); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var hub_1 = __nccwpck_require__(17237); -var utils_1 = __nccwpck_require__(6785); -var flags_1 = __nccwpck_require__(15314); -/** - * Internal function to create a new SDK client instance. The client is - * installed and then bound to the current scope. - * - * @param clientClass The client class to instantiate. - * @param options Options to pass to the client. - */ -function initAndBind(clientClass, options) { - if (options.debug === true) { - if (flags_1.IS_DEBUG_BUILD) { - utils_1.logger.enable(); - } - else { - // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped - // eslint-disable-next-line no-console - console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.'); - } + // Keep on() & emit() signatures in sync with types' client.ts interface + /* eslint-disable @typescript-eslint/unified-signatures */ + + /** @inheritdoc */ + + /** @inheritdoc */ + on(hook, callback) { + if (!this._hooks[hook]) { + this._hooks[hook] = []; } - var hub = hub_1.getCurrentHub(); - var scope = hub.getScope(); - if (scope) { - scope.update(options.initialScope); + + // @ts-expect-error We assue the types are correct + this._hooks[hook].push(callback); + } + + /** @inheritdoc */ + + /** @inheritdoc */ + emit(hook, ...rest) { + if (this._hooks[hook]) { + this._hooks[hook].forEach(callback => callback(...rest)); } - var client = new clientClass(options); - hub.bindClient(client); -} -exports.initAndBind = initAndBind; -//# sourceMappingURL=sdk.js.map + } -/***/ }), + /* eslint-enable @typescript-eslint/unified-signatures */ -/***/ 62575: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + /** Setup integrations for this client. */ + _setupIntegrations() { + const { integrations } = this._options; + this._integrations = integration.setupIntegrations(this, integrations); + integration.afterSetupIntegrations(this, integrations); -Object.defineProperty(exports, "__esModule", ({ value: true })); -var utils_1 = __nccwpck_require__(6785); -exports.ERROR_TRANSPORT_CATEGORY = 'error'; -exports.TRANSACTION_TRANSPORT_CATEGORY = 'transaction'; -exports.ATTACHMENT_TRANSPORT_CATEGORY = 'attachment'; -exports.SESSION_TRANSPORT_CATEGORY = 'session'; -exports.DEFAULT_TRANSPORT_BUFFER_SIZE = 30; -/** - * Creates a `NewTransport` - * - * @param options - * @param makeRequest - */ -function createTransport(options, makeRequest, buffer) { - if (buffer === void 0) { buffer = utils_1.makePromiseBuffer(options.bufferSize || exports.DEFAULT_TRANSPORT_BUFFER_SIZE); } - var rateLimits = {}; - var flush = function (timeout) { return buffer.drain(timeout); }; - function send(envelope) { - var envCategory = utils_1.getEnvelopeType(envelope); - var category = envCategory === 'event' ? 'error' : envCategory; - var request = { - category: category, - body: utils_1.serializeEnvelope(envelope), - }; - // Don't add to buffer if transport is already rate-limited - if (utils_1.isRateLimited(rateLimits, category)) { - return utils_1.rejectedSyncPromise({ - status: 'rate_limit', - reason: getRateLimitReason(rateLimits, category), - }); + // TODO v8: We don't need this flag anymore + this._integrationsInitialized = true; + } + + /** Updates existing session based on the provided event */ + _updateSessionFromEvent(session$1, event) { + let crashed = false; + let errored = false; + const exceptions = event.exception && event.exception.values; + + if (exceptions) { + errored = true; + + for (const ex of exceptions) { + const mechanism = ex.mechanism; + if (mechanism && mechanism.handled === false) { + crashed = true; + break; } - var requestTask = function () { - return makeRequest(request).then(function (_a) { - var body = _a.body, headers = _a.headers, reason = _a.reason, statusCode = _a.statusCode; - var status = utils_1.eventStatusFromHttpCode(statusCode); - if (headers) { - rateLimits = utils_1.updateRateLimits(rateLimits, headers); - } - if (status === 'success') { - return utils_1.resolvedSyncPromise({ status: status, reason: reason }); - } - return utils_1.rejectedSyncPromise({ - status: status, - reason: reason || - body || - (status === 'rate_limit' ? getRateLimitReason(rateLimits, category) : 'Unknown transport error'), - }); - }); - }; - return buffer.add(requestTask); + } } - return { - send: send, - flush: flush, - }; -} -exports.createTransport = createTransport; -function getRateLimitReason(rateLimits, category) { - return "Too many " + category + " requests, backing off until: " + new Date(utils_1.disabledUntil(rateLimits, category)).toISOString(); -} -//# sourceMappingURL=base.js.map - -/***/ }), -/***/ 74534: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + // A session is updated and that session update is sent in only one of the two following scenarios: + // 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update + // 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update + const sessionNonTerminal = session$1.status === 'ok'; + const shouldUpdateAndSend = (sessionNonTerminal && session$1.errors === 0) || (sessionNonTerminal && crashed); -Object.defineProperty(exports, "__esModule", ({ value: true })); -var utils_1 = __nccwpck_require__(6785); -/** Noop transport */ -var NoopTransport = /** @class */ (function () { - function NoopTransport() { + if (shouldUpdateAndSend) { + session.updateSession(session$1, { + ...(crashed && { status: 'crashed' }), + errors: session$1.errors || Number(errored || crashed), + }); + this.captureSession(session$1); } - /** - * @inheritDoc - */ - NoopTransport.prototype.sendEvent = function (_) { - return utils_1.resolvedSyncPromise({ - reason: 'NoopTransport: Event has been skipped because no Dsn is configured.', - status: 'skipped', - }); - }; - /** - * @inheritDoc - */ - NoopTransport.prototype.close = function (_) { - return utils_1.resolvedSyncPromise(true); - }; - return NoopTransport; -}()); -exports.NoopTransport = NoopTransport; -//# sourceMappingURL=noop.js.map + } -/***/ }), + /** + * Determine if the client is finished processing. Returns a promise because it will wait `timeout` ms before saying + * "no" (resolving to `false`) in order to give the client a chance to potentially finish first. + * + * @param timeout The time, in ms, after which to resolve to `false` if the client is still busy. Passing `0` (or not + * passing anything) will make the promise wait as long as it takes for processing to finish before resolving to + * `true`. + * @returns A promise which will resolve to `true` if processing is already done or finishes before the timeout, and + * `false` otherwise + */ + _isClientDoneProcessing(timeout) { + return new utils.SyncPromise(resolve => { + let ticked = 0; + const tick = 1; + + const interval = setInterval(() => { + if (this._numProcessing == 0) { + clearInterval(interval); + resolve(true); + } else { + ticked += tick; + if (timeout && ticked >= timeout) { + clearInterval(interval); + resolve(false); + } + } + }, tick); + }); + } -/***/ 3693: -/***/ ((__unused_webpack_module, exports) => { + /** Determines whether this SDK is enabled and a transport is present. */ + _isEnabled() { + return this.getOptions().enabled !== false && this._transport !== undefined; + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.SDK_VERSION = '6.19.7'; -//# sourceMappingURL=version.js.map + /** + * Adds common information to events. + * + * The information includes release and environment from `options`, + * breadcrumbs and context (extra, tags and user) from the scope. + * + * Information that is already present in the event is never overwritten. For + * nested objects, such as the context, keys are merged. + * + * @param event The original event. + * @param hint May contain additional information about the original exception. + * @param scope A scope containing event metadata. + * @returns A new event with more information. + */ + _prepareEvent( + event, + hint, + scope, + isolationScope = hub.getIsolationScope(), + ) { + const options = this.getOptions(); + const integrations = Object.keys(this._integrations); + if (!hint.integrations && integrations.length > 0) { + hint.integrations = integrations; + } -/***/ }), + this.emit('preprocessEvent', event, hint); -/***/ 66482: -/***/ ((__unused_webpack_module, exports) => { + return prepareEvent.prepareEvent(options, event, hint, scope, this, isolationScope).then(evt => { + if (evt === null) { + return evt; + } -/* - * This file defines flags and constants that can be modified during compile time in order to facilitate tree shaking - * for users. - * - * Debug flags need to be declared in each package individually and must not be imported across package boundaries, - * because some build tools have trouble tree-shaking imported guards. - * - * As a convention, we define debug flags in a `flags.ts` file in the root of a package's `src` folder. - * - * Debug flag files will contain "magic strings" like `__SENTRY_DEBUG__` that may get replaced with actual values during - * our, or the user's build process. Take care when introducing new flags - they must not throw if they are not - * replaced. - */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -/** Flag that is true for debug builds, false otherwise. */ -exports.IS_DEBUG_BUILD = typeof __SENTRY_DEBUG__ === 'undefined' ? true : __SENTRY_DEBUG__; -//# sourceMappingURL=flags.js.map + const propagationContext = { + ...isolationScope.getPropagationContext(), + ...(scope ? scope.getPropagationContext() : undefined), + }; -/***/ }), + const trace = evt.contexts && evt.contexts.trace; + if (!trace && propagationContext) { + const { traceId: trace_id, spanId, parentSpanId, dsc } = propagationContext; + evt.contexts = { + trace: { + trace_id, + span_id: spanId, + parent_span_id: parentSpanId, + }, + ...evt.contexts, + }; -/***/ 18070: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + const dynamicSamplingContext$1 = dsc ? dsc : dynamicSamplingContext.getDynamicSamplingContextFromClient(trace_id, this, scope); -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var utils_1 = __nccwpck_require__(6785); -var flags_1 = __nccwpck_require__(66482); -var scope_1 = __nccwpck_require__(69077); -var session_1 = __nccwpck_require__(90949); -/** - * API compatibility version of this hub. - * - * WARNING: This number should only be increased when the global interface - * changes and new methods are introduced. - * - * @hidden - */ -exports.API_VERSION = 4; -/** - * Default maximum number of breadcrumbs added to an event. Can be overwritten - * with {@link Options.maxBreadcrumbs}. - */ -var DEFAULT_BREADCRUMBS = 100; -/** - * @inheritDoc - */ -var Hub = /** @class */ (function () { - /** - * Creates a new instance of the hub, will push one {@link Layer} into the - * internal stack on creation. - * - * @param client bound to the hub. - * @param scope bound to the hub. - * @param version number, higher number means higher priority. - */ - function Hub(client, scope, _version) { - if (scope === void 0) { scope = new scope_1.Scope(); } - if (_version === void 0) { _version = exports.API_VERSION; } - this._version = _version; - /** Is a {@link Layer}[] containing the client and scope */ - this._stack = [{}]; - this.getStackTop().scope = scope; - if (client) { - this.bindClient(client); + evt.sdkProcessingMetadata = { + dynamicSamplingContext: dynamicSamplingContext$1, + ...evt.sdkProcessingMetadata, + }; + } + return evt; + }); + } + + /** + * Processes the event and logs an error in case of rejection + * @param event + * @param hint + * @param scope + */ + _captureEvent(event, hint = {}, scope) { + return this._processEvent(event, hint, scope).then( + finalEvent => { + return finalEvent.event_id; + }, + reason => { + if (debugBuild.DEBUG_BUILD) { + // If something's gone wrong, log the error as a warning. If it's just us having used a `SentryError` for + // control flow, log just the message (no stack) as a log-level log. + const sentryError = reason ; + if (sentryError.logLevel === 'log') { + utils.logger.log(sentryError.message); + } else { + utils.logger.warn(sentryError); + } } + return undefined; + }, + ); + } + + /** + * Processes an event (either error or message) and sends it to Sentry. + * + * This also adds breadcrumbs and context information to the event. However, + * platform specific meta data (such as the User's IP address) must be added + * by the SDK implementor. + * + * + * @param event The event to send to Sentry. + * @param hint May contain additional information about the original exception. + * @param scope A scope containing event metadata. + * @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send. + */ + _processEvent(event, hint, scope) { + const options = this.getOptions(); + const { sampleRate } = options; + + const isTransaction = isTransactionEvent(event); + const isError = isErrorEvent(event); + const eventType = event.type || 'error'; + const beforeSendLabel = `before send for type \`${eventType}\``; + + // 1.0 === 100% events are sent + // 0.0 === 0% events are sent + // Sampling for transaction happens somewhere else + if (isError && typeof sampleRate === 'number' && Math.random() > sampleRate) { + this.recordDroppedEvent('sample_rate', 'error', event); + return utils.rejectedSyncPromise( + new utils.SentryError( + `Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`, + 'log', + ), + ); } - /** - * @inheritDoc - */ - Hub.prototype.isOlderThan = function (version) { - return this._version < version; - }; - /** - * @inheritDoc - */ - Hub.prototype.bindClient = function (client) { - var top = this.getStackTop(); - top.client = client; - if (client && client.setupIntegrations) { - client.setupIntegrations(); - } - }; - /** - * @inheritDoc - */ - Hub.prototype.pushScope = function () { - // We want to clone the content of prev scope - var scope = scope_1.Scope.clone(this.getScope()); - this.getStack().push({ - client: this.getClient(), - scope: scope, - }); - return scope; - }; - /** - * @inheritDoc - */ - Hub.prototype.popScope = function () { - if (this.getStack().length <= 1) - return false; - return !!this.getStack().pop(); - }; - /** - * @inheritDoc - */ - Hub.prototype.withScope = function (callback) { - var scope = this.pushScope(); - try { - callback(scope); - } - finally { - this.popScope(); - } - }; - /** - * @inheritDoc - */ - Hub.prototype.getClient = function () { - return this.getStackTop().client; - }; - /** Returns the scope of the top stack. */ - Hub.prototype.getScope = function () { - return this.getStackTop().scope; - }; - /** Returns the scope stack for domains or the process. */ - Hub.prototype.getStack = function () { - return this._stack; - }; - /** Returns the topmost scope layer in the order domain > local > process. */ - Hub.prototype.getStackTop = function () { - return this._stack[this._stack.length - 1]; - }; - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types - Hub.prototype.captureException = function (exception, hint) { - var eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : utils_1.uuid4()); - var finalHint = hint; - // If there's no explicit hint provided, mimic the same thing that would happen - // in the minimal itself to create a consistent behavior. - // We don't do this in the client, as it's the lowest level API, and doing this, - // would prevent user from having full control over direct calls. - if (!hint) { - var syntheticException = void 0; - try { - throw new Error('Sentry syntheticException'); - } - catch (exception) { - syntheticException = exception; - } - finalHint = { - originalException: exception, - syntheticException: syntheticException, - }; - } - this._invokeClient('captureException', exception, tslib_1.__assign(tslib_1.__assign({}, finalHint), { event_id: eventId })); - return eventId; - }; - /** - * @inheritDoc - */ - Hub.prototype.captureMessage = function (message, level, hint) { - var eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : utils_1.uuid4()); - var finalHint = hint; - // If there's no explicit hint provided, mimic the same thing that would happen - // in the minimal itself to create a consistent behavior. - // We don't do this in the client, as it's the lowest level API, and doing this, - // would prevent user from having full control over direct calls. - if (!hint) { - var syntheticException = void 0; - try { - throw new Error(message); - } - catch (exception) { - syntheticException = exception; - } - finalHint = { - originalException: message, - syntheticException: syntheticException, - }; - } - this._invokeClient('captureMessage', message, level, tslib_1.__assign(tslib_1.__assign({}, finalHint), { event_id: eventId })); - return eventId; - }; - /** - * @inheritDoc - */ - Hub.prototype.captureEvent = function (event, hint) { - var eventId = hint && hint.event_id ? hint.event_id : utils_1.uuid4(); - if (event.type !== 'transaction') { - this._lastEventId = eventId; - } - this._invokeClient('captureEvent', event, tslib_1.__assign(tslib_1.__assign({}, hint), { event_id: eventId })); - return eventId; - }; - /** - * @inheritDoc - */ - Hub.prototype.lastEventId = function () { - return this._lastEventId; - }; - /** - * @inheritDoc - */ - Hub.prototype.addBreadcrumb = function (breadcrumb, hint) { - var _a = this.getStackTop(), scope = _a.scope, client = _a.client; - if (!scope || !client) - return; - // eslint-disable-next-line @typescript-eslint/unbound-method - var _b = (client.getOptions && client.getOptions()) || {}, _c = _b.beforeBreadcrumb, beforeBreadcrumb = _c === void 0 ? null : _c, _d = _b.maxBreadcrumbs, maxBreadcrumbs = _d === void 0 ? DEFAULT_BREADCRUMBS : _d; - if (maxBreadcrumbs <= 0) - return; - var timestamp = utils_1.dateTimestampInSeconds(); - var mergedBreadcrumb = tslib_1.__assign({ timestamp: timestamp }, breadcrumb); - var finalBreadcrumb = beforeBreadcrumb - ? utils_1.consoleSandbox(function () { return beforeBreadcrumb(mergedBreadcrumb, hint); }) - : mergedBreadcrumb; - if (finalBreadcrumb === null) - return; - scope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs); - }; - /** - * @inheritDoc - */ - Hub.prototype.setUser = function (user) { - var scope = this.getScope(); - if (scope) - scope.setUser(user); - }; - /** - * @inheritDoc - */ - Hub.prototype.setTags = function (tags) { - var scope = this.getScope(); - if (scope) - scope.setTags(tags); - }; - /** - * @inheritDoc - */ - Hub.prototype.setExtras = function (extras) { - var scope = this.getScope(); - if (scope) - scope.setExtras(extras); - }; - /** - * @inheritDoc - */ - Hub.prototype.setTag = function (key, value) { - var scope = this.getScope(); - if (scope) - scope.setTag(key, value); - }; - /** - * @inheritDoc - */ - Hub.prototype.setExtra = function (key, extra) { - var scope = this.getScope(); - if (scope) - scope.setExtra(key, extra); - }; - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - Hub.prototype.setContext = function (name, context) { - var scope = this.getScope(); - if (scope) - scope.setContext(name, context); - }; - /** - * @inheritDoc - */ - Hub.prototype.configureScope = function (callback) { - var _a = this.getStackTop(), scope = _a.scope, client = _a.client; - if (scope && client) { - callback(scope); - } - }; - /** - * @inheritDoc - */ - Hub.prototype.run = function (callback) { - var oldHub = makeMain(this); - try { - callback(this); - } - finally { - makeMain(oldHub); - } - }; - /** - * @inheritDoc - */ - Hub.prototype.getIntegration = function (integration) { - var client = this.getClient(); - if (!client) - return null; - try { - return client.getIntegration(integration); - } - catch (_oO) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn("Cannot retrieve integration " + integration.id + " from the current Hub"); - return null; - } - }; - /** - * @inheritDoc - */ - Hub.prototype.startSpan = function (context) { - return this._callExtensionMethod('startSpan', context); - }; - /** - * @inheritDoc - */ - Hub.prototype.startTransaction = function (context, customSamplingContext) { - return this._callExtensionMethod('startTransaction', context, customSamplingContext); - }; - /** - * @inheritDoc - */ - Hub.prototype.traceHeaders = function () { - return this._callExtensionMethod('traceHeaders'); - }; - /** - * @inheritDoc - */ - Hub.prototype.captureSession = function (endSession) { - if (endSession === void 0) { endSession = false; } - // both send the update and pull the session from the scope - if (endSession) { - return this.endSession(); - } - // only send the update - this._sendSessionUpdate(); - }; - /** - * @inheritDoc - */ - Hub.prototype.endSession = function () { - var layer = this.getStackTop(); - var scope = layer && layer.scope; - var session = scope && scope.getSession(); - if (session) { - session.close(); - } - this._sendSessionUpdate(); - // the session is over; take it off of the scope - if (scope) { - scope.setSession(); + + const dataCategory = eventType === 'replay_event' ? 'replay' : eventType; + + const sdkProcessingMetadata = event.sdkProcessingMetadata || {}; + const capturedSpanIsolationScope = sdkProcessingMetadata.capturedSpanIsolationScope; + + return this._prepareEvent(event, hint, scope, capturedSpanIsolationScope) + .then(prepared => { + if (prepared === null) { + this.recordDroppedEvent('event_processor', dataCategory, event); + throw new utils.SentryError('An event processor returned `null`, will not send event.', 'log'); } - }; - /** - * @inheritDoc - */ - Hub.prototype.startSession = function (context) { - var _a = this.getStackTop(), scope = _a.scope, client = _a.client; - var _b = (client && client.getOptions()) || {}, release = _b.release, environment = _b.environment; - // Will fetch userAgent if called from browser sdk - var global = utils_1.getGlobalObject(); - var userAgent = (global.navigator || {}).userAgent; - var session = new session_1.Session(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ release: release, - environment: environment }, (scope && { user: scope.getUser() })), (userAgent && { userAgent: userAgent })), context)); - if (scope) { - // End existing session if there's one - var currentSession = scope.getSession && scope.getSession(); - if (currentSession && currentSession.status === 'ok') { - currentSession.update({ status: 'exited' }); - } - this.endSession(); - // Afterwards we set the new session on the scope - scope.setSession(session); + + const isInternalException = hint.data && (hint.data ).__sentry__ === true; + if (isInternalException) { + return prepared; } - return session; - }; - /** - * Sends the current Session on the scope - */ - Hub.prototype._sendSessionUpdate = function () { - var _a = this.getStackTop(), scope = _a.scope, client = _a.client; - if (!scope) - return; - var session = scope.getSession && scope.getSession(); - if (session) { - if (client && client.captureSession) { - client.captureSession(session); - } + + const result = processBeforeSend(options, prepared, hint); + return _validateBeforeSendResult(result, beforeSendLabel); + }) + .then(processedEvent => { + if (processedEvent === null) { + this.recordDroppedEvent('before_send', dataCategory, event); + if (isTransaction) { + const spans = event.spans || []; + // the transaction itself counts as one span, plus all the child spans that are added + const spanCount = 1 + spans.length; + this.recordDroppedEvent('before_send', 'span', spanCount); + } + throw new utils.SentryError(`${beforeSendLabel} returned \`null\`, will not send event.`, 'log'); } - }; - /** - * Internal helper function to call a method on the top client if it exists. - * - * @param method The method to call on the client. - * @param args Arguments to pass to the client function. - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - Hub.prototype._invokeClient = function (method) { - var _a; - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; + + const session = scope && scope.getSession(); + if (!isTransaction && session) { + this._updateSessionFromEvent(session, processedEvent); } - var _b = this.getStackTop(), scope = _b.scope, client = _b.client; - if (client && client[method]) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - (_a = client)[method].apply(_a, tslib_1.__spread(args, [scope])); + + if (isTransaction) { + const spanCountBefore = + (processedEvent.sdkProcessingMetadata && processedEvent.sdkProcessingMetadata.spanCountBeforeProcessing) || + 0; + const spanCountAfter = processedEvent.spans ? processedEvent.spans.length : 0; + + const droppedSpanCount = spanCountBefore - spanCountAfter; + if (droppedSpanCount > 0) { + this.recordDroppedEvent('before_send', 'span', droppedSpanCount); + } } - }; - /** - * Calls global extension method and binding current instance to the function call - */ - // @ts-ignore Function lacks ending return statement and return type does not include 'undefined'. ts(2366) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - Hub.prototype._callExtensionMethod = function (method) { - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; + + // None of the Sentry built event processor will update transaction name, + // so if the transaction name has been changed by an event processor, we know + // it has to come from custom event processor added by a user + const transactionInfo = processedEvent.transaction_info; + if (isTransaction && transactionInfo && processedEvent.transaction !== event.transaction) { + const source = 'custom'; + processedEvent.transaction_info = { + ...transactionInfo, + source, + }; } - var carrier = getMainCarrier(); - var sentry = carrier.__SENTRY__; - if (sentry && sentry.extensions && typeof sentry.extensions[method] === 'function') { - return sentry.extensions[method].apply(this, args); + + this.sendEvent(processedEvent, hint); + return processedEvent; + }) + .then(null, reason => { + if (reason instanceof utils.SentryError) { + throw reason; } - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn("Extension method " + method + " couldn't be found, doing nothing."); - }; - return Hub; -}()); -exports.Hub = Hub; -/** - * Returns the global shim registry. - * - * FIXME: This function is problematic, because despite always returning a valid Carrier, - * it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check - * at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there. - **/ -function getMainCarrier() { - var carrier = utils_1.getGlobalObject(); - carrier.__SENTRY__ = carrier.__SENTRY__ || { - extensions: {}, - hub: undefined, - }; - return carrier; + + this.captureException(reason, { + data: { + __sentry__: true, + }, + originalException: reason, + }); + throw new utils.SentryError( + `Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\nReason: ${reason}`, + ); + }); + } + + /** + * Occupies the client with processing and event + */ + _process(promise) { + this._numProcessing++; + void promise.then( + value => { + this._numProcessing--; + return value; + }, + reason => { + this._numProcessing--; + return reason; + }, + ); + } + + /** + * @inheritdoc + */ + _sendEnvelope(envelope) { + this.emit('beforeEnvelope', envelope); + + if (this._isEnabled() && this._transport) { + return this._transport.send(envelope).then(null, reason => { + debugBuild.DEBUG_BUILD && utils.logger.error('Error while sending event:', reason); + }); + } else { + debugBuild.DEBUG_BUILD && utils.logger.error('Transport disabled'); + } + } + + /** + * Clears outcomes on this client and returns them. + */ + _clearOutcomes() { + const outcomes = this._outcomes; + this._outcomes = {}; + return Object.keys(outcomes).map(key => { + const [reason, category] = key.split(':') ; + return { + reason, + category, + quantity: outcomes[key], + }; + }); + } + + /** + * @inheritDoc + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types + } -exports.getMainCarrier = getMainCarrier; + /** - * Replaces the current main hub with the passed one on the global object - * - * @returns The old replaced hub + * Verifies that return value of configured `beforeSend` or `beforeSendTransaction` is of expected type, and returns the value if so. */ -function makeMain(hub) { - var registry = getMainCarrier(); - var oldHub = getHubFromCarrier(registry); - setHubOnCarrier(registry, hub); - return oldHub; +function _validateBeforeSendResult( + beforeSendResult, + beforeSendLabel, +) { + const invalidValueError = `${beforeSendLabel} must return \`null\` or a valid event.`; + if (utils.isThenable(beforeSendResult)) { + return beforeSendResult.then( + event => { + if (!utils.isPlainObject(event) && event !== null) { + throw new utils.SentryError(invalidValueError); + } + return event; + }, + e => { + throw new utils.SentryError(`${beforeSendLabel} rejected with ${e}`); + }, + ); + } else if (!utils.isPlainObject(beforeSendResult) && beforeSendResult !== null) { + throw new utils.SentryError(invalidValueError); + } + return beforeSendResult; } -exports.makeMain = makeMain; + /** - * Returns the default hub instance. - * - * If a hub is already registered in the global carrier but this module - * contains a more recent version, it replaces the registered version. - * Otherwise, the currently registered hub will be returned. + * Process the matching `beforeSendXXX` callback. */ -function getCurrentHub() { - // Get main carrier (global for every environment) - var registry = getMainCarrier(); - // If there's no hub, or its an old API, assign a new one - if (!hasHubOnCarrier(registry) || getHubFromCarrier(registry).isOlderThan(exports.API_VERSION)) { - setHubOnCarrier(registry, new Hub()); - } - // Prefer domains over global if they are there (applicable only to Node environment) - if (utils_1.isNodeEnv()) { - return getHubFromActiveDomain(registry); +function processBeforeSend( + options, + event, + hint, +) { + const { beforeSend, beforeSendTransaction } = options; + + if (isErrorEvent(event) && beforeSend) { + return beforeSend(event, hint); + } + + if (isTransactionEvent(event) && beforeSendTransaction) { + if (event.spans) { + // We store the # of spans before processing in SDK metadata, + // so we can compare it afterwards to determine how many spans were dropped + const spanCountBefore = event.spans.length; + event.sdkProcessingMetadata = { + ...event.sdkProcessingMetadata, + spanCountBeforeProcessing: spanCountBefore, + }; } - // Return hub that lives on a global object - return getHubFromCarrier(registry); + return beforeSendTransaction(event, hint); + } + + return event; } -exports.getCurrentHub = getCurrentHub; -/** - * Returns the active domain, if one exists - * @deprecated No longer used; remove in v7 - * @returns The domain, or undefined if there is no active domain - */ -// eslint-disable-next-line deprecation/deprecation -function getActiveDomain() { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn('Function `getActiveDomain` is deprecated and will be removed in a future version.'); - var sentry = getMainCarrier().__SENTRY__; - return sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active; + +function isErrorEvent(event) { + return event.type === undefined; } -exports.getActiveDomain = getActiveDomain; -/** - * Try to read the hub from an active domain, and fallback to the registry if one doesn't exist - * @returns discovered hub - */ -function getHubFromActiveDomain(registry) { - try { - var sentry = getMainCarrier().__SENTRY__; - var activeDomain = sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active; - // If there's no active domain, just return global hub - if (!activeDomain) { - return getHubFromCarrier(registry); - } - // If there's no hub on current domain, or it's an old API, assign a new one - if (!hasHubOnCarrier(activeDomain) || getHubFromCarrier(activeDomain).isOlderThan(exports.API_VERSION)) { - var registryHubTopStack = getHubFromCarrier(registry).getStackTop(); - setHubOnCarrier(activeDomain, new Hub(registryHubTopStack.client, scope_1.Scope.clone(registryHubTopStack.scope))); - } - // Return hub that lives on a domain - return getHubFromCarrier(activeDomain); - } - catch (_Oo) { - // Return hub that lives on a global object - return getHubFromCarrier(registry); - } + +function isTransactionEvent(event) { + return event.type === 'transaction'; } + /** - * This will tell whether a carrier has a hub on it or not - * @param carrier object + * Add an event processor to the current client. + * This event processor will run for all events processed by this client. */ -function hasHubOnCarrier(carrier) { - return !!(carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub); +function addEventProcessor(callback) { + const client = exports$1.getClient(); + + if (!client || !client.addEventProcessor) { + return; + } + + client.addEventProcessor(callback); } + +exports.BaseClient = BaseClient; +exports.addEventProcessor = addEventProcessor; +//# sourceMappingURL=baseclient.js.map + + +/***/ }), + +/***/ 31265: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); + /** - * This will create a new {@link Hub} and add to the passed object on - * __SENTRY__.hub. - * @param carrier object - * @hidden + * Create envelope from check in item. */ -function getHubFromCarrier(carrier) { - return utils_1.getGlobalSingleton('hub', function () { return new Hub(); }, carrier); +function createCheckInEnvelope( + checkIn, + dynamicSamplingContext, + metadata, + tunnel, + dsn, +) { + const headers = { + sent_at: new Date().toISOString(), + }; + + if (metadata && metadata.sdk) { + headers.sdk = { + name: metadata.sdk.name, + version: metadata.sdk.version, + }; + } + + if (!!tunnel && !!dsn) { + headers.dsn = utils.dsnToString(dsn); + } + + if (dynamicSamplingContext) { + headers.trace = utils.dropUndefinedKeys(dynamicSamplingContext) ; + } + + const item = createCheckInEnvelopeItem(checkIn); + return utils.createEnvelope(headers, [item]); } -exports.getHubFromCarrier = getHubFromCarrier; -/** - * This will set passed {@link Hub} on the passed object's __SENTRY__.hub attribute - * @param carrier object - * @param hub Hub - * @returns A boolean indicating success or failure - */ -function setHubOnCarrier(carrier, hub) { - if (!carrier) - return false; - var __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {}); - __SENTRY__.hub = hub; - return true; + +function createCheckInEnvelopeItem(checkIn) { + const checkInHeaders = { + type: 'check_in', + }; + return [checkInHeaders, checkIn]; } -exports.setHubOnCarrier = setHubOnCarrier; -//# sourceMappingURL=hub.js.map + +exports.createCheckInEnvelope = createCheckInEnvelope; +//# sourceMappingURL=checkin.js.map + /***/ }), -/***/ 17237: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 11363: +/***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var scope_1 = __nccwpck_require__(69077); -exports.addGlobalEventProcessor = scope_1.addGlobalEventProcessor; -exports.Scope = scope_1.Scope; -var session_1 = __nccwpck_require__(90949); -exports.Session = session_1.Session; -var sessionflusher_1 = __nccwpck_require__(93472); -exports.SessionFlusher = sessionflusher_1.SessionFlusher; -var hub_1 = __nccwpck_require__(18070); -// eslint-disable-next-line deprecation/deprecation -exports.getActiveDomain = hub_1.getActiveDomain; -exports.getCurrentHub = hub_1.getCurrentHub; -exports.getHubFromCarrier = hub_1.getHubFromCarrier; -exports.getMainCarrier = hub_1.getMainCarrier; -exports.Hub = hub_1.Hub; -exports.makeMain = hub_1.makeMain; -exports.setHubOnCarrier = hub_1.setHubOnCarrier; -//# sourceMappingURL=index.js.map + +const DEFAULT_ENVIRONMENT = 'production'; + +exports.DEFAULT_ENVIRONMENT = DEFAULT_ENVIRONMENT; +//# sourceMappingURL=constants.js.map + /***/ }), -/***/ 69077: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 93376: +/***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var utils_1 = __nccwpck_require__(6785); + /** - * Absolute maximum number of breadcrumbs added to an event. - * The `maxBreadcrumbs` option cannot be higher than this value. + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. */ -var MAX_BREADCRUMBS = 100; +const DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__); + +exports.DEBUG_BUILD = DEBUG_BUILD; +//# sourceMappingURL=debug-build.js.map + + +/***/ }), + +/***/ 90820: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); + /** - * Holds additional event information. {@link Scope.applyToEvent} will be - * called by the client before an event will be sent. - */ -var Scope = /** @class */ (function () { - function Scope() { - /** Flag if notifying is happening. */ - this._notifyingListeners = false; - /** Callback for client to receive scope changes. */ - this._scopeListeners = []; - /** Callback list that will be called after {@link applyToEvent}. */ - this._eventProcessors = []; - /** Array of breadcrumbs. */ - this._breadcrumbs = []; - /** User */ - this._user = {}; - /** Tags */ - this._tags = {}; - /** Extra */ - this._extra = {}; - /** Contexts */ - this._contexts = {}; - /** - * A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get - * sent to Sentry - */ - this._sdkProcessingMetadata = {}; - } - /** - * Inherit values from the parent scope. - * @param scope to clone. - */ - Scope.clone = function (scope) { - var newScope = new Scope(); - if (scope) { - newScope._breadcrumbs = tslib_1.__spread(scope._breadcrumbs); - newScope._tags = tslib_1.__assign({}, scope._tags); - newScope._extra = tslib_1.__assign({}, scope._extra); - newScope._contexts = tslib_1.__assign({}, scope._contexts); - newScope._user = scope._user; - newScope._level = scope._level; - newScope._span = scope._span; - newScope._session = scope._session; - newScope._transactionName = scope._transactionName; - newScope._fingerprint = scope._fingerprint; - newScope._eventProcessors = tslib_1.__spread(scope._eventProcessors); - newScope._requestSession = scope._requestSession; - } - return newScope; - }; - /** - * Add internal on change listener. Used for sub SDKs that need to store the scope. - * @hidden - */ - Scope.prototype.addScopeListener = function (callback) { - this._scopeListeners.push(callback); - }; - /** - * @inheritDoc - */ - Scope.prototype.addEventProcessor = function (callback) { - this._eventProcessors.push(callback); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.setUser = function (user) { - this._user = user || {}; - if (this._session) { - this._session.update({ user: user }); - } - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.getUser = function () { - return this._user; - }; - /** - * @inheritDoc - */ - Scope.prototype.getRequestSession = function () { - return this._requestSession; - }; - /** - * @inheritDoc - */ - Scope.prototype.setRequestSession = function (requestSession) { - this._requestSession = requestSession; - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.setTags = function (tags) { - this._tags = tslib_1.__assign(tslib_1.__assign({}, this._tags), tags); - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.setTag = function (key, value) { - var _a; - this._tags = tslib_1.__assign(tslib_1.__assign({}, this._tags), (_a = {}, _a[key] = value, _a)); - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.setExtras = function (extras) { - this._extra = tslib_1.__assign(tslib_1.__assign({}, this._extra), extras); - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.setExtra = function (key, extra) { - var _a; - this._extra = tslib_1.__assign(tslib_1.__assign({}, this._extra), (_a = {}, _a[key] = extra, _a)); - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.setFingerprint = function (fingerprint) { - this._fingerprint = fingerprint; - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.setLevel = function (level) { - this._level = level; - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.setTransactionName = function (name) { - this._transactionName = name; - this._notifyScopeListeners(); - return this; - }; - /** - * Can be removed in major version. - * @deprecated in favor of {@link this.setTransactionName} - */ - Scope.prototype.setTransaction = function (name) { - return this.setTransactionName(name); - }; - /** - * @inheritDoc - */ - Scope.prototype.setContext = function (key, context) { - var _a; - if (context === null) { - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete - delete this._contexts[key]; - } - else { - this._contexts = tslib_1.__assign(tslib_1.__assign({}, this._contexts), (_a = {}, _a[key] = context, _a)); - } - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.setSpan = function (span) { - this._span = span; - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.getSpan = function () { - return this._span; - }; - /** - * @inheritDoc - */ - Scope.prototype.getTransaction = function () { - // Often, this span (if it exists at all) will be a transaction, but it's not guaranteed to be. Regardless, it will - // have a pointer to the currently-active transaction. - var span = this.getSpan(); - return span && span.transaction; - }; - /** - * @inheritDoc - */ - Scope.prototype.setSession = function (session) { - if (!session) { - delete this._session; - } - else { - this._session = session; - } - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.getSession = function () { - return this._session; - }; - /** - * @inheritDoc - */ - Scope.prototype.update = function (captureContext) { - if (!captureContext) { - return this; - } - if (typeof captureContext === 'function') { - var updatedScope = captureContext(this); - return updatedScope instanceof Scope ? updatedScope : this; - } - if (captureContext instanceof Scope) { - this._tags = tslib_1.__assign(tslib_1.__assign({}, this._tags), captureContext._tags); - this._extra = tslib_1.__assign(tslib_1.__assign({}, this._extra), captureContext._extra); - this._contexts = tslib_1.__assign(tslib_1.__assign({}, this._contexts), captureContext._contexts); - if (captureContext._user && Object.keys(captureContext._user).length) { - this._user = captureContext._user; - } - if (captureContext._level) { - this._level = captureContext._level; - } - if (captureContext._fingerprint) { - this._fingerprint = captureContext._fingerprint; - } - if (captureContext._requestSession) { - this._requestSession = captureContext._requestSession; - } - } - else if (utils_1.isPlainObject(captureContext)) { - // eslint-disable-next-line no-param-reassign - captureContext = captureContext; - this._tags = tslib_1.__assign(tslib_1.__assign({}, this._tags), captureContext.tags); - this._extra = tslib_1.__assign(tslib_1.__assign({}, this._extra), captureContext.extra); - this._contexts = tslib_1.__assign(tslib_1.__assign({}, this._contexts), captureContext.contexts); - if (captureContext.user) { - this._user = captureContext.user; - } - if (captureContext.level) { - this._level = captureContext.level; - } - if (captureContext.fingerprint) { - this._fingerprint = captureContext.fingerprint; - } - if (captureContext.requestSession) { - this._requestSession = captureContext.requestSession; - } - } - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.clear = function () { - this._breadcrumbs = []; - this._tags = {}; - this._extra = {}; - this._user = {}; - this._contexts = {}; - this._level = undefined; - this._transactionName = undefined; - this._fingerprint = undefined; - this._requestSession = undefined; - this._span = undefined; - this._session = undefined; - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.addBreadcrumb = function (breadcrumb, maxBreadcrumbs) { - var maxCrumbs = typeof maxBreadcrumbs === 'number' ? Math.min(maxBreadcrumbs, MAX_BREADCRUMBS) : MAX_BREADCRUMBS; - // No data has been changed, so don't notify scope listeners - if (maxCrumbs <= 0) { - return this; - } - var mergedBreadcrumb = tslib_1.__assign({ timestamp: utils_1.dateTimestampInSeconds() }, breadcrumb); - this._breadcrumbs = tslib_1.__spread(this._breadcrumbs, [mergedBreadcrumb]).slice(-maxCrumbs); - this._notifyScopeListeners(); - return this; - }; - /** - * @inheritDoc - */ - Scope.prototype.clearBreadcrumbs = function () { - this._breadcrumbs = []; - this._notifyScopeListeners(); - return this; - }; - /** - * Applies the current context and fingerprint to the event. - * Note that breadcrumbs will be added by the client. - * Also if the event has already breadcrumbs on it, we do not merge them. - * @param event Event - * @param hint May contain additional information about the original exception. - * @hidden - */ - Scope.prototype.applyToEvent = function (event, hint) { - if (this._extra && Object.keys(this._extra).length) { - event.extra = tslib_1.__assign(tslib_1.__assign({}, this._extra), event.extra); - } - if (this._tags && Object.keys(this._tags).length) { - event.tags = tslib_1.__assign(tslib_1.__assign({}, this._tags), event.tags); - } - if (this._user && Object.keys(this._user).length) { - event.user = tslib_1.__assign(tslib_1.__assign({}, this._user), event.user); - } - if (this._contexts && Object.keys(this._contexts).length) { - event.contexts = tslib_1.__assign(tslib_1.__assign({}, this._contexts), event.contexts); - } - if (this._level) { - event.level = this._level; - } - if (this._transactionName) { - event.transaction = this._transactionName; - } - // We want to set the trace context for normal events only if there isn't already - // a trace context on the event. There is a product feature in place where we link - // errors with transaction and it relies on that. - if (this._span) { - event.contexts = tslib_1.__assign({ trace: this._span.getTraceContext() }, event.contexts); - var transactionName = this._span.transaction && this._span.transaction.name; - if (transactionName) { - event.tags = tslib_1.__assign({ transaction: transactionName }, event.tags); - } - } - this._applyFingerprint(event); - event.breadcrumbs = tslib_1.__spread((event.breadcrumbs || []), this._breadcrumbs); - event.breadcrumbs = event.breadcrumbs.length > 0 ? event.breadcrumbs : undefined; - event.sdkProcessingMetadata = this._sdkProcessingMetadata; - return this._notifyEventProcessors(tslib_1.__spread(getGlobalEventProcessors(), this._eventProcessors), event, hint); - }; - /** - * Add data which will be accessible during event processing but won't get sent to Sentry - */ - Scope.prototype.setSDKProcessingMetadata = function (newData) { - this._sdkProcessingMetadata = tslib_1.__assign(tslib_1.__assign({}, this._sdkProcessingMetadata), newData); - return this; - }; - /** - * This will be called after {@link applyToEvent} is finished. - */ - Scope.prototype._notifyEventProcessors = function (processors, event, hint, index) { - var _this = this; - if (index === void 0) { index = 0; } - return new utils_1.SyncPromise(function (resolve, reject) { - var processor = processors[index]; - if (event === null || typeof processor !== 'function') { - resolve(event); - } - else { - var result = processor(tslib_1.__assign({}, event), hint); - if (utils_1.isThenable(result)) { - void result - .then(function (final) { return _this._notifyEventProcessors(processors, final, hint, index + 1).then(resolve); }) - .then(null, reject); - } - else { - void _this._notifyEventProcessors(processors, result, hint, index + 1) - .then(resolve) - .then(null, reject); - } - } - }); - }; - /** - * This will be called on every set call. - */ - Scope.prototype._notifyScopeListeners = function () { - var _this = this; - // We need this check for this._notifyingListeners to be able to work on scope during updates - // If this check is not here we'll produce endless recursion when something is done with the scope - // during the callback. - if (!this._notifyingListeners) { - this._notifyingListeners = true; - this._scopeListeners.forEach(function (callback) { - callback(_this); - }); - this._notifyingListeners = false; - } - }; - /** - * Applies fingerprint from the scope to the event if there's one, - * uses message if there's one instead or get rid of empty fingerprint - */ - Scope.prototype._applyFingerprint = function (event) { - // Make sure it's an array first and we actually have something in place - event.fingerprint = event.fingerprint - ? Array.isArray(event.fingerprint) - ? event.fingerprint - : [event.fingerprint] - : []; - // If we have something on the scope, then merge it with event - if (this._fingerprint) { - event.fingerprint = event.fingerprint.concat(this._fingerprint); - } - // If we have no data at all, remove empty array default - if (event.fingerprint && !event.fingerprint.length) { - delete event.fingerprint; - } - }; - return Scope; -}()); -exports.Scope = Scope; -/** - * Returns the global event processors. - */ -function getGlobalEventProcessors() { - return utils_1.getGlobalSingleton('globalEventProcessors', function () { return []; }); + * Apply SdkInfo (name, version, packages, integrations) to the corresponding event key. + * Merge with existing data if any. + **/ +function enhanceEventWithSdkInfo(event, sdkInfo) { + if (!sdkInfo) { + return event; + } + event.sdk = event.sdk || {}; + event.sdk.name = event.sdk.name || sdkInfo.name; + event.sdk.version = event.sdk.version || sdkInfo.version; + event.sdk.integrations = [...(event.sdk.integrations || []), ...(sdkInfo.integrations || [])]; + event.sdk.packages = [...(event.sdk.packages || []), ...(sdkInfo.packages || [])]; + return event; +} + +/** Creates an envelope from a Session */ +function createSessionEnvelope( + session, + dsn, + metadata, + tunnel, +) { + const sdkInfo = utils.getSdkMetadataForEnvelopeHeader(metadata); + const envelopeHeaders = { + sent_at: new Date().toISOString(), + ...(sdkInfo && { sdk: sdkInfo }), + ...(!!tunnel && dsn && { dsn: utils.dsnToString(dsn) }), + }; + + const envelopeItem = + 'aggregates' in session ? [{ type: 'sessions' }, session] : [{ type: 'session' }, session.toJSON()]; + + return utils.createEnvelope(envelopeHeaders, [envelopeItem]); } + /** - * Add a EventProcessor to be kept globally. - * @param callback EventProcessor to add + * Create an Envelope from an event. */ -function addGlobalEventProcessor(callback) { - getGlobalEventProcessors().push(callback); +function createEventEnvelope( + event, + dsn, + metadata, + tunnel, +) { + const sdkInfo = utils.getSdkMetadataForEnvelopeHeader(metadata); + + /* + Note: Due to TS, event.type may be `replay_event`, theoretically. + In practice, we never call `createEventEnvelope` with `replay_event` type, + and we'd have to adjut a looot of types to make this work properly. + We want to avoid casting this around, as that could lead to bugs (e.g. when we add another type) + So the safe choice is to really guard against the replay_event type here. + */ + const eventType = event.type && event.type !== 'replay_event' ? event.type : 'event'; + + enhanceEventWithSdkInfo(event, metadata && metadata.sdk); + + const envelopeHeaders = utils.createEventEnvelopeHeaders(event, sdkInfo, tunnel, dsn); + + // Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to + // sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may + // have temporarily added, etc. Even if we don't happen to be using it at some point in the future, let's not get rid + // of this `delete`, lest we miss putting it back in the next time the property is in use.) + delete event.sdkProcessingMetadata; + + const eventItem = [{ type: eventType }, event]; + return utils.createEnvelope(envelopeHeaders, [eventItem]); } -exports.addGlobalEventProcessor = addGlobalEventProcessor; -//# sourceMappingURL=scope.js.map + +exports.createEventEnvelope = createEventEnvelope; +exports.createSessionEnvelope = createSessionEnvelope; +//# sourceMappingURL=envelope.js.map + /***/ }), -/***/ 90949: +/***/ 88807: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var utils_1 = __nccwpck_require__(6785); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); + /** - * @inheritdoc + * Returns the global event processors. + * @deprecated Global event processors will be removed in v8. */ -var Session = /** @class */ (function () { - function Session(context) { - this.errors = 0; - this.sid = utils_1.uuid4(); - this.duration = 0; - this.status = 'ok'; - this.init = true; - this.ignoreDuration = false; - // Both timestamp and started are in seconds since the UNIX epoch. - var startingTime = utils_1.timestampInSeconds(); - this.timestamp = startingTime; - this.started = startingTime; - if (context) { - this.update(context); - } - } - /** JSDoc */ - // eslint-disable-next-line complexity - Session.prototype.update = function (context) { - if (context === void 0) { context = {}; } - if (context.user) { - if (!this.ipAddress && context.user.ip_address) { - this.ipAddress = context.user.ip_address; - } - if (!this.did && !context.did) { - this.did = context.user.id || context.user.email || context.user.username; - } - } - this.timestamp = context.timestamp || utils_1.timestampInSeconds(); - if (context.ignoreDuration) { - this.ignoreDuration = context.ignoreDuration; - } - if (context.sid) { - // Good enough uuid validation. — Kamil - this.sid = context.sid.length === 32 ? context.sid : utils_1.uuid4(); - } - if (context.init !== undefined) { - this.init = context.init; - } - if (!this.did && context.did) { - this.did = "" + context.did; - } - if (typeof context.started === 'number') { - this.started = context.started; - } - if (this.ignoreDuration) { - this.duration = undefined; - } - else if (typeof context.duration === 'number') { - this.duration = context.duration; - } - else { - var duration = this.timestamp - this.started; - this.duration = duration >= 0 ? duration : 0; - } - if (context.release) { - this.release = context.release; - } - if (context.environment) { - this.environment = context.environment; - } - if (!this.ipAddress && context.ipAddress) { - this.ipAddress = context.ipAddress; - } - if (!this.userAgent && context.userAgent) { - this.userAgent = context.userAgent; - } - if (typeof context.errors === 'number') { - this.errors = context.errors; - } - if (context.status) { - this.status = context.status; - } - }; - /** JSDoc */ - Session.prototype.close = function (status) { - if (status) { - this.update({ status: status }); - } - else if (this.status === 'ok') { - this.update({ status: 'exited' }); - } - else { - this.update(); - } - }; - /** JSDoc */ - Session.prototype.toJSON = function () { - return utils_1.dropUndefinedKeys({ - sid: "" + this.sid, - init: this.init, - // Make sure that sec is converted to ms for date constructor - started: new Date(this.started * 1000).toISOString(), - timestamp: new Date(this.timestamp * 1000).toISOString(), - status: this.status, - errors: this.errors, - did: typeof this.did === 'number' || typeof this.did === 'string' ? "" + this.did : undefined, - duration: this.duration, - attrs: { - release: this.release, - environment: this.environment, - ip_address: this.ipAddress, - user_agent: this.userAgent, - }, - }); - }; - return Session; -}()); -exports.Session = Session; -//# sourceMappingURL=session.js.map - -/***/ }), +function getGlobalEventProcessors() { + return utils.getGlobalSingleton('globalEventProcessors', () => []); +} -/***/ 93472: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/** + * Add a EventProcessor to be kept globally. + * @deprecated Use `addEventProcessor` instead. Global event processors will be removed in v8. + */ +function addGlobalEventProcessor(callback) { + // eslint-disable-next-line deprecation/deprecation + getGlobalEventProcessors().push(callback); +} -Object.defineProperty(exports, "__esModule", ({ value: true })); -var utils_1 = __nccwpck_require__(6785); -var flags_1 = __nccwpck_require__(66482); -var hub_1 = __nccwpck_require__(18070); /** - * @inheritdoc + * Process an array of event processors, returning the processed event (or `null` if the event was dropped). */ -var SessionFlusher = /** @class */ (function () { - function SessionFlusher(transport, attrs) { - var _this = this; - this.flushTimeout = 60; - this._pendingAggregates = {}; - this._isEnabled = true; - this._transport = transport; - // Call to setInterval, so that flush is called every 60 seconds - this._intervalId = setInterval(function () { return _this.flush(); }, this.flushTimeout * 1000); - this._sessionAttrs = attrs; - } - /** Sends session aggregates to Transport */ - SessionFlusher.prototype.sendSessionAggregates = function (sessionAggregates) { - if (!this._transport.sendSession) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn("Dropping session because custom transport doesn't implement sendSession"); - return; - } - void this._transport.sendSession(sessionAggregates).then(null, function (reason) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.error('Error while sending session:', reason); - }); - }; - /** Checks if `pendingAggregates` has entries, and if it does flushes them by calling `sendSessions` */ - SessionFlusher.prototype.flush = function () { - var sessionAggregates = this.getSessionAggregates(); - if (sessionAggregates.aggregates.length === 0) { - return; - } - this._pendingAggregates = {}; - this.sendSessionAggregates(sessionAggregates); - }; - /** Massages the entries in `pendingAggregates` and returns aggregated sessions */ - SessionFlusher.prototype.getSessionAggregates = function () { - var _this = this; - var aggregates = Object.keys(this._pendingAggregates).map(function (key) { - return _this._pendingAggregates[parseInt(key)]; - }); - var sessionAggregates = { - attrs: this._sessionAttrs, - aggregates: aggregates, - }; - return utils_1.dropUndefinedKeys(sessionAggregates); - }; - /** JSDoc */ - SessionFlusher.prototype.close = function () { - clearInterval(this._intervalId); - this._isEnabled = false; - this.flush(); - }; - /** - * Wrapper function for _incrementSessionStatusCount that checks if the instance of SessionFlusher is enabled then - * fetches the session status of the request from `Scope.getRequestSession().status` on the scope and passes them to - * `_incrementSessionStatusCount` along with the start date - */ - SessionFlusher.prototype.incrementSessionStatusCount = function () { - if (!this._isEnabled) { - return; - } - var scope = hub_1.getCurrentHub().getScope(); - var requestSession = scope && scope.getRequestSession(); - if (requestSession && requestSession.status) { - this._incrementSessionStatusCount(requestSession.status, new Date()); - // This is not entirely necessarily but is added as a safe guard to indicate the bounds of a request and so in - // case captureRequestSession is called more than once to prevent double count - if (scope) { - scope.setRequestSession(undefined); - } - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ - } - }; - /** - * Increments status bucket in pendingAggregates buffer (internal state) corresponding to status of - * the session received - */ - SessionFlusher.prototype._incrementSessionStatusCount = function (status, date) { - // Truncate minutes and seconds on Session Started attribute to have one minute bucket keys - var sessionStartedTrunc = new Date(date).setSeconds(0, 0); - this._pendingAggregates[sessionStartedTrunc] = this._pendingAggregates[sessionStartedTrunc] || {}; - // corresponds to aggregated sessions in one specific minute bucket - // for example, {"started":"2021-03-16T08:00:00.000Z","exited":4, "errored": 1} - var aggregationCounts = this._pendingAggregates[sessionStartedTrunc]; - if (!aggregationCounts.started) { - aggregationCounts.started = new Date(sessionStartedTrunc).toISOString(); - } - switch (status) { - case 'errored': - aggregationCounts.errored = (aggregationCounts.errored || 0) + 1; - return aggregationCounts.errored; - case 'ok': - aggregationCounts.exited = (aggregationCounts.exited || 0) + 1; - return aggregationCounts.exited; - default: - aggregationCounts.crashed = (aggregationCounts.crashed || 0) + 1; - return aggregationCounts.crashed; - } - }; - return SessionFlusher; -}()); -exports.SessionFlusher = SessionFlusher; -//# sourceMappingURL=sessionflusher.js.map +function notifyEventProcessors( + processors, + event, + hint, + index = 0, +) { + return new utils.SyncPromise((resolve, reject) => { + const processor = processors[index]; + if (event === null || typeof processor !== 'function') { + resolve(event); + } else { + const result = processor({ ...event }, hint) ; + + debugBuild.DEBUG_BUILD && processor.id && result === null && utils.logger.log(`Event processor "${processor.id}" dropped event`); + + if (utils.isThenable(result)) { + void result + .then(final => notifyEventProcessors(processors, final, hint, index + 1).then(resolve)) + .then(null, reject); + } else { + void notifyEventProcessors(processors, result, hint, index + 1) + .then(resolve) + .then(null, reject); + } + } + }); +} + +exports.addGlobalEventProcessor = addGlobalEventProcessor; +exports.getGlobalEventProcessors = getGlobalEventProcessors; +exports.notifyEventProcessors = notifyEventProcessors; +//# sourceMappingURL=eventProcessors.js.map + /***/ }), -/***/ 85509: +/***/ 74313: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var hub_1 = __nccwpck_require__(17237); -/** - * This calls a function on the current hub. - * @param method function to call on hub. - * @param args to pass to function. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function callOnHub(method) { - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - var hub = hub_1.getCurrentHub(); - if (hub && hub[method]) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return hub[method].apply(hub, tslib_1.__spread(args)); - } - throw new Error("No hub defined or " + method + " was not found on the hub, please open a bug report."); -} + +const utils = __nccwpck_require__(57540); +const constants = __nccwpck_require__(11363); +const debugBuild = __nccwpck_require__(93376); +const hub = __nccwpck_require__(18205); +const session = __nccwpck_require__(14638); +const prepareEvent = __nccwpck_require__(57847); + /** * Captures an exception event and sends it to Sentry. * - * @param exception An exception-like object. - * @returns The generated eventId. + * @param exception The exception to capture. + * @param hint Optional additional data to attach to the Sentry event. + * @returns the id of the captured Sentry event. */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types -function captureException(exception, captureContext) { - var syntheticException = new Error('Sentry syntheticException'); - return callOnHub('captureException', exception, { - captureContext: captureContext, - originalException: exception, - syntheticException: syntheticException, - }); +function captureException( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + exception, + hint, +) { + // eslint-disable-next-line deprecation/deprecation + return hub.getCurrentHub().captureException(exception, prepareEvent.parseEventHintOrCaptureContext(hint)); } -exports.captureException = captureException; + /** * Captures a message event and sends it to Sentry. * - * @param message The message to send to Sentry. - * @param Severity Define the level of the message. - * @returns The generated eventId. + * @param exception The exception to capture. + * @param captureContext Define the level of the message or pass in additional data to attach to the message. + * @returns the id of the captured message. */ -function captureMessage(message, captureContext) { - var syntheticException = new Error(message); - // This is necessary to provide explicit scopes upgrade, without changing the original - // arity of the `captureMessage(message, level)` method. - var level = typeof captureContext === 'string' ? captureContext : undefined; - var context = typeof captureContext !== 'string' ? { captureContext: captureContext } : undefined; - return callOnHub('captureMessage', message, level, tslib_1.__assign({ originalException: message, syntheticException: syntheticException }, context)); +function captureMessage( + message, + // eslint-disable-next-line deprecation/deprecation + captureContext, +) { + // This is necessary to provide explicit scopes upgrade, without changing the original + // arity of the `captureMessage(message, level)` method. + const level = typeof captureContext === 'string' ? captureContext : undefined; + const context = typeof captureContext !== 'string' ? { captureContext } : undefined; + // eslint-disable-next-line deprecation/deprecation + return hub.getCurrentHub().captureMessage(message, level, context); } -exports.captureMessage = captureMessage; + /** * Captures a manually created event and sends it to Sentry. * - * @param event The event to send to Sentry. - * @returns The generated eventId. + * @param exception The event to send to Sentry. + * @param hint Optional additional data to attach to the Sentry event. + * @returns the id of the captured event. */ -function captureEvent(event) { - return callOnHub('captureEvent', event); +function captureEvent(event, hint) { + // eslint-disable-next-line deprecation/deprecation + return hub.getCurrentHub().captureEvent(event, hint); } -exports.captureEvent = captureEvent; + /** * Callback to set context information onto the scope. * @param callback Callback function that receives Scope. + * + * @deprecated Use getCurrentScope() directly. */ +// eslint-disable-next-line deprecation/deprecation function configureScope(callback) { - callOnHub('configureScope', callback); + // eslint-disable-next-line deprecation/deprecation + hub.getCurrentHub().configureScope(callback); } -exports.configureScope = configureScope; + /** * Records a new breadcrumb which will be attached to future events. * @@ -13424,45 +11846,54 @@ exports.configureScope = configureScope; * * @param breadcrumb The breadcrumb to record. */ -function addBreadcrumb(breadcrumb) { - callOnHub('addBreadcrumb', breadcrumb); +// eslint-disable-next-line deprecation/deprecation +function addBreadcrumb(breadcrumb, hint) { + // eslint-disable-next-line deprecation/deprecation + hub.getCurrentHub().addBreadcrumb(breadcrumb, hint); } -exports.addBreadcrumb = addBreadcrumb; + /** * Sets context data with the given name. * @param name of the context * @param context Any kind of data. This data will be normalized. */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any, deprecation/deprecation function setContext(name, context) { - callOnHub('setContext', name, context); + // eslint-disable-next-line deprecation/deprecation + hub.getCurrentHub().setContext(name, context); } -exports.setContext = setContext; + /** * Set an object that will be merged sent as extra data with the event. * @param extras Extras object to merge into current context. */ +// eslint-disable-next-line deprecation/deprecation function setExtras(extras) { - callOnHub('setExtras', extras); + // eslint-disable-next-line deprecation/deprecation + hub.getCurrentHub().setExtras(extras); } -exports.setExtras = setExtras; -/** - * Set an object that will be merged sent as tags data with the event. - * @param tags Tags context object to merge into current context. - */ -function setTags(tags) { - callOnHub('setTags', tags); -} -exports.setTags = setTags; + /** * Set key:value that will be sent as extra data with the event. * @param key String of extra * @param extra Any kind of data. This data will be normalized. */ +// eslint-disable-next-line deprecation/deprecation function setExtra(key, extra) { - callOnHub('setExtra', key, extra); + // eslint-disable-next-line deprecation/deprecation + hub.getCurrentHub().setExtra(key, extra); } -exports.setExtra = setExtra; + +/** + * Set an object that will be merged sent as tags data with the event. + * @param tags Tags context object to merge into current context. + */ +// eslint-disable-next-line deprecation/deprecation +function setTags(tags) { + // eslint-disable-next-line deprecation/deprecation + hub.getCurrentHub().setTags(tags); +} + /** * Set key:value that will be sent as tags data with the event. * @@ -13471,19 +11902,23 @@ exports.setExtra = setExtra; * @param key String key of tag * @param value Value of tag */ +// eslint-disable-next-line deprecation/deprecation function setTag(key, value) { - callOnHub('setTag', key, value); + // eslint-disable-next-line deprecation/deprecation + hub.getCurrentHub().setTag(key, value); } -exports.setTag = setTag; + /** * Updates user context information for future events. * * @param user User context object to be set in the current context. Pass `null` to unset the user. */ +// eslint-disable-next-line deprecation/deprecation function setUser(user) { - callOnHub('setUser', user); + // eslint-disable-next-line deprecation/deprecation + hub.getCurrentHub().setUser(user); } -exports.setUser = setUser; + /** * Creates a new scope with and executes the given operation within. * The scope is automatically removed once the operation @@ -13494,32 +11929,72 @@ exports.setUser = setUser; * pushScope(); * callback(); * popScope(); + */ + +/** + * Either creates a new active scope, or sets the given scope as active scope in the given callback. + */ +function withScope( + ...rest +) { + // eslint-disable-next-line deprecation/deprecation + const hub$1 = hub.getCurrentHub(); + + // If a scope is defined, we want to make this the active scope instead of the default one + if (rest.length === 2) { + const [scope, callback] = rest; + if (!scope) { + // eslint-disable-next-line deprecation/deprecation + return hub$1.withScope(callback); + } + + // eslint-disable-next-line deprecation/deprecation + return hub$1.withScope(() => { + // eslint-disable-next-line deprecation/deprecation + hub$1.getStackTop().scope = scope ; + return callback(scope ); + }); + } + + // eslint-disable-next-line deprecation/deprecation + return hub$1.withScope(rest[0]); +} + +/** + * Attempts to fork the current isolation scope and the current scope based on the current async context strategy. If no + * async context strategy is set, the isolation scope and the current scope will not be forked (this is currently the + * case, for example, in the browser). + * + * Usage of this function in environments without async context strategy is discouraged and may lead to unexpected behaviour. * - * @param callback that will be enclosed into push/popScope. + * This function is intended for Sentry SDK and SDK integration development. It is not recommended to be used in "normal" + * applications directly because it comes with pitfalls. Use at your own risk! + * + * @param callback The callback in which the passed isolation scope is active. (Note: In environments without async + * context strategy, the currently active isolation scope may change within execution of the callback.) + * @returns The same value that `callback` returns. */ -function withScope(callback) { - callOnHub('withScope', callback); +function withIsolationScope(callback) { + return hub.runWithAsyncContext(() => { + return callback(hub.getIsolationScope()); + }); } -exports.withScope = withScope; + /** - * Calls a function on the latest client. Use this with caution, it's meant as - * in "internal" helper so we don't need to expose every possible function in - * the shim. It is not guaranteed that the client actually implements the - * function. + * Forks the current scope and sets the provided span as active span in the context of the provided callback. * - * @param method The method to call on the client/client. - * @param args Arguments to pass to the client/fontend. - * @hidden + * @param span Spans started in the context of the provided callback will be children of this span. + * @param callback Execution context in which the provided span will be active. Is passed the newly forked scope. + * @returns the value returned from the provided callback function. */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function _callOnClient(method) { - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - callOnHub.apply(void 0, tslib_1.__spread(['_invokeClient', method], args)); +function withActiveSpan(span, callback) { + return withScope(scope => { + // eslint-disable-next-line deprecation/deprecation + scope.setSpan(span); + return callback(scope); + }); } -exports._callOnClient = _callOnClient; + /** * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation. * @@ -13528,22385 +12003,27471 @@ exports._callOnClient = _callOnClient; * * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded. * - * The transaction must be finished with a call to its `.finish()` method, at which point the transaction with all its + * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its * finished child spans will be sent to Sentry. * + * NOTE: This function should only be used for *manual* instrumentation. Auto-instrumentation should call + * `startTransaction` directly on the hub. + * * @param context Properties of the new `Transaction`. * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent * default values). See {@link Options.tracesSampler}. * * @returns The transaction which was just started + * + * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead. */ -function startTransaction(context, customSamplingContext) { - return callOnHub('startTransaction', tslib_1.__assign({}, context), customSamplingContext); +function startTransaction( + context, + customSamplingContext, + // eslint-disable-next-line deprecation/deprecation +) { + // eslint-disable-next-line deprecation/deprecation + return hub.getCurrentHub().startTransaction({ ...context }, customSamplingContext); } -exports.startTransaction = startTransaction; -//# sourceMappingURL=index.js.map - -/***/ }), - -/***/ 61647: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var types_1 = __nccwpck_require__(34105); -var utils_1 = __nccwpck_require__(6785); -var eventbuilder_1 = __nccwpck_require__(77196); -var transports_1 = __nccwpck_require__(54950); -/** - * The Sentry Node SDK Backend. - * @hidden +/** + * Create a cron monitor check in and send it to Sentry. + * + * @param checkIn An object that describes a check in. + * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want + * to create a monitor automatically when sending a check in. */ -var NodeBackend = /** @class */ (function (_super) { - tslib_1.__extends(NodeBackend, _super); - function NodeBackend() { - return _super !== null && _super.apply(this, arguments) || this; - } - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types - NodeBackend.prototype.eventFromException = function (exception, hint) { - return utils_1.resolvedSyncPromise(eventbuilder_1.eventFromUnknownInput(exception, hint)); - }; - /** - * @inheritDoc - */ - NodeBackend.prototype.eventFromMessage = function (message, level, hint) { - if (level === void 0) { level = types_1.Severity.Info; } - return utils_1.resolvedSyncPromise(eventbuilder_1.eventFromMessage(message, level, hint, this._options.attachStacktrace)); - }; - /** - * @inheritDoc - */ - NodeBackend.prototype._setupTransport = function () { - if (!this._options.dsn) { - // We return the noop transport here in case there is no Dsn. - return _super.prototype._setupTransport.call(this); - } - var dsn = utils_1.makeDsn(this._options.dsn); - var transportOptions = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, this._options.transportOptions), (this._options.httpProxy && { httpProxy: this._options.httpProxy })), (this._options.httpsProxy && { httpsProxy: this._options.httpsProxy })), (this._options.caCerts && { caCerts: this._options.caCerts })), { dsn: this._options.dsn, tunnel: this._options.tunnel, _metadata: this._options._metadata }); - if (this._options.transport) { - return new this._options.transport(transportOptions); - } - var api = core_1.initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); - var url = core_1.getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); - this._newTransport = transports_1.makeNodeTransport({ - url: url, - headers: transportOptions.headers, - proxy: transportOptions.httpProxy, - caCerts: transportOptions.caCerts, - }); - if (dsn.protocol === 'http') { - return new transports_1.HTTPTransport(transportOptions); - } - return new transports_1.HTTPSTransport(transportOptions); - }; - return NodeBackend; -}(core_1.BaseBackend)); -exports.NodeBackend = NodeBackend; -//# sourceMappingURL=backend.js.map - -/***/ }), +function captureCheckIn(checkIn, upsertMonitorConfig) { + const scope = getCurrentScope(); + const client = getClient(); + if (!client) { + debugBuild.DEBUG_BUILD && utils.logger.warn('Cannot capture check-in. No client defined.'); + } else if (!client.captureCheckIn) { + debugBuild.DEBUG_BUILD && utils.logger.warn('Cannot capture check-in. Client does not support sending check-ins.'); + } else { + return client.captureCheckIn(checkIn, upsertMonitorConfig, scope); + } -/***/ 49652: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + return utils.uuid4(); +} -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var hub_1 = __nccwpck_require__(17237); -var utils_1 = __nccwpck_require__(6785); -var backend_1 = __nccwpck_require__(61647); -var flags_1 = __nccwpck_require__(62976); /** - * The Sentry Node SDK Client. + * Wraps a callback with a cron monitor check in. The check in will be sent to Sentry when the callback finishes. * - * @see NodeOptions for documentation on configuration options. - * @see SentryClient for usage documentation. + * @param monitorSlug The distinct slug of the monitor. + * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want + * to create a monitor automatically when sending a check in. */ -var NodeClient = /** @class */ (function (_super) { - tslib_1.__extends(NodeClient, _super); - /** - * Creates a new Node SDK instance. - * @param options Configuration options for this SDK. - */ - function NodeClient(options) { - var _this = this; - options._metadata = options._metadata || {}; - options._metadata.sdk = options._metadata.sdk || { - name: 'sentry.javascript.node', - packages: [ - { - name: 'npm:@sentry/node', - version: core_1.SDK_VERSION, - }, - ], - version: core_1.SDK_VERSION, - }; - _this = _super.call(this, backend_1.NodeBackend, options) || this; - return _this; - } - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types - NodeClient.prototype.captureException = function (exception, hint, scope) { - // Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only - // when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload - // sent to the Server only when the `requestHandler` middleware is used - if (this._options.autoSessionTracking && this._sessionFlusher && scope) { - var requestSession = scope.getRequestSession(); - // Necessary checks to ensure this is code block is executed only within a request - // Should override the status only if `requestSession.status` is `Ok`, which is its initial stage - if (requestSession && requestSession.status === 'ok') { - requestSession.status = 'errored'; - } - } - return _super.prototype.captureException.call(this, exception, hint, scope); - }; - /** - * @inheritDoc - */ - NodeClient.prototype.captureEvent = function (event, hint, scope) { - // Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only - // when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload - // sent to the Server only when the `requestHandler` middleware is used - if (this._options.autoSessionTracking && this._sessionFlusher && scope) { - var eventType = event.type || 'exception'; - var isException = eventType === 'exception' && event.exception && event.exception.values && event.exception.values.length > 0; - // If the event is of type Exception, then a request session should be captured - if (isException) { - var requestSession = scope.getRequestSession(); - // Ensure that this is happening within the bounds of a request, and make sure not to override - // Session Status if Errored / Crashed - if (requestSession && requestSession.status === 'ok') { - requestSession.status = 'errored'; - } - } - } - return _super.prototype.captureEvent.call(this, event, hint, scope); - }; - /** - * - * @inheritdoc - */ - NodeClient.prototype.close = function (timeout) { - var _a; - (_a = this._sessionFlusher) === null || _a === void 0 ? void 0 : _a.close(); - return _super.prototype.close.call(this, timeout); - }; - /** Method that initialises an instance of SessionFlusher on Client */ - NodeClient.prototype.initSessionFlusher = function () { - var _a = this._options, release = _a.release, environment = _a.environment; - if (!release) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn('Cannot initialise an instance of SessionFlusher if no release is provided!'); - } - else { - this._sessionFlusher = new hub_1.SessionFlusher(this.getTransport(), { - release: release, - environment: environment, - }); - } - }; - /** - * @inheritDoc - */ - NodeClient.prototype._prepareEvent = function (event, scope, hint) { - event.platform = event.platform || 'node'; - if (this.getOptions().serverName) { - event.server_name = this.getOptions().serverName; - } - return _super.prototype._prepareEvent.call(this, event, scope, hint); - }; - /** - * Method responsible for capturing/ending a request session by calling `incrementSessionStatusCount` to increment - * appropriate session aggregates bucket - */ - NodeClient.prototype._captureRequestSession = function () { - if (!this._sessionFlusher) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn('Discarded request mode session because autoSessionTracking option was disabled'); - } - else { - this._sessionFlusher.incrementSessionStatusCount(); - } - }; - return NodeClient; -}(core_1.BaseClient)); -exports.NodeClient = NodeClient; -//# sourceMappingURL=client.js.map +function withMonitor( + monitorSlug, + callback, + upsertMonitorConfig, +) { + const checkInId = captureCheckIn({ monitorSlug, status: 'in_progress' }, upsertMonitorConfig); + const now = utils.timestampInSeconds(); -/***/ }), + function finishCheckIn(status) { + captureCheckIn({ monitorSlug, status, checkInId, duration: utils.timestampInSeconds() - now }); + } -/***/ 77196: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + let maybePromiseResult; + try { + maybePromiseResult = callback(); + } catch (e) { + finishCheckIn('error'); + throw e; + } + + if (utils.isThenable(maybePromiseResult)) { + Promise.resolve(maybePromiseResult).then( + () => { + finishCheckIn('ok'); + }, + () => { + finishCheckIn('error'); + }, + ); + } else { + finishCheckIn('ok'); + } + + return maybePromiseResult; +} -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var hub_1 = __nccwpck_require__(17237); -var types_1 = __nccwpck_require__(34105); -var utils_1 = __nccwpck_require__(6785); -var stack_parser_1 = __nccwpck_require__(39503); /** - * Extracts stack frames from the error.stack string + * Call `flush()` on the current client, if there is one. See {@link Client.flush}. + * + * @param timeout Maximum time in ms the client should wait to flush its event queue. Omitting this parameter will cause + * the client to wait until all events are sent before resolving the promise. + * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it + * doesn't (or if there's no client defined). */ -function parseStackFrames(error) { - return utils_1.createStackParser(stack_parser_1.nodeStackParser)(error.stack || '', 1); +async function flush(timeout) { + const client = getClient(); + if (client) { + return client.flush(timeout); + } + debugBuild.DEBUG_BUILD && utils.logger.warn('Cannot flush events. No client defined.'); + return Promise.resolve(false); } -exports.parseStackFrames = parseStackFrames; + /** - * Extracts stack frames from the error and builds a Sentry Exception + * Call `close()` on the current client, if there is one. See {@link Client.close}. + * + * @param timeout Maximum time in ms the client should wait to flush its event queue before shutting down. Omitting this + * parameter will cause the client to wait until all events are sent before disabling itself. + * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it + * doesn't (or if there's no client defined). */ -function exceptionFromError(error) { - var exception = { - type: error.name || error.constructor.name, - value: error.message, - }; - var frames = parseStackFrames(error); - if (frames.length) { - exception.stacktrace = { frames: frames }; - } - return exception; +async function close(timeout) { + const client = getClient(); + if (client) { + return client.close(timeout); + } + debugBuild.DEBUG_BUILD && utils.logger.warn('Cannot flush events and disable SDK. No client defined.'); + return Promise.resolve(false); } -exports.exceptionFromError = exceptionFromError; + /** - * Builds and Event from a Exception - * @hidden + * This is the getter for lastEventId. + * + * @returns The last event id of a captured event. */ -function eventFromUnknownInput(exception, hint) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - var ex = exception; - var providedMechanism = hint && hint.data && hint.data.mechanism; - var mechanism = providedMechanism || { - handled: true, - type: 'generic', - }; - if (!utils_1.isError(exception)) { - if (utils_1.isPlainObject(exception)) { - // This will allow us to group events based on top-level keys - // which is much better than creating new group when any key/value change - var message = "Non-Error exception captured with keys: " + utils_1.extractExceptionKeysForMessage(exception); - hub_1.getCurrentHub().configureScope(function (scope) { - scope.setExtra('__serialized__', utils_1.normalizeToSize(exception)); - }); - ex = (hint && hint.syntheticException) || new Error(message); - ex.message = message; - } - else { - // This handles when someone does: `throw "something awesome";` - // We use synthesized Error here so we can extract a (rough) stack trace. - ex = (hint && hint.syntheticException) || new Error(exception); - ex.message = exception; - } - mechanism.synthetic = true; - } - var event = { - exception: { - values: [exceptionFromError(ex)], - }, - }; - utils_1.addExceptionTypeValue(event, undefined, undefined); - utils_1.addExceptionMechanism(event, mechanism); - return tslib_1.__assign(tslib_1.__assign({}, event), { event_id: hint && hint.event_id }); +function lastEventId() { + // eslint-disable-next-line deprecation/deprecation + return hub.getCurrentHub().lastEventId(); } -exports.eventFromUnknownInput = eventFromUnknownInput; + /** - * Builds and Event from a Message - * @hidden + * Get the currently active client. */ -function eventFromMessage(message, level, hint, attachStacktrace) { - if (level === void 0) { level = types_1.Severity.Info; } - var event = { - event_id: hint && hint.event_id, - level: level, - message: message, - }; - if (attachStacktrace && hint && hint.syntheticException) { - var frames_1 = parseStackFrames(hint.syntheticException); - if (frames_1.length) { - event.stacktrace = { frames: frames_1 }; - } - } - return event; +function getClient() { + // eslint-disable-next-line deprecation/deprecation + return hub.getCurrentHub().getClient(); } -exports.eventFromMessage = eventFromMessage; -//# sourceMappingURL=eventbuilder.js.map -/***/ }), +/** + * Returns true if Sentry has been properly initialized. + */ +function isInitialized() { + return !!getClient(); +} -/***/ 62976: -/***/ ((__unused_webpack_module, exports) => { +/** + * Get the currently active scope. + */ +function getCurrentScope() { + // eslint-disable-next-line deprecation/deprecation + return hub.getCurrentHub().getScope(); +} -/* - * This file defines flags and constants that can be modified during compile time in order to facilitate tree shaking - * for users. - * - * Debug flags need to be declared in each package individually and must not be imported across package boundaries, - * because some build tools have trouble tree-shaking imported guards. +/** + * Start a session on the current isolation scope. * - * As a convention, we define debug flags in a `flags.ts` file in the root of a package's `src` folder. + * @param context (optional) additional properties to be applied to the returned session object * - * Debug flag files will contain "magic strings" like `__SENTRY_DEBUG__` that may get replaced with actual values during - * our, or the user's build process. Take care when introducing new flags - they must not throw if they are not - * replaced. + * @returns the new active session */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -/** Flag that is true for debug builds, false otherwise. */ -exports.IS_DEBUG_BUILD = typeof __SENTRY_DEBUG__ === 'undefined' ? true : __SENTRY_DEBUG__; -//# sourceMappingURL=flags.js.map +function startSession(context) { + const client = getClient(); + const isolationScope = hub.getIsolationScope(); + const currentScope = getCurrentScope(); -/***/ }), + const { release, environment = constants.DEFAULT_ENVIRONMENT } = (client && client.getOptions()) || {}; -/***/ 60038: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + // Will fetch userAgent if called from browser sdk + const { userAgent } = utils.GLOBAL_OBJ.navigator || {}; + + const session$1 = session.makeSession({ + release, + environment, + user: currentScope.getUser() || isolationScope.getUser(), + ...(userAgent && { userAgent }), + ...context, + }); + + // End existing session if there's one + const currentSession = isolationScope.getSession(); + if (currentSession && currentSession.status === 'ok') { + session.updateSession(currentSession, { status: 'exited' }); + } + + endSession(); + + // Afterwards we set the new session on the scope + isolationScope.setSession(session$1); + + // TODO (v8): Remove this and only use the isolation scope(?). + // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession() + currentScope.setSession(session$1); + + return session$1; +} -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -/* eslint-disable max-lines */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -var core_1 = __nccwpck_require__(41429); -var utils_1 = __nccwpck_require__(6785); -var cookie = __nccwpck_require__(10011); -var domain = __nccwpck_require__(73167); -var os = __nccwpck_require__(70857); -var url = __nccwpck_require__(87016); -var flags_1 = __nccwpck_require__(62976); -var sdk_1 = __nccwpck_require__(80915); /** - * Express-compatible tracing handler. - * @see Exposed as `Handlers.tracingHandler` - */ -function tracingHandler() { - return function sentryTracingMiddleware(req, res, next) { - // If there is a trace header set, we extract the data from it (parentSpanId, traceId, and sampling decision) - var traceparentData; - if (req.headers && utils_1.isString(req.headers['sentry-trace'])) { - traceparentData = utils_1.extractTraceparentData(req.headers['sentry-trace']); - } - var transaction = core_1.startTransaction(tslib_1.__assign({ name: extractExpressTransactionName(req, { path: true, method: true }), op: 'http.server' }, traceparentData), - // extra context passed to the tracesSampler - { request: extractRequestData(req) }); - // We put the transaction on the scope so users can attach children to it - core_1.getCurrentHub().configureScope(function (scope) { - scope.setSpan(transaction); - }); - // We also set __sentry_transaction on the response so people can grab the transaction there to add - // spans to it later. - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - res.__sentry_transaction = transaction; - res.once('finish', function () { - // Push `transaction.finish` to the next event loop so open spans have a chance to finish before the transaction - // closes - setImmediate(function () { - addExpressReqToTransaction(transaction, req); - transaction.setHttpStatus(res.statusCode); - transaction.finish(); - }); - }); - next(); - }; -} -exports.tracingHandler = tracingHandler; -/** - * Set parameterized as transaction name e.g.: `GET /users/:id` - * Also adds more context data on the transaction from the request - */ -function addExpressReqToTransaction(transaction, req) { - if (!transaction) - return; - transaction.name = extractExpressTransactionName(req, { path: true, method: true }); - transaction.setData('url', req.originalUrl); - transaction.setData('baseUrl', req.baseUrl); - transaction.setData('query', req.query); -} -/** - * Extracts complete generalized path from the request object and uses it to construct transaction name. - * - * eg. GET /mountpoint/user/:id - * - * @param req The ExpressRequest object - * @param options What to include in the transaction name (method, path, or both) - * - * @returns The fully constructed transaction name + * End the session on the current isolation scope. */ -function extractExpressTransactionName(req, options) { - if (options === void 0) { options = {}; } - var _a; - var method = (_a = req.method) === null || _a === void 0 ? void 0 : _a.toUpperCase(); - var path = ''; - if (req.route) { - path = "" + (req.baseUrl || '') + req.route.path; - } - else if (req.originalUrl || req.url) { - path = utils_1.stripUrlQueryAndFragment(req.originalUrl || req.url || ''); - } - var info = ''; - if (options.method && method) { - info += method; - } - if (options.method && options.path) { - info += ' '; - } - if (options.path && path) { - info += path; - } - return info; -} -/** JSDoc */ -function extractTransaction(req, type) { - var _a; - switch (type) { - case 'path': { - return extractExpressTransactionName(req, { path: true }); - } - case 'handler': { - return ((_a = req.route) === null || _a === void 0 ? void 0 : _a.stack[0].name) || ''; - } - case 'methodPath': - default: { - return extractExpressTransactionName(req, { path: true, method: true }); - } - } -} -/** Default user keys that'll be used to extract data from the request */ -var DEFAULT_USER_KEYS = ['id', 'username', 'email']; -/** JSDoc */ -function extractUserData(user, keys) { - var extractedUser = {}; - var attributes = Array.isArray(keys) ? keys : DEFAULT_USER_KEYS; - attributes.forEach(function (key) { - if (user && key in user) { - extractedUser[key] = user[key]; - } - }); - return extractedUser; +function endSession() { + const isolationScope = hub.getIsolationScope(); + const currentScope = getCurrentScope(); + + const session$1 = currentScope.getSession() || isolationScope.getSession(); + if (session$1) { + session.closeSession(session$1); + } + _sendSessionUpdate(); + + // the session is over; take it off of the scope + isolationScope.setSession(); + + // TODO (v8): Remove this and only use the isolation scope(?). + // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession() + currentScope.setSession(); } -/** Default request keys that'll be used to extract data from the request */ -var DEFAULT_REQUEST_KEYS = ['cookies', 'data', 'headers', 'method', 'query_string', 'url']; + /** - * Normalizes data from the request object, accounting for framework differences. - * - * @param req The request object from which to extract data - * @param keys An optional array of keys to include in the normalized data. Defaults to DEFAULT_REQUEST_KEYS if not - * provided. - * @returns An object containing normalized request data + * Sends the current Session on the scope */ -function extractRequestData(req, keys) { - if (keys === void 0) { keys = DEFAULT_REQUEST_KEYS; } - var requestData = {}; - // headers: - // node, express, nextjs: req.headers - // koa: req.header - var headers = (req.headers || req.header || {}); - // method: - // node, express, koa, nextjs: req.method - var method = req.method; - // host: - // express: req.hostname in > 4 and req.host in < 4 - // koa: req.host - // node, nextjs: req.headers.host - var host = req.hostname || req.host || headers.host || ''; - // protocol: - // node, nextjs: - // express, koa: req.protocol - var protocol = req.protocol === 'https' || req.secure || (req.socket || {}).encrypted - ? 'https' - : 'http'; - // url (including path and query string): - // node, express: req.originalUrl - // koa, nextjs: req.url - var originalUrl = (req.originalUrl || req.url || ''); - // absolute url - var absoluteUrl = protocol + "://" + host + originalUrl; - keys.forEach(function (key) { - switch (key) { - case 'headers': - requestData.headers = headers; - break; - case 'method': - requestData.method = method; - break; - case 'url': - requestData.url = absoluteUrl; - break; - case 'cookies': - // cookies: - // node, express, koa: req.headers.cookie - // vercel, sails.js, express (w/ cookie middleware), nextjs: req.cookies - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - requestData.cookies = req.cookies || cookie.parse(headers.cookie || ''); - break; - case 'query_string': - // query string: - // node: req.url (raw) - // express, koa, nextjs: req.query - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - requestData.query_string = req.query || url.parse(originalUrl || '', false).query; - break; - case 'data': - if (method === 'GET' || method === 'HEAD') { - break; - } - // body data: - // express, koa, nextjs: req.body - // - // when using node by itself, you have to read the incoming stream(see - // https://nodejs.dev/learn/get-http-request-body-data-using-nodejs); if a user is doing that, we can't know - // where they're going to store the final result, so they'll have to capture this data themselves - if (req.body !== undefined) { - requestData.data = utils_1.isString(req.body) ? req.body : JSON.stringify(utils_1.normalize(req.body)); - } - break; - default: - if ({}.hasOwnProperty.call(req, key)) { - requestData[key] = req[key]; - } - } - }); - return requestData; +function _sendSessionUpdate() { + const isolationScope = hub.getIsolationScope(); + const currentScope = getCurrentScope(); + const client = getClient(); + // TODO (v8): Remove currentScope and only use the isolation scope(?). + // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession() + const session = currentScope.getSession() || isolationScope.getSession(); + if (session && client && client.captureSession) { + client.captureSession(session); + } } -exports.extractRequestData = extractRequestData; + /** - * Enriches passed event with request data. + * Sends the current session on the scope to Sentry * - * @param event Will be mutated and enriched with req data - * @param req Request object - * @param options object containing flags to enable functionality - * @hidden - */ -function parseRequest(event, req, options) { - // eslint-disable-next-line no-param-reassign - options = tslib_1.__assign({ ip: false, request: true, serverName: true, transaction: true, user: true, version: true }, options); - if (options.version) { - event.contexts = tslib_1.__assign(tslib_1.__assign({}, event.contexts), { runtime: { - name: 'node', - version: global.process.version, - } }); - } - if (options.request) { - // if the option value is `true`, use the default set of keys by not passing anything to `extractRequestData()` - var extractedRequestData = Array.isArray(options.request) - ? extractRequestData(req, options.request) - : extractRequestData(req); - event.request = tslib_1.__assign(tslib_1.__assign({}, event.request), extractedRequestData); - } - if (options.serverName && !event.server_name) { - event.server_name = global.process.env.SENTRY_NAME || os.hostname(); - } - if (options.user) { - var extractedUser = req.user && utils_1.isPlainObject(req.user) ? extractUserData(req.user, options.user) : {}; - if (Object.keys(extractedUser)) { - event.user = tslib_1.__assign(tslib_1.__assign({}, event.user), extractedUser); - } - } - // client ip: - // node, nextjs: req.connection.remoteAddress - // express, koa: req.ip - if (options.ip) { - var ip = req.ip || (req.connection && req.connection.remoteAddress); - if (ip) { - event.user = tslib_1.__assign(tslib_1.__assign({}, event.user), { ip_address: ip }); - } - } - if (options.transaction && !event.transaction) { - // TODO do we even need this anymore? - // TODO make this work for nextjs - event.transaction = extractTransaction(req, options.transaction); - } - return event; -} -exports.parseRequest = parseRequest; -/** - * Express compatible request handler. - * @see Exposed as `Handlers.requestHandler` - */ -function requestHandler(options) { - var currentHub = core_1.getCurrentHub(); - var client = currentHub.getClient(); - // Initialise an instance of SessionFlusher on the client when `autoSessionTracking` is enabled and the - // `requestHandler` middleware is used indicating that we are running in SessionAggregates mode - if (client && sdk_1.isAutoSessionTrackingEnabled(client)) { - client.initSessionFlusher(); - // If Scope contains a Single mode Session, it is removed in favor of using Session Aggregates mode - var scope = currentHub.getScope(); - if (scope && scope.getSession()) { - scope.setSession(); - } - } - return function sentryRequestMiddleware(req, res, next) { - if (options && options.flushTimeout && options.flushTimeout > 0) { - // eslint-disable-next-line @typescript-eslint/unbound-method - var _end_1 = res.end; - res.end = function (chunk, encoding, cb) { - var _this = this; - void sdk_1.flush(options.flushTimeout) - .then(function () { - _end_1.call(_this, chunk, encoding, cb); - }) - .then(null, function (e) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.error(e); - _end_1.call(_this, chunk, encoding, cb); - }); - }; - } - var local = domain.create(); - local.add(req); - local.add(res); - local.on('error', next); - local.run(function () { - var currentHub = core_1.getCurrentHub(); - currentHub.configureScope(function (scope) { - scope.addEventProcessor(function (event) { return parseRequest(event, req, options); }); - var client = currentHub.getClient(); - if (sdk_1.isAutoSessionTrackingEnabled(client)) { - var scope_1 = currentHub.getScope(); - if (scope_1) { - // Set `status` of `RequestSession` to Ok, at the beginning of the request - scope_1.setRequestSession({ status: 'ok' }); - } - } - }); - res.once('finish', function () { - var client = currentHub.getClient(); - if (sdk_1.isAutoSessionTrackingEnabled(client)) { - setImmediate(function () { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - if (client && client._captureRequestSession) { - // Calling _captureRequestSession to capture request session at the end of the request by incrementing - // the correct SessionAggregates bucket i.e. crashed, errored or exited - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - client._captureRequestSession(); - } - }); - } - }); - next(); - }); - }; -} -exports.requestHandler = requestHandler; -/** JSDoc */ -function getStatusCodeFromResponse(error) { - var statusCode = error.status || error.statusCode || error.status_code || (error.output && error.output.statusCode); - return statusCode ? parseInt(statusCode, 10) : 500; -} -/** Returns true if response code is internal server error */ -function defaultShouldHandleError(error) { - var status = getStatusCodeFromResponse(error); - return status >= 500; -} -/** - * Express compatible error handler. - * @see Exposed as `Handlers.errorHandler` + * @param end If set the session will be marked as exited and removed from the scope. + * Defaults to `false`. */ -function errorHandler(options) { - return function sentryErrorMiddleware(error, _req, res, next) { - // eslint-disable-next-line @typescript-eslint/unbound-method - var shouldHandleError = (options && options.shouldHandleError) || defaultShouldHandleError; - if (shouldHandleError(error)) { - core_1.withScope(function (_scope) { - // For some reason we need to set the transaction on the scope again - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - var transaction = res.__sentry_transaction; - if (transaction && _scope.getSpan() === undefined) { - _scope.setSpan(transaction); - } - var client = core_1.getCurrentHub().getClient(); - if (client && sdk_1.isAutoSessionTrackingEnabled(client)) { - // Check if the `SessionFlusher` is instantiated on the client to go into this branch that marks the - // `requestSession.status` as `Crashed`, and this check is necessary because the `SessionFlusher` is only - // instantiated when the the`requestHandler` middleware is initialised, which indicates that we should be - // running in SessionAggregates mode - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - var isSessionAggregatesMode = client._sessionFlusher !== undefined; - if (isSessionAggregatesMode) { - var requestSession = _scope.getRequestSession(); - // If an error bubbles to the `errorHandler`, then this is an unhandled error, and should be reported as a - // Crashed session. The `_requestSession.status` is checked to ensure that this error is happening within - // the bounds of a request, and if so the status is updated - if (requestSession && requestSession.status !== undefined) { - requestSession.status = 'crashed'; - } - } - } - var eventId = core_1.captureException(error); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - res.sentry = eventId; - next(error); - }); - return; - } - next(error); - }; -} -exports.errorHandler = errorHandler; -//# sourceMappingURL=handlers.js.map +function captureSession(end = false) { + // both send the update and pull the session from the scope + if (end) { + endSession(); + return; + } -/***/ }), + // only send the update + _sendSessionUpdate(); +} -/***/ 99931: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +exports.addBreadcrumb = addBreadcrumb; +exports.captureCheckIn = captureCheckIn; +exports.captureEvent = captureEvent; +exports.captureException = captureException; +exports.captureMessage = captureMessage; +exports.captureSession = captureSession; +exports.close = close; +exports.configureScope = configureScope; +exports.endSession = endSession; +exports.flush = flush; +exports.getClient = getClient; +exports.getCurrentScope = getCurrentScope; +exports.isInitialized = isInitialized; +exports.lastEventId = lastEventId; +exports.setContext = setContext; +exports.setExtra = setExtra; +exports.setExtras = setExtras; +exports.setTag = setTag; +exports.setTags = setTags; +exports.setUser = setUser; +exports.startSession = startSession; +exports.startTransaction = startTransaction; +exports.withActiveSpan = withActiveSpan; +exports.withIsolationScope = withIsolationScope; +exports.withMonitor = withMonitor; +exports.withScope = withScope; +//# sourceMappingURL=exports.js.map -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var types_1 = __nccwpck_require__(34105); -exports.Severity = types_1.Severity; -var core_1 = __nccwpck_require__(41429); -exports.addGlobalEventProcessor = core_1.addGlobalEventProcessor; -exports.addBreadcrumb = core_1.addBreadcrumb; -exports.captureException = core_1.captureException; -exports.captureEvent = core_1.captureEvent; -exports.captureMessage = core_1.captureMessage; -exports.configureScope = core_1.configureScope; -exports.getHubFromCarrier = core_1.getHubFromCarrier; -exports.getCurrentHub = core_1.getCurrentHub; -exports.Hub = core_1.Hub; -exports.makeMain = core_1.makeMain; -exports.Scope = core_1.Scope; -exports.Session = core_1.Session; -exports.startTransaction = core_1.startTransaction; -exports.SDK_VERSION = core_1.SDK_VERSION; -exports.setContext = core_1.setContext; -exports.setExtra = core_1.setExtra; -exports.setExtras = core_1.setExtras; -exports.setTag = core_1.setTag; -exports.setTags = core_1.setTags; -exports.setUser = core_1.setUser; -exports.withScope = core_1.withScope; -var backend_1 = __nccwpck_require__(61647); -exports.NodeBackend = backend_1.NodeBackend; -var client_1 = __nccwpck_require__(49652); -exports.NodeClient = client_1.NodeClient; -var sdk_1 = __nccwpck_require__(80915); -exports.defaultIntegrations = sdk_1.defaultIntegrations; -exports.init = sdk_1.init; -exports.lastEventId = sdk_1.lastEventId; -exports.flush = sdk_1.flush; -exports.close = sdk_1.close; -exports.getSentryRelease = sdk_1.getSentryRelease; -var utils_1 = __nccwpck_require__(73254); -exports.deepReadDirSync = utils_1.deepReadDirSync; -var version_1 = __nccwpck_require__(40275); -exports.SDK_NAME = version_1.SDK_NAME; -var core_2 = __nccwpck_require__(41429); -var hub_1 = __nccwpck_require__(17237); -var domain = __nccwpck_require__(73167); -var Handlers = __nccwpck_require__(60038); -exports.Handlers = Handlers; -var NodeIntegrations = __nccwpck_require__(75887); -var Transports = __nccwpck_require__(54950); -exports.Transports = Transports; -var INTEGRATIONS = tslib_1.__assign(tslib_1.__assign({}, core_2.Integrations), NodeIntegrations); -exports.Integrations = INTEGRATIONS; -// We need to patch domain on the global __SENTRY__ object to make it work for node in cross-platform packages like -// @sentry/hub. If we don't do this, browser bundlers will have troubles resolving `require('domain')`. -var carrier = hub_1.getMainCarrier(); -if (carrier.__SENTRY__) { - carrier.__SENTRY__.extensions = carrier.__SENTRY__.extensions || {}; - carrier.__SENTRY__.extensions.domain = carrier.__SENTRY__.extensions.domain || domain; -} -//# sourceMappingURL=index.js.map /***/ }), -/***/ 21342: +/***/ 18205: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var utils_1 = __nccwpck_require__(6785); -var util = __nccwpck_require__(39023); -/** Console module integration */ -var Console = /** @class */ (function () { - function Console() { - /** - * @inheritDoc - */ - this.name = Console.id; - } - /** - * @inheritDoc - */ - Console.prototype.setupOnce = function () { - var e_1, _a; - try { - for (var _b = tslib_1.__values(['debug', 'info', 'warn', 'error', 'log']), _c = _b.next(); !_c.done; _c = _b.next()) { - var level = _c.value; - utils_1.fill(console, level, createConsoleWrapper(level)); - } - } - 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; } - } - }; - /** - * @inheritDoc - */ - Console.id = 'Console'; - return Console; -}()); -exports.Console = Console; -/** - * Wrapper function that'll be used for every console level - */ -function createConsoleWrapper(level) { - return function consoleWrapper(originalConsoleMethod) { - var sentryLevel = utils_1.severityFromString(level); - /* eslint-disable prefer-rest-params */ - return function () { - if (core_1.getCurrentHub().getIntegration(Console)) { - core_1.getCurrentHub().addBreadcrumb({ - category: 'console', - level: sentryLevel, - message: util.format.apply(undefined, arguments), - }, { - input: tslib_1.__spread(arguments), - level: level, - }); - } - originalConsoleMethod.apply(this, arguments); - }; - /* eslint-enable prefer-rest-params */ - }; -} -//# sourceMappingURL=console.js.map - -/***/ }), -/***/ 23157: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +const utils = __nccwpck_require__(57540); +const constants = __nccwpck_require__(11363); +const debugBuild = __nccwpck_require__(93376); +const scope = __nccwpck_require__(77226); +const session = __nccwpck_require__(14638); +const version = __nccwpck_require__(3206); -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var utils_1 = __nccwpck_require__(6785); -var fs_1 = __nccwpck_require__(79896); -var lru_map_1 = __nccwpck_require__(94012); -var FILE_CONTENT_CACHE = new lru_map_1.LRUMap(100); -var DEFAULT_LINES_OF_CONTEXT = 7; -// TODO: Replace with promisify when minimum supported node >= v8 -function readTextFileAsync(path) { - return new Promise(function (resolve, reject) { - fs_1.readFile(path, 'utf8', function (err, data) { - if (err) - reject(err); - else - resolve(data); - }); - }); -} /** - * Resets the file cache. Exists for testing purposes. + * API compatibility version of this hub. + * + * WARNING: This number should only be increased when the global interface + * changes and new methods are introduced. + * * @hidden */ -function resetFileContentCache() { - FILE_CONTENT_CACHE.clear(); -} -exports.resetFileContentCache = resetFileContentCache; -/** Add node modules / packages to the event */ -var ContextLines = /** @class */ (function () { - function ContextLines(_options) { - if (_options === void 0) { _options = {}; } - this._options = _options; - /** - * @inheritDoc - */ - this.name = ContextLines.id; - } - Object.defineProperty(ContextLines.prototype, "_contextLines", { - /** Get's the number of context lines to add */ - get: function () { - var _a, _b; - // This is only here to copy frameContextLines from init options if it hasn't - // been set via this integrations constructor. - // - // TODO: Remove on next major! - if (this._options.frameContextLines === undefined) { - var initOptions = (_a = core_1.getCurrentHub().getClient()) === null || _a === void 0 ? void 0 : _a.getOptions(); - // eslint-disable-next-line deprecation/deprecation - this._options.frameContextLines = (_b = initOptions) === null || _b === void 0 ? void 0 : _b.frameContextLines; - } - return this._options.frameContextLines !== undefined ? this._options.frameContextLines : DEFAULT_LINES_OF_CONTEXT; - }, - enumerable: true, - configurable: true - }); - /** - * @inheritDoc - */ - ContextLines.prototype.setupOnce = function (addGlobalEventProcessor) { - var _this = this; - addGlobalEventProcessor(function (event) { return _this.addSourceContext(event); }); - }; - /** Processes an event and adds context lines */ - ContextLines.prototype.addSourceContext = function (event) { - var _a, _b; - return tslib_1.__awaiter(this, void 0, void 0, function () { - var _c, _d, exception, e_1_1; - var e_1, _e; - return tslib_1.__generator(this, function (_f) { - switch (_f.label) { - case 0: - if (!(this._contextLines > 0 && ((_a = event.exception) === null || _a === void 0 ? void 0 : _a.values))) return [3 /*break*/, 8]; - _f.label = 1; - case 1: - _f.trys.push([1, 6, 7, 8]); - _c = tslib_1.__values(event.exception.values), _d = _c.next(); - _f.label = 2; - case 2: - if (!!_d.done) return [3 /*break*/, 5]; - exception = _d.value; - if (!((_b = exception.stacktrace) === null || _b === void 0 ? void 0 : _b.frames)) return [3 /*break*/, 4]; - return [4 /*yield*/, this.addSourceContextToFrames(exception.stacktrace.frames)]; - case 3: - _f.sent(); - _f.label = 4; - case 4: - _d = _c.next(); - return [3 /*break*/, 2]; - case 5: return [3 /*break*/, 8]; - case 6: - e_1_1 = _f.sent(); - e_1 = { error: e_1_1 }; - return [3 /*break*/, 8]; - case 7: - try { - if (_d && !_d.done && (_e = _c.return)) _e.call(_c); - } - finally { if (e_1) throw e_1.error; } - return [7 /*endfinally*/]; - case 8: return [2 /*return*/, event]; - } - }); - }); - }; - /** Adds context lines to frames */ - ContextLines.prototype.addSourceContextToFrames = function (frames) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var contextLines, frames_1, frames_1_1, frame, sourceFile, lines, e_2_1; - var e_2, _a; - return tslib_1.__generator(this, function (_b) { - switch (_b.label) { - case 0: - contextLines = this._contextLines; - _b.label = 1; - case 1: - _b.trys.push([1, 6, 7, 8]); - frames_1 = tslib_1.__values(frames), frames_1_1 = frames_1.next(); - _b.label = 2; - case 2: - if (!!frames_1_1.done) return [3 /*break*/, 5]; - frame = frames_1_1.value; - if (!(frame.filename && frame.context_line === undefined)) return [3 /*break*/, 4]; - return [4 /*yield*/, _readSourceFile(frame.filename)]; - case 3: - sourceFile = _b.sent(); - if (sourceFile) { - try { - lines = sourceFile.split('\n'); - utils_1.addContextToFrame(lines, frame, contextLines); - } - catch (e) { - // anomaly, being defensive in case - // unlikely to ever happen in practice but can definitely happen in theory - } - } - _b.label = 4; - case 4: - frames_1_1 = frames_1.next(); - return [3 /*break*/, 2]; - case 5: return [3 /*break*/, 8]; - case 6: - e_2_1 = _b.sent(); - e_2 = { error: e_2_1 }; - return [3 /*break*/, 8]; - case 7: - try { - if (frames_1_1 && !frames_1_1.done && (_a = frames_1.return)) _a.call(frames_1); - } - finally { if (e_2) throw e_2.error; } - return [7 /*endfinally*/]; - case 8: return [2 /*return*/]; - } - }); - }); - }; - /** - * @inheritDoc - */ - ContextLines.id = 'ContextLines'; - return ContextLines; -}()); -exports.ContextLines = ContextLines; +const API_VERSION = parseFloat(version.SDK_VERSION); + /** - * Reads file contents and caches them in a global LRU cache. - * - * @param filename filepath to read content from. + * Default maximum number of breadcrumbs added to an event. Can be overwritten + * with {@link Options.maxBreadcrumbs}. */ -function _readSourceFile(filename) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var cachedFile, content, _1; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - cachedFile = FILE_CONTENT_CACHE.get(filename); - // We have a cache hit - if (cachedFile !== undefined) { - return [2 /*return*/, cachedFile]; - } - content = null; - _a.label = 1; - case 1: - _a.trys.push([1, 3, , 4]); - return [4 /*yield*/, readTextFileAsync(filename)]; - case 2: - content = _a.sent(); - return [3 /*break*/, 4]; - case 3: - _1 = _a.sent(); - return [3 /*break*/, 4]; - case 4: - FILE_CONTENT_CACHE.set(filename, content); - return [2 /*return*/, content]; - } - }); - }); -} -//# sourceMappingURL=contextlines.js.map - -/***/ }), - -/***/ 89563: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +const DEFAULT_BREADCRUMBS = 100; -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var utils_1 = __nccwpck_require__(6785); -var flags_1 = __nccwpck_require__(62976); -var http_1 = __nccwpck_require__(97909); -var NODE_VERSION = utils_1.parseSemver(process.versions.node); -/** http module integration */ -var Http = /** @class */ (function () { - /** - * @inheritDoc - */ - function Http(options) { - if (options === void 0) { options = {}; } - /** - * @inheritDoc - */ - this.name = Http.id; - this._breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs; - this._tracing = typeof options.tracing === 'undefined' ? false : options.tracing; - } - /** - * @inheritDoc - */ - Http.prototype.setupOnce = function () { - // No need to instrument if we don't want to track anything - if (!this._breadcrumbs && !this._tracing) { - return; - } - var wrappedHandlerMaker = _createWrappedRequestMethodFactory(this._breadcrumbs, this._tracing); - // eslint-disable-next-line @typescript-eslint/no-var-requires - var httpModule = __nccwpck_require__(58611); - utils_1.fill(httpModule, 'get', wrappedHandlerMaker); - utils_1.fill(httpModule, 'request', wrappedHandlerMaker); - // NOTE: Prior to Node 9, `https` used internals of `http` module, thus we don't patch it. - // If we do, we'd get double breadcrumbs and double spans for `https` calls. - // It has been changed in Node 9, so for all versions equal and above, we patch `https` separately. - if (NODE_VERSION.major && NODE_VERSION.major > 8) { - // eslint-disable-next-line @typescript-eslint/no-var-requires - var httpsModule = __nccwpck_require__(65692); - utils_1.fill(httpsModule, 'get', wrappedHandlerMaker); - utils_1.fill(httpsModule, 'request', wrappedHandlerMaker); - } - }; - /** - * @inheritDoc - */ - Http.id = 'Http'; - return Http; -}()); -exports.Http = Http; /** - * Function which creates a function which creates wrapped versions of internal `request` and `get` calls within `http` - * and `https` modules. (NB: Not a typo - this is a creator^2!) + * @deprecated The `Hub` class will be removed in version 8 of the SDK in favour of `Scope` and `Client` objects. * - * @param breadcrumbsEnabled Whether or not to record outgoing requests as breadcrumbs - * @param tracingEnabled Whether or not to record outgoing requests as tracing spans + * If you previously used the `Hub` class directly, replace it with `Scope` and `Client` objects. More information: + * - [Multiple Sentry Instances](https://docs.sentry.io/platforms/javascript/best-practices/multiple-sentry-instances/) + * - [Browser Extensions](https://docs.sentry.io/platforms/javascript/best-practices/browser-extensions/) * - * @returns A function which accepts the exiting handler and returns a wrapped handler - */ -function _createWrappedRequestMethodFactory(breadcrumbsEnabled, tracingEnabled) { - return function wrappedRequestMethodFactory(originalRequestMethod) { - return function wrappedMethod() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - // eslint-disable-next-line @typescript-eslint/no-this-alias - var httpModule = this; - var requestArgs = http_1.normalizeRequestArgs(this, args); - var requestOptions = requestArgs[0]; - var requestUrl = http_1.extractUrl(requestOptions); - // we don't want to record requests to Sentry as either breadcrumbs or spans, so just use the original method - if (http_1.isSentryRequest(requestUrl)) { - return originalRequestMethod.apply(httpModule, requestArgs); - } - var span; - var parentSpan; - var scope = core_1.getCurrentHub().getScope(); - if (scope && tracingEnabled) { - parentSpan = scope.getSpan(); - if (parentSpan) { - span = parentSpan.startChild({ - description: (requestOptions.method || 'GET') + " " + requestUrl, - op: 'http.client', - }); - var sentryTraceHeader = span.toTraceparent(); - flags_1.IS_DEBUG_BUILD && - utils_1.logger.log("[Tracing] Adding sentry-trace header " + sentryTraceHeader + " to outgoing request to " + requestUrl + ": "); - requestOptions.headers = tslib_1.__assign(tslib_1.__assign({}, requestOptions.headers), { 'sentry-trace': sentryTraceHeader }); - } - } - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - return originalRequestMethod - .apply(httpModule, requestArgs) - .once('response', function (res) { - // eslint-disable-next-line @typescript-eslint/no-this-alias - var req = this; - if (breadcrumbsEnabled) { - addRequestBreadcrumb('response', requestUrl, req, res); - } - if (tracingEnabled && span) { - if (res.statusCode) { - span.setHttpStatus(res.statusCode); - } - span.description = http_1.cleanSpanDescription(span.description, requestOptions, req); - span.finish(); - } - }) - .once('error', function () { - // eslint-disable-next-line @typescript-eslint/no-this-alias - var req = this; - if (breadcrumbsEnabled) { - addRequestBreadcrumb('error', requestUrl, req); - } - if (tracingEnabled && span) { - span.setHttpStatus(500); - span.description = http_1.cleanSpanDescription(span.description, requestOptions, req); - span.finish(); - } - }); - }; - }; -} -/** - * Captures Breadcrumb based on provided request/response pair + * Some of our APIs are typed with the Hub class instead of the interface (e.g. `getCurrentHub`). Most of them are deprecated + * themselves and will also be removed in version 8. More information: + * - [Migration Guide](https://github.com/getsentry/sentry-javascript/blob/develop/MIGRATION.md#deprecate-hub) */ -function addRequestBreadcrumb(event, url, req, res) { - if (!core_1.getCurrentHub().getIntegration(Http)) { - return; +// eslint-disable-next-line deprecation/deprecation +class Hub { + /** Is a {@link Layer}[] containing the client and scope */ + + /** Contains the last event id of a captured event. */ + + /** + * Creates a new instance of the hub, will push one {@link Layer} into the + * internal stack on creation. + * + * @param client bound to the hub. + * @param scope bound to the hub. + * @param version number, higher number means higher priority. + * + * @deprecated Instantiation of Hub objects is deprecated and the constructor will be removed in version 8 of the SDK. + * + * If you are currently using the Hub for multi-client use like so: + * + * ``` + * // OLD + * const hub = new Hub(); + * hub.bindClient(client); + * makeMain(hub) + * ``` + * + * instead initialize the client as follows: + * + * ``` + * // NEW + * Sentry.withIsolationScope(() => { + * Sentry.setCurrentClient(client); + * client.init(); + * }); + * ``` + * + * If you are using the Hub to capture events like so: + * + * ``` + * // OLD + * const client = new Client(); + * const hub = new Hub(client); + * hub.captureException() + * ``` + * + * instead capture isolated events as follows: + * + * ``` + * // NEW + * const client = new Client(); + * const scope = new Scope(); + * scope.setClient(client); + * scope.captureException(); + * ``` + */ + constructor( + client, + scope$1, + isolationScope, + _version = API_VERSION, + ) {this._version = _version; + let assignedScope; + if (!scope$1) { + assignedScope = new scope.Scope(); + assignedScope.setClient(client); + } else { + assignedScope = scope$1; } - core_1.getCurrentHub().addBreadcrumb({ - category: 'http', - data: { - method: req.method, - status_code: res && res.statusCode, - url: url, - }, - type: 'http', - }, { - event: event, - request: req, - response: res, - }); -} -//# sourceMappingURL=http.js.map -/***/ }), + let assignedIsolationScope; + if (!isolationScope) { + assignedIsolationScope = new scope.Scope(); + assignedIsolationScope.setClient(client); + } else { + assignedIsolationScope = isolationScope; + } -/***/ 75887: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + this._stack = [{ scope: assignedScope }]; -Object.defineProperty(exports, "__esModule", ({ value: true })); -var console_1 = __nccwpck_require__(21342); -exports.Console = console_1.Console; -var http_1 = __nccwpck_require__(89563); -exports.Http = http_1.Http; -var onuncaughtexception_1 = __nccwpck_require__(44516); -exports.OnUncaughtException = onuncaughtexception_1.OnUncaughtException; -var onunhandledrejection_1 = __nccwpck_require__(43564); -exports.OnUnhandledRejection = onunhandledrejection_1.OnUnhandledRejection; -var linkederrors_1 = __nccwpck_require__(76545); -exports.LinkedErrors = linkederrors_1.LinkedErrors; -var modules_1 = __nccwpck_require__(66790); -exports.Modules = modules_1.Modules; -var contextlines_1 = __nccwpck_require__(23157); -exports.ContextLines = contextlines_1.ContextLines; -//# sourceMappingURL=index.js.map + if (client) { + // eslint-disable-next-line deprecation/deprecation + this.bindClient(client); + } -/***/ }), + this._isolationScope = assignedIsolationScope; + } -/***/ 76545: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + /** + * Checks if this hub's version is older than the given version. + * + * @param version A version number to compare to. + * @return True if the given version is newer; otherwise false. + * + * @deprecated This will be removed in v8. + */ + isOlderThan(version) { + return this._version < version; + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var utils_1 = __nccwpck_require__(6785); -var eventbuilder_1 = __nccwpck_require__(77196); -var contextlines_1 = __nccwpck_require__(23157); -var DEFAULT_KEY = 'cause'; -var DEFAULT_LIMIT = 5; -/** Adds SDK info to an event. */ -var LinkedErrors = /** @class */ (function () { - /** - * @inheritDoc - */ - function LinkedErrors(options) { - if (options === void 0) { options = {}; } - /** - * @inheritDoc - */ - this.name = LinkedErrors.id; - this._key = options.key || DEFAULT_KEY; - this._limit = options.limit || DEFAULT_LIMIT; + /** + * This binds the given client to the current scope. + * @param client An SDK client (client) instance. + * + * @deprecated Use `initAndBind()` directly, or `setCurrentClient()` and/or `client.init()` instead. + */ + bindClient(client) { + // eslint-disable-next-line deprecation/deprecation + const top = this.getStackTop(); + top.client = client; + top.scope.setClient(client); + // eslint-disable-next-line deprecation/deprecation + if (client && client.setupIntegrations) { + // eslint-disable-next-line deprecation/deprecation + client.setupIntegrations(); } - /** - * @inheritDoc - */ - LinkedErrors.prototype.setupOnce = function () { - core_1.addGlobalEventProcessor(function (event, hint) { - var self = core_1.getCurrentHub().getIntegration(LinkedErrors); - if (self) { - var handler = self._handler && self._handler.bind(self); - return typeof handler === 'function' ? handler(event, hint) : event; - } - return event; - }); - }; - /** - * @inheritDoc - */ - LinkedErrors.prototype._handler = function (event, hint) { - var _this = this; - if (!event.exception || !event.exception.values || !hint || !utils_1.isInstanceOf(hint.originalException, Error)) { - return utils_1.resolvedSyncPromise(event); - } - return new utils_1.SyncPromise(function (resolve) { - void _this._walkErrorTree(hint.originalException, _this._key) - .then(function (linkedErrors) { - if (event && event.exception && event.exception.values) { - event.exception.values = tslib_1.__spread(linkedErrors, event.exception.values); - } - resolve(event); - }) - .then(null, function () { - resolve(event); - }); - }); - }; - /** - * @inheritDoc - */ - LinkedErrors.prototype._walkErrorTree = function (error, key, stack) { - if (stack === void 0) { stack = []; } - var _a; - return tslib_1.__awaiter(this, void 0, void 0, function () { - var exception, contextLines; - var _this = this; - return tslib_1.__generator(this, function (_b) { - switch (_b.label) { - case 0: - if (!utils_1.isInstanceOf(error[key], Error) || stack.length + 1 >= this._limit) { - return [2 /*return*/, Promise.resolve(stack)]; - } - exception = eventbuilder_1.exceptionFromError(error[key]); - contextLines = core_1.getCurrentHub().getIntegration(contextlines_1.ContextLines); - if (!(contextLines && ((_a = exception.stacktrace) === null || _a === void 0 ? void 0 : _a.frames))) return [3 /*break*/, 2]; - return [4 /*yield*/, contextLines.addSourceContextToFrames(exception.stacktrace.frames)]; - case 1: - _b.sent(); - _b.label = 2; - case 2: return [2 /*return*/, new Promise(function (resolve, reject) { - void _this._walkErrorTree(error[key], key, tslib_1.__spread([exception], stack)) - .then(resolve) - .then(null, function () { - reject(); - }); - })]; - } - }); - }); - }; - /** - * @inheritDoc - */ - LinkedErrors.id = 'LinkedErrors'; - return LinkedErrors; -}()); -exports.LinkedErrors = LinkedErrors; -//# sourceMappingURL=linkederrors.js.map + } -/***/ }), + /** + * @inheritDoc + * + * @deprecated Use `withScope` instead. + */ + pushScope() { + // We want to clone the content of prev scope + // eslint-disable-next-line deprecation/deprecation + const scope = this.getScope().clone(); + // eslint-disable-next-line deprecation/deprecation + this.getStack().push({ + // eslint-disable-next-line deprecation/deprecation + client: this.getClient(), + scope, + }); + return scope; + } -/***/ 66790: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + /** + * @inheritDoc + * + * @deprecated Use `withScope` instead. + */ + popScope() { + // eslint-disable-next-line deprecation/deprecation + if (this.getStack().length <= 1) return false; + // eslint-disable-next-line deprecation/deprecation + return !!this.getStack().pop(); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var fs_1 = __nccwpck_require__(79896); -var path_1 = __nccwpck_require__(16928); -var moduleCache; -/** Extract information about paths */ -function getPaths() { + /** + * @inheritDoc + * + * @deprecated Use `Sentry.withScope()` instead. + */ + withScope(callback) { + // eslint-disable-next-line deprecation/deprecation + const scope = this.pushScope(); + + let maybePromiseResult; try { - return require.cache ? Object.keys(require.cache) : []; - } - catch (e) { - return []; - } -} -/** Extract information about package.json modules */ -function collectModules() { - var mainPaths = (require.main && require.main.paths) || []; - var paths = getPaths(); - var infos = {}; - var seen = {}; - paths.forEach(function (path) { - var dir = path; - /** Traverse directories upward in the search of package.json file */ - var updir = function () { - var orig = dir; - dir = path_1.dirname(orig); - if (!dir || orig === dir || seen[orig]) { - return undefined; - } - if (mainPaths.indexOf(dir) < 0) { - return updir(); - } - var pkgfile = path_1.join(orig, 'package.json'); - seen[orig] = true; - if (!fs_1.existsSync(pkgfile)) { - return updir(); - } - try { - var info = JSON.parse(fs_1.readFileSync(pkgfile, 'utf8')); - infos[info.name] = info.version; - } - catch (_oO) { - // no-empty - } - }; - updir(); - }); - return infos; -} -/** Add node modules / packages to the event */ -var Modules = /** @class */ (function () { - function Modules() { - /** - * @inheritDoc - */ - this.name = Modules.id; + maybePromiseResult = callback(scope); + } catch (e) { + // eslint-disable-next-line deprecation/deprecation + this.popScope(); + throw e; + } + + if (utils.isThenable(maybePromiseResult)) { + // @ts-expect-error - isThenable returns the wrong type + return maybePromiseResult.then( + res => { + // eslint-disable-next-line deprecation/deprecation + this.popScope(); + return res; + }, + e => { + // eslint-disable-next-line deprecation/deprecation + this.popScope(); + throw e; + }, + ); } - /** - * @inheritDoc - */ - Modules.prototype.setupOnce = function (addGlobalEventProcessor, getCurrentHub) { - var _this = this; - addGlobalEventProcessor(function (event) { - if (!getCurrentHub().getIntegration(Modules)) { - return event; - } - return tslib_1.__assign(tslib_1.__assign({}, event), { modules: _this._getModules() }); - }); - }; - /** Fetches the list of modules and the versions loaded by the entry file for your node.js app. */ - Modules.prototype._getModules = function () { - if (!moduleCache) { - moduleCache = collectModules(); - } - return moduleCache; - }; - /** - * @inheritDoc - */ - Modules.id = 'Modules'; - return Modules; -}()); -exports.Modules = Modules; -//# sourceMappingURL=modules.js.map -/***/ }), + // eslint-disable-next-line deprecation/deprecation + this.popScope(); + return maybePromiseResult; + } -/***/ 44516: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + /** + * @inheritDoc + * + * @deprecated Use `Sentry.getClient()` instead. + */ + getClient() { + // eslint-disable-next-line deprecation/deprecation + return this.getStackTop().client ; + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var core_1 = __nccwpck_require__(41429); -var types_1 = __nccwpck_require__(34105); -var utils_1 = __nccwpck_require__(6785); -var flags_1 = __nccwpck_require__(62976); -var errorhandling_1 = __nccwpck_require__(87574); -/** Global Promise Rejection handler */ -var OnUncaughtException = /** @class */ (function () { - /** - * @inheritDoc - */ - function OnUncaughtException(_options) { - if (_options === void 0) { _options = {}; } - this._options = _options; - /** - * @inheritDoc - */ - this.name = OnUncaughtException.id; - /** - * @inheritDoc - */ - this.handler = this._makeErrorHandler(); - } - /** - * @inheritDoc - */ - OnUncaughtException.prototype.setupOnce = function () { - global.process.on('uncaughtException', this.handler.bind(this)); - }; - /** - * @hidden - */ - OnUncaughtException.prototype._makeErrorHandler = function () { - var _this = this; - var timeout = 2000; - var caughtFirstError = false; - var caughtSecondError = false; - var calledFatalError = false; - var firstError; - return function (error) { - var onFatalError = errorhandling_1.logAndExitProcess; - var client = core_1.getCurrentHub().getClient(); - if (_this._options.onFatalError) { - // eslint-disable-next-line @typescript-eslint/unbound-method - onFatalError = _this._options.onFatalError; - } - else if (client && client.getOptions().onFatalError) { - // eslint-disable-next-line @typescript-eslint/unbound-method - onFatalError = client.getOptions().onFatalError; - } - if (!caughtFirstError) { - var hub_1 = core_1.getCurrentHub(); - // this is the first uncaught error and the ultimate reason for shutting down - // we want to do absolutely everything possible to ensure it gets captured - // also we want to make sure we don't go recursion crazy if more errors happen after this one - firstError = error; - caughtFirstError = true; - if (hub_1.getIntegration(OnUncaughtException)) { - hub_1.withScope(function (scope) { - scope.setLevel(types_1.Severity.Fatal); - hub_1.captureException(error, { - originalException: error, - data: { mechanism: { handled: false, type: 'onuncaughtexception' } }, - }); - if (!calledFatalError) { - calledFatalError = true; - onFatalError(error); - } - }); - } - else { - if (!calledFatalError) { - calledFatalError = true; - onFatalError(error); - } - } - } - else if (calledFatalError) { - // we hit an error *after* calling onFatalError - pretty boned at this point, just shut it down - flags_1.IS_DEBUG_BUILD && - utils_1.logger.warn('uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown'); - errorhandling_1.logAndExitProcess(error); - } - else if (!caughtSecondError) { - // two cases for how we can hit this branch: - // - capturing of first error blew up and we just caught the exception from that - // - quit trying to capture, proceed with shutdown - // - a second independent error happened while waiting for first error to capture - // - want to avoid causing premature shutdown before first error capture finishes - // it's hard to immediately tell case 1 from case 2 without doing some fancy/questionable domain stuff - // so let's instead just delay a bit before we proceed with our action here - // in case 1, we just wait a bit unnecessarily but ultimately do the same thing - // in case 2, the delay hopefully made us wait long enough for the capture to finish - // two potential nonideal outcomes: - // nonideal case 1: capturing fails fast, we sit around for a few seconds unnecessarily before proceeding correctly by calling onFatalError - // nonideal case 2: case 2 happens, 1st error is captured but slowly, timeout completes before capture and we treat second error as the sendErr of (nonexistent) failure from trying to capture first error - // note that after hitting this branch, we might catch more errors where (caughtSecondError && !calledFatalError) - // we ignore them - they don't matter to us, we're just waiting for the second error timeout to finish - caughtSecondError = true; - setTimeout(function () { - if (!calledFatalError) { - // it was probably case 1, let's treat err as the sendErr and call onFatalError - calledFatalError = true; - onFatalError(firstError, error); - } - else { - // it was probably case 2, our first error finished capturing while we waited, cool, do nothing - } - }, timeout); // capturing could take at least sendTimeout to fail, plus an arbitrary second for how long it takes to collect surrounding source etc - } - }; - }; - /** - * @inheritDoc - */ - OnUncaughtException.id = 'OnUncaughtException'; - return OnUncaughtException; -}()); -exports.OnUncaughtException = OnUncaughtException; -//# sourceMappingURL=onuncaughtexception.js.map + /** + * Returns the scope of the top stack. + * + * @deprecated Use `Sentry.getCurrentScope()` instead. + */ + getScope() { + // eslint-disable-next-line deprecation/deprecation + return this.getStackTop().scope; + } -/***/ }), + /** + * @deprecated Use `Sentry.getIsolationScope()` instead. + */ + getIsolationScope() { + return this._isolationScope; + } -/***/ 43564: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + /** + * Returns the scope stack for domains or the process. + * @deprecated This will be removed in v8. + */ + getStack() { + return this._stack; + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var core_1 = __nccwpck_require__(41429); -var utils_1 = __nccwpck_require__(6785); -var errorhandling_1 = __nccwpck_require__(87574); -/** Global Promise Rejection handler */ -var OnUnhandledRejection = /** @class */ (function () { - /** - * @inheritDoc - */ - function OnUnhandledRejection(_options) { - if (_options === void 0) { _options = { mode: 'warn' }; } - this._options = _options; - /** - * @inheritDoc - */ - this.name = OnUnhandledRejection.id; - } - /** - * @inheritDoc - */ - OnUnhandledRejection.prototype.setupOnce = function () { - global.process.on('unhandledRejection', this.sendUnhandledPromise.bind(this)); - }; - /** - * Send an exception with reason - * @param reason string - * @param promise promise - */ - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any - OnUnhandledRejection.prototype.sendUnhandledPromise = function (reason, promise) { - var hub = core_1.getCurrentHub(); - if (!hub.getIntegration(OnUnhandledRejection)) { - this._handleRejection(reason); - return; - } - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - var context = (promise.domain && promise.domain.sentryContext) || {}; - hub.withScope(function (scope) { - scope.setExtra('unhandledPromiseRejection', true); - // Preserve backwards compatibility with raven-node for now - if (context.user) { - scope.setUser(context.user); - } - if (context.tags) { - scope.setTags(context.tags); - } - if (context.extra) { - scope.setExtras(context.extra); - } - hub.captureException(reason, { - originalException: promise, - data: { mechanism: { handled: false, type: 'onunhandledrejection' } }, - }); - }); - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - this._handleRejection(reason); - }; - /** - * Handler for `mode` option - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - OnUnhandledRejection.prototype._handleRejection = function (reason) { - // https://github.com/nodejs/node/blob/7cf6f9e964aa00772965391c23acda6d71972a9a/lib/internal/process/promises.js#L234-L240 - var rejectionWarning = 'This error originated either by ' + - 'throwing inside of an async function without a catch block, ' + - 'or by rejecting a promise which was not handled with .catch().' + - ' The promise rejected with the reason:'; - /* eslint-disable no-console */ - if (this._options.mode === 'warn') { - utils_1.consoleSandbox(function () { - console.warn(rejectionWarning); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - console.error(reason && reason.stack ? reason.stack : reason); - }); - } - else if (this._options.mode === 'strict') { - utils_1.consoleSandbox(function () { - console.warn(rejectionWarning); - }); - errorhandling_1.logAndExitProcess(reason); - } - /* eslint-enable no-console */ - }; - /** - * @inheritDoc - */ - OnUnhandledRejection.id = 'OnUnhandledRejection'; - return OnUnhandledRejection; -}()); -exports.OnUnhandledRejection = OnUnhandledRejection; -//# sourceMappingURL=onunhandledrejection.js.map + /** + * Returns the topmost scope layer in the order domain > local > process. + * @deprecated This will be removed in v8. + */ + getStackTop() { + return this._stack[this._stack.length - 1]; + } -/***/ }), + /** + * @inheritDoc + * + * @deprecated Use `Sentry.captureException()` instead. + */ + captureException(exception, hint) { + const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : utils.uuid4()); + const syntheticException = new Error('Sentry syntheticException'); + // eslint-disable-next-line deprecation/deprecation + this.getScope().captureException(exception, { + originalException: exception, + syntheticException, + ...hint, + event_id: eventId, + }); -/***/ 87574: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + return eventId; + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var core_1 = __nccwpck_require__(41429); -var utils_1 = __nccwpck_require__(6785); -var flags_1 = __nccwpck_require__(62976); -var DEFAULT_SHUTDOWN_TIMEOUT = 2000; -/** - * @hidden - */ -function logAndExitProcess(error) { - // eslint-disable-next-line no-console - console.error(error && error.stack ? error.stack : error); - var client = core_1.getCurrentHub().getClient(); - if (client === undefined) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn('No NodeClient was defined, we are exiting the process now.'); - global.process.exit(1); - } - var options = client.getOptions(); - var timeout = (options && options.shutdownTimeout && options.shutdownTimeout > 0 && options.shutdownTimeout) || - DEFAULT_SHUTDOWN_TIMEOUT; - utils_1.forget(client.close(timeout).then(function (result) { - if (!result) { - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn('We reached the timeout for emptying the request buffer, still exiting now!'); - } - global.process.exit(1); - })); -} -exports.logAndExitProcess = logAndExitProcess; -//# sourceMappingURL=errorhandling.js.map + /** + * @inheritDoc + * + * @deprecated Use `Sentry.captureMessage()` instead. + */ + captureMessage( + message, + // eslint-disable-next-line deprecation/deprecation + level, + hint, + ) { + const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : utils.uuid4()); + const syntheticException = new Error(message); + // eslint-disable-next-line deprecation/deprecation + this.getScope().captureMessage(message, level, { + originalException: message, + syntheticException, + ...hint, + event_id: eventId, + }); -/***/ }), + return eventId; + } -/***/ 97909: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + /** + * @inheritDoc + * + * @deprecated Use `Sentry.captureEvent()` instead. + */ + captureEvent(event, hint) { + const eventId = hint && hint.event_id ? hint.event_id : utils.uuid4(); + if (!event.type) { + this._lastEventId = eventId; + } + // eslint-disable-next-line deprecation/deprecation + this.getScope().captureEvent(event, { ...hint, event_id: eventId }); + return eventId; + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var utils_1 = __nccwpck_require__(6785); -var url_1 = __nccwpck_require__(87016); -var NODE_VERSION = utils_1.parseSemver(process.versions.node); -/** - * Checks whether given url points to Sentry server - * @param url url to verify - */ -function isSentryRequest(url) { - var _a; - var dsn = (_a = core_1.getCurrentHub().getClient()) === null || _a === void 0 ? void 0 : _a.getDsn(); - return dsn ? url.includes(dsn.host) : false; + /** + * @inheritDoc + * + * @deprecated This will be removed in v8. + */ + lastEventId() { + return this._lastEventId; + } + + /** + * @inheritDoc + * + * @deprecated Use `Sentry.addBreadcrumb()` instead. + */ + addBreadcrumb(breadcrumb, hint) { + // eslint-disable-next-line deprecation/deprecation + const { scope, client } = this.getStackTop(); + + if (!client) return; + + const { beforeBreadcrumb = null, maxBreadcrumbs = DEFAULT_BREADCRUMBS } = + (client.getOptions && client.getOptions()) || {}; + + if (maxBreadcrumbs <= 0) return; + + const timestamp = utils.dateTimestampInSeconds(); + const mergedBreadcrumb = { timestamp, ...breadcrumb }; + const finalBreadcrumb = beforeBreadcrumb + ? (utils.consoleSandbox(() => beforeBreadcrumb(mergedBreadcrumb, hint)) ) + : mergedBreadcrumb; + + if (finalBreadcrumb === null) return; + + if (client.emit) { + client.emit('beforeAddBreadcrumb', finalBreadcrumb, hint); + } + + // TODO(v8): I know this comment doesn't make much sense because the hub will be deprecated but I still wanted to + // write it down. In theory, we would have to add the breadcrumbs to the isolation scope here, however, that would + // duplicate all of the breadcrumbs. There was the possibility of adding breadcrumbs to both, the isolation scope + // and the normal scope, and deduplicating it down the line in the event processing pipeline. However, that would + // have been very fragile, because the breadcrumb objects would have needed to keep their identity all throughout + // the event processing pipeline. + // In the new implementation, the top level `Sentry.addBreadcrumb()` should ONLY write to the isolation scope. + + scope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs); + } + + /** + * @inheritDoc + * @deprecated Use `Sentry.setUser()` instead. + */ + setUser(user) { + // TODO(v8): The top level `Sentry.setUser()` function should write ONLY to the isolation scope. + // eslint-disable-next-line deprecation/deprecation + this.getScope().setUser(user); + // eslint-disable-next-line deprecation/deprecation + this.getIsolationScope().setUser(user); + } + + /** + * @inheritDoc + * @deprecated Use `Sentry.setTags()` instead. + */ + setTags(tags) { + // TODO(v8): The top level `Sentry.setTags()` function should write ONLY to the isolation scope. + // eslint-disable-next-line deprecation/deprecation + this.getScope().setTags(tags); + // eslint-disable-next-line deprecation/deprecation + this.getIsolationScope().setTags(tags); + } + + /** + * @inheritDoc + * @deprecated Use `Sentry.setExtras()` instead. + */ + setExtras(extras) { + // TODO(v8): The top level `Sentry.setExtras()` function should write ONLY to the isolation scope. + // eslint-disable-next-line deprecation/deprecation + this.getScope().setExtras(extras); + // eslint-disable-next-line deprecation/deprecation + this.getIsolationScope().setExtras(extras); + } + + /** + * @inheritDoc + * @deprecated Use `Sentry.setTag()` instead. + */ + setTag(key, value) { + // TODO(v8): The top level `Sentry.setTag()` function should write ONLY to the isolation scope. + // eslint-disable-next-line deprecation/deprecation + this.getScope().setTag(key, value); + // eslint-disable-next-line deprecation/deprecation + this.getIsolationScope().setTag(key, value); + } + + /** + * @inheritDoc + * @deprecated Use `Sentry.setExtra()` instead. + */ + setExtra(key, extra) { + // TODO(v8): The top level `Sentry.setExtra()` function should write ONLY to the isolation scope. + // eslint-disable-next-line deprecation/deprecation + this.getScope().setExtra(key, extra); + // eslint-disable-next-line deprecation/deprecation + this.getIsolationScope().setExtra(key, extra); + } + + /** + * @inheritDoc + * @deprecated Use `Sentry.setContext()` instead. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + setContext(name, context) { + // TODO(v8): The top level `Sentry.setContext()` function should write ONLY to the isolation scope. + // eslint-disable-next-line deprecation/deprecation + this.getScope().setContext(name, context); + // eslint-disable-next-line deprecation/deprecation + this.getIsolationScope().setContext(name, context); + } + + /** + * @inheritDoc + * + * @deprecated Use `getScope()` directly. + */ + configureScope(callback) { + // eslint-disable-next-line deprecation/deprecation + const { scope, client } = this.getStackTop(); + if (client) { + callback(scope); + } + } + + /** + * @inheritDoc + */ + // eslint-disable-next-line deprecation/deprecation + run(callback) { + // eslint-disable-next-line deprecation/deprecation + const oldHub = makeMain(this); + try { + callback(this); + } finally { + // eslint-disable-next-line deprecation/deprecation + makeMain(oldHub); + } + } + + /** + * @inheritDoc + * @deprecated Use `Sentry.getClient().getIntegrationByName()` instead. + */ + getIntegration(integration) { + // eslint-disable-next-line deprecation/deprecation + const client = this.getClient(); + if (!client) return null; + try { + // eslint-disable-next-line deprecation/deprecation + return client.getIntegration(integration); + } catch (_oO) { + debugBuild.DEBUG_BUILD && utils.logger.warn(`Cannot retrieve integration ${integration.id} from the current Hub`); + return null; + } + } + + /** + * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation. + * + * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a + * new child span within the transaction or any span, call the respective `.startChild()` method. + * + * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded. + * + * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its + * finished child spans will be sent to Sentry. + * + * @param context Properties of the new `Transaction`. + * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent + * default values). See {@link Options.tracesSampler}. + * + * @returns The transaction which was just started + * + * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead. + */ + startTransaction(context, customSamplingContext) { + const result = this._callExtensionMethod('startTransaction', context, customSamplingContext); + + if (debugBuild.DEBUG_BUILD && !result) { + // eslint-disable-next-line deprecation/deprecation + const client = this.getClient(); + if (!client) { + utils.logger.warn( + "Tracing extension 'startTransaction' is missing. You should 'init' the SDK before calling 'startTransaction'", + ); + } else { + utils.logger.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init': +Sentry.addTracingExtensions(); +Sentry.init({...}); +`); + } + } + + return result; + } + + /** + * @inheritDoc + * @deprecated Use `spanToTraceHeader()` instead. + */ + traceHeaders() { + return this._callExtensionMethod('traceHeaders'); + } + + /** + * @inheritDoc + * + * @deprecated Use top level `captureSession` instead. + */ + captureSession(endSession = false) { + // both send the update and pull the session from the scope + if (endSession) { + // eslint-disable-next-line deprecation/deprecation + return this.endSession(); + } + + // only send the update + this._sendSessionUpdate(); + } + + /** + * @inheritDoc + * @deprecated Use top level `endSession` instead. + */ + endSession() { + // eslint-disable-next-line deprecation/deprecation + const layer = this.getStackTop(); + const scope = layer.scope; + const session$1 = scope.getSession(); + if (session$1) { + session.closeSession(session$1); + } + this._sendSessionUpdate(); + + // the session is over; take it off of the scope + scope.setSession(); + } + + /** + * @inheritDoc + * @deprecated Use top level `startSession` instead. + */ + startSession(context) { + // eslint-disable-next-line deprecation/deprecation + const { scope, client } = this.getStackTop(); + const { release, environment = constants.DEFAULT_ENVIRONMENT } = (client && client.getOptions()) || {}; + + // Will fetch userAgent if called from browser sdk + const { userAgent } = utils.GLOBAL_OBJ.navigator || {}; + + const session$1 = session.makeSession({ + release, + environment, + user: scope.getUser(), + ...(userAgent && { userAgent }), + ...context, + }); + + // End existing session if there's one + const currentSession = scope.getSession && scope.getSession(); + if (currentSession && currentSession.status === 'ok') { + session.updateSession(currentSession, { status: 'exited' }); + } + // eslint-disable-next-line deprecation/deprecation + this.endSession(); + + // Afterwards we set the new session on the scope + scope.setSession(session$1); + + return session$1; + } + + /** + * Returns if default PII should be sent to Sentry and propagated in ourgoing requests + * when Tracing is used. + * + * @deprecated Use top-level `getClient().getOptions().sendDefaultPii` instead. This function + * only unnecessarily increased API surface but only wrapped accessing the option. + */ + shouldSendDefaultPii() { + // eslint-disable-next-line deprecation/deprecation + const client = this.getClient(); + const options = client && client.getOptions(); + return Boolean(options && options.sendDefaultPii); + } + + /** + * Sends the current Session on the scope + */ + _sendSessionUpdate() { + // eslint-disable-next-line deprecation/deprecation + const { scope, client } = this.getStackTop(); + + const session = scope.getSession(); + if (session && client && client.captureSession) { + client.captureSession(session); + } + } + + /** + * Calls global extension method and binding current instance to the function call + */ + // @ts-expect-error Function lacks ending return statement and return type does not include 'undefined'. ts(2366) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + _callExtensionMethod(method, ...args) { + const carrier = getMainCarrier(); + const sentry = carrier.__SENTRY__; + if (sentry && sentry.extensions && typeof sentry.extensions[method] === 'function') { + return sentry.extensions[method].apply(this, args); + } + debugBuild.DEBUG_BUILD && utils.logger.warn(`Extension method ${method} couldn't be found, doing nothing.`); + } } -exports.isSentryRequest = isSentryRequest; + /** - * Assemble a URL to be used for breadcrumbs and spans. + * Returns the global shim registry. * - * @param requestOptions RequestOptions object containing the component parts for a URL - * @returns Fully-formed URL - */ -function extractUrl(requestOptions) { - var protocol = requestOptions.protocol || ''; - var hostname = requestOptions.hostname || requestOptions.host || ''; - // Don't log standard :80 (http) and :443 (https) ports to reduce the noise - var port = !requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 ? '' : ":" + requestOptions.port; - var path = requestOptions.path ? requestOptions.path : '/'; - return protocol + "//" + hostname + port + path; + * FIXME: This function is problematic, because despite always returning a valid Carrier, + * it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check + * at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there. + **/ +function getMainCarrier() { + utils.GLOBAL_OBJ.__SENTRY__ = utils.GLOBAL_OBJ.__SENTRY__ || { + extensions: {}, + hub: undefined, + }; + return utils.GLOBAL_OBJ; } -exports.extractUrl = extractUrl; + /** - * Handle various edge cases in the span description (for spans representing http(s) requests). + * Replaces the current main hub with the passed one on the global object * - * @param description current `description` property of the span representing the request - * @param requestOptions Configuration data for the request - * @param Request Request object + * @returns The old replaced hub * - * @returns The cleaned description + * @deprecated Use `setCurrentClient()` instead. */ -function cleanSpanDescription(description, requestOptions, request) { - var _a, _b, _c; - // nothing to clean - if (!description) { - return description; - } - // eslint-disable-next-line prefer-const - var _d = tslib_1.__read(description.split(' '), 2), method = _d[0], requestUrl = _d[1]; - // superagent sticks the protocol in a weird place (we check for host because if both host *and* protocol are missing, - // we're likely dealing with an internal route and this doesn't apply) - if (requestOptions.host && !requestOptions.protocol) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - requestOptions.protocol = (_b = (_a = request) === null || _a === void 0 ? void 0 : _a.agent) === null || _b === void 0 ? void 0 : _b.protocol; // worst comes to worst, this is undefined and nothing changes - requestUrl = extractUrl(requestOptions); - } - // internal routes can end up starting with a triple slash rather than a single one - if ((_c = requestUrl) === null || _c === void 0 ? void 0 : _c.startsWith('///')) { - requestUrl = requestUrl.slice(2); - } - return method + " " + requestUrl; +// eslint-disable-next-line deprecation/deprecation +function makeMain(hub) { + const registry = getMainCarrier(); + const oldHub = getHubFromCarrier(registry); + setHubOnCarrier(registry, hub); + return oldHub; } -exports.cleanSpanDescription = cleanSpanDescription; + /** - * Convert a URL object into a RequestOptions object. + * Returns the default hub instance. * - * Copied from Node's internals (where it's used in http(s).request() and http(s).get()), modified only to use the - * RequestOptions type above. + * If a hub is already registered in the global carrier but this module + * contains a more recent version, it replaces the registered version. + * Otherwise, the currently registered hub will be returned. * - * See https://github.com/nodejs/node/blob/master/lib/internal/url.js. + * @deprecated Use the respective replacement method directly instead. */ -function urlToOptions(url) { - var options = { - protocol: url.protocol, - hostname: typeof url.hostname === 'string' && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname, - hash: url.hash, - search: url.search, - pathname: url.pathname, - path: "" + (url.pathname || '') + (url.search || ''), - href: url.href, - }; - if (url.port !== '') { - options.port = Number(url.port); - } - if (url.username || url.password) { - options.auth = url.username + ":" + url.password; +// eslint-disable-next-line deprecation/deprecation +function getCurrentHub() { + // Get main carrier (global for every environment) + const registry = getMainCarrier(); + + if (registry.__SENTRY__ && registry.__SENTRY__.acs) { + const hub = registry.__SENTRY__.acs.getCurrentHub(); + + if (hub) { + return hub; } - return options; + } + + // Return hub that lives on a global object + return getGlobalHub(registry); } -exports.urlToOptions = urlToOptions; + /** - * Normalize inputs to `http(s).request()` and `http(s).get()`. - * - * Legal inputs to `http(s).request()` and `http(s).get()` can take one of ten forms: - * [ RequestOptions | string | URL ], - * [ RequestOptions | string | URL, RequestCallback ], - * [ string | URL, RequestOptions ], and - * [ string | URL, RequestOptions, RequestCallback ]. - * - * This standardizes to one of two forms: [ RequestOptions ] and [ RequestOptions, RequestCallback ]. A similar thing is - * done as the first step of `http(s).request()` and `http(s).get()`; this just does it early so that we can interact - * with the args in a standard way. - * - * @param requestArgs The inputs to `http(s).request()` or `http(s).get()`, as an array. - * - * @returns Equivalent args of the form [ RequestOptions ] or [ RequestOptions, RequestCallback ]. + * Get the currently active isolation scope. + * The isolation scope is active for the current exection context, + * meaning that it will remain stable for the same Hub. */ -function normalizeRequestArgs(httpModule, requestArgs) { - var _a, _b, _c, _d, _e, _f, _g, _h; - var callback, requestOptions; - // pop off the callback, if there is one - if (typeof requestArgs[requestArgs.length - 1] === 'function') { - callback = requestArgs.pop(); - } - // create a RequestOptions object of whatever's at index 0 - if (typeof requestArgs[0] === 'string') { - requestOptions = urlToOptions(new url_1.URL(requestArgs[0])); - } - else if (requestArgs[0] instanceof url_1.URL) { - requestOptions = urlToOptions(requestArgs[0]); - } - else { - requestOptions = requestArgs[0]; - } - // if the options were given separately from the URL, fold them in - if (requestArgs.length === 2) { - requestOptions = tslib_1.__assign(tslib_1.__assign({}, requestOptions), requestArgs[1]); - } - // Figure out the protocol if it's currently missing - if (requestOptions.protocol === undefined) { - // Worst case we end up populating protocol with undefined, which it already is - /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */ - // NOTE: Prior to Node 9, `https` used internals of `http` module, thus we don't patch it. - // Because of that, we cannot rely on `httpModule` to provide us with valid protocol, - // as it will always return `http`, even when using `https` module. - // - // See test/integrations/http.test.ts for more details on Node <=v8 protocol issue. - if (NODE_VERSION.major && NODE_VERSION.major > 8) { - requestOptions.protocol = - ((_b = (_a = httpModule) === null || _a === void 0 ? void 0 : _a.globalAgent) === null || _b === void 0 ? void 0 : _b.protocol) || ((_c = requestOptions.agent) === null || _c === void 0 ? void 0 : _c.protocol) || ((_d = requestOptions._defaultAgent) === null || _d === void 0 ? void 0 : _d.protocol); - } - else { - requestOptions.protocol = - ((_e = requestOptions.agent) === null || _e === void 0 ? void 0 : _e.protocol) || ((_f = requestOptions._defaultAgent) === null || _f === void 0 ? void 0 : _f.protocol) || ((_h = (_g = httpModule) === null || _g === void 0 ? void 0 : _g.globalAgent) === null || _h === void 0 ? void 0 : _h.protocol); - } - /* eslint-enable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */ - } - // return args in standardized form - if (callback) { - return [requestOptions, callback]; - } - else { - return [requestOptions]; - } +function getIsolationScope() { + // eslint-disable-next-line deprecation/deprecation + return getCurrentHub().getIsolationScope(); } -exports.normalizeRequestArgs = normalizeRequestArgs; -//# sourceMappingURL=http.js.map -/***/ }), +// eslint-disable-next-line deprecation/deprecation +function getGlobalHub(registry = getMainCarrier()) { + // If there's no hub, or its an old API, assign a new one -/***/ 80915: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + if ( + !hasHubOnCarrier(registry) || + // eslint-disable-next-line deprecation/deprecation + getHubFromCarrier(registry).isOlderThan(API_VERSION) + ) { + // eslint-disable-next-line deprecation/deprecation + setHubOnCarrier(registry, new Hub()); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var hub_1 = __nccwpck_require__(17237); -var utils_1 = __nccwpck_require__(6785); -var domain = __nccwpck_require__(73167); -var client_1 = __nccwpck_require__(49652); -var flags_1 = __nccwpck_require__(62976); -var integrations_1 = __nccwpck_require__(75887); -exports.defaultIntegrations = [ - // Common - new core_1.Integrations.InboundFilters(), - new core_1.Integrations.FunctionToString(), - new integrations_1.ContextLines(), - // Native Wrappers - new integrations_1.Console(), - new integrations_1.Http(), - // Global Handlers - new integrations_1.OnUncaughtException(), - new integrations_1.OnUnhandledRejection(), - // Misc - new integrations_1.LinkedErrors(), -]; -/** - * The Sentry Node SDK Client. - * - * To use this SDK, call the {@link init} function as early as possible in the - * main entry module. To set context information or send manual events, use the - * provided methods. - * - * @example - * ``` - * - * const { init } = require('@sentry/node'); - * - * init({ - * dsn: '__DSN__', - * // ... - * }); - * ``` - * - * @example - * ``` - * - * const { configureScope } = require('@sentry/node'); - * configureScope((scope: Scope) => { - * scope.setExtra({ battery: 0.7 }); - * scope.setTag({ user_mode: 'admin' }); - * scope.setUser({ id: '4711' }); - * }); - * ``` - * - * @example - * ``` - * - * const { addBreadcrumb } = require('@sentry/node'); - * addBreadcrumb({ - * message: 'My Breadcrumb', - * // ... - * }); - * ``` - * - * @example - * ``` - * - * const Sentry = require('@sentry/node'); - * Sentry.captureMessage('Hello, world!'); - * Sentry.captureException(new Error('Good bye')); - * Sentry.captureEvent({ - * message: 'Manual', - * stacktrace: [ - * // ... - * ], - * }); - * ``` - * - * @see {@link NodeOptions} for documentation on configuration options. - */ -function init(options) { - if (options === void 0) { options = {}; } - var _a; - var carrier = hub_1.getMainCarrier(); - var autoloadedIntegrations = ((_a = carrier.__SENTRY__) === null || _a === void 0 ? void 0 : _a.integrations) || []; - options.defaultIntegrations = - options.defaultIntegrations === false - ? [] - : tslib_1.__spread((Array.isArray(options.defaultIntegrations) ? options.defaultIntegrations : exports.defaultIntegrations), autoloadedIntegrations); - if (options.dsn === undefined && process.env.SENTRY_DSN) { - options.dsn = process.env.SENTRY_DSN; - } - if (options.tracesSampleRate === undefined && process.env.SENTRY_TRACES_SAMPLE_RATE) { - var tracesSampleRate = parseFloat(process.env.SENTRY_TRACES_SAMPLE_RATE); - if (isFinite(tracesSampleRate)) { - options.tracesSampleRate = tracesSampleRate; - } - } - if (options.release === undefined) { - var detectedRelease = getSentryRelease(); - if (detectedRelease !== undefined) { - options.release = detectedRelease; - } - else { - // If release is not provided, then we should disable autoSessionTracking - options.autoSessionTracking = false; - } - } - if (options.environment === undefined && process.env.SENTRY_ENVIRONMENT) { - options.environment = process.env.SENTRY_ENVIRONMENT; - } - if (options.autoSessionTracking === undefined && options.dsn !== undefined) { - options.autoSessionTracking = true; - } - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - if (domain.active) { - hub_1.setHubOnCarrier(carrier, core_1.getCurrentHub()); - } - core_1.initAndBind(client_1.NodeClient, options); - if (options.autoSessionTracking) { - startSessionTracking(); - } + // Return hub that lives on a global object + return getHubFromCarrier(registry); } -exports.init = init; + /** - * This is the getter for lastEventId. + * @private Private API with no semver guarantees! * - * @returns The last event id of a captured event. + * If the carrier does not contain a hub, a new hub is created with the global hub client and scope. */ -function lastEventId() { - return core_1.getCurrentHub().lastEventId(); +// eslint-disable-next-line deprecation/deprecation +function ensureHubOnCarrier(carrier, parent = getGlobalHub()) { + // If there's no hub on current domain, or it's an old API, assign a new one + if ( + !hasHubOnCarrier(carrier) || + // eslint-disable-next-line deprecation/deprecation + getHubFromCarrier(carrier).isOlderThan(API_VERSION) + ) { + // eslint-disable-next-line deprecation/deprecation + const client = parent.getClient(); + // eslint-disable-next-line deprecation/deprecation + const scope = parent.getScope(); + // eslint-disable-next-line deprecation/deprecation + const isolationScope = parent.getIsolationScope(); + // eslint-disable-next-line deprecation/deprecation + setHubOnCarrier(carrier, new Hub(client, scope.clone(), isolationScope.clone())); + } } -exports.lastEventId = lastEventId; + /** - * Call `flush()` on the current client, if there is one. See {@link Client.flush}. + * @private Private API with no semver guarantees! * - * @param timeout Maximum time in ms the client should wait to flush its event queue. Omitting this parameter will cause - * the client to wait until all events are sent before resolving the promise. - * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it - * doesn't (or if there's no client defined). + * Sets the global async context strategy */ -function flush(timeout) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var client; - return tslib_1.__generator(this, function (_a) { - client = core_1.getCurrentHub().getClient(); - if (client) { - return [2 /*return*/, client.flush(timeout)]; - } - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn('Cannot flush events. No client defined.'); - return [2 /*return*/, Promise.resolve(false)]; - }); - }); +function setAsyncContextStrategy(strategy) { + // Get main carrier (global for every environment) + const registry = getMainCarrier(); + registry.__SENTRY__ = registry.__SENTRY__ || {}; + registry.__SENTRY__.acs = strategy; } -exports.flush = flush; + /** - * Call `close()` on the current client, if there is one. See {@link Client.close}. + * Runs the supplied callback in its own async context. Async Context strategies are defined per SDK. * - * @param timeout Maximum time in ms the client should wait to flush its event queue before shutting down. Omitting this - * parameter will cause the client to wait until all events are sent before disabling itself. - * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it - * doesn't (or if there's no client defined). + * @param callback The callback to run in its own async context + * @param options Options to pass to the async context strategy + * @returns The result of the callback */ -function close(timeout) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var client; - return tslib_1.__generator(this, function (_a) { - client = core_1.getCurrentHub().getClient(); - if (client) { - return [2 /*return*/, client.close(timeout)]; - } - flags_1.IS_DEBUG_BUILD && utils_1.logger.warn('Cannot flush events and disable SDK. No client defined.'); - return [2 /*return*/, Promise.resolve(false)]; - }); - }); +function runWithAsyncContext(callback, options = {}) { + const registry = getMainCarrier(); + + if (registry.__SENTRY__ && registry.__SENTRY__.acs) { + return registry.__SENTRY__.acs.runWithAsyncContext(callback, options); + } + + // if there was no strategy, fallback to just calling the callback + return callback(); } -exports.close = close; + /** - * Function that takes an instance of NodeClient and checks if autoSessionTracking option is enabled for that client + * This will tell whether a carrier has a hub on it or not + * @param carrier object */ -function isAutoSessionTrackingEnabled(client) { - if (client === undefined) { - return false; - } - var clientOptions = client && client.getOptions(); - if (clientOptions && clientOptions.autoSessionTracking !== undefined) { - return clientOptions.autoSessionTracking; - } - return false; +function hasHubOnCarrier(carrier) { + return !!(carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub); } -exports.isAutoSessionTrackingEnabled = isAutoSessionTrackingEnabled; + /** - * Returns a release dynamically from environment variables. + * This will create a new {@link Hub} and add to the passed object on + * __SENTRY__.hub. + * @param carrier object + * @hidden */ -function getSentryRelease(fallback) { - // Always read first as Sentry takes this as precedence - if (process.env.SENTRY_RELEASE) { - return process.env.SENTRY_RELEASE; - } - // This supports the variable that sentry-webpack-plugin injects - var global = utils_1.getGlobalObject(); - if (global.SENTRY_RELEASE && global.SENTRY_RELEASE.id) { - return global.SENTRY_RELEASE.id; - } - return ( - // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables - process.env.GITHUB_SHA || - // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata - process.env.COMMIT_REF || - // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables - process.env.VERCEL_GIT_COMMIT_SHA || - process.env.VERCEL_GITHUB_COMMIT_SHA || - process.env.VERCEL_GITLAB_COMMIT_SHA || - process.env.VERCEL_BITBUCKET_COMMIT_SHA || - // Zeit (now known as Vercel) - process.env.ZEIT_GITHUB_COMMIT_SHA || - process.env.ZEIT_GITLAB_COMMIT_SHA || - process.env.ZEIT_BITBUCKET_COMMIT_SHA || - fallback); +// eslint-disable-next-line deprecation/deprecation +function getHubFromCarrier(carrier) { + // eslint-disable-next-line deprecation/deprecation + return utils.getGlobalSingleton('hub', () => new Hub(), carrier); } -exports.getSentryRelease = getSentryRelease; + /** - * Enable automatic Session Tracking for the node process. + * This will set passed {@link Hub} on the passed object's __SENTRY__.hub attribute + * @param carrier object + * @param hub Hub + * @returns A boolean indicating success or failure */ -function startSessionTracking() { - var hub = core_1.getCurrentHub(); - hub.startSession(); - // Emitted in the case of healthy sessions, error of `mechanism.handled: true` and unhandledrejections because - // The 'beforeExit' event is not emitted for conditions causing explicit termination, - // such as calling process.exit() or uncaught exceptions. - // Ref: https://nodejs.org/api/process.html#process_event_beforeexit - process.on('beforeExit', function () { - var _a; - var session = (_a = hub.getScope()) === null || _a === void 0 ? void 0 : _a.getSession(); - var terminalStates = ['exited', 'crashed']; - // Only call endSession, if the Session exists on Scope and SessionStatus is not a - // Terminal Status i.e. Exited or Crashed because - // "When a session is moved away from ok it must not be updated anymore." - // Ref: https://develop.sentry.dev/sdk/sessions/ - if (session && !terminalStates.includes(session.status)) - hub.endSession(); - }); +// eslint-disable-next-line deprecation/deprecation +function setHubOnCarrier(carrier, hub) { + if (!carrier) return false; + const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {}); + __SENTRY__.hub = hub; + return true; } -//# sourceMappingURL=sdk.js.map + +exports.API_VERSION = API_VERSION; +exports.Hub = Hub; +exports.ensureHubOnCarrier = ensureHubOnCarrier; +exports.getCurrentHub = getCurrentHub; +exports.getHubFromCarrier = getHubFromCarrier; +exports.getIsolationScope = getIsolationScope; +exports.getMainCarrier = getMainCarrier; +exports.makeMain = makeMain; +exports.runWithAsyncContext = runWithAsyncContext; +exports.setAsyncContextStrategy = setAsyncContextStrategy; +exports.setHubOnCarrier = setHubOnCarrier; +//# sourceMappingURL=hub.js.map + /***/ }), -/***/ 39503: +/***/ 75442: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var utils_1 = __nccwpck_require__(6785); -/** Gets the module */ -function getModule(filename) { - if (!filename) { - return; - } - // We could use optional chaining here but webpack does like that mixed with require - var base = ((require && require.main && require.main.filename && utils_1.dirname(require.main.filename)) || global.process.cwd()) + "/"; - // It's specifically a module - var file = utils_1.basename(filename, '.js'); - var path = utils_1.dirname(filename); - var n = path.lastIndexOf('/node_modules/'); - if (n > -1) { - // /node_modules/ is 14 chars - return path.substr(n + 14).replace(/\//g, '.') + ":" + file; - } - // Let's see if it's a part of the main module - // To be a part of main module, it has to share the same base - n = (path + "/").lastIndexOf(base, 0); - if (n === 0) { - var moduleName = path.substr(base.length).replace(/\//g, '.'); - if (moduleName) { - moduleName += ':'; - } - moduleName += file; - return moduleName; - } - return file; -} -var FILENAME_MATCH = /^\s*[-]{4,}$/; -var FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/; -// eslint-disable-next-line complexity -var node = function (line) { - var _a; - if (line.match(FILENAME_MATCH)) { - return { - filename: line, - }; - } - var lineMatch = line.match(FULL_MATCH); - if (!lineMatch) { - return undefined; - } - var object; - var method; - var functionName; - var typeName; - var methodName; - if (lineMatch[1]) { - functionName = lineMatch[1]; - var methodStart = functionName.lastIndexOf('.'); - if (functionName[methodStart - 1] === '.') { - // eslint-disable-next-line no-plusplus - methodStart--; - } - if (methodStart > 0) { - object = functionName.substr(0, methodStart); - method = functionName.substr(methodStart + 1); - var objectEnd = object.indexOf('.Module'); - if (objectEnd > 0) { - functionName = functionName.substr(objectEnd + 1); - object = object.substr(0, objectEnd); - } - } - typeName = undefined; - } - if (method) { - typeName = object; - methodName = method; - } - if (method === '') { - methodName = undefined; - functionName = undefined; - } - if (functionName === undefined) { - methodName = methodName || ''; - functionName = typeName ? typeName + "." + methodName : methodName; - } - var filename = ((_a = lineMatch[2]) === null || _a === void 0 ? void 0 : _a.startsWith('file://')) ? lineMatch[2].substr(7) : lineMatch[2]; - var isNative = lineMatch[5] === 'native'; - var isInternal = isNative || (filename && !filename.startsWith('/') && !filename.startsWith('.') && filename.indexOf(':\\') !== 1); - // in_app is all that's not an internal Node function or a module within node_modules - // note that isNative appears to return true even for node core libraries - // see https://github.com/getsentry/raven-node/issues/176 - var in_app = !isInternal && filename !== undefined && !filename.includes('node_modules/'); - return { - filename: filename, - module: getModule(filename), - function: functionName, - lineno: parseInt(lineMatch[3], 10) || undefined, - colno: parseInt(lineMatch[4], 10) || undefined, - in_app: in_app, - }; -}; -exports.nodeStackParser = [90, node]; -//# sourceMappingURL=stack-parser.js.map + +const hubextensions = __nccwpck_require__(44758); +const idletransaction = __nccwpck_require__(46629); +const span$1 = __nccwpck_require__(36283); +const transaction = __nccwpck_require__(7827); +const utils = __nccwpck_require__(49194); +const spanstatus = __nccwpck_require__(14769); +const trace = __nccwpck_require__(75150); +const dynamicSamplingContext = __nccwpck_require__(76248); +const measurement = __nccwpck_require__(64599); +const sampling = __nccwpck_require__(88210); +const semanticAttributes = __nccwpck_require__(44513); +const envelope = __nccwpck_require__(90820); +const exports$1 = __nccwpck_require__(74313); +const hub = __nccwpck_require__(18205); +const session = __nccwpck_require__(14638); +const sessionflusher = __nccwpck_require__(48409); +const scope = __nccwpck_require__(77226); +const eventProcessors = __nccwpck_require__(88807); +const api = __nccwpck_require__(91458); +const baseclient = __nccwpck_require__(36950); +const serverRuntimeClient = __nccwpck_require__(19144); +const sdk = __nccwpck_require__(39158); +const base = __nccwpck_require__(91148); +const offline = __nccwpck_require__(61006); +const multiplexed = __nccwpck_require__(47864); +const version = __nccwpck_require__(3206); +const integration = __nccwpck_require__(11000); +const applyScopeDataToEvent = __nccwpck_require__(87059); +const prepareEvent = __nccwpck_require__(57847); +const checkin = __nccwpck_require__(31265); +const span = __nccwpck_require__(67084); +const hasTracingEnabled = __nccwpck_require__(7747); +const isSentryRequestUrl = __nccwpck_require__(75227); +const handleCallbackErrors = __nccwpck_require__(57116); +const parameterize = __nccwpck_require__(70113); +const spanUtils = __nccwpck_require__(98313); +const getRootSpan = __nccwpck_require__(27304); +const sdkMetadata = __nccwpck_require__(45229); +const constants = __nccwpck_require__(11363); +const metadata = __nccwpck_require__(18567); +const requestdata = __nccwpck_require__(24781); +const inboundfilters = __nccwpck_require__(81050); +const functiontostring = __nccwpck_require__(37714); +const linkederrors = __nccwpck_require__(87132); +const index = __nccwpck_require__(3104); +const exports$2 = __nccwpck_require__(59955); + +/** @deprecated Import the integration function directly, e.g. `inboundFiltersIntegration()` instead of `new Integrations.InboundFilter(). */ +const Integrations = index; + +exports.addTracingExtensions = hubextensions.addTracingExtensions; +exports.startIdleTransaction = hubextensions.startIdleTransaction; +exports.IdleTransaction = idletransaction.IdleTransaction; +exports.TRACING_DEFAULTS = idletransaction.TRACING_DEFAULTS; +exports.Span = span$1.Span; +exports.Transaction = transaction.Transaction; +exports.extractTraceparentData = utils.extractTraceparentData; +exports.getActiveTransaction = utils.getActiveTransaction; +Object.defineProperty(exports, "SpanStatus", ({ + enumerable: true, + get: () => spanstatus.SpanStatus +})); +exports.getSpanStatusFromHttpCode = spanstatus.getSpanStatusFromHttpCode; +exports.setHttpStatus = spanstatus.setHttpStatus; +exports.spanStatusfromHttpCode = spanstatus.spanStatusfromHttpCode; +exports.continueTrace = trace.continueTrace; +exports.getActiveSpan = trace.getActiveSpan; +exports.startActiveSpan = trace.startActiveSpan; +exports.startInactiveSpan = trace.startInactiveSpan; +exports.startSpan = trace.startSpan; +exports.startSpanManual = trace.startSpanManual; +exports.trace = trace.trace; +exports.getDynamicSamplingContextFromClient = dynamicSamplingContext.getDynamicSamplingContextFromClient; +exports.getDynamicSamplingContextFromSpan = dynamicSamplingContext.getDynamicSamplingContextFromSpan; +exports.setMeasurement = measurement.setMeasurement; +exports.isValidSampleRate = sampling.isValidSampleRate; +exports.SEMANTIC_ATTRIBUTE_PROFILE_ID = semanticAttributes.SEMANTIC_ATTRIBUTE_PROFILE_ID; +exports.SEMANTIC_ATTRIBUTE_SENTRY_OP = semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP; +exports.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN; +exports.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE; +exports.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE; +exports.createEventEnvelope = envelope.createEventEnvelope; +exports.createSessionEnvelope = envelope.createSessionEnvelope; +exports.addBreadcrumb = exports$1.addBreadcrumb; +exports.captureCheckIn = exports$1.captureCheckIn; +exports.captureEvent = exports$1.captureEvent; +exports.captureException = exports$1.captureException; +exports.captureMessage = exports$1.captureMessage; +exports.captureSession = exports$1.captureSession; +exports.close = exports$1.close; +exports.configureScope = exports$1.configureScope; +exports.endSession = exports$1.endSession; +exports.flush = exports$1.flush; +exports.getClient = exports$1.getClient; +exports.getCurrentScope = exports$1.getCurrentScope; +exports.isInitialized = exports$1.isInitialized; +exports.lastEventId = exports$1.lastEventId; +exports.setContext = exports$1.setContext; +exports.setExtra = exports$1.setExtra; +exports.setExtras = exports$1.setExtras; +exports.setTag = exports$1.setTag; +exports.setTags = exports$1.setTags; +exports.setUser = exports$1.setUser; +exports.startSession = exports$1.startSession; +exports.startTransaction = exports$1.startTransaction; +exports.withActiveSpan = exports$1.withActiveSpan; +exports.withIsolationScope = exports$1.withIsolationScope; +exports.withMonitor = exports$1.withMonitor; +exports.withScope = exports$1.withScope; +exports.Hub = hub.Hub; +exports.ensureHubOnCarrier = hub.ensureHubOnCarrier; +exports.getCurrentHub = hub.getCurrentHub; +exports.getHubFromCarrier = hub.getHubFromCarrier; +exports.getIsolationScope = hub.getIsolationScope; +exports.getMainCarrier = hub.getMainCarrier; +exports.makeMain = hub.makeMain; +exports.runWithAsyncContext = hub.runWithAsyncContext; +exports.setAsyncContextStrategy = hub.setAsyncContextStrategy; +exports.setHubOnCarrier = hub.setHubOnCarrier; +exports.closeSession = session.closeSession; +exports.makeSession = session.makeSession; +exports.updateSession = session.updateSession; +exports.SessionFlusher = sessionflusher.SessionFlusher; +exports.Scope = scope.Scope; +exports.getGlobalScope = scope.getGlobalScope; +exports.setGlobalScope = scope.setGlobalScope; +exports.addGlobalEventProcessor = eventProcessors.addGlobalEventProcessor; +exports.notifyEventProcessors = eventProcessors.notifyEventProcessors; +exports.getEnvelopeEndpointWithUrlEncodedAuth = api.getEnvelopeEndpointWithUrlEncodedAuth; +exports.getReportDialogEndpoint = api.getReportDialogEndpoint; +exports.BaseClient = baseclient.BaseClient; +exports.addEventProcessor = baseclient.addEventProcessor; +exports.ServerRuntimeClient = serverRuntimeClient.ServerRuntimeClient; +exports.initAndBind = sdk.initAndBind; +exports.setCurrentClient = sdk.setCurrentClient; +exports.createTransport = base.createTransport; +exports.makeOfflineTransport = offline.makeOfflineTransport; +exports.makeMultiplexedTransport = multiplexed.makeMultiplexedTransport; +exports.SDK_VERSION = version.SDK_VERSION; +exports.addIntegration = integration.addIntegration; +exports.convertIntegrationFnToClass = integration.convertIntegrationFnToClass; +exports.defineIntegration = integration.defineIntegration; +exports.getIntegrationsToSetup = integration.getIntegrationsToSetup; +exports.applyScopeDataToEvent = applyScopeDataToEvent.applyScopeDataToEvent; +exports.mergeScopeData = applyScopeDataToEvent.mergeScopeData; +exports.prepareEvent = prepareEvent.prepareEvent; +exports.createCheckInEnvelope = checkin.createCheckInEnvelope; +exports.createSpanEnvelope = span.createSpanEnvelope; +exports.hasTracingEnabled = hasTracingEnabled.hasTracingEnabled; +exports.isSentryRequestUrl = isSentryRequestUrl.isSentryRequestUrl; +exports.handleCallbackErrors = handleCallbackErrors.handleCallbackErrors; +exports.parameterize = parameterize.parameterize; +exports.spanIsSampled = spanUtils.spanIsSampled; +exports.spanToJSON = spanUtils.spanToJSON; +exports.spanToTraceContext = spanUtils.spanToTraceContext; +exports.spanToTraceHeader = spanUtils.spanToTraceHeader; +exports.getRootSpan = getRootSpan.getRootSpan; +exports.applySdkMetadata = sdkMetadata.applySdkMetadata; +exports.DEFAULT_ENVIRONMENT = constants.DEFAULT_ENVIRONMENT; +exports.ModuleMetadata = metadata.ModuleMetadata; +exports.moduleMetadataIntegration = metadata.moduleMetadataIntegration; +exports.RequestData = requestdata.RequestData; +exports.requestDataIntegration = requestdata.requestDataIntegration; +exports.InboundFilters = inboundfilters.InboundFilters; +exports.inboundFiltersIntegration = inboundfilters.inboundFiltersIntegration; +exports.FunctionToString = functiontostring.FunctionToString; +exports.functionToStringIntegration = functiontostring.functionToStringIntegration; +exports.LinkedErrors = linkederrors.LinkedErrors; +exports.linkedErrorsIntegration = linkederrors.linkedErrorsIntegration; +exports.metrics = exports$2.metrics; +exports.Integrations = Integrations; +//# sourceMappingURL=index.js.map + /***/ }), -/***/ 62006: +/***/ 11000: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var utils_1 = __nccwpck_require__(6785); -var fs = __nccwpck_require__(79896); -var url_1 = __nccwpck_require__(87016); -var flags_1 = __nccwpck_require__(62976); -var version_1 = __nccwpck_require__(40275); -var CATEGORY_MAPPING = { - event: 'error', - transaction: 'transaction', - session: 'session', - attachment: 'attachment', -}; -/** Base Transport class implementation */ -var BaseTransport = /** @class */ (function () { - /** Create instance and set this.dsn */ - function BaseTransport(options) { - this.options = options; - /** A simple buffer holding all requests. */ - this._buffer = utils_1.makePromiseBuffer(30); - /** Locks transport after receiving rate limits in a response */ - this._rateLimits = {}; - /** Default function used to parse URLs */ - this.urlParser = function (url) { return new url_1.URL(url); }; - // eslint-disable-next-line deprecation/deprecation - this._api = core_1.initAPIDetails(options.dsn, options._metadata, options.tunnel); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const eventProcessors = __nccwpck_require__(88807); +const exports$1 = __nccwpck_require__(74313); +const hub = __nccwpck_require__(18205); + +const installedIntegrations = []; + +/** Map of integrations assigned to a client */ + +/** + * Remove duplicates from the given array, preferring the last instance of any duplicate. Not guaranteed to + * preseve the order of integrations in the array. + * + * @private + */ +function filterDuplicates(integrations) { + const integrationsByName = {}; + + integrations.forEach(currentInstance => { + const { name } = currentInstance; + + const existingInstance = integrationsByName[name]; + + // We want integrations later in the array to overwrite earlier ones of the same type, except that we never want a + // default instance to overwrite an existing user instance + if (existingInstance && !existingInstance.isDefaultInstance && currentInstance.isDefaultInstance) { + return; } - /** - * @inheritDoc - */ - BaseTransport.prototype.sendEvent = function (_) { - throw new utils_1.SentryError('Transport Class has to implement `sendEvent` method.'); - }; - /** - * @inheritDoc - */ - BaseTransport.prototype.close = function (timeout) { - return this._buffer.drain(timeout); - }; - /** - * Extracts proxy settings from client options and env variables. - * - * Honors `no_proxy` env variable with the highest priority to allow for hosts exclusion. - * - * An order of priority for available protocols is: - * `http` => `options.httpProxy` | `process.env.http_proxy` - * `https` => `options.httpsProxy` | `options.httpProxy` | `process.env.https_proxy` | `process.env.http_proxy` - */ - BaseTransport.prototype._getProxy = function (protocol) { - var e_1, _a; - var _b = process.env, no_proxy = _b.no_proxy, http_proxy = _b.http_proxy, https_proxy = _b.https_proxy; - var _c = this.options, httpProxy = _c.httpProxy, httpsProxy = _c.httpsProxy; - var proxy = protocol === 'http' ? httpProxy || http_proxy : httpsProxy || httpProxy || https_proxy || http_proxy; - if (!no_proxy) { - return proxy; - } - var _d = this._api.dsn, host = _d.host, port = _d.port; - try { - for (var _e = tslib_1.__values(no_proxy.split(',')), _f = _e.next(); !_f.done; _f = _e.next()) { - var np = _f.value; - if (host.endsWith(np) || (host + ":" + port).endsWith(np)) { - return; - } - } - } - catch (e_1_1) { e_1 = { error: e_1_1 }; } - finally { - try { - if (_f && !_f.done && (_a = _e.return)) _a.call(_e); - } - finally { if (e_1) throw e_1.error; } - } - return proxy; - }; - /** Returns a build request option object used by request */ - BaseTransport.prototype._getRequestOptions = function (urlParts) { - var headers = tslib_1.__assign(tslib_1.__assign({}, core_1.getRequestHeaders(this._api.dsn, version_1.SDK_NAME, core_1.SDK_VERSION)), this.options.headers); - var hostname = urlParts.hostname, pathname = urlParts.pathname, port = urlParts.port, protocol = urlParts.protocol; - // See https://github.com/nodejs/node/blob/38146e717fed2fabe3aacb6540d839475e0ce1c6/lib/internal/url.js#L1268-L1290 - // We ignore the query string on purpose - var path = "" + pathname; - return tslib_1.__assign({ agent: this.client, headers: headers, - hostname: hostname, method: 'POST', path: path, - port: port, - protocol: protocol }, (this.options.caCerts && { - ca: fs.readFileSync(this.options.caCerts), - })); - }; - /** - * Gets the time that given category is disabled until for rate limiting - */ - BaseTransport.prototype._disabledUntil = function (requestType) { - var category = CATEGORY_MAPPING[requestType]; - return this._rateLimits[category] || this._rateLimits.all; - }; - /** - * Checks if a category is rate limited - */ - BaseTransport.prototype._isRateLimited = function (requestType) { - return this._disabledUntil(requestType) > new Date(Date.now()); - }; - /** - * Sets internal _rateLimits from incoming headers. Returns true if headers contains a non-empty rate limiting header. - */ - BaseTransport.prototype._handleRateLimit = function (headers) { - var e_2, _a, e_3, _b; - var now = Date.now(); - var rlHeader = headers['x-sentry-rate-limits']; - var raHeader = headers['retry-after']; - if (rlHeader) { - try { - // rate limit headers are of the form - //
,
,.. - // where each
is of the form - // : : : - // where - // is a delay in ms - // is the event type(s) (error, transaction, etc) being rate limited and is of the form - // ;;... - // is what's being limited (org, project, or key) - ignored by SDK - // is an arbitrary string like "org_quota" - ignored by SDK - for (var _c = tslib_1.__values(rlHeader.trim().split(',')), _d = _c.next(); !_d.done; _d = _c.next()) { - var limit = _d.value; - var parameters = limit.split(':', 2); - var headerDelay = parseInt(parameters[0], 10); - var delay = (!isNaN(headerDelay) ? headerDelay : 60) * 1000; // 60sec default - try { - for (var _e = (e_3 = void 0, tslib_1.__values((parameters[1] && parameters[1].split(';')) || ['all'])), _f = _e.next(); !_f.done; _f = _e.next()) { - var category = _f.value; - // categoriesAllowed is added here to ensure we are only storing rate limits for categories we support in this - // sdk and any categories that are not supported will not be added redundantly to the rateLimits object - var categoriesAllowed = tslib_1.__spread(Object.keys(CATEGORY_MAPPING).map(function (k) { return CATEGORY_MAPPING[k]; }), [ - 'all', - ]); - if (categoriesAllowed.includes(category)) - this._rateLimits[category] = new Date(now + delay); - } - } - catch (e_3_1) { e_3 = { error: e_3_1 }; } - finally { - try { - if (_f && !_f.done && (_b = _e.return)) _b.call(_e); - } - finally { if (e_3) throw e_3.error; } - } - } - } - catch (e_2_1) { e_2 = { error: e_2_1 }; } - finally { - try { - if (_d && !_d.done && (_a = _c.return)) _a.call(_c); - } - finally { if (e_2) throw e_2.error; } - } - return true; - } - else if (raHeader) { - this._rateLimits.all = new Date(now + utils_1.parseRetryAfterHeader(raHeader, now)); - return true; - } - return false; - }; - /** JSDoc */ - BaseTransport.prototype._send = function (sentryRequest, originalPayload) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var _this = this; - return tslib_1.__generator(this, function (_a) { - if (!this.module) { - throw new utils_1.SentryError('No module available'); - } - if (originalPayload && this._isRateLimited(sentryRequest.type)) { - return [2 /*return*/, Promise.reject({ - payload: originalPayload, - type: sentryRequest.type, - reason: "Transport for " + sentryRequest.type + " requests locked till " + this._disabledUntil(sentryRequest.type) + " due to too many requests.", - status: 429, - })]; - } - return [2 /*return*/, this._buffer.add(function () { - return new Promise(function (resolve, reject) { - if (!_this.module) { - throw new utils_1.SentryError('No module available'); - } - var options = _this._getRequestOptions(_this.urlParser(sentryRequest.url)); - var req = _this.module.request(options, function (res) { - var statusCode = res.statusCode || 500; - var status = utils_1.eventStatusFromHttpCode(statusCode); - res.setEncoding('utf8'); - /** - * "Key-value pairs of header names and values. Header names are lower-cased." - * https://nodejs.org/api/http.html#http_message_headers - */ - var retryAfterHeader = res.headers ? res.headers['retry-after'] : ''; - retryAfterHeader = (Array.isArray(retryAfterHeader) ? retryAfterHeader[0] : retryAfterHeader); - var rlHeader = res.headers ? res.headers['x-sentry-rate-limits'] : ''; - rlHeader = (Array.isArray(rlHeader) ? rlHeader[0] : rlHeader); - var headers = { - 'x-sentry-rate-limits': rlHeader, - 'retry-after': retryAfterHeader, - }; - var limited = _this._handleRateLimit(headers); - if (limited) - flags_1.IS_DEBUG_BUILD && - utils_1.logger.warn("Too many " + sentryRequest.type + " requests, backing off until: " + _this._disabledUntil(sentryRequest.type)); - if (status === 'success') { - resolve({ status: status }); - } - else { - var rejectionMessage = "HTTP Error (" + statusCode + ")"; - if (res.headers && res.headers['x-sentry-error']) { - rejectionMessage += ": " + res.headers['x-sentry-error']; - } - reject(new utils_1.SentryError(rejectionMessage)); - } - // Force the socket to drain - res.on('data', function () { - // Drain - }); - res.on('end', function () { - // Drain - }); - }); - req.on('error', reject); - req.end(sentryRequest.body); - }); - })]; - }); - }); - }; - return BaseTransport; -}()); -exports.BaseTransport = BaseTransport; -//# sourceMappingURL=index.js.map -/***/ }), + integrationsByName[name] = currentInstance; + }); -/***/ 57580: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + return Object.keys(integrationsByName).map(k => integrationsByName[k]); +} -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var http = __nccwpck_require__(58611); -var base_1 = __nccwpck_require__(62006); -/** Node http module transport */ -var HTTPTransport = /** @class */ (function (_super) { - tslib_1.__extends(HTTPTransport, _super); - /** Create a new instance and set this.agent */ - function HTTPTransport(options) { - var _this = _super.call(this, options) || this; - _this.options = options; - var proxy = _this._getProxy('http'); - _this.module = http; - _this.client = proxy - ? new (__nccwpck_require__(42926))(proxy) - : new http.Agent({ keepAlive: false, maxSockets: 30, timeout: 2000 }); - return _this; - } - /** - * @inheritDoc - */ - HTTPTransport.prototype.sendEvent = function (event) { - return this._send(core_1.eventToSentryRequest(event, this._api), event); - }; - /** - * @inheritDoc - */ - HTTPTransport.prototype.sendSession = function (session) { - return this._send(core_1.sessionToSentryRequest(session, this._api), session); - }; - return HTTPTransport; -}(base_1.BaseTransport)); -exports.HTTPTransport = HTTPTransport; -//# sourceMappingURL=http.js.map +/** Gets integrations to install */ +function getIntegrationsToSetup(options) { + const defaultIntegrations = options.defaultIntegrations || []; + const userIntegrations = options.integrations; -/***/ }), + // We flag default instances, so that later we can tell them apart from any user-created instances of the same class + defaultIntegrations.forEach(integration => { + integration.isDefaultInstance = true; + }); -/***/ 48419: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + let integrations; -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var core_1 = __nccwpck_require__(41429); -var https = __nccwpck_require__(65692); -var base_1 = __nccwpck_require__(62006); -/** Node https module transport */ -var HTTPSTransport = /** @class */ (function (_super) { - tslib_1.__extends(HTTPSTransport, _super); - /** Create a new instance and set this.agent */ - function HTTPSTransport(options) { - var _this = _super.call(this, options) || this; - _this.options = options; - var proxy = _this._getProxy('https'); - _this.module = https; - _this.client = proxy - ? new (__nccwpck_require__(42926))(proxy) - : new https.Agent({ keepAlive: false, maxSockets: 30, timeout: 2000 }); - return _this; - } - /** - * @inheritDoc - */ - HTTPSTransport.prototype.sendEvent = function (event) { - return this._send(core_1.eventToSentryRequest(event, this._api), event); - }; - /** - * @inheritDoc - */ - HTTPSTransport.prototype.sendSession = function (session) { - return this._send(core_1.sessionToSentryRequest(session, this._api), session); - }; - return HTTPSTransport; -}(base_1.BaseTransport)); -exports.HTTPSTransport = HTTPSTransport; -//# sourceMappingURL=https.js.map + if (Array.isArray(userIntegrations)) { + integrations = [...defaultIntegrations, ...userIntegrations]; + } else if (typeof userIntegrations === 'function') { + integrations = utils.arrayify(userIntegrations(defaultIntegrations)); + } else { + integrations = defaultIntegrations; + } -/***/ }), + const finalIntegrations = filterDuplicates(integrations); -/***/ 54950: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + // The `Debug` integration prints copies of the `event` and `hint` which will be passed to `beforeSend` or + // `beforeSendTransaction`. It therefore has to run after all other integrations, so that the changes of all event + // processors will be reflected in the printed values. For lack of a more elegant way to guarantee that, we therefore + // locate it and, assuming it exists, pop it out of its current spot and shove it onto the end of the array. + const debugIndex = findIndex(finalIntegrations, integration => integration.name === 'Debug'); + if (debugIndex !== -1) { + const [debugInstance] = finalIntegrations.splice(debugIndex, 1); + finalIntegrations.push(debugInstance); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var base_1 = __nccwpck_require__(62006); -exports.BaseTransport = base_1.BaseTransport; -var http_1 = __nccwpck_require__(57580); -exports.HTTPTransport = http_1.HTTPTransport; -var https_1 = __nccwpck_require__(48419); -exports.HTTPSTransport = https_1.HTTPSTransport; -var new_1 = __nccwpck_require__(84988); -exports.makeNodeTransport = new_1.makeNodeTransport; -//# sourceMappingURL=index.js.map + return finalIntegrations; +} -/***/ }), +/** + * Given a list of integration instances this installs them all. When `withDefaults` is set to `true` then all default + * integrations are added unless they were already provided before. + * @param integrations array of integration instances + * @param withDefault should enable default integrations + */ +function setupIntegrations(client, integrations) { + const integrationIndex = {}; -/***/ 84988: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + integrations.forEach(integration => { + // guard against empty provided integrations + if (integration) { + setupIntegration(client, integration, integrationIndex); + } + }); + + return integrationIndex; +} -Object.defineProperty(exports, "__esModule", ({ value: true })); -var core_1 = __nccwpck_require__(41429); -var utils_1 = __nccwpck_require__(6785); -var http = __nccwpck_require__(58611); -var https = __nccwpck_require__(65692); -var url_1 = __nccwpck_require__(87016); /** - * Creates a Transport that uses native the native 'http' and 'https' modules to send events to Sentry. + * Execute the `afterAllSetup` hooks of the given integrations. */ -function makeNodeTransport(options) { - var _a; - var urlSegments = new url_1.URL(options.url); - var isHttps = urlSegments.protocol === 'https:'; - // Proxy prioritization: http => `options.proxy` | `process.env.http_proxy` - // Proxy prioritization: https => `options.proxy` | `process.env.https_proxy` | `process.env.http_proxy` - var proxy = applyNoProxyOption(urlSegments, options.proxy || (isHttps ? process.env.https_proxy : undefined) || process.env.http_proxy); - var nativeHttpModule = isHttps ? https : http; - // TODO(v7): Evaluate if we can set keepAlive to true. This would involve testing for memory leaks in older node - // versions(>= 8) as they had memory leaks when using it: #2555 - var agent = proxy - ? new (__nccwpck_require__(42926))(proxy) - : new nativeHttpModule.Agent({ keepAlive: false, maxSockets: 30, timeout: 2000 }); - var requestExecutor = createRequestExecutor(options, (_a = options.httpModule, (_a !== null && _a !== void 0 ? _a : nativeHttpModule)), agent); - return core_1.createTransport({ bufferSize: options.bufferSize }, requestExecutor); +function afterSetupIntegrations(client, integrations) { + for (const integration of integrations) { + // guard against empty provided integrations + if (integration && integration.afterAllSetup) { + integration.afterAllSetup(client); + } + } } -exports.makeNodeTransport = makeNodeTransport; + +/** Setup a single integration. */ +function setupIntegration(client, integration, integrationIndex) { + if (integrationIndex[integration.name]) { + debugBuild.DEBUG_BUILD && utils.logger.log(`Integration skipped because it was already installed: ${integration.name}`); + return; + } + integrationIndex[integration.name] = integration; + + // `setupOnce` is only called the first time + if (installedIntegrations.indexOf(integration.name) === -1) { + // eslint-disable-next-line deprecation/deprecation + integration.setupOnce(eventProcessors.addGlobalEventProcessor, hub.getCurrentHub); + installedIntegrations.push(integration.name); + } + + // `setup` is run for each client + if (integration.setup && typeof integration.setup === 'function') { + integration.setup(client); + } + + if (client.on && typeof integration.preprocessEvent === 'function') { + const callback = integration.preprocessEvent.bind(integration) ; + client.on('preprocessEvent', (event, hint) => callback(event, hint, client)); + } + + if (client.addEventProcessor && typeof integration.processEvent === 'function') { + const callback = integration.processEvent.bind(integration) ; + + const processor = Object.assign((event, hint) => callback(event, hint, client), { + id: integration.name, + }); + + client.addEventProcessor(processor); + } + + debugBuild.DEBUG_BUILD && utils.logger.log(`Integration installed: ${integration.name}`); +} + +/** Add an integration to the current hub's client. */ +function addIntegration(integration) { + const client = exports$1.getClient(); + + if (!client || !client.addIntegration) { + debugBuild.DEBUG_BUILD && utils.logger.warn(`Cannot add integration "${integration.name}" because no SDK Client is available.`); + return; + } + + client.addIntegration(integration); +} + +// Polyfill for Array.findIndex(), which is not supported in ES5 +function findIndex(arr, callback) { + for (let i = 0; i < arr.length; i++) { + if (callback(arr[i]) === true) { + return i; + } + } + + return -1; +} + /** - * Honors the `no_proxy` env variable with the highest priority to allow for hosts exclusion. + * Convert a new integration function to the legacy class syntax. + * In v8, we can remove this and instead export the integration functions directly. * - * @param transportUrl The URL the transport intends to send events to. - * @param proxy The client configured proxy. - * @returns A proxy the transport should use. + * @deprecated This will be removed in v8! */ -function applyNoProxyOption(transportUrlSegments, proxy) { - var no_proxy = process.env.no_proxy; - var urlIsExemptFromProxy = no_proxy && - no_proxy - .split(',') - .some(function (exemption) { return transportUrlSegments.host.endsWith(exemption) || transportUrlSegments.hostname.endsWith(exemption); }); - if (urlIsExemptFromProxy) { - return undefined; - } - else { - return proxy; - } +function convertIntegrationFnToClass( + name, + fn, +) { + return Object.assign( + function ConvertedIntegration(...args) { + return fn(...args); + }, + { id: name }, + ) ; } + /** - * Creates a RequestExecutor to be used with `createTransport`. + * Define an integration function that can be used to create an integration instance. + * Note that this by design hides the implementation details of the integration, as they are considered internal. */ -function createRequestExecutor(options, httpModule, agent) { - var _a = new url_1.URL(options.url), hostname = _a.hostname, pathname = _a.pathname, port = _a.port, protocol = _a.protocol, search = _a.search; - return function makeRequest(request) { - return new Promise(function (resolve, reject) { - var req = httpModule.request({ - method: 'POST', - agent: agent, - headers: options.headers, - hostname: hostname, - path: "" + pathname + search, - port: port, - protocol: protocol, - ca: options.caCerts, - }, function (res) { - var _a, _b, _c; - res.on('data', function () { - // Drain socket - }); - res.on('end', function () { - // Drain socket - }); - var statusCode = (_a = res.statusCode, (_a !== null && _a !== void 0 ? _a : 500)); - var status = utils_1.eventStatusFromHttpCode(statusCode); - res.setEncoding('utf8'); - // "Key-value pairs of header names and values. Header names are lower-cased." - // https://nodejs.org/api/http.html#http_message_headers - var retryAfterHeader = (_b = res.headers['retry-after'], (_b !== null && _b !== void 0 ? _b : null)); - var rateLimitsHeader = (_c = res.headers['x-sentry-rate-limits'], (_c !== null && _c !== void 0 ? _c : null)); - resolve({ - headers: { - 'retry-after': retryAfterHeader, - 'x-sentry-rate-limits': Array.isArray(rateLimitsHeader) ? rateLimitsHeader[0] : rateLimitsHeader, - }, - reason: status, - statusCode: statusCode, - }); - }); - req.on('error', reject); - req.end(request.body); - }); - }; +function defineIntegration(fn) { + return fn; } -//# sourceMappingURL=new.js.map + +exports.addIntegration = addIntegration; +exports.afterSetupIntegrations = afterSetupIntegrations; +exports.convertIntegrationFnToClass = convertIntegrationFnToClass; +exports.defineIntegration = defineIntegration; +exports.getIntegrationsToSetup = getIntegrationsToSetup; +exports.installedIntegrations = installedIntegrations; +exports.setupIntegration = setupIntegration; +exports.setupIntegrations = setupIntegrations; +//# sourceMappingURL=integration.js.map + /***/ }), -/***/ 73254: +/***/ 37714: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var fs = __nccwpck_require__(79896); -var path = __nccwpck_require__(16928); + +const utils = __nccwpck_require__(57540); +const exports$1 = __nccwpck_require__(74313); +const integration = __nccwpck_require__(11000); + +let originalFunctionToString; + +const INTEGRATION_NAME = 'FunctionToString'; + +const SETUP_CLIENTS = new WeakMap(); + +const _functionToStringIntegration = (() => { + return { + name: INTEGRATION_NAME, + setupOnce() { + // eslint-disable-next-line @typescript-eslint/unbound-method + originalFunctionToString = Function.prototype.toString; + + // intrinsics (like Function.prototype) might be immutable in some environments + // e.g. Node with --frozen-intrinsics, XS (an embedded JavaScript engine) or SES (a JavaScript proposal) + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Function.prototype.toString = function ( ...args) { + const originalFunction = utils.getOriginalFunction(this); + const context = + SETUP_CLIENTS.has(exports$1.getClient() ) && originalFunction !== undefined ? originalFunction : this; + return originalFunctionToString.apply(context, args); + }; + } catch (e) { + // ignore errors here, just don't patch this + } + }, + setup(client) { + SETUP_CLIENTS.set(client, true); + }, + }; +}) ; + /** - * Recursively read the contents of a directory. + * Patch toString calls to return proper name for wrapped functions. * - * @param targetDir Absolute or relative path of the directory to scan. All returned paths will be relative to this - * directory. - * @returns Array holding all relative paths + * ```js + * Sentry.init({ + * integrations: [ + * functionToStringIntegration(), + * ], + * }); + * ``` */ -function deepReadDirSync(targetDir) { - var targetDirAbsPath = path.resolve(targetDir); - if (!fs.existsSync(targetDirAbsPath)) { - throw new Error("Cannot read contents of " + targetDirAbsPath + ". Directory does not exist."); - } - if (!fs.statSync(targetDirAbsPath).isDirectory()) { - throw new Error("Cannot read contents of " + targetDirAbsPath + ", because it is not a directory."); - } - // This does the same thing as its containing function, `deepReadDirSync` (except that - purely for convenience - it - // deals in absolute paths rather than relative ones). We need this to be separate from the outer function to preserve - // the difference between `targetDirAbsPath` and `currentDirAbsPath`. - var deepReadCurrentDir = function (currentDirAbsPath) { - return fs.readdirSync(currentDirAbsPath).reduce(function (absPaths, itemName) { - var itemAbsPath = path.join(currentDirAbsPath, itemName); - if (fs.statSync(itemAbsPath).isDirectory()) { - return tslib_1.__spread(absPaths, deepReadCurrentDir(itemAbsPath)); - } - return tslib_1.__spread(absPaths, [itemAbsPath]); - }, []); - }; - return deepReadCurrentDir(targetDirAbsPath).map(function (absPath) { return path.relative(targetDirAbsPath, absPath); }); -} -exports.deepReadDirSync = deepReadDirSync; -//# sourceMappingURL=utils.js.map +const functionToStringIntegration = integration.defineIntegration(_functionToStringIntegration); -/***/ }), +/** + * Patch toString calls to return proper name for wrapped functions. + * + * @deprecated Use `functionToStringIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const FunctionToString = integration.convertIntegrationFnToClass( + INTEGRATION_NAME, + functionToStringIntegration, +) ; -/***/ 40275: -/***/ ((__unused_webpack_module, exports) => { +// eslint-disable-next-line deprecation/deprecation + +exports.FunctionToString = FunctionToString; +exports.functionToStringIntegration = functionToStringIntegration; +//# sourceMappingURL=functiontostring.js.map -Object.defineProperty(exports, "__esModule", ({ value: true })); -// TODO: Remove in the next major release and rely only on @sentry/core SDK_VERSION and SdkMetadata -exports.SDK_NAME = 'sentry.javascript.node'; -//# sourceMappingURL=version.js.map /***/ }), -/***/ 34105: +/***/ 81050: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var severity_1 = __nccwpck_require__(83030); -exports.Severity = severity_1.Severity; -var severity_2 = __nccwpck_require__(83030); -exports.SeverityLevels = severity_2.SeverityLevels; -//# sourceMappingURL=index.js.map -/***/ }), +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const integration = __nccwpck_require__(11000); -/***/ 83030: -/***/ ((__unused_webpack_module, exports) => { +// "Script error." is hard coded into browsers for errors that it can't read. +// this is the result of a script being pulled in from an external domain and CORS. +const DEFAULT_IGNORE_ERRORS = [ + /^Script error\.?$/, + /^Javascript error: Script error\.? on line 0$/, + /^ResizeObserver loop completed with undelivered notifications.$/, + /^Cannot redefine property: googletag$/, +]; -Object.defineProperty(exports, "__esModule", ({ value: true })); -/** - * TODO(v7): Remove this enum and replace with SeverityLevel - */ -var Severity; -(function (Severity) { - /** JSDoc */ - Severity["Fatal"] = "fatal"; - /** JSDoc */ - Severity["Error"] = "error"; - /** JSDoc */ - Severity["Warning"] = "warning"; - /** JSDoc */ - Severity["Log"] = "log"; - /** JSDoc */ - Severity["Info"] = "info"; - /** JSDoc */ - Severity["Debug"] = "debug"; - /** JSDoc */ - Severity["Critical"] = "critical"; -})(Severity = exports.Severity || (exports.Severity = {})); -// TODO: in v7, these can disappear, because they now also exist in `@sentry/utils`. (Having them there rather than here -// is nice because then it enforces the idea that only types are exported from `@sentry/types`.) -exports.SeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug', 'critical']; -//# sourceMappingURL=severity.js.map +const DEFAULT_IGNORE_TRANSACTIONS = [ + /^.*\/healthcheck$/, + /^.*\/healthy$/, + /^.*\/live$/, + /^.*\/ready$/, + /^.*\/heartbeat$/, + /^.*\/health$/, + /^.*\/healthz$/, +]; -/***/ }), +/** Options for the InboundFilters integration */ -/***/ 23809: -/***/ ((__unused_webpack_module, exports) => { +const INTEGRATION_NAME = 'InboundFilters'; +const _inboundFiltersIntegration = ((options = {}) => { + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(event, _hint, client) { + const clientOptions = client.getOptions(); + const mergedOptions = _mergeOptions(options, clientOptions); + return _shouldDropEvent(event, mergedOptions) ? null : event; + }, + }; +}) ; + +const inboundFiltersIntegration = integration.defineIntegration(_inboundFiltersIntegration); -Object.defineProperty(exports, "__esModule", ({ value: true })); /** - * Consumes the promise and logs the error when it rejects. - * @param promise A promise to forget. + * Inbound filters configurable by the user. + * @deprecated Use `inboundFiltersIntegration()` instead. */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function forget(promise) { - void promise.then(null, function (e) { - // TODO: Use a better logging mechanism - // eslint-disable-next-line no-console - console.error(e); - }); +// eslint-disable-next-line deprecation/deprecation +const InboundFilters = integration.convertIntegrationFnToClass( + INTEGRATION_NAME, + inboundFiltersIntegration, +) + +; + +function _mergeOptions( + internalOptions = {}, + clientOptions = {}, +) { + return { + allowUrls: [...(internalOptions.allowUrls || []), ...(clientOptions.allowUrls || [])], + denyUrls: [...(internalOptions.denyUrls || []), ...(clientOptions.denyUrls || [])], + ignoreErrors: [ + ...(internalOptions.ignoreErrors || []), + ...(clientOptions.ignoreErrors || []), + ...(internalOptions.disableErrorDefaults ? [] : DEFAULT_IGNORE_ERRORS), + ], + ignoreTransactions: [ + ...(internalOptions.ignoreTransactions || []), + ...(clientOptions.ignoreTransactions || []), + ...(internalOptions.disableTransactionDefaults ? [] : DEFAULT_IGNORE_TRANSACTIONS), + ], + ignoreInternal: internalOptions.ignoreInternal !== undefined ? internalOptions.ignoreInternal : true, + }; } -exports.forget = forget; -//# sourceMappingURL=async.js.map -/***/ }), +function _shouldDropEvent(event, options) { + if (options.ignoreInternal && _isSentryError(event)) { + debugBuild.DEBUG_BUILD && + utils.logger.warn(`Event dropped due to being internal Sentry Error.\nEvent: ${utils.getEventDescription(event)}`); + return true; + } + if (_isIgnoredError(event, options.ignoreErrors)) { + debugBuild.DEBUG_BUILD && + utils.logger.warn( + `Event dropped due to being matched by \`ignoreErrors\` option.\nEvent: ${utils.getEventDescription(event)}`, + ); + return true; + } + if (_isIgnoredTransaction(event, options.ignoreTransactions)) { + debugBuild.DEBUG_BUILD && + utils.logger.warn( + `Event dropped due to being matched by \`ignoreTransactions\` option.\nEvent: ${utils.getEventDescription(event)}`, + ); + return true; + } + if (_isDeniedUrl(event, options.denyUrls)) { + debugBuild.DEBUG_BUILD && + utils.logger.warn( + `Event dropped due to being matched by \`denyUrls\` option.\nEvent: ${utils.getEventDescription( + event, + )}.\nUrl: ${_getEventFilterUrl(event)}`, + ); + return true; + } + if (!_isAllowedUrl(event, options.allowUrls)) { + debugBuild.DEBUG_BUILD && + utils.logger.warn( + `Event dropped due to not being matched by \`allowUrls\` option.\nEvent: ${utils.getEventDescription( + event, + )}.\nUrl: ${_getEventFilterUrl(event)}`, + ); + return true; + } + return false; +} -/***/ 90865: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +function _isIgnoredError(event, ignoreErrors) { + // If event.type, this is not an error + if (event.type || !ignoreErrors || !ignoreErrors.length) { + return false; + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var global_1 = __nccwpck_require__(16734); -var is_1 = __nccwpck_require__(79409); -/** - * Given a child DOM element, returns a query-selector statement describing that - * and its ancestors - * e.g. [HTMLElement] => body > div > input#foo.btn[name=baz] - * @returns generated DOM path - */ -function htmlTreeAsString(elem, keyAttrs) { - // try/catch both: - // - accessing event.target (see getsentry/raven-js#838, #768) - // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly - // - can throw an exception in some circumstances. - try { - var currentElem = elem; - var MAX_TRAVERSE_HEIGHT = 5; - var MAX_OUTPUT_LEN = 80; - var out = []; - var height = 0; - var len = 0; - var separator = ' > '; - var sepLength = separator.length; - var nextStr = void 0; - // eslint-disable-next-line no-plusplus - while (currentElem && height++ < MAX_TRAVERSE_HEIGHT) { - nextStr = _htmlElementAsString(currentElem, keyAttrs); - // bail out if - // - nextStr is the 'html' element - // - the length of the string that would be created exceeds MAX_OUTPUT_LEN - // (ignore this limit if we are on the first iteration) - if (nextStr === 'html' || (height > 1 && len + out.length * sepLength + nextStr.length >= MAX_OUTPUT_LEN)) { - break; - } - out.push(nextStr); - len += nextStr.length; - currentElem = currentElem.parentNode; - } - return out.reverse().join(separator); - } - catch (_oO) { - return ''; - } + return _getPossibleEventMessages(event).some(message => utils.stringMatchesSomePattern(message, ignoreErrors)); } -exports.htmlTreeAsString = htmlTreeAsString; -/** - * Returns a simple, query-selector representation of a DOM element - * e.g. [HTMLElement] => input#foo.btn[name=baz] - * @returns generated DOM path - */ -function _htmlElementAsString(el, keyAttrs) { - var elem = el; - var out = []; - var className; - var classes; - var key; - var attr; - var i; - if (!elem || !elem.tagName) { - return ''; - } - out.push(elem.tagName.toLowerCase()); - // Pairs of attribute keys defined in `serializeAttribute` and their values on element. - var keyAttrPairs = keyAttrs && keyAttrs.length - ? keyAttrs.filter(function (keyAttr) { return elem.getAttribute(keyAttr); }).map(function (keyAttr) { return [keyAttr, elem.getAttribute(keyAttr)]; }) - : null; - if (keyAttrPairs && keyAttrPairs.length) { - keyAttrPairs.forEach(function (keyAttrPair) { - out.push("[" + keyAttrPair[0] + "=\"" + keyAttrPair[1] + "\"]"); - }); - } - else { - if (elem.id) { - out.push("#" + elem.id); - } - // eslint-disable-next-line prefer-const - className = elem.className; - if (className && is_1.isString(className)) { - classes = className.split(/\s+/); - for (i = 0; i < classes.length; i++) { - out.push("." + classes[i]); - } - } - } - var allowedAttrs = ['type', 'name', 'title', 'alt']; - for (i = 0; i < allowedAttrs.length; i++) { - key = allowedAttrs[i]; - attr = elem.getAttribute(key); - if (attr) { - out.push("[" + key + "=\"" + attr + "\"]"); - } - } - return out.join(''); + +function _isIgnoredTransaction(event, ignoreTransactions) { + if (event.type !== 'transaction' || !ignoreTransactions || !ignoreTransactions.length) { + return false; + } + + const name = event.transaction; + return name ? utils.stringMatchesSomePattern(name, ignoreTransactions) : false; } -/** - * A safe form of location.href - */ -function getLocationHref() { - var global = global_1.getGlobalObject(); - try { - return global.document.location.href; - } - catch (oO) { - return ''; - } + +function _isDeniedUrl(event, denyUrls) { + // TODO: Use Glob instead? + if (!denyUrls || !denyUrls.length) { + return false; + } + const url = _getEventFilterUrl(event); + return !url ? false : utils.stringMatchesSomePattern(url, denyUrls); } -exports.getLocationHref = getLocationHref; -//# sourceMappingURL=browser.js.map -/***/ }), +function _isAllowedUrl(event, allowUrls) { + // TODO: Use Glob instead? + if (!allowUrls || !allowUrls.length) { + return true; + } + const url = _getEventFilterUrl(event); + return !url ? true : utils.stringMatchesSomePattern(url, allowUrls); +} -/***/ 21796: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +function _getPossibleEventMessages(event) { + const possibleMessages = []; -Object.defineProperty(exports, "__esModule", ({ value: true })); -var envelope_1 = __nccwpck_require__(86989); -var time_1 = __nccwpck_require__(86800); -/** - * Creates client report envelope - * @param discarded_events An array of discard events - * @param dsn A DSN that can be set on the header. Optional. - */ -function createClientReportEnvelope(discarded_events, dsn, timestamp) { - var clientReportItem = [ - { type: 'client_report' }, - { - timestamp: timestamp || time_1.dateTimestampInSeconds(), - discarded_events: discarded_events, - }, - ]; - return envelope_1.createEnvelope(dsn ? { dsn: dsn } : {}, [clientReportItem]); -} -exports.createClientReportEnvelope = createClientReportEnvelope; -//# sourceMappingURL=clientreport.js.map + if (event.message) { + possibleMessages.push(event.message); + } -/***/ }), + let lastException; + try { + // @ts-expect-error Try catching to save bundle size + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + lastException = event.exception.values[event.exception.values.length - 1]; + } catch (e) { + // try catching to save bundle size checking existence of variables + } -/***/ 58236: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + if (lastException) { + if (lastException.value) { + possibleMessages.push(lastException.value); + if (lastException.type) { + possibleMessages.push(`${lastException.type}: ${lastException.value}`); + } + } + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var error_1 = __nccwpck_require__(62163); -var flags_1 = __nccwpck_require__(8142); -/** Regular expression used to parse a Dsn. */ -var DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+))?@)([\w.-]+)(?::(\d+))?\/(.+)/; -function isValidProtocol(protocol) { - return protocol === 'http' || protocol === 'https'; -} -/** - * Renders the string representation of this Dsn. - * - * By default, this will render the public representation without the password - * component. To get the deprecated private representation, set `withPassword` - * to true. - * - * @param withPassword When set to true, the password will be included. - */ -function dsnToString(dsn, withPassword) { - if (withPassword === void 0) { withPassword = false; } - var host = dsn.host, path = dsn.path, pass = dsn.pass, port = dsn.port, projectId = dsn.projectId, protocol = dsn.protocol, publicKey = dsn.publicKey; - return (protocol + "://" + publicKey + (withPassword && pass ? ":" + pass : '') + - ("@" + host + (port ? ":" + port : '') + "/" + (path ? path + "/" : path) + projectId)); + if (debugBuild.DEBUG_BUILD && possibleMessages.length === 0) { + utils.logger.error(`Could not extract message for event ${utils.getEventDescription(event)}`); + } + + return possibleMessages; } -exports.dsnToString = dsnToString; -function dsnFromString(str) { - var match = DSN_REGEX.exec(str); - if (!match) { - throw new error_1.SentryError("Invalid Sentry Dsn: " + str); - } - var _a = tslib_1.__read(match.slice(1), 6), protocol = _a[0], publicKey = _a[1], _b = _a[2], pass = _b === void 0 ? '' : _b, host = _a[3], _c = _a[4], port = _c === void 0 ? '' : _c, lastPath = _a[5]; - var path = ''; - var projectId = lastPath; - var split = projectId.split('/'); - if (split.length > 1) { - path = split.slice(0, -1).join('/'); - projectId = split.pop(); - } - if (projectId) { - var projectMatch = projectId.match(/^\d+/); - if (projectMatch) { - projectId = projectMatch[0]; - } - } - return dsnFromComponents({ host: host, pass: pass, path: path, projectId: projectId, port: port, protocol: protocol, publicKey: publicKey }); + +function _isSentryError(event) { + try { + // @ts-expect-error can't be a sentry error if undefined + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + return event.exception.values[0].type === 'SentryError'; + } catch (e) { + // ignore + } + return false; } -function dsnFromComponents(components) { - // TODO this is for backwards compatibility, and can be removed in a future version - if ('user' in components && !('publicKey' in components)) { - components.publicKey = components.user; + +function _getLastValidUrl(frames = []) { + for (let i = frames.length - 1; i >= 0; i--) { + const frame = frames[i]; + + if (frame && frame.filename !== '' && frame.filename !== '[native code]') { + return frame.filename || null; } - return { - user: components.publicKey || '', - protocol: components.protocol, - publicKey: components.publicKey || '', - pass: components.pass || '', - host: components.host, - port: components.port || '', - path: components.path || '', - projectId: components.projectId, - }; + } + + return null; } -function validateDsn(dsn) { - if (!flags_1.IS_DEBUG_BUILD) { - return; - } - var port = dsn.port, projectId = dsn.projectId, protocol = dsn.protocol; - var requiredComponents = ['protocol', 'publicKey', 'host', 'projectId']; - requiredComponents.forEach(function (component) { - if (!dsn[component]) { - throw new error_1.SentryError("Invalid Sentry Dsn: " + component + " missing"); - } - }); - if (!projectId.match(/^\d+$/)) { - throw new error_1.SentryError("Invalid Sentry Dsn: Invalid projectId " + projectId); - } - if (!isValidProtocol(protocol)) { - throw new error_1.SentryError("Invalid Sentry Dsn: Invalid protocol " + protocol); - } - if (port && isNaN(parseInt(port, 10))) { - throw new error_1.SentryError("Invalid Sentry Dsn: Invalid port " + port); + +function _getEventFilterUrl(event) { + try { + let frames; + try { + // @ts-expect-error we only care about frames if the whole thing here is defined + frames = event.exception.values[0].stacktrace.frames; + } catch (e) { + // ignore } - return true; -} -/** The Sentry Dsn, identifying a Sentry instance and project. */ -function makeDsn(from) { - var components = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from); - validateDsn(components); - return components; + return frames ? _getLastValidUrl(frames) : null; + } catch (oO) { + debugBuild.DEBUG_BUILD && utils.logger.error(`Cannot extract url for event ${utils.getEventDescription(event)}`); + return null; + } } -exports.makeDsn = makeDsn; -//# sourceMappingURL=dsn.js.map + +exports.InboundFilters = InboundFilters; +exports.inboundFiltersIntegration = inboundFiltersIntegration; +//# sourceMappingURL=inboundfilters.js.map + /***/ }), -/***/ 60663: -/***/ ((__unused_webpack_module, exports) => { +/***/ 3104: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.SeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug', 'critical']; -//# sourceMappingURL=enums.js.map -/***/ }), +const functiontostring = __nccwpck_require__(37714); +const inboundfilters = __nccwpck_require__(81050); +const linkederrors = __nccwpck_require__(87132); -/***/ 93478: -/***/ ((__unused_webpack_module, exports) => { +/* eslint-disable deprecation/deprecation */ + +exports.FunctionToString = functiontostring.FunctionToString; +exports.InboundFilters = inboundfilters.InboundFilters; +exports.LinkedErrors = linkederrors.LinkedErrors; +//# sourceMappingURL=index.js.map -/* - * This module exists for optimizations in the build process through rollup and terser. We define some global - * constants, which can be overridden during build. By guarding certain pieces of code with functions that return these - * constants, we can control whether or not they appear in the final bundle. (Any code guarded by a false condition will - * never run, and will hence be dropped during treeshaking.) The two primary uses for this are stripping out calls to - * `logger` and preventing node-related code from appearing in browser bundles. - * - * Attention: - * This file should not be used to define constants/flags that are intended to be used for tree-shaking conducted by - * users. These fags should live in their respective packages, as we identified user tooling (specifically webpack) - * having issues tree-shaking these constants across package boundaries. - * An example for this is the __SENTRY_DEBUG__ constant. It is declared in each package individually because we want - * users to be able to shake away expressions that it guards. - */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -/** - * Figures out if we're building a browser bundle. - * - * @returns true if this is a browser bundle build. - */ -function isBrowserBundle() { - return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__; -} -exports.isBrowserBundle = isBrowserBundle; -//# sourceMappingURL=env.js.map /***/ }), -/***/ 86989: +/***/ 87132: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var is_1 = __nccwpck_require__(79409); -/** - * Creates an envelope. - * Make sure to always explicitly provide the generic to this function - * so that the envelope types resolve correctly. - */ -function createEnvelope(headers, items) { - if (items === void 0) { items = []; } - return [headers, items]; -} -exports.createEnvelope = createEnvelope; -/** - * Add an item to an envelope. - * Make sure to always explicitly provide the generic to this function - * so that the envelope types resolve correctly. - */ -function addItemToEnvelope(envelope, newItem) { - var _a = tslib_1.__read(envelope, 2), headers = _a[0], items = _a[1]; - return [headers, tslib_1.__spread(items, [newItem])]; -} -exports.addItemToEnvelope = addItemToEnvelope; -/** - * Get the type of the envelope. Grabs the type from the first envelope item. - */ -function getEnvelopeType(envelope) { - var _a = tslib_1.__read(envelope, 2), _b = tslib_1.__read(_a[1], 1), _c = tslib_1.__read(_b[0], 1), firstItemHeader = _c[0]; - return firstItemHeader.type; -} -exports.getEnvelopeType = getEnvelopeType; + +const utils = __nccwpck_require__(57540); +const integration = __nccwpck_require__(11000); + +const DEFAULT_KEY = 'cause'; +const DEFAULT_LIMIT = 5; + +const INTEGRATION_NAME = 'LinkedErrors'; + +const _linkedErrorsIntegration = ((options = {}) => { + const limit = options.limit || DEFAULT_LIMIT; + const key = options.key || DEFAULT_KEY; + + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + preprocessEvent(event, hint, client) { + const options = client.getOptions(); + + utils.applyAggregateErrorsToEvent( + utils.exceptionFromError, + options.stackParser, + options.maxValueLength, + key, + limit, + event, + hint, + ); + }, + }; +}) ; + +const linkedErrorsIntegration = integration.defineIntegration(_linkedErrorsIntegration); + /** - * Serializes an envelope into a string. + * Adds SDK info to an event. + * @deprecated Use `linkedErrorsIntegration()` instead. */ -function serializeEnvelope(envelope) { - var _a = tslib_1.__read(envelope, 2), headers = _a[0], items = _a[1]; - var serializedHeaders = JSON.stringify(headers); - // Have to cast items to any here since Envelope is a union type - // Fixed in Typescript 4.2 - // TODO: Remove any[] cast when we upgrade to TS 4.2 - // https://github.com/microsoft/TypeScript/issues/36390 - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return items.reduce(function (acc, item) { - var _a = tslib_1.__read(item, 2), itemHeaders = _a[0], payload = _a[1]; - // We do not serialize payloads that are primitives - var serializedPayload = is_1.isPrimitive(payload) ? String(payload) : JSON.stringify(payload); - return acc + "\n" + JSON.stringify(itemHeaders) + "\n" + serializedPayload; - }, serializedHeaders); -} -exports.serializeEnvelope = serializeEnvelope; -//# sourceMappingURL=envelope.js.map +// eslint-disable-next-line deprecation/deprecation +const LinkedErrors = integration.convertIntegrationFnToClass(INTEGRATION_NAME, linkedErrorsIntegration) + +; + +exports.LinkedErrors = LinkedErrors; +exports.linkedErrorsIntegration = linkedErrorsIntegration; +//# sourceMappingURL=linkederrors.js.map + /***/ }), -/***/ 62163: +/***/ 18567: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var polyfill_1 = __nccwpck_require__(12486); -/** An error emitted by Sentry SDKs and related utilities. */ -var SentryError = /** @class */ (function (_super) { - tslib_1.__extends(SentryError, _super); - function SentryError(message) { - var _newTarget = this.constructor; - var _this = _super.call(this, message) || this; - _this.message = message; - _this.name = _newTarget.prototype.constructor.name; - polyfill_1.setPrototypeOf(_this, _newTarget.prototype); - return _this; - } - return SentryError; -}(Error)); -exports.SentryError = SentryError; -//# sourceMappingURL=error.js.map -/***/ }), +const utils = __nccwpck_require__(57540); +const integration = __nccwpck_require__(11000); +const metadata = __nccwpck_require__(68465); -/***/ 8142: -/***/ ((__unused_webpack_module, exports) => { +const INTEGRATION_NAME = 'ModuleMetadata'; -/* - * This file defines flags and constants that can be modified during compile time in order to facilitate tree shaking - * for users. - * - * Debug flags need to be declared in each package individually and must not be imported across package boundaries, - * because some build tools have trouble tree-shaking imported guards. - * - * As a convention, we define debug flags in a `flags.ts` file in the root of a package's `src` folder. - * - * Debug flag files will contain "magic strings" like `__SENTRY_DEBUG__` that may get replaced with actual values during - * our, or the user's build process. Take care when introducing new flags - they must not throw if they are not - * replaced. - */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -/** Flag that is true for debug builds, false otherwise. */ -exports.IS_DEBUG_BUILD = typeof __SENTRY_DEBUG__ === 'undefined' ? true : __SENTRY_DEBUG__; -//# sourceMappingURL=flags.js.map +const _moduleMetadataIntegration = (() => { + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + setup(client) { + if (typeof client.on !== 'function') { + return; + } -/***/ }), + // We need to strip metadata from stack frames before sending them to Sentry since these are client side only. + client.on('beforeEnvelope', envelope => { + utils.forEachEnvelopeItem(envelope, (item, type) => { + if (type === 'event') { + const event = Array.isArray(item) ? (item )[1] : undefined; -/***/ 16734: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + if (event) { + metadata.stripMetadataFromStackFrames(event); + item[1] = event; + } + } + }); + }); + }, + + processEvent(event, _hint, client) { + const stackParser = client.getOptions().stackParser; + metadata.addMetadataToStackFrames(stackParser, event); + return event; + }, + }; +}) ; + +const moduleMetadataIntegration = integration.defineIntegration(_moduleMetadataIntegration); /** - * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something, - * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere. - */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -var node_1 = __nccwpck_require__(361); -var fallbackGlobalObject = {}; -/** - * Safely get global scope object + * Adds module metadata to stack frames. * - * @returns Global scope object - */ -function getGlobalObject() { - return (node_1.isNodeEnv() - ? global - : typeof window !== 'undefined' // eslint-disable-line no-restricted-globals - ? window // eslint-disable-line no-restricted-globals - : typeof self !== 'undefined' - ? self - : fallbackGlobalObject); -} -exports.getGlobalObject = getGlobalObject; -/** - * Returns a global singleton contained in the global `__SENTRY__` object. + * Metadata can be injected by the Sentry bundler plugins using the `_experiments.moduleMetadata` config option. * - * If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory - * function and added to the `__SENTRY__` object. + * When this integration is added, the metadata passed to the bundler plugin is added to the stack frames of all events + * under the `module_metadata` property. This can be used to help in tagging or routing of events from different teams + * our sources * - * @param name name of the global singleton on __SENTRY__ - * @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__` - * @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `getGlobalObject`'s return value - * @returns the singleton + * @deprecated Use `moduleMetadataIntegration()` instead. */ -function getGlobalSingleton(name, creator, obj) { - var global = (obj || getGlobalObject()); - var __SENTRY__ = (global.__SENTRY__ = global.__SENTRY__ || {}); - var singleton = __SENTRY__[name] || (__SENTRY__[name] = creator()); - return singleton; -} -exports.getGlobalSingleton = getGlobalSingleton; -//# sourceMappingURL=global.js.map +// eslint-disable-next-line deprecation/deprecation +const ModuleMetadata = integration.convertIntegrationFnToClass( + INTEGRATION_NAME, + moduleMetadataIntegration, +) -/***/ }), +; -/***/ 6785: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +exports.ModuleMetadata = ModuleMetadata; +exports.moduleMetadataIntegration = moduleMetadataIntegration; +//# sourceMappingURL=metadata.js.map -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -tslib_1.__exportStar(__nccwpck_require__(23809), exports); -tslib_1.__exportStar(__nccwpck_require__(90865), exports); -tslib_1.__exportStar(__nccwpck_require__(58236), exports); -tslib_1.__exportStar(__nccwpck_require__(60663), exports); -tslib_1.__exportStar(__nccwpck_require__(62163), exports); -tslib_1.__exportStar(__nccwpck_require__(16734), exports); -tslib_1.__exportStar(__nccwpck_require__(65448), exports); -tslib_1.__exportStar(__nccwpck_require__(79409), exports); -tslib_1.__exportStar(__nccwpck_require__(29697), exports); -tslib_1.__exportStar(__nccwpck_require__(23279), exports); -tslib_1.__exportStar(__nccwpck_require__(55205), exports); -tslib_1.__exportStar(__nccwpck_require__(361), exports); -tslib_1.__exportStar(__nccwpck_require__(64706), exports); -tslib_1.__exportStar(__nccwpck_require__(11002), exports); -tslib_1.__exportStar(__nccwpck_require__(5554), exports); -tslib_1.__exportStar(__nccwpck_require__(76034), exports); -tslib_1.__exportStar(__nccwpck_require__(78430), exports); -tslib_1.__exportStar(__nccwpck_require__(60996), exports); -tslib_1.__exportStar(__nccwpck_require__(13707), exports); -tslib_1.__exportStar(__nccwpck_require__(17256), exports); -tslib_1.__exportStar(__nccwpck_require__(64473), exports); -tslib_1.__exportStar(__nccwpck_require__(19705), exports); -tslib_1.__exportStar(__nccwpck_require__(86800), exports); -tslib_1.__exportStar(__nccwpck_require__(88711), exports); -tslib_1.__exportStar(__nccwpck_require__(93478), exports); -tslib_1.__exportStar(__nccwpck_require__(86989), exports); -tslib_1.__exportStar(__nccwpck_require__(21796), exports); -tslib_1.__exportStar(__nccwpck_require__(1464), exports); -//# sourceMappingURL=index.js.map /***/ }), -/***/ 65448: +/***/ 24781: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var flags_1 = __nccwpck_require__(8142); -var global_1 = __nccwpck_require__(16734); -var is_1 = __nccwpck_require__(79409); -var logger_1 = __nccwpck_require__(29697); -var object_1 = __nccwpck_require__(11002); -var stacktrace_1 = __nccwpck_require__(60996); -var supports_1 = __nccwpck_require__(64473); -var global = global_1.getGlobalObject(); -/** - * Instrument native APIs to call handlers that can be used to create breadcrumbs, APM spans etc. - * - Console API - * - Fetch API - * - XHR API - * - History API - * - DOM API (click/typing) - * - Error API - * - UnhandledRejection API - */ -var handlers = {}; -var instrumented = {}; -/** Instruments given API */ -function instrument(type) { - if (instrumented[type]) { - return; - } - instrumented[type] = true; - switch (type) { - case 'console': - instrumentConsole(); - break; - case 'dom': - instrumentDOM(); - break; - case 'xhr': - instrumentXHR(); - break; - case 'fetch': - instrumentFetch(); - break; - case 'history': - instrumentHistory(); - break; - case 'error': - instrumentError(); - break; - case 'unhandledrejection': - instrumentUnhandledRejection(); - break; - default: - flags_1.IS_DEBUG_BUILD && logger_1.logger.warn('unknown instrumentation type:', type); - return; - } -} + +const utils = __nccwpck_require__(57540); +const integration = __nccwpck_require__(11000); +const spanUtils = __nccwpck_require__(98313); + +const DEFAULT_OPTIONS = { + include: { + cookies: true, + data: true, + headers: true, + ip: false, + query_string: true, + url: true, + user: { + id: true, + username: true, + email: true, + }, + }, + transactionNamingScheme: 'methodPath', +}; + +const INTEGRATION_NAME = 'RequestData'; + +const _requestDataIntegration = ((options = {}) => { + const _addRequestData = utils.addRequestDataToEvent; + const _options = { + ...DEFAULT_OPTIONS, + ...options, + include: { + // @ts-expect-error It's mad because `method` isn't a known `include` key. (It's only here and not set by default in + // `addRequestDataToEvent` for legacy reasons. TODO (v8): Change that.) + method: true, + ...DEFAULT_OPTIONS.include, + ...options.include, + user: + options.include && typeof options.include.user === 'boolean' + ? options.include.user + : { + ...DEFAULT_OPTIONS.include.user, + // Unclear why TS still thinks `options.include.user` could be a boolean at this point + ...((options.include || {}).user ), + }, + }, + }; + + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(event, _hint, client) { + // Note: In the long run, most of the logic here should probably move into the request data utility functions. For + // the moment it lives here, though, until https://github.com/getsentry/sentry-javascript/issues/5718 is addressed. + // (TL;DR: Those functions touch many parts of the repo in many different ways, and need to be clened up. Once + // that's happened, it will be easier to add this logic in without worrying about unexpected side effects.) + const { transactionNamingScheme } = _options; + + const { sdkProcessingMetadata = {} } = event; + const req = sdkProcessingMetadata.request; + + if (!req) { + return event; + } + + // The Express request handler takes a similar `include` option to that which can be passed to this integration. + // If passed there, we store it in `sdkProcessingMetadata`. TODO(v8): Force express and GCP people to use this + // integration, so that all of this passing and conversion isn't necessary + const addRequestDataOptions = + sdkProcessingMetadata.requestDataOptionsFromExpressHandler || + sdkProcessingMetadata.requestDataOptionsFromGCPWrapper || + convertReqDataIntegrationOptsToAddReqDataOpts(_options); + + const processedEvent = _addRequestData(event, req, addRequestDataOptions); + + // Transaction events already have the right `transaction` value + if (event.type === 'transaction' || transactionNamingScheme === 'handler') { + return processedEvent; + } + + // In all other cases, use the request's associated transaction (if any) to overwrite the event's `transaction` + // value with a high-quality one + const reqWithTransaction = req ; + const transaction = reqWithTransaction._sentryTransaction; + if (transaction) { + const name = spanUtils.spanToJSON(transaction).description || ''; + + // TODO (v8): Remove the nextjs check and just base it on `transactionNamingScheme` for all SDKs. (We have to + // keep it the way it is for the moment, because changing the names of transactions in Sentry has the potential + // to break things like alert rules.) + const shouldIncludeMethodInTransactionName = + getSDKName(client) === 'sentry.javascript.nextjs' + ? name.startsWith('/api') + : transactionNamingScheme !== 'path'; + + const [transactionValue] = utils.extractPathForTransaction(req, { + path: true, + method: shouldIncludeMethodInTransactionName, + customRoute: name, + }); + + processedEvent.transaction = transactionValue; + } + + return processedEvent; + }, + }; +}) ; + +const requestDataIntegration = integration.defineIntegration(_requestDataIntegration); + /** - * Add handler that will be called when given type of instrumentation triggers. - * Use at your own risk, this might break without changelog notice, only used internally. - * @hidden + * Add data about a request to an event. Primarily for use in Node-based SDKs, but included in `@sentry/integrations` + * so it can be used in cross-platform SDKs like `@sentry/nextjs`. + * @deprecated Use `requestDataIntegration()` instead. */ -function addInstrumentationHandler(type, callback) { - handlers[type] = handlers[type] || []; - handlers[type].push(callback); - instrument(type); -} -exports.addInstrumentationHandler = addInstrumentationHandler; -/** JSDoc */ -function triggerHandlers(type, data) { - var e_1, _a; - if (!type || !handlers[type]) { - return; +// eslint-disable-next-line deprecation/deprecation +const RequestData = integration.convertIntegrationFnToClass(INTEGRATION_NAME, requestDataIntegration) + +; + +/** Convert this integration's options to match what `addRequestDataToEvent` expects */ +/** TODO: Can possibly be deleted once https://github.com/getsentry/sentry-javascript/issues/5718 is fixed */ +function convertReqDataIntegrationOptsToAddReqDataOpts( + integrationOptions, +) { + const { + transactionNamingScheme, + include: { ip, user, ...requestOptions }, + } = integrationOptions; + + const requestIncludeKeys = []; + for (const [key, value] of Object.entries(requestOptions)) { + if (value) { + requestIncludeKeys.push(key); } - try { - for (var _b = tslib_1.__values(handlers[type] || []), _c = _b.next(); !_c.done; _c = _b.next()) { - var handler = _c.value; - try { - handler(data); - } - catch (e) { - flags_1.IS_DEBUG_BUILD && - logger_1.logger.error("Error while triggering instrumentation handler.\nType: " + type + "\nName: " + stacktrace_1.getFunctionName(handler) + "\nError:", e); - } - } + } + + let addReqDataUserOpt; + if (user === undefined) { + addReqDataUserOpt = true; + } else if (typeof user === 'boolean') { + addReqDataUserOpt = user; + } else { + const userIncludeKeys = []; + for (const [key, value] of Object.entries(user)) { + if (value) { + userIncludeKeys.push(key); + } } - 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; } + addReqDataUserOpt = userIncludeKeys; + } + + return { + include: { + ip, + user: addReqDataUserOpt, + request: requestIncludeKeys.length !== 0 ? requestIncludeKeys : undefined, + transaction: transactionNamingScheme, + }, + }; +} + +function getSDKName(client) { + try { + // For a long chain like this, it's fewer bytes to combine a try-catch with assuming everything is there than to + // write out a long chain of `a && a.b && a.b.c && ...` + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return client.getOptions()._metadata.sdk.name; + } catch (err) { + // In theory we should never get here + return undefined; + } +} + +exports.RequestData = RequestData; +exports.requestDataIntegration = requestDataIntegration; +//# sourceMappingURL=requestdata.js.map + + +/***/ }), + +/***/ 68465: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); + +/** Keys are source filename/url, values are metadata objects. */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const filenameMetadataMap = new Map(); +/** Set of stack strings that have already been parsed. */ +const parsedStacks = new Set(); + +function ensureMetadataStacksAreParsed(parser) { + if (!utils.GLOBAL_OBJ._sentryModuleMetadata) { + return; + } + + for (const stack of Object.keys(utils.GLOBAL_OBJ._sentryModuleMetadata)) { + const metadata = utils.GLOBAL_OBJ._sentryModuleMetadata[stack]; + + if (parsedStacks.has(stack)) { + continue; + } + + // Ensure this stack doesn't get parsed again + parsedStacks.add(stack); + + const frames = parser(stack); + + // Go through the frames starting from the top of the stack and find the first one with a filename + for (const frame of frames.reverse()) { + if (frame.filename) { + // Save the metadata for this filename + filenameMetadataMap.set(frame.filename, metadata); + break; + } } + } } -/** JSDoc */ -function instrumentConsole() { - if (!('console' in global)) { + +/** + * Retrieve metadata for a specific JavaScript file URL. + * + * Metadata is injected by the Sentry bundler plugins using the `_experiments.moduleMetadata` config option. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function getMetadataForUrl(parser, filename) { + ensureMetadataStacksAreParsed(parser); + return filenameMetadataMap.get(filename); +} + +/** + * Adds metadata to stack frames. + * + * Metadata is injected by the Sentry bundler plugins using the `_experiments.moduleMetadata` config option. + */ +function addMetadataToStackFrames(parser, event) { + try { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + event.exception.values.forEach(exception => { + if (!exception.stacktrace) { return; - } - logger_1.CONSOLE_LEVELS.forEach(function (level) { - if (!(level in global.console)) { - return; + } + + for (const frame of exception.stacktrace.frames || []) { + if (!frame.filename) { + continue; } - object_1.fill(global.console, level, function (originalConsoleMethod) { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - triggerHandlers('console', { args: args, level: level }); - // this fails for some browsers. :( - if (originalConsoleMethod) { - originalConsoleMethod.apply(global.console, args); - } - }; - }); + + const metadata = getMetadataForUrl(parser, frame.filename); + + if (metadata) { + frame.module_metadata = metadata; + } + } }); + } catch (_) { + // To save bundle size we're just try catching here instead of checking for the existence of all the different objects. + } } -/** JSDoc */ -function instrumentFetch() { - if (!supports_1.supportsNativeFetch()) { + +/** + * Strips metadata from stack frames. + */ +function stripMetadataFromStackFrames(event) { + try { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + event.exception.values.forEach(exception => { + if (!exception.stacktrace) { return; - } - object_1.fill(global, 'fetch', function (originalFetch) { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var handlerData = { - args: args, - fetchData: { - method: getFetchMethod(args), - url: getFetchUrl(args), - }, - startTimestamp: Date.now(), - }; - triggerHandlers('fetch', tslib_1.__assign({}, handlerData)); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - return originalFetch.apply(global, args).then(function (response) { - triggerHandlers('fetch', tslib_1.__assign(tslib_1.__assign({}, handlerData), { endTimestamp: Date.now(), response: response })); - return response; - }, function (error) { - triggerHandlers('fetch', tslib_1.__assign(tslib_1.__assign({}, handlerData), { endTimestamp: Date.now(), error: error })); - // NOTE: If you are a Sentry user, and you are seeing this stack frame, - // it means the sentry.javascript SDK caught an error invoking your application code. - // This is expected behavior and NOT indicative of a bug with sentry.javascript. - throw error; - }); - }; + } + + for (const frame of exception.stacktrace.frames || []) { + delete frame.module_metadata; + } }); + } catch (_) { + // To save bundle size we're just try catching here instead of checking for the existence of all the different objects. + } } -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/** Extract `method` from fetch call arguments */ -function getFetchMethod(fetchArgs) { - if (fetchArgs === void 0) { fetchArgs = []; } - if ('Request' in global && is_1.isInstanceOf(fetchArgs[0], Request) && fetchArgs[0].method) { - return String(fetchArgs[0].method).toUpperCase(); + +exports.addMetadataToStackFrames = addMetadataToStackFrames; +exports.getMetadataForUrl = getMetadataForUrl; +exports.stripMetadataFromStackFrames = stripMetadataFromStackFrames; +//# sourceMappingURL=metadata.js.map + + +/***/ }), + +/***/ 66327: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils$1 = __nccwpck_require__(57540); +const constants = __nccwpck_require__(25913); +const instance = __nccwpck_require__(26457); +const metricSummary = __nccwpck_require__(61479); +const utils = __nccwpck_require__(21629); + +/** + * A metrics aggregator that aggregates metrics in memory and flushes them periodically. + */ +class MetricsAggregator { + // TODO(@anonrig): Use FinalizationRegistry to have a proper way of flushing the buckets + // when the aggregator is garbage collected. + // Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry + + // Different metrics have different weights. We use this to limit the number of metrics + // that we store in memory. + + // Cast to any so that it can use Node.js timeout + // eslint-disable-next-line @typescript-eslint/no-explicit-any + + // SDKs are required to shift the flush interval by random() * rollup_in_seconds. + // That shift is determined once per startup to create jittering. + + // An SDK is required to perform force flushing ahead of scheduled time if the memory + // pressure is too high. There is no rule for this other than that SDKs should be tracking + // abstract aggregation complexity (eg: a counter only carries a single float, whereas a + // distribution is a float per emission). + // + // Force flush is used on either shutdown, flush() or when we exceed the max weight. + + constructor( _client) {this._client = _client; + this._buckets = new Map(); + this._bucketsTotalWeight = 0; + + this._interval = setInterval(() => this._flush(), constants.DEFAULT_FLUSH_INTERVAL) ; + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (this._interval.unref) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + this._interval.unref(); } - if (fetchArgs[1] && fetchArgs[1].method) { - return String(fetchArgs[1].method).toUpperCase(); + + this._flushShift = Math.floor((Math.random() * constants.DEFAULT_FLUSH_INTERVAL) / 1000); + this._forceFlush = false; + } + + /** + * @inheritDoc + */ + add( + metricType, + unsanitizedName, + value, + unsanitizedUnit = 'none', + unsanitizedTags = {}, + maybeFloatTimestamp = utils$1.timestampInSeconds(), + ) { + const timestamp = Math.floor(maybeFloatTimestamp); + const name = utils.sanitizeMetricKey(unsanitizedName); + const tags = utils.sanitizeTags(unsanitizedTags); + const unit = utils.sanitizeUnit(unsanitizedUnit ); + + const bucketKey = utils.getBucketKey(metricType, name, unit, tags); + + let bucketItem = this._buckets.get(bucketKey); + // If this is a set metric, we need to calculate the delta from the previous weight. + const previousWeight = bucketItem && metricType === constants.SET_METRIC_TYPE ? bucketItem.metric.weight : 0; + + if (bucketItem) { + bucketItem.metric.add(value); + // TODO(abhi): Do we need this check? + if (bucketItem.timestamp < timestamp) { + bucketItem.timestamp = timestamp; + } + } else { + bucketItem = { + // @ts-expect-error we don't need to narrow down the type of value here, saves bundle size. + metric: new instance.METRIC_MAP[metricType](value), + timestamp, + metricType, + name, + unit, + tags, + }; + this._buckets.set(bucketKey, bucketItem); } - return 'GET'; -} -/** Extract `url` from fetch call arguments */ -function getFetchUrl(fetchArgs) { - if (fetchArgs === void 0) { fetchArgs = []; } - if (typeof fetchArgs[0] === 'string') { - return fetchArgs[0]; + + // If value is a string, it's a set metric so calculate the delta from the previous weight. + const val = typeof value === 'string' ? bucketItem.metric.weight - previousWeight : value; + metricSummary.updateMetricSummaryOnActiveSpan(metricType, name, val, unit, unsanitizedTags, bucketKey); + + // We need to keep track of the total weight of the buckets so that we can + // flush them when we exceed the max weight. + this._bucketsTotalWeight += bucketItem.metric.weight; + + if (this._bucketsTotalWeight >= constants.MAX_WEIGHT) { + this.flush(); } - if ('Request' in global && is_1.isInstanceOf(fetchArgs[0], Request)) { - return fetchArgs[0].url; + } + + /** + * Flushes the current metrics to the transport via the transport. + */ + flush() { + this._forceFlush = true; + this._flush(); + } + + /** + * Shuts down metrics aggregator and clears all metrics. + */ + close() { + this._forceFlush = true; + clearInterval(this._interval); + this._flush(); + } + + /** + * Flushes the buckets according to the internal state of the aggregator. + * If it is a force flush, which happens on shutdown, it will flush all buckets. + * Otherwise, it will only flush buckets that are older than the flush interval, + * and according to the flush shift. + * + * This function mutates `_forceFlush` and `_bucketsTotalWeight` properties. + */ + _flush() { + // TODO(@anonrig): Add Atomics for locking to avoid having force flush and regular flush + // running at the same time. + // Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics + + // This path eliminates the need for checking for timestamps since we're forcing a flush. + // Remember to reset the flag, or it will always flush all metrics. + if (this._forceFlush) { + this._forceFlush = false; + this._bucketsTotalWeight = 0; + this._captureMetrics(this._buckets); + this._buckets.clear(); + return; } - return String(fetchArgs[0]); -} -/* eslint-enable @typescript-eslint/no-unsafe-member-access */ -/** JSDoc */ -function instrumentXHR() { - if (!('XMLHttpRequest' in global)) { - return; + const cutoffSeconds = Math.floor(utils$1.timestampInSeconds()) - constants.DEFAULT_FLUSH_INTERVAL / 1000 - this._flushShift; + // TODO(@anonrig): Optimization opportunity. + // Convert this map to an array and store key in the bucketItem. + const flushedBuckets = new Map(); + for (const [key, bucket] of this._buckets) { + if (bucket.timestamp <= cutoffSeconds) { + flushedBuckets.set(key, bucket); + this._bucketsTotalWeight -= bucket.metric.weight; + } } - var xhrproto = XMLHttpRequest.prototype; - object_1.fill(xhrproto, 'open', function (originalOpen) { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - // eslint-disable-next-line @typescript-eslint/no-this-alias - var xhr = this; - var url = args[1]; - var xhrInfo = (xhr.__sentry_xhr__ = { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - method: is_1.isString(args[0]) ? args[0].toUpperCase() : args[0], - url: args[1], - }); - // if Sentry key appears in URL, don't capture it as a request - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - if (is_1.isString(url) && xhrInfo.method === 'POST' && url.match(/sentry_key/)) { - xhr.__sentry_own_request__ = true; - } - var onreadystatechangeHandler = function () { - if (xhr.readyState === 4) { - try { - // touching statusCode in some platforms throws - // an exception - xhrInfo.status_code = xhr.status; - } - catch (e) { - /* do nothing */ - } - triggerHandlers('xhr', { - args: args, - endTimestamp: Date.now(), - startTimestamp: Date.now(), - xhr: xhr, - }); - } - }; - if ('onreadystatechange' in xhr && typeof xhr.onreadystatechange === 'function') { - object_1.fill(xhr, 'onreadystatechange', function (original) { - return function () { - var readyStateArgs = []; - for (var _i = 0; _i < arguments.length; _i++) { - readyStateArgs[_i] = arguments[_i]; - } - onreadystatechangeHandler(); - return original.apply(xhr, readyStateArgs); - }; - }); - } - else { - xhr.addEventListener('readystatechange', onreadystatechangeHandler); - } - return originalOpen.apply(xhr, args); - }; - }); - object_1.fill(xhrproto, 'send', function (originalSend) { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - if (this.__sentry_xhr__ && args[0] !== undefined) { - this.__sentry_xhr__.body = args[0]; - } - triggerHandlers('xhr', { - args: args, - startTimestamp: Date.now(), - xhr: this, - }); - return originalSend.apply(this, args); - }; - }); -} -var lastHref; -/** JSDoc */ -function instrumentHistory() { - if (!supports_1.supportsHistory()) { - return; + + for (const [key] of flushedBuckets) { + this._buckets.delete(key); } - var oldOnPopState = global.onpopstate; - global.onpopstate = function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var to = global.location.href; - // keep track of the current URL state, as we always receive only the updated state - var from = lastHref; - lastHref = to; - triggerHandlers('history', { - from: from, - to: to, - }); - if (oldOnPopState) { - // Apparently this can throw in Firefox when incorrectly implemented plugin is installed. - // https://github.com/getsentry/sentry-javascript/issues/3344 - // https://github.com/bugsnag/bugsnag-js/issues/469 - try { - return oldOnPopState.apply(this, args); - } - catch (_oO) { - // no-empty - } - } - }; - /** @hidden */ - function historyReplacementFunction(originalHistoryFunction) { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var url = args.length > 2 ? args[2] : undefined; - if (url) { - // coerce to string (this is what pushState does) - var from = lastHref; - var to = String(url); - // keep track of the current URL state, as we always receive only the updated state - lastHref = to; - triggerHandlers('history', { - from: from, - to: to, - }); - } - return originalHistoryFunction.apply(this, args); - }; + + this._captureMetrics(flushedBuckets); + } + + /** + * Only captures a subset of the buckets passed to this function. + * @param flushedBuckets + */ + _captureMetrics(flushedBuckets) { + if (flushedBuckets.size > 0 && this._client.captureAggregateMetrics) { + // TODO(@anonrig): Optimization opportunity. + // This copy operation can be avoided if we store the key in the bucketItem. + const buckets = Array.from(flushedBuckets).map(([, bucketItem]) => bucketItem); + this._client.captureAggregateMetrics(buckets); } - object_1.fill(global.history, 'pushState', historyReplacementFunction); - object_1.fill(global.history, 'replaceState', historyReplacementFunction); + } } -var debounceDuration = 1000; -var debounceTimerID; -var lastCapturedEvent; + +exports.MetricsAggregator = MetricsAggregator; +//# sourceMappingURL=aggregator.js.map + + +/***/ }), + +/***/ 39416: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils$1 = __nccwpck_require__(57540); +const constants = __nccwpck_require__(25913); +const instance = __nccwpck_require__(26457); +const metricSummary = __nccwpck_require__(61479); +const utils = __nccwpck_require__(21629); + /** - * Decide whether the current event should finish the debounce of previously captured one. - * @param previous previously captured event - * @param current event to be captured + * A simple metrics aggregator that aggregates metrics in memory and flushes them periodically. + * Default flush interval is 5 seconds. + * + * @experimental This API is experimental and might change in the future. */ -function shouldShortcircuitPreviousDebounce(previous, current) { - // If there was no previous event, it should always be swapped for the new one. - if (!previous) { - return true; - } - // If both events have different type, then user definitely performed two separate actions. e.g. click + keypress. - if (previous.type !== current.type) { - return true; +class BrowserMetricsAggregator { + // TODO(@anonrig): Use FinalizationRegistry to have a proper way of flushing the buckets + // when the aggregator is garbage collected. + // Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry + + constructor( _client) {this._client = _client; + this._buckets = new Map(); + this._interval = setInterval(() => this.flush(), constants.DEFAULT_BROWSER_FLUSH_INTERVAL); + } + + /** + * @inheritDoc + */ + add( + metricType, + unsanitizedName, + value, + unsanitizedUnit = 'none', + unsanitizedTags = {}, + maybeFloatTimestamp = utils$1.timestampInSeconds(), + ) { + const timestamp = Math.floor(maybeFloatTimestamp); + const name = utils.sanitizeMetricKey(unsanitizedName); + const tags = utils.sanitizeTags(unsanitizedTags); + const unit = utils.sanitizeUnit(unsanitizedUnit ); + + const bucketKey = utils.getBucketKey(metricType, name, unit, tags); + + let bucketItem = this._buckets.get(bucketKey); + // If this is a set metric, we need to calculate the delta from the previous weight. + const previousWeight = bucketItem && metricType === constants.SET_METRIC_TYPE ? bucketItem.metric.weight : 0; + + if (bucketItem) { + bucketItem.metric.add(value); + // TODO(abhi): Do we need this check? + if (bucketItem.timestamp < timestamp) { + bucketItem.timestamp = timestamp; + } + } else { + bucketItem = { + // @ts-expect-error we don't need to narrow down the type of value here, saves bundle size. + metric: new instance.METRIC_MAP[metricType](value), + timestamp, + metricType, + name, + unit, + tags, + }; + this._buckets.set(bucketKey, bucketItem); } - try { - // If both events have the same type, it's still possible that actions were performed on different targets. - // e.g. 2 clicks on different buttons. - if (previous.target !== current.target) { - return true; - } + + // If value is a string, it's a set metric so calculate the delta from the previous weight. + const val = typeof value === 'string' ? bucketItem.metric.weight - previousWeight : value; + metricSummary.updateMetricSummaryOnActiveSpan(metricType, name, val, unit, unsanitizedTags, bucketKey); + } + + /** + * @inheritDoc + */ + flush() { + // short circuit if buckets are empty. + if (this._buckets.size === 0) { + return; } - catch (e) { - // just accessing `target` property can throw an exception in some rare circumstances - // see: https://github.com/getsentry/sentry-javascript/issues/838 + + if (this._client.captureAggregateMetrics) { + // TODO(@anonrig): Use Object.values() when we support ES6+ + const metricBuckets = Array.from(this._buckets).map(([, bucketItem]) => bucketItem); + this._client.captureAggregateMetrics(metricBuckets); } - // If both events have the same type _and_ same `target` (an element which triggered an event, _not necessarily_ - // to which an event listener was attached), we treat them as the same action, as we want to capture - // only one breadcrumb. e.g. multiple clicks on the same button, or typing inside a user input box. - return false; + + this._buckets.clear(); + } + + /** + * @inheritDoc + */ + close() { + clearInterval(this._interval); + this.flush(); + } } + +exports.BrowserMetricsAggregator = BrowserMetricsAggregator; +//# sourceMappingURL=browser-aggregator.js.map + + +/***/ }), + +/***/ 25913: +/***/ ((__unused_webpack_module, exports) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const COUNTER_METRIC_TYPE = 'c' ; +const GAUGE_METRIC_TYPE = 'g' ; +const SET_METRIC_TYPE = 's' ; +const DISTRIBUTION_METRIC_TYPE = 'd' ; + /** - * Decide whether an event should be captured. - * @param event event to be captured + * This does not match spec in https://develop.sentry.dev/sdk/metrics + * but was chosen to optimize for the most common case in browser environments. */ -function shouldSkipDOMEvent(event) { - // We are only interested in filtering `keypress` events for now. - if (event.type !== 'keypress') { - return false; - } - try { - var target = event.target; - if (!target || !target.tagName) { - return true; - } - // Only consider keypress events on actual input elements. This will disregard keypresses targeting body - // e.g.tabbing through elements, hotkeys, etc. - if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) { - return false; - } - } - catch (e) { - // just accessing `target` property can throw an exception in some rare circumstances - // see: https://github.com/getsentry/sentry-javascript/issues/838 - } - return true; -} +const DEFAULT_BROWSER_FLUSH_INTERVAL = 5000; + /** - * Wraps addEventListener to capture UI breadcrumbs - * @param handler function that will be triggered - * @param globalListener indicates whether event was captured by the global event listener - * @returns wrapped breadcrumb events handler - * @hidden + * SDKs are required to bucket into 10 second intervals (rollup in seconds) + * which is the current lower bound of metric accuracy. */ -function makeDOMEventHandler(handler, globalListener) { - if (globalListener === void 0) { globalListener = false; } - return function (event) { - // It's possible this handler might trigger multiple times for the same - // event (e.g. event propagation through node ancestors). - // Ignore if we've already captured that event. - if (!event || lastCapturedEvent === event) { - return; - } - // We always want to skip _some_ events. - if (shouldSkipDOMEvent(event)) { - return; - } - var name = event.type === 'keypress' ? 'input' : event.type; - // If there is no debounce timer, it means that we can safely capture the new event and store it for future comparisons. - if (debounceTimerID === undefined) { - handler({ - event: event, - name: name, - global: globalListener, - }); - lastCapturedEvent = event; - } - // If there is a debounce awaiting, see if the new event is different enough to treat it as a unique one. - // If that's the case, emit the previous event and store locally the newly-captured DOM event. - else if (shouldShortcircuitPreviousDebounce(lastCapturedEvent, event)) { - handler({ - event: event, - name: name, - global: globalListener, - }); - lastCapturedEvent = event; - } - // Start a new debounce timer that will prevent us from capturing multiple events that should be grouped together. - clearTimeout(debounceTimerID); - debounceTimerID = global.setTimeout(function () { - debounceTimerID = undefined; - }, debounceDuration); - }; -} -/** JSDoc */ -function instrumentDOM() { - if (!('document' in global)) { - return; - } - // Make it so that any click or keypress that is unhandled / bubbled up all the way to the document triggers our dom - // handlers. (Normally we have only one, which captures a breadcrumb for each click or keypress.) Do this before - // we instrument `addEventListener` so that we don't end up attaching this handler twice. - var triggerDOMHandler = triggerHandlers.bind(null, 'dom'); - var globalDOMEventHandler = makeDOMEventHandler(triggerDOMHandler, true); - global.document.addEventListener('click', globalDOMEventHandler, false); - global.document.addEventListener('keypress', globalDOMEventHandler, false); - // After hooking into click and keypress events bubbled up to `document`, we also hook into user-handled - // clicks & keypresses, by adding an event listener of our own to any element to which they add a listener. That - // way, whenever one of their handlers is triggered, ours will be, too. (This is needed because their handler - // could potentially prevent the event from bubbling up to our global listeners. This way, our handler are still - // guaranteed to fire at least once.) - ['EventTarget', 'Node'].forEach(function (target) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - var proto = global[target] && global[target].prototype; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins - if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) { - return; - } - object_1.fill(proto, 'addEventListener', function (originalAddEventListener) { - return function (type, listener, options) { - if (type === 'click' || type == 'keypress') { - try { - var el = this; - var handlers_1 = (el.__sentry_instrumentation_handlers__ = el.__sentry_instrumentation_handlers__ || {}); - var handlerForType = (handlers_1[type] = handlers_1[type] || { refCount: 0 }); - if (!handlerForType.handler) { - var handler = makeDOMEventHandler(triggerDOMHandler); - handlerForType.handler = handler; - originalAddEventListener.call(this, type, handler, options); - } - handlerForType.refCount += 1; - } - catch (e) { - // Accessing dom properties is always fragile. - // Also allows us to skip `addEventListenrs` calls with no proper `this` context. - } - } - return originalAddEventListener.call(this, type, listener, options); - }; - }); - object_1.fill(proto, 'removeEventListener', function (originalRemoveEventListener) { - return function (type, listener, options) { - if (type === 'click' || type == 'keypress') { - try { - var el = this; - var handlers_2 = el.__sentry_instrumentation_handlers__ || {}; - var handlerForType = handlers_2[type]; - if (handlerForType) { - handlerForType.refCount -= 1; - // If there are no longer any custom handlers of the current type on this element, we can remove ours, too. - if (handlerForType.refCount <= 0) { - originalRemoveEventListener.call(this, type, handlerForType.handler, options); - handlerForType.handler = undefined; - delete handlers_2[type]; // eslint-disable-line @typescript-eslint/no-dynamic-delete - } - // If there are no longer any custom handlers of any type on this element, cleanup everything. - if (Object.keys(handlers_2).length === 0) { - delete el.__sentry_instrumentation_handlers__; - } - } - } - catch (e) { - // Accessing dom properties is always fragile. - // Also allows us to skip `addEventListenrs` calls with no proper `this` context. - } - } - return originalRemoveEventListener.call(this, type, listener, options); - }; - }); - }); -} -var _oldOnErrorHandler = null; -/** JSDoc */ -function instrumentError() { - _oldOnErrorHandler = global.onerror; - global.onerror = function (msg, url, line, column, error) { - triggerHandlers('error', { - column: column, - error: error, - line: line, - msg: msg, - url: url, - }); - if (_oldOnErrorHandler) { - // eslint-disable-next-line prefer-rest-params - return _oldOnErrorHandler.apply(this, arguments); - } - return false; +const DEFAULT_FLUSH_INTERVAL = 10000; + +/** + * The maximum number of metrics that should be stored in memory. + */ +const MAX_WEIGHT = 10000; + +exports.COUNTER_METRIC_TYPE = COUNTER_METRIC_TYPE; +exports.DEFAULT_BROWSER_FLUSH_INTERVAL = DEFAULT_BROWSER_FLUSH_INTERVAL; +exports.DEFAULT_FLUSH_INTERVAL = DEFAULT_FLUSH_INTERVAL; +exports.DISTRIBUTION_METRIC_TYPE = DISTRIBUTION_METRIC_TYPE; +exports.GAUGE_METRIC_TYPE = GAUGE_METRIC_TYPE; +exports.MAX_WEIGHT = MAX_WEIGHT; +exports.SET_METRIC_TYPE = SET_METRIC_TYPE; +//# sourceMappingURL=constants.js.map + + +/***/ }), + +/***/ 67258: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); +const utils$1 = __nccwpck_require__(21629); + +/** + * Create envelope from a metric aggregate. + */ +function createMetricEnvelope( + metricBucketItems, + dsn, + metadata, + tunnel, +) { + const headers = { + sent_at: new Date().toISOString(), + }; + + if (metadata && metadata.sdk) { + headers.sdk = { + name: metadata.sdk.name, + version: metadata.sdk.version, }; + } + + if (!!tunnel && dsn) { + headers.dsn = utils.dsnToString(dsn); + } + + const item = createMetricEnvelopeItem(metricBucketItems); + return utils.createEnvelope(headers, [item]); } -var _oldOnUnhandledRejectionHandler = null; -/** JSDoc */ -function instrumentUnhandledRejection() { - _oldOnUnhandledRejectionHandler = global.onunhandledrejection; - global.onunhandledrejection = function (e) { - triggerHandlers('unhandledrejection', e); - if (_oldOnUnhandledRejectionHandler) { - // eslint-disable-next-line prefer-rest-params - return _oldOnUnhandledRejectionHandler.apply(this, arguments); - } - return true; - }; + +function createMetricEnvelopeItem(metricBucketItems) { + const payload = utils$1.serializeMetricBuckets(metricBucketItems); + const metricHeaders = { + type: 'statsd', + length: payload.length, + }; + return [metricHeaders, payload]; } -//# sourceMappingURL=instrument.js.map + +exports.createMetricEnvelope = createMetricEnvelope; +//# sourceMappingURL=envelope.js.map + /***/ }), -/***/ 79409: -/***/ ((__unused_webpack_module, exports) => { +/***/ 59955: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ Object.defineProperty(exports, "__esModule", ({ value: true })); -// eslint-disable-next-line @typescript-eslint/unbound-method -var objectToString = Object.prototype.toString; -/** - * Checks whether given value's type is one of a few Error or Error-like - * {@link isError}. - * - * @param wat A value to be checked. - * @returns A boolean representing the result. - */ -function isError(wat) { - switch (objectToString.call(wat)) { - case '[object Error]': - case '[object Exception]': - case '[object DOMException]': - return true; - default: - return isInstanceOf(wat, Error); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const exports$1 = __nccwpck_require__(74313); +const spanUtils = __nccwpck_require__(98313); +const constants = __nccwpck_require__(25913); +const integration = __nccwpck_require__(58274); + +function addToMetricsAggregator( + metricType, + name, + value, + data = {}, +) { + const client = exports$1.getClient(); + const scope = exports$1.getCurrentScope(); + if (client) { + if (!client.metricsAggregator) { + debugBuild.DEBUG_BUILD && + utils.logger.warn('No metrics aggregator enabled. Please add the MetricsAggregator integration to use metrics APIs'); + return; } + const { unit, tags, timestamp } = data; + const { release, environment } = client.getOptions(); + // eslint-disable-next-line deprecation/deprecation + const transaction = scope.getTransaction(); + const metricTags = {}; + if (release) { + metricTags.release = release; + } + if (environment) { + metricTags.environment = environment; + } + if (transaction) { + metricTags.transaction = spanUtils.spanToJSON(transaction).description || ''; + } + + debugBuild.DEBUG_BUILD && utils.logger.log(`Adding value of ${value} to ${metricType} metric ${name}`); + client.metricsAggregator.add(metricType, name, value, unit, { ...metricTags, ...tags }, timestamp); + } } -exports.isError = isError; -function isBuiltin(wat, ty) { - return objectToString.call(wat) === "[object " + ty + "]"; -} + /** - * Checks whether given value's type is ErrorEvent - * {@link isErrorEvent}. + * Adds a value to a counter metric * - * @param wat A value to be checked. - * @returns A boolean representing the result. + * @experimental This API is experimental and might have breaking changes in the future. */ -function isErrorEvent(wat) { - return isBuiltin(wat, 'ErrorEvent'); +function increment(name, value = 1, data) { + addToMetricsAggregator(constants.COUNTER_METRIC_TYPE, name, value, data); } -exports.isErrorEvent = isErrorEvent; + /** - * Checks whether given value's type is DOMError - * {@link isDOMError}. + * Adds a value to a distribution metric * - * @param wat A value to be checked. - * @returns A boolean representing the result. + * @experimental This API is experimental and might have breaking changes in the future. */ -function isDOMError(wat) { - return isBuiltin(wat, 'DOMError'); +function distribution(name, value, data) { + addToMetricsAggregator(constants.DISTRIBUTION_METRIC_TYPE, name, value, data); } -exports.isDOMError = isDOMError; + /** - * Checks whether given value's type is DOMException - * {@link isDOMException}. + * Adds a value to a set metric. Value must be a string or integer. * - * @param wat A value to be checked. - * @returns A boolean representing the result. + * @experimental This API is experimental and might have breaking changes in the future. */ -function isDOMException(wat) { - return isBuiltin(wat, 'DOMException'); +function set(name, value, data) { + addToMetricsAggregator(constants.SET_METRIC_TYPE, name, value, data); } -exports.isDOMException = isDOMException; + /** - * Checks whether given value's type is a string - * {@link isString}. + * Adds a value to a gauge metric * - * @param wat A value to be checked. - * @returns A boolean representing the result. + * @experimental This API is experimental and might have breaking changes in the future. */ -function isString(wat) { - return isBuiltin(wat, 'String'); +function gauge(name, value, data) { + addToMetricsAggregator(constants.GAUGE_METRIC_TYPE, name, value, data); } -exports.isString = isString; + +const metrics = { + increment, + distribution, + set, + gauge, + /** @deprecated Use `metrics.metricsAggregratorIntegration()` instead. */ + // eslint-disable-next-line deprecation/deprecation + MetricsAggregator: integration.MetricsAggregator, + metricsAggregatorIntegration: integration.metricsAggregatorIntegration, +}; + +exports.distribution = distribution; +exports.gauge = gauge; +exports.increment = increment; +exports.metrics = metrics; +exports.set = set; +//# sourceMappingURL=exports.js.map + + +/***/ }), + +/***/ 26457: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const constants = __nccwpck_require__(25913); +const utils = __nccwpck_require__(21629); + /** - * Checks whether given value is a primitive (undefined, null, number, boolean, string, bigint, symbol) - * {@link isPrimitive}. - * - * @param wat A value to be checked. - * @returns A boolean representing the result. + * A metric instance representing a counter. */ -function isPrimitive(wat) { - return wat === null || (typeof wat !== 'object' && typeof wat !== 'function'); +class CounterMetric { + constructor( _value) {this._value = _value;} + + /** @inheritDoc */ + get weight() { + return 1; + } + + /** @inheritdoc */ + add(value) { + this._value += value; + } + + /** @inheritdoc */ + toString() { + return `${this._value}`; + } } -exports.isPrimitive = isPrimitive; + /** - * Checks whether given value's type is an object literal - * {@link isPlainObject}. - * - * @param wat A value to be checked. - * @returns A boolean representing the result. + * A metric instance representing a gauge. */ -function isPlainObject(wat) { - return isBuiltin(wat, 'Object'); +class GaugeMetric { + + constructor(value) { + this._last = value; + this._min = value; + this._max = value; + this._sum = value; + this._count = 1; + } + + /** @inheritDoc */ + get weight() { + return 5; + } + + /** @inheritdoc */ + add(value) { + this._last = value; + if (value < this._min) { + this._min = value; + } + if (value > this._max) { + this._max = value; + } + this._sum += value; + this._count++; + } + + /** @inheritdoc */ + toString() { + return `${this._last}:${this._min}:${this._max}:${this._sum}:${this._count}`; + } } -exports.isPlainObject = isPlainObject; + /** - * Checks whether given value's type is an Event instance - * {@link isEvent}. - * - * @param wat A value to be checked. - * @returns A boolean representing the result. + * A metric instance representing a distribution. */ -function isEvent(wat) { - return typeof Event !== 'undefined' && isInstanceOf(wat, Event); +class DistributionMetric { + + constructor(first) { + this._value = [first]; + } + + /** @inheritDoc */ + get weight() { + return this._value.length; + } + + /** @inheritdoc */ + add(value) { + this._value.push(value); + } + + /** @inheritdoc */ + toString() { + return this._value.join(':'); + } } -exports.isEvent = isEvent; + /** - * Checks whether given value's type is an Element instance - * {@link isElement}. - * - * @param wat A value to be checked. - * @returns A boolean representing the result. + * A metric instance representing a set. */ -function isElement(wat) { - return typeof Element !== 'undefined' && isInstanceOf(wat, Element); -} -exports.isElement = isElement; -/** - * Checks whether given value's type is an regexp - * {@link isRegExp}. - * - * @param wat A value to be checked. - * @returns A boolean representing the result. - */ -function isRegExp(wat) { - return isBuiltin(wat, 'RegExp'); -} -exports.isRegExp = isRegExp; -/** - * Checks whether given value has a then function. - * @param wat A value to be checked. - */ -function isThenable(wat) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - return Boolean(wat && wat.then && typeof wat.then === 'function'); -} -exports.isThenable = isThenable; -/** - * Checks whether given value's type is a SyntheticEvent - * {@link isSyntheticEvent}. - * - * @param wat A value to be checked. - * @returns A boolean representing the result. - */ -function isSyntheticEvent(wat) { - return isPlainObject(wat) && 'nativeEvent' in wat && 'preventDefault' in wat && 'stopPropagation' in wat; -} -exports.isSyntheticEvent = isSyntheticEvent; -/** - * Checks whether given value is NaN - * {@link isNaN}. - * - * @param wat A value to be checked. - * @returns A boolean representing the result. - */ -function isNaN(wat) { - return typeof wat === 'number' && wat !== wat; -} -exports.isNaN = isNaN; -/** - * Checks whether given value's type is an instance of provided constructor. - * {@link isInstanceOf}. - * - * @param wat A value to be checked. - * @param base A constructor to be used in a check. - * @returns A boolean representing the result. - */ -function isInstanceOf(wat, base) { - try { - return wat instanceof base; - } - catch (_e) { - return false; - } +class SetMetric { + + constructor( first) {this.first = first; + this._value = new Set([first]); + } + + /** @inheritDoc */ + get weight() { + return this._value.size; + } + + /** @inheritdoc */ + add(value) { + this._value.add(value); + } + + /** @inheritdoc */ + toString() { + return Array.from(this._value) + .map(val => (typeof val === 'string' ? utils.simpleHash(val) : val)) + .join(':'); + } } -exports.isInstanceOf = isInstanceOf; -//# sourceMappingURL=is.js.map + +const METRIC_MAP = { + [constants.COUNTER_METRIC_TYPE]: CounterMetric, + [constants.GAUGE_METRIC_TYPE]: GaugeMetric, + [constants.DISTRIBUTION_METRIC_TYPE]: DistributionMetric, + [constants.SET_METRIC_TYPE]: SetMetric, +}; + +exports.CounterMetric = CounterMetric; +exports.DistributionMetric = DistributionMetric; +exports.GaugeMetric = GaugeMetric; +exports.METRIC_MAP = METRIC_MAP; +exports.SetMetric = SetMetric; +//# sourceMappingURL=instance.js.map + /***/ }), -/***/ 29697: +/***/ 58274: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var flags_1 = __nccwpck_require__(8142); -var global_1 = __nccwpck_require__(16734); -// TODO: Implement different loggers for different environments -var global = global_1.getGlobalObject(); -/** Prefix for logging strings */ -var PREFIX = 'Sentry Logger '; -exports.CONSOLE_LEVELS = ['debug', 'info', 'warn', 'error', 'log', 'assert']; -/** - * Temporarily disable sentry console instrumentations. - * - * @param callback The function to run against the original `console` messages - * @returns The results of the callback - */ -function consoleSandbox(callback) { - var global = global_1.getGlobalObject(); - if (!('console' in global)) { - return callback(); - } - var originalConsole = global.console; - var wrappedLevels = {}; - // Restore all wrapped console methods - exports.CONSOLE_LEVELS.forEach(function (level) { - // TODO(v7): Remove this check as it's only needed for Node 6 - var originalWrappedFunc = originalConsole[level] && originalConsole[level].__sentry_original__; - if (level in global.console && originalWrappedFunc) { - wrappedLevels[level] = originalConsole[level]; - originalConsole[level] = originalWrappedFunc; - } - }); - try { - return callback(); - } - finally { - // Revert restoration to wrapped state - Object.keys(wrappedLevels).forEach(function (level) { - originalConsole[level] = wrappedLevels[level]; - }); - } -} -exports.consoleSandbox = consoleSandbox; -function makeLogger() { - var enabled = false; - var logger = { - enable: function () { - enabled = true; - }, - disable: function () { - enabled = false; - }, - }; - if (flags_1.IS_DEBUG_BUILD) { - exports.CONSOLE_LEVELS.forEach(function (name) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - logger[name] = function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - if (enabled) { - consoleSandbox(function () { - var _a; - (_a = global.console)[name].apply(_a, tslib_1.__spread([PREFIX + "[" + name + "]:"], args)); - }); - } - }; - }); - } - else { - exports.CONSOLE_LEVELS.forEach(function (name) { - logger[name] = function () { return undefined; }; - }); - } - return logger; -} -// Ensure we only have a single logger instance, even if multiple versions of @sentry/utils are being used -var logger; -exports.logger = logger; -if (flags_1.IS_DEBUG_BUILD) { - exports.logger = logger = global_1.getGlobalSingleton('logger', makeLogger); -} -else { - exports.logger = logger = makeLogger(); -} -//# sourceMappingURL=logger.js.map -/***/ }), +const integration = __nccwpck_require__(11000); +const browserAggregator = __nccwpck_require__(39416); -/***/ 23279: -/***/ ((__unused_webpack_module, exports) => { +const INTEGRATION_NAME = 'MetricsAggregator'; + +const _metricsAggregatorIntegration = (() => { + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + setup(client) { + client.metricsAggregator = new browserAggregator.BrowserMetricsAggregator(client); + }, + }; +}) ; + +const metricsAggregatorIntegration = integration.defineIntegration(_metricsAggregatorIntegration); -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -Object.defineProperty(exports, "__esModule", ({ value: true })); /** - * Helper to decycle json objects + * Enables Sentry metrics monitoring. + * + * @experimental This API is experimental and might having breaking changes in the future. + * @deprecated Use `metricsAggegratorIntegration()` instead. */ -function memoBuilder() { - var hasWeakSet = typeof WeakSet === 'function'; - var inner = hasWeakSet ? new WeakSet() : []; - function memoize(obj) { - if (hasWeakSet) { - if (inner.has(obj)) { - return true; - } - inner.add(obj); - return false; - } - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (var i = 0; i < inner.length; i++) { - var value = inner[i]; - if (value === obj) { - return true; - } - } - inner.push(obj); - return false; - } - function unmemoize(obj) { - if (hasWeakSet) { - inner.delete(obj); - } - else { - for (var i = 0; i < inner.length; i++) { - if (inner[i] === obj) { - inner.splice(i, 1); - break; - } - } - } - } - return [memoize, unmemoize]; -} -exports.memoBuilder = memoBuilder; -//# sourceMappingURL=memo.js.map +// eslint-disable-next-line deprecation/deprecation +const MetricsAggregator = integration.convertIntegrationFnToClass( + INTEGRATION_NAME, + metricsAggregatorIntegration, +) ; + +exports.MetricsAggregator = MetricsAggregator; +exports.metricsAggregatorIntegration = metricsAggregatorIntegration; +//# sourceMappingURL=integration.js.map + /***/ }), -/***/ 55205: +/***/ 61479: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var global_1 = __nccwpck_require__(16734); -var object_1 = __nccwpck_require__(11002); -var string_1 = __nccwpck_require__(17256); -/** - * UUID4 generator - * - * @returns string Generated UUID4. - */ -function uuid4() { - var global = global_1.getGlobalObject(); - var crypto = global.crypto || global.msCrypto; - if (!(crypto === void 0) && crypto.getRandomValues) { - // Use window.crypto API if available - var arr = new Uint16Array(8); - crypto.getRandomValues(arr); - // set 4 in byte 7 - // eslint-disable-next-line no-bitwise - arr[3] = (arr[3] & 0xfff) | 0x4000; - // set 2 most significant bits of byte 9 to '10' - // eslint-disable-next-line no-bitwise - arr[4] = (arr[4] & 0x3fff) | 0x8000; - var pad = function (num) { - var v = num.toString(16); - while (v.length < 4) { - v = "0" + v; - } - return v; - }; - return (pad(arr[0]) + pad(arr[1]) + pad(arr[2]) + pad(arr[3]) + pad(arr[4]) + pad(arr[5]) + pad(arr[6]) + pad(arr[7])); - } - // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 - return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - // eslint-disable-next-line no-bitwise - var r = (Math.random() * 16) | 0; - // eslint-disable-next-line no-bitwise - var v = c === 'x' ? r : (r & 0x3) | 0x8; - return v.toString(16); - }); -} -exports.uuid4 = uuid4; -/** - * Parses string form of URL into an object - * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B - * // intentionally using regex and not href parsing trick because React Native and other - * // environments where DOM might not be available - * @returns parsed URL object - */ -function parseUrl(url) { - if (!url) { - return {}; - } - var match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/); - if (!match) { - return {}; - } - // coerce to undefined values to empty string so we don't get 'undefined' - var query = match[6] || ''; - var fragment = match[8] || ''; - return { - host: match[4], - path: match[5], - protocol: match[2], - relative: match[5] + query + fragment, - }; -} -exports.parseUrl = parseUrl; -function getFirstException(event) { - return event.exception && event.exception.values ? event.exception.values[0] : undefined; -} -/** - * Extracts either message or type+value from an event that can be used for user-facing logs - * @returns event's description - */ -function getEventDescription(event) { - var message = event.message, eventId = event.event_id; - if (message) { - return message; - } - var firstException = getFirstException(event); - if (firstException) { - if (firstException.type && firstException.value) { - return firstException.type + ": " + firstException.value; - } - return firstException.type || firstException.value || eventId || ''; - } - return eventId || ''; -} -exports.getEventDescription = getEventDescription; + +const utils = __nccwpck_require__(57540); +__nccwpck_require__(93376); +__nccwpck_require__(55448); +__nccwpck_require__(14769); +const trace = __nccwpck_require__(75150); + /** - * Adds exception values, type and value to an synthetic Exception. - * @param event The event to modify. - * @param value Value of the exception. - * @param type Type of the exception. - * @hidden + * key: bucketKey + * value: [exportKey, MetricSummary] */ -function addExceptionTypeValue(event, value, type) { - var exception = (event.exception = event.exception || {}); - var values = (exception.values = exception.values || []); - var firstException = (values[0] = values[0] || {}); - if (!firstException.value) { - firstException.value = value || ''; - } - if (!firstException.type) { - firstException.type = type || 'Error'; - } + +let SPAN_METRIC_SUMMARY; + +function getMetricStorageForSpan(span) { + return SPAN_METRIC_SUMMARY ? SPAN_METRIC_SUMMARY.get(span) : undefined; } -exports.addExceptionTypeValue = addExceptionTypeValue; + /** - * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed. - * - * @param event The event to modify. - * @param newMechanism Mechanism data to add to the event. - * @hidden + * Fetches the metric summary if it exists for the passed span */ -function addExceptionMechanism(event, newMechanism) { - var firstException = getFirstException(event); - if (!firstException) { - return; - } - var defaultMechanism = { type: 'generic', handled: true }; - var currentMechanism = firstException.mechanism; - firstException.mechanism = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, defaultMechanism), currentMechanism), newMechanism); - if (newMechanism && 'data' in newMechanism) { - var mergedData = tslib_1.__assign(tslib_1.__assign({}, (currentMechanism && currentMechanism.data)), newMechanism.data); - firstException.mechanism.data = mergedData; +function getMetricSummaryJsonForSpan(span) { + const storage = getMetricStorageForSpan(span); + + if (!storage) { + return undefined; + } + const output = {}; + + for (const [, [exportKey, summary]] of storage) { + if (!output[exportKey]) { + output[exportKey] = []; } + + output[exportKey].push(utils.dropUndefinedKeys(summary)); + } + + return output; } -exports.addExceptionMechanism = addExceptionMechanism; -// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string -var SEMVER_REGEXP = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/; -/** - * Parses input into a SemVer interface - * @param input string representation of a semver version - */ -function parseSemver(input) { - var match = input.match(SEMVER_REGEXP) || []; - var major = parseInt(match[1], 10); - var minor = parseInt(match[2], 10); - var patch = parseInt(match[3], 10); - return { - buildmetadata: match[5], - major: isNaN(major) ? undefined : major, - minor: isNaN(minor) ? undefined : minor, - patch: isNaN(patch) ? undefined : patch, - prerelease: match[4], - }; -} -exports.parseSemver = parseSemver; -/** - * This function adds context (pre/post/line) lines to the provided frame - * - * @param lines string[] containing all lines - * @param frame StackFrame that will be mutated - * @param linesOfContext number of context lines we want to add pre/post - */ -function addContextToFrame(lines, frame, linesOfContext) { - if (linesOfContext === void 0) { linesOfContext = 5; } - var lineno = frame.lineno || 0; - var maxLines = lines.length; - var sourceLine = Math.max(Math.min(maxLines, lineno - 1), 0); - frame.pre_context = lines - .slice(Math.max(0, sourceLine - linesOfContext), sourceLine) - .map(function (line) { return string_1.snipLine(line, 0); }); - frame.context_line = string_1.snipLine(lines[Math.min(maxLines - 1, sourceLine)], frame.colno || 0); - frame.post_context = lines - .slice(Math.min(sourceLine + 1, maxLines), sourceLine + 1 + linesOfContext) - .map(function (line) { return string_1.snipLine(line, 0); }); -} -exports.addContextToFrame = addContextToFrame; -/** - * Strip the query string and fragment off of a given URL or path (if present) - * - * @param urlPath Full URL or path, including possible query string and/or fragment - * @returns URL or path without query string or fragment - */ -function stripUrlQueryAndFragment(urlPath) { - // eslint-disable-next-line no-useless-escape - return urlPath.split(/[\?#]/, 1)[0]; -} -exports.stripUrlQueryAndFragment = stripUrlQueryAndFragment; + /** - * Checks whether or not we've already captured the given exception (note: not an identical exception - the very object - * in question), and marks it captured if not. - * - * This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and - * record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so - * that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because - * the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not - * caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This - * function helps us ensure that even if we encounter the same error more than once, we only record it the first time we - * see it. - * - * Note: It will ignore primitives (always return `false` and not mark them as seen), as properties can't be set on - * them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent - * object wrapper forms so that this check will always work. However, because we need to flag the exact object which - * will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification - * must be done before the exception captured. - * - * @param A thrown exception to check or flag as having been seen - * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen) + * Updates the metric summary on the currently active span */ -function checkOrSetAlreadyCaught(exception) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - if (exception && exception.__sentry_captured__) { - return true; - } - try { - // set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the - // `ExtraErrorData` integration - object_1.addNonEnumerableProperty(exception, '__sentry_captured__', true); +function updateMetricSummaryOnActiveSpan( + metricType, + sanitizedName, + value, + unit, + tags, + bucketKey, +) { + const span = trace.getActiveSpan(); + if (span) { + const storage = getMetricStorageForSpan(span) || new Map(); + + const exportKey = `${metricType}:${sanitizedName}@${unit}`; + const bucketItem = storage.get(bucketKey); + + if (bucketItem) { + const [, summary] = bucketItem; + storage.set(bucketKey, [ + exportKey, + { + min: Math.min(summary.min, value), + max: Math.max(summary.max, value), + count: (summary.count += 1), + sum: (summary.sum += value), + tags: summary.tags, + }, + ]); + } else { + storage.set(bucketKey, [ + exportKey, + { + min: value, + max: value, + count: 1, + sum: value, + tags, + }, + ]); } - catch (err) { - // `exception` is a primitive, so we can't mark it seen + + if (!SPAN_METRIC_SUMMARY) { + SPAN_METRIC_SUMMARY = new WeakMap(); } - return false; + + SPAN_METRIC_SUMMARY.set(span, storage); + } } -exports.checkOrSetAlreadyCaught = checkOrSetAlreadyCaught; -//# sourceMappingURL=misc.js.map + +exports.getMetricSummaryJsonForSpan = getMetricSummaryJsonForSpan; +exports.updateMetricSummaryOnActiveSpan = updateMetricSummaryOnActiveSpan; +//# sourceMappingURL=metric-summary.js.map + /***/ }), -/***/ 361: -/***/ ((module, exports, __nccwpck_require__) => { +/***/ 21629: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/* module decorator */ module = __nccwpck_require__.nmd(module); -/** - * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something, - * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere. - */ Object.defineProperty(exports, "__esModule", ({ value: true })); -var env_1 = __nccwpck_require__(93478); + +const utils = __nccwpck_require__(57540); + /** - * Checks whether we're in the Node.js or Browser environment - * - * @returns Answer to given question + * Generate bucket key from metric properties. */ -function isNodeEnv() { - // explicitly check for browser bundles as those can be optimized statically - // by terser/rollup. - return (!env_1.isBrowserBundle() && - Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]'); +function getBucketKey( + metricType, + name, + unit, + tags, +) { + const stringifiedTags = Object.entries(utils.dropUndefinedKeys(tags)).sort((a, b) => a[0].localeCompare(b[0])); + return `${metricType}${name}${unit}${stringifiedTags}`; } -exports.isNodeEnv = isNodeEnv; + +/* eslint-disable no-bitwise */ /** - * Requires a module which is protected against bundler minification. - * - * @param request The module path to resolve + * Simple hash function for strings. */ -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -function dynamicRequire(mod, request) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - return mod.require(request); +function simpleHash(s) { + let rv = 0; + for (let i = 0; i < s.length; i++) { + const c = s.charCodeAt(i); + rv = (rv << 5) - rv + c; + rv &= rv; + } + return rv >>> 0; } -exports.dynamicRequire = dynamicRequire; +/* eslint-enable no-bitwise */ + /** - * Helper for dynamically loading module that should work with linked dependencies. - * The problem is that we _should_ be using `require(require.resolve(moduleName, { paths: [cwd()] }))` - * However it's _not possible_ to do that with Webpack, as it has to know all the dependencies during - * build time. `require.resolve` is also not available in any other way, so we cannot create, - * a fake helper like we do with `dynamicRequire`. - * - * We always prefer to use local package, thus the value is not returned early from each `try/catch` block. - * That is to mimic the behavior of `require.resolve` exactly. + * Serialize metrics buckets into a string based on statsd format. * - * @param moduleName module name to require - * @returns possibly required module + * Example of format: + * metric.name@second:1:1.2|d|#a:value,b:anothervalue|T12345677 + * Segments: + * name: metric.name + * unit: second + * value: [1, 1.2] + * type of metric: d (distribution) + * tags: { a: value, b: anothervalue } + * timestamp: 12345677 */ -function loadModule(moduleName) { - var mod; - try { - mod = dynamicRequire(module, moduleName); - } - catch (e) { - // no-empty - } - try { - var cwd = dynamicRequire(module, 'process').cwd; - mod = dynamicRequire(module, cwd() + "/node_modules/" + moduleName); - } - catch (e) { - // no-empty - } - return mod; +function serializeMetricBuckets(metricBucketItems) { + let out = ''; + for (const item of metricBucketItems) { + const tagEntries = Object.entries(item.tags); + const maybeTags = tagEntries.length > 0 ? `|#${tagEntries.map(([key, value]) => `${key}:${value}`).join(',')}` : ''; + out += `${item.name}@${item.unit}:${item.metric}|${item.metricType}${maybeTags}|T${item.timestamp}\n`; + } + return out; } -exports.loadModule = loadModule; -//# sourceMappingURL=node.js.map - -/***/ }), -/***/ 64706: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/** Sanitizes units */ +function sanitizeUnit(unit) { + return unit.replace(/[^\w]+/gi, '_'); +} -Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var is_1 = __nccwpck_require__(79409); -var memo_1 = __nccwpck_require__(23279); -var object_1 = __nccwpck_require__(11002); -var stacktrace_1 = __nccwpck_require__(60996); -/** - * Recursively normalizes the given object. - * - * - Creates a copy to prevent original input mutation - * - Skips non-enumerable properties - * - When stringifying, calls `toJSON` if implemented - * - Removes circular references - * - Translates non-serializable values (`undefined`/`NaN`/functions) to serializable format - * - Translates known global objects/classes to a string representations - * - Takes care of `Error` object serialization - * - Optionally limits depth of final output - * - Optionally limits number of properties/elements included in any single object/array - * - * @param input The object to be normalized. - * @param depth The max depth to which to normalize the object. (Anything deeper stringified whole.) - * @param maxProperties The max number of elements or properties to be included in any single array or - * object in the normallized output.. - * @returns A normalized version of the object, or `"**non-serializable**"` if any errors are thrown during normalization. - */ -function normalize(input, depth, maxProperties) { - if (depth === void 0) { depth = +Infinity; } - if (maxProperties === void 0) { maxProperties = +Infinity; } - try { - // since we're at the outermost level, there is no key - return visit('', input, depth, maxProperties); - } - catch (err) { - return { ERROR: "**non-serializable** (" + err + ")" }; - } +/** Sanitizes metric keys */ +function sanitizeMetricKey(key) { + return key.replace(/[^\w\-.]+/gi, '_'); } -exports.normalize = normalize; -/** JSDoc */ -function normalizeToSize(object, -// Default Node.js REPL depth -depth, -// 100kB, as 200kB is max payload size, so half sounds reasonable -maxSize) { - if (depth === void 0) { depth = 3; } - if (maxSize === void 0) { maxSize = 100 * 1024; } - var normalized = normalize(object, depth); - if (jsonSize(normalized) > maxSize) { - return normalizeToSize(object, depth - 1, maxSize); - } - return normalized; + +function sanitizeTagKey(key) { + return key.replace(/[^\w\-./]+/gi, ''); } -exports.normalizeToSize = normalizeToSize; -/** - * Visits a node to perform normalization on it - * - * @param key The key corresponding to the given node - * @param value The node to be visited - * @param depth Optional number indicating the maximum recursion depth - * @param maxProperties Optional maximum number of properties/elements included in any single object/array - * @param memo Optional Memo class handling decycling - */ -function visit(key, value, depth, maxProperties, memo) { - if (depth === void 0) { depth = +Infinity; } - if (maxProperties === void 0) { maxProperties = +Infinity; } - if (memo === void 0) { memo = memo_1.memoBuilder(); } - var _a = tslib_1.__read(memo, 2), memoize = _a[0], unmemoize = _a[1]; - // If the value has a `toJSON` method, see if we can bail and let it do the work - var valueWithToJSON = value; - if (valueWithToJSON && typeof valueWithToJSON.toJSON === 'function') { - try { - return valueWithToJSON.toJSON(); - } - catch (err) { - // pass (The built-in `toJSON` failed, but we can still try to do it ourselves) - } - } - // Get the simple cases out of the way first - if (value === null || (['number', 'boolean', 'string'].includes(typeof value) && !is_1.isNaN(value))) { - return value; - } - var stringified = stringifyValue(key, value); - // Anything we could potentially dig into more (objects or arrays) will have come back as `"[object XXXX]"`. - // Everything else will have already been serialized, so if we don't see that pattern, we're done. - if (!stringified.startsWith('[object ')) { - return stringified; - } - // We're also done if we've reached the max depth - if (depth === 0) { - // At this point we know `serialized` is a string of the form `"[object XXXX]"`. Clean it up so it's just `"[XXXX]"`. - return stringified.replace('object ', ''); - } - // If we've already visited this branch, bail out, as it's circular reference. If not, note that we're seeing it now. - if (memoize(value)) { - return '[Circular ~]'; - } - // At this point we know we either have an object or an array, we haven't seen it before, and we're going to recurse - // because we haven't yet reached the max depth. Create an accumulator to hold the results of visiting each - // property/entry, and keep track of the number of items we add to it. - var normalized = (Array.isArray(value) ? [] : {}); - var numAdded = 0; - // Before we begin, convert`Error` and`Event` instances into plain objects, since some of each of their relevant - // properties are non-enumerable and otherwise would get missed. - var visitable = (is_1.isError(value) || is_1.isEvent(value) ? object_1.convertToPlainObject(value) : value); - for (var visitKey in visitable) { - // Avoid iterating over fields in the prototype if they've somehow been exposed to enumeration. - if (!Object.prototype.hasOwnProperty.call(visitable, visitKey)) { - continue; - } - if (numAdded >= maxProperties) { - normalized[visitKey] = '[MaxProperties ~]'; - break; - } - // Recursively visit all the child nodes - var visitValue = visitable[visitKey]; - normalized[visitKey] = visit(visitKey, visitValue, depth - 1, maxProperties, memo); - numAdded += 1; + +const tagValueReplacements = [ + ['\n', '\\n'], + ['\r', '\\r'], + ['\t', '\\t'], + ['\\', '\\\\'], + ['|', '\\u{7c}'], + [',', '\\u{2c}'], +]; + +function getCharOrReplacement(input) { + for (const [search, replacement] of tagValueReplacements) { + if (input === search) { + return replacement; } - // Once we've visited all the branches, remove the parent from memo storage - unmemoize(value); - // Return accumulated values - return normalized; + } + + return input; } -exports.walk = visit; + +function sanitizeTagValue(value) { + return [...value].reduce((acc, char) => acc + getCharOrReplacement(char), ''); +} + /** - * Stringify the given value. Handles various known special values and types. - * - * Not meant to be used on simple primitives which already have a string representation, as it will, for example, turn - * the number 1231 into "[Object Number]", nor on `null`, as it will throw. - * - * @param value The value to stringify - * @returns A stringified representation of the given value + * Sanitizes tags. */ -function stringifyValue(key, -// this type is a tiny bit of a cheat, since this function does handle NaN (which is technically a number), but for -// our internal use, it'll do -value) { - try { - if (key === 'domain' && value && typeof value === 'object' && value._events) { - return '[Domain]'; - } - if (key === 'domainEmitter') { - return '[DomainEmitter]'; - } - // It's safe to use `global`, `window`, and `document` here in this manner, as we are asserting using `typeof` first - // which won't throw if they are not present. - if (typeof global !== 'undefined' && value === global) { - return '[Global]'; - } - // eslint-disable-next-line no-restricted-globals - if (typeof window !== 'undefined' && value === window) { - return '[Window]'; - } - // eslint-disable-next-line no-restricted-globals - if (typeof document !== 'undefined' && value === document) { - return '[Document]'; - } - // React's SyntheticEvent thingy - if (is_1.isSyntheticEvent(value)) { - return '[SyntheticEvent]'; - } - if (typeof value === 'number' && value !== value) { - return '[NaN]'; - } - // this catches `undefined` (but not `null`, which is a primitive and can be serialized on its own) - if (value === void 0) { - return '[undefined]'; - } - if (typeof value === 'function') { - return "[Function: " + stacktrace_1.getFunctionName(value) + "]"; - } - if (typeof value === 'symbol') { - return "[" + String(value) + "]"; - } - // stringified BigInts are indistinguishable from regular numbers, so we need to label them to avoid confusion - if (typeof value === 'bigint') { - return "[BigInt: " + String(value) + "]"; - } - // Now that we've knocked out all the special cases and the primitives, all we have left are objects. Simply casting - // them to strings means that instances of classes which haven't defined their `toStringTag` will just come out as - // `"[object Object]"`. If we instead look at the constructor's name (which is the same as the name of the class), - // we can make sure that only plain objects come out that way. - return "[object " + Object.getPrototypeOf(value).constructor.name + "]"; - } - catch (err) { - return "**non-serializable** (" + err + ")"; +function sanitizeTags(unsanitizedTags) { + const tags = {}; + for (const key in unsanitizedTags) { + if (Object.prototype.hasOwnProperty.call(unsanitizedTags, key)) { + const sanitizedKey = sanitizeTagKey(key); + tags[sanitizedKey] = sanitizeTagValue(String(unsanitizedTags[key])); } + } + return tags; } -/** Calculates bytes size of input string */ -function utf8Length(value) { - // eslint-disable-next-line no-bitwise - return ~-encodeURI(value).split(/%..|./).length; -} -/** Calculates bytes size of input object */ -function jsonSize(value) { - return utf8Length(JSON.stringify(value)); -} -//# sourceMappingURL=normalize.js.map + +exports.getBucketKey = getBucketKey; +exports.sanitizeMetricKey = sanitizeMetricKey; +exports.sanitizeTags = sanitizeTags; +exports.sanitizeUnit = sanitizeUnit; +exports.serializeMetricBuckets = serializeMetricBuckets; +exports.simpleHash = simpleHash; +//# sourceMappingURL=utils.js.map + /***/ }), -/***/ 11002: +/***/ 77226: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var browser_1 = __nccwpck_require__(90865); -var is_1 = __nccwpck_require__(79409); -var string_1 = __nccwpck_require__(17256); -/** - * Replace a method in an object with a wrapped version of itself. - * - * @param source An object that contains a method to be wrapped. - * @param name The name of the method to be wrapped. - * @param replacementFactory A higher-order function that takes the original version of the given method and returns a - * wrapped version. Note: The function returned by `replacementFactory` needs to be a non-arrow function, in order to - * preserve the correct value of `this`, and the original method must be called using `origMethod.call(this, )` or `origMethod.apply(this, [])` (rather than being called directly), again to preserve `this`. - * @returns void - */ -function fill(source, name, replacementFactory) { - if (!(name in source)) { - return; - } - var original = source[name]; - var wrapped = replacementFactory(original); - // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work - // otherwise it'll throw "TypeError: Object.defineProperties called on non-object" - if (typeof wrapped === 'function') { - try { - markFunctionWrapped(wrapped, original); - } - catch (_Oo) { - // This can throw if multiple fill happens on a global object like XMLHttpRequest - // Fixes https://github.com/getsentry/sentry-javascript/issues/2043 - } - } - source[name] = wrapped; -} -exports.fill = fill; -/** - * Defines a non-enumerable property on the given object. - * - * @param obj The object on which to set the property - * @param name The name of the property to be set - * @param value The value to which to set the property - */ -function addNonEnumerableProperty(obj, name, value) { - Object.defineProperty(obj, name, { - // enumerable: false, // the default, so we can save on bundle size by not explicitly setting it - value: value, - writable: true, - configurable: true, - }); -} -exports.addNonEnumerableProperty = addNonEnumerableProperty; -/** - * Remembers the original function on the wrapped function and - * patches up the prototype. - * - * @param wrapped the wrapper function - * @param original the original function that gets wrapped - */ -function markFunctionWrapped(wrapped, original) { - var proto = original.prototype || {}; - wrapped.prototype = original.prototype = proto; - addNonEnumerableProperty(wrapped, '__sentry_original__', original); -} -exports.markFunctionWrapped = markFunctionWrapped; -/** - * This extracts the original function if available. See - * `markFunctionWrapped` for more information. - * - * @param func the function to unwrap - * @returns the unwrapped version of the function if available. - */ -function getOriginalFunction(func) { - return func.__sentry_original__; -} -exports.getOriginalFunction = getOriginalFunction; + +const utils = __nccwpck_require__(57540); +const eventProcessors = __nccwpck_require__(88807); +const session = __nccwpck_require__(14638); +const applyScopeDataToEvent = __nccwpck_require__(87059); + /** - * Encodes given object into url-friendly format - * - * @param object An object that contains serializable values - * @returns string Encoded + * Default value for maximum number of breadcrumbs added to an event. */ -function urlEncode(object) { - return Object.keys(object) - .map(function (key) { return encodeURIComponent(key) + "=" + encodeURIComponent(object[key]); }) - .join('&'); -} -exports.urlEncode = urlEncode; +const DEFAULT_MAX_BREADCRUMBS = 100; + /** - * Transforms any object into an object literal with all its attributes - * attached to it. - * - * @param value Initial source that we have to transform in order for it to be usable by the serializer + * The global scope is kept in this module. + * When accessing this via `getGlobalScope()` we'll make sure to set one if none is currently present. */ -function convertToPlainObject(value) { - var newObj = value; - if (is_1.isError(value)) { - newObj = tslib_1.__assign({ message: value.message, name: value.name, stack: value.stack }, getOwnProperties(value)); - } - else if (is_1.isEvent(value)) { - var event_1 = value; - newObj = tslib_1.__assign({ type: event_1.type, target: serializeEventTarget(event_1.target), currentTarget: serializeEventTarget(event_1.currentTarget) }, getOwnProperties(event_1)); - if (typeof CustomEvent !== 'undefined' && is_1.isInstanceOf(value, CustomEvent)) { - newObj.detail = event_1.detail; - } - } - return newObj; -} -exports.convertToPlainObject = convertToPlainObject; -/** Creates a string representation of the target of an `Event` object */ -function serializeEventTarget(target) { - try { - return is_1.isElement(target) ? browser_1.htmlTreeAsString(target) : Object.prototype.toString.call(target); - } - catch (_oO) { - return ''; - } -} -/** Filters out all but an object's own properties */ -function getOwnProperties(obj) { - var extractedProps = {}; - for (var property in obj) { - if (Object.prototype.hasOwnProperty.call(obj, property)) { - extractedProps[property] = obj[property]; - } - } - return extractedProps; -} +let globalScope; + /** - * Given any captured exception, extract its keys and create a sorted - * and truncated list that will be used inside the event message. - * eg. `Non-error exception captured with keys: foo, bar, baz` + * Holds additional event information. {@link Scope.applyToEvent} will be + * called by the client before an event will be sent. */ -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -function extractExceptionKeysForMessage(exception, maxLength) { - if (maxLength === void 0) { maxLength = 40; } - var keys = Object.keys(convertToPlainObject(exception)); - keys.sort(); - if (!keys.length) { - return '[object has no keys]'; - } - if (keys[0].length >= maxLength) { - return string_1.truncate(keys[0], maxLength); - } - for (var includedKeys = keys.length; includedKeys > 0; includedKeys--) { - var serialized = keys.slice(0, includedKeys).join(', '); - if (serialized.length > maxLength) { - continue; - } - if (includedKeys === keys.length) { - return serialized; - } - return string_1.truncate(serialized, maxLength); - } - return ''; -} -exports.extractExceptionKeysForMessage = extractExceptionKeysForMessage; -/** - * Given any object, return the new object with removed keys that value was `undefined`. - * Works recursively on objects and arrays. - */ -function dropUndefinedKeys(val) { - var e_1, _a; - if (is_1.isPlainObject(val)) { - var rv = {}; - try { - for (var _b = tslib_1.__values(Object.keys(val)), _c = _b.next(); !_c.done; _c = _b.next()) { - var key = _c.value; - if (typeof val[key] !== 'undefined') { - rv[key] = dropUndefinedKeys(val[key]); - } - } - } - 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; } - } - return rv; - } - if (Array.isArray(val)) { - return val.map(dropUndefinedKeys); - } - return val; -} -exports.dropUndefinedKeys = dropUndefinedKeys; -/** - * Ensure that something is an object. - * - * Turns `undefined` and `null` into `String`s and all other primitives into instances of their respective wrapper - * classes (String, Boolean, Number, etc.). Acts as the identity function on non-primitives. - * - * @param wat The subject of the objectification - * @returns A version of `wat` which can safely be used with `Object` class methods - */ -function objectify(wat) { - var objectified; - switch (true) { - case wat === undefined || wat === null: - objectified = new String(wat); - break; - // Though symbols and bigints do have wrapper classes (`Symbol` and `BigInt`, respectively), for whatever reason - // those classes don't have constructors which can be used with the `new` keyword. We therefore need to cast each as - // an object in order to wrap it. - case typeof wat === 'symbol' || typeof wat === 'bigint': - objectified = Object(wat); - break; - // this will catch the remaining primitives: `String`, `Number`, and `Boolean` - case is_1.isPrimitive(wat): - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - objectified = new wat.constructor(wat); - break; - // by process of elimination, at this point we know that `wat` must already be an object - default: - objectified = wat; - break; - } - return objectified; -} -exports.objectify = objectify; -//# sourceMappingURL=object.js.map +class Scope { + /** Flag if notifying is happening. */ -/***/ }), + /** Callback for client to receive scope changes. */ -/***/ 5554: -/***/ ((__unused_webpack_module, exports) => { + /** Callback list that will be called after {@link applyToEvent}. */ -// Slightly modified (no IE8 support, ES6) and transcribed to TypeScript -// https://raw.githubusercontent.com/calvinmetcalf/rollup-plugin-node-builtins/master/src/es6/path.js -Object.defineProperty(exports, "__esModule", ({ value: true })); -/** JSDoc */ -function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } - else if (last === '..') { - parts.splice(i, 1); - // eslint-disable-next-line no-plusplus - up++; - } - else if (up) { - parts.splice(i, 1); - // eslint-disable-next-line no-plusplus - up--; - } - } - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - // eslint-disable-next-line no-plusplus - for (; up--; up) { - parts.unshift('..'); - } - } - return parts; -} -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/; -/** JSDoc */ -function splitPath(filename) { - var parts = splitPathRe.exec(filename); - return parts ? parts.slice(1) : []; -} -// path.resolve([from ...], to) -// posix version -/** JSDoc */ -function resolve() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var resolvedPath = ''; - var resolvedAbsolute = false; - for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = i >= 0 ? args[i] : '/'; - // Skip empty entries - if (!path) { - continue; - } - resolvedPath = path + "/" + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - // Normalize the path - resolvedPath = normalizeArray(resolvedPath.split('/').filter(function (p) { return !!p; }), !resolvedAbsolute).join('/'); - return (resolvedAbsolute ? '/' : '') + resolvedPath || '.'; -} -exports.resolve = resolve; -/** JSDoc */ -function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') { - break; - } - } - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') { - break; - } - } - if (start > end) { - return []; + /** Array of breadcrumbs. */ + + /** User */ + + /** Tags */ + + /** Extra */ + + /** Contexts */ + + /** Attachments */ + + /** Propagation Context for distributed tracing */ + + /** + * A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get + * sent to Sentry + */ + + /** Fingerprint */ + + /** Severity */ + // eslint-disable-next-line deprecation/deprecation + + /** + * Transaction Name + */ + + /** Span */ + + /** Session */ + + /** Request Mode Session Status */ + + /** The client on this scope */ + + // NOTE: Any field which gets added here should get added not only to the constructor but also to the `clone` method. + + constructor() { + this._notifyingListeners = false; + this._scopeListeners = []; + this._eventProcessors = []; + this._breadcrumbs = []; + this._attachments = []; + this._user = {}; + this._tags = {}; + this._extra = {}; + this._contexts = {}; + this._sdkProcessingMetadata = {}; + this._propagationContext = generatePropagationContext(); + } + + /** + * Inherit values from the parent scope. + * @deprecated Use `scope.clone()` and `new Scope()` instead. + */ + static clone(scope) { + return scope ? scope.clone() : new Scope(); + } + + /** + * Clone this scope instance. + */ + clone() { + const newScope = new Scope(); + newScope._breadcrumbs = [...this._breadcrumbs]; + newScope._tags = { ...this._tags }; + newScope._extra = { ...this._extra }; + newScope._contexts = { ...this._contexts }; + newScope._user = this._user; + newScope._level = this._level; + newScope._span = this._span; + newScope._session = this._session; + newScope._transactionName = this._transactionName; + newScope._fingerprint = this._fingerprint; + newScope._eventProcessors = [...this._eventProcessors]; + newScope._requestSession = this._requestSession; + newScope._attachments = [...this._attachments]; + newScope._sdkProcessingMetadata = { ...this._sdkProcessingMetadata }; + newScope._propagationContext = { ...this._propagationContext }; + newScope._client = this._client; + + return newScope; + } + + /** Update the client on the scope. */ + setClient(client) { + this._client = client; + } + + /** + * Get the client assigned to this scope. + * + * It is generally recommended to use the global function `Sentry.getClient()` instead, unless you know what you are doing. + */ + getClient() { + return this._client; + } + + /** + * Add internal on change listener. Used for sub SDKs that need to store the scope. + * @hidden + */ + addScopeListener(callback) { + this._scopeListeners.push(callback); + } + + /** + * @inheritDoc + */ + addEventProcessor(callback) { + this._eventProcessors.push(callback); + return this; + } + + /** + * @inheritDoc + */ + setUser(user) { + // If null is passed we want to unset everything, but still define keys, + // so that later down in the pipeline any existing values are cleared. + this._user = user || { + email: undefined, + id: undefined, + ip_address: undefined, + segment: undefined, + username: undefined, + }; + + if (this._session) { + session.updateSession(this._session, { user }); } - return arr.slice(start, end - start + 1); -} -// path.relative(from, to) -// posix version -/** JSDoc */ -function relative(from, to) { - /* eslint-disable no-param-reassign */ - from = resolve(from).substr(1); - to = resolve(to).substr(1); - /* eslint-enable no-param-reassign */ - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } + + this._notifyScopeListeners(); + return this; + } + + /** + * @inheritDoc + */ + getUser() { + return this._user; + } + + /** + * @inheritDoc + */ + getRequestSession() { + return this._requestSession; + } + + /** + * @inheritDoc + */ + setRequestSession(requestSession) { + this._requestSession = requestSession; + return this; + } + + /** + * @inheritDoc + */ + setTags(tags) { + this._tags = { + ...this._tags, + ...tags, + }; + this._notifyScopeListeners(); + return this; + } + + /** + * @inheritDoc + */ + setTag(key, value) { + this._tags = { ...this._tags, [key]: value }; + this._notifyScopeListeners(); + return this; + } + + /** + * @inheritDoc + */ + setExtras(extras) { + this._extra = { + ...this._extra, + ...extras, + }; + this._notifyScopeListeners(); + return this; + } + + /** + * @inheritDoc + */ + setExtra(key, extra) { + this._extra = { ...this._extra, [key]: extra }; + this._notifyScopeListeners(); + return this; + } + + /** + * @inheritDoc + */ + setFingerprint(fingerprint) { + this._fingerprint = fingerprint; + this._notifyScopeListeners(); + return this; + } + + /** + * @inheritDoc + */ + setLevel( + // eslint-disable-next-line deprecation/deprecation + level, + ) { + this._level = level; + this._notifyScopeListeners(); + return this; + } + + /** + * Sets the transaction name on the scope for future events. + */ + setTransactionName(name) { + this._transactionName = name; + this._notifyScopeListeners(); + return this; + } + + /** + * @inheritDoc + */ + setContext(key, context) { + if (context === null) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete this._contexts[key]; + } else { + this._contexts[key] = context; } - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); + + this._notifyScopeListeners(); + return this; + } + + /** + * Sets the Span on the scope. + * @param span Span + * @deprecated Instead of setting a span on a scope, use `startSpan()`/`startSpanManual()` instead. + */ + setSpan(span) { + this._span = span; + this._notifyScopeListeners(); + return this; + } + + /** + * Returns the `Span` if there is one. + * @deprecated Use `getActiveSpan()` instead. + */ + getSpan() { + return this._span; + } + + /** + * Returns the `Transaction` attached to the scope (if there is one). + * @deprecated You should not rely on the transaction, but just use `startSpan()` APIs instead. + */ + getTransaction() { + // Often, this span (if it exists at all) will be a transaction, but it's not guaranteed to be. Regardless, it will + // have a pointer to the currently-active transaction. + const span = this._span; + // Cannot replace with getRootSpan because getRootSpan returns a span, not a transaction + // Also, this method will be removed anyway. + // eslint-disable-next-line deprecation/deprecation + return span && span.transaction; + } + + /** + * @inheritDoc + */ + setSession(session) { + if (!session) { + delete this._session; + } else { + this._session = session; } - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - return outputParts.join('/'); -} -exports.relative = relative; -// path.normalize(path) -// posix version -/** JSDoc */ -function normalizePath(path) { - var isPathAbsolute = isAbsolute(path); - var trailingSlash = path.substr(-1) === '/'; - // Normalize the path - var normalizedPath = normalizeArray(path.split('/').filter(function (p) { return !!p; }), !isPathAbsolute).join('/'); - if (!normalizedPath && !isPathAbsolute) { - normalizedPath = '.'; + this._notifyScopeListeners(); + return this; + } + + /** + * @inheritDoc + */ + getSession() { + return this._session; + } + + /** + * @inheritDoc + */ + update(captureContext) { + if (!captureContext) { + return this; } - if (normalizedPath && trailingSlash) { - normalizedPath += '/'; + + const scopeToMerge = typeof captureContext === 'function' ? captureContext(this) : captureContext; + + if (scopeToMerge instanceof Scope) { + const scopeData = scopeToMerge.getScopeData(); + + this._tags = { ...this._tags, ...scopeData.tags }; + this._extra = { ...this._extra, ...scopeData.extra }; + this._contexts = { ...this._contexts, ...scopeData.contexts }; + if (scopeData.user && Object.keys(scopeData.user).length) { + this._user = scopeData.user; + } + if (scopeData.level) { + this._level = scopeData.level; + } + if (scopeData.fingerprint.length) { + this._fingerprint = scopeData.fingerprint; + } + if (scopeToMerge.getRequestSession()) { + this._requestSession = scopeToMerge.getRequestSession(); + } + if (scopeData.propagationContext) { + this._propagationContext = scopeData.propagationContext; + } + } else if (utils.isPlainObject(scopeToMerge)) { + const scopeContext = captureContext ; + this._tags = { ...this._tags, ...scopeContext.tags }; + this._extra = { ...this._extra, ...scopeContext.extra }; + this._contexts = { ...this._contexts, ...scopeContext.contexts }; + if (scopeContext.user) { + this._user = scopeContext.user; + } + if (scopeContext.level) { + this._level = scopeContext.level; + } + if (scopeContext.fingerprint) { + this._fingerprint = scopeContext.fingerprint; + } + if (scopeContext.requestSession) { + this._requestSession = scopeContext.requestSession; + } + if (scopeContext.propagationContext) { + this._propagationContext = scopeContext.propagationContext; + } } - return (isPathAbsolute ? '/' : '') + normalizedPath; -} -exports.normalizePath = normalizePath; -// posix version -/** JSDoc */ -function isAbsolute(path) { - return path.charAt(0) === '/'; -} -exports.isAbsolute = isAbsolute; -// posix version -/** JSDoc */ -function join() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; + + return this; + } + + /** + * @inheritDoc + */ + clear() { + this._breadcrumbs = []; + this._tags = {}; + this._extra = {}; + this._user = {}; + this._contexts = {}; + this._level = undefined; + this._transactionName = undefined; + this._fingerprint = undefined; + this._requestSession = undefined; + this._span = undefined; + this._session = undefined; + this._notifyScopeListeners(); + this._attachments = []; + this._propagationContext = generatePropagationContext(); + return this; + } + + /** + * @inheritDoc + */ + addBreadcrumb(breadcrumb, maxBreadcrumbs) { + const maxCrumbs = typeof maxBreadcrumbs === 'number' ? maxBreadcrumbs : DEFAULT_MAX_BREADCRUMBS; + + // No data has been changed, so don't notify scope listeners + if (maxCrumbs <= 0) { + return this; } - return normalizePath(args.join('/')); -} -exports.join = join; -/** JSDoc */ -function dirname(path) { - var result = splitPath(path); - var root = result[0]; - var dir = result[1]; - if (!root && !dir) { - // No dirname whatsoever - return '.'; + + const mergedBreadcrumb = { + timestamp: utils.dateTimestampInSeconds(), + ...breadcrumb, + }; + + const breadcrumbs = this._breadcrumbs; + breadcrumbs.push(mergedBreadcrumb); + this._breadcrumbs = breadcrumbs.length > maxCrumbs ? breadcrumbs.slice(-maxCrumbs) : breadcrumbs; + + this._notifyScopeListeners(); + + return this; + } + + /** + * @inheritDoc + */ + getLastBreadcrumb() { + return this._breadcrumbs[this._breadcrumbs.length - 1]; + } + + /** + * @inheritDoc + */ + clearBreadcrumbs() { + this._breadcrumbs = []; + this._notifyScopeListeners(); + return this; + } + + /** + * @inheritDoc + */ + addAttachment(attachment) { + this._attachments.push(attachment); + return this; + } + + /** + * @inheritDoc + * @deprecated Use `getScopeData()` instead. + */ + getAttachments() { + const data = this.getScopeData(); + + return data.attachments; + } + + /** + * @inheritDoc + */ + clearAttachments() { + this._attachments = []; + return this; + } + + /** @inheritDoc */ + getScopeData() { + const { + _breadcrumbs, + _attachments, + _contexts, + _tags, + _extra, + _user, + _level, + _fingerprint, + _eventProcessors, + _propagationContext, + _sdkProcessingMetadata, + _transactionName, + _span, + } = this; + + return { + breadcrumbs: _breadcrumbs, + attachments: _attachments, + contexts: _contexts, + tags: _tags, + extra: _extra, + user: _user, + level: _level, + fingerprint: _fingerprint || [], + eventProcessors: _eventProcessors, + propagationContext: _propagationContext, + sdkProcessingMetadata: _sdkProcessingMetadata, + transactionName: _transactionName, + span: _span, + }; + } + + /** + * Applies data from the scope to the event and runs all event processors on it. + * + * @param event Event + * @param hint Object containing additional information about the original exception, for use by the event processors. + * @hidden + * @deprecated Use `applyScopeDataToEvent()` directly + */ + applyToEvent( + event, + hint = {}, + additionalEventProcessors = [], + ) { + applyScopeDataToEvent.applyScopeDataToEvent(event, this.getScopeData()); + + // TODO (v8): Update this order to be: Global > Client > Scope + const eventProcessors$1 = [ + ...additionalEventProcessors, + // eslint-disable-next-line deprecation/deprecation + ...eventProcessors.getGlobalEventProcessors(), + ...this._eventProcessors, + ]; + + return eventProcessors.notifyEventProcessors(eventProcessors$1, event, hint); + } + + /** + * Add data which will be accessible during event processing but won't get sent to Sentry + */ + setSDKProcessingMetadata(newData) { + this._sdkProcessingMetadata = { ...this._sdkProcessingMetadata, ...newData }; + + return this; + } + + /** + * @inheritDoc + */ + setPropagationContext(context) { + this._propagationContext = context; + return this; + } + + /** + * @inheritDoc + */ + getPropagationContext() { + return this._propagationContext; + } + + /** + * Capture an exception for this scope. + * + * @param exception The exception to capture. + * @param hint Optinal additional data to attach to the Sentry event. + * @returns the id of the captured Sentry event. + */ + captureException(exception, hint) { + const eventId = hint && hint.event_id ? hint.event_id : utils.uuid4(); + + if (!this._client) { + utils.logger.warn('No client configured on scope - will not capture exception!'); + return eventId; } - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); + + const syntheticException = new Error('Sentry syntheticException'); + + this._client.captureException( + exception, + { + originalException: exception, + syntheticException, + ...hint, + event_id: eventId, + }, + this, + ); + + return eventId; + } + + /** + * Capture a message for this scope. + * + * @param message The message to capture. + * @param level An optional severity level to report the message with. + * @param hint Optional additional data to attach to the Sentry event. + * @returns the id of the captured message. + */ + captureMessage(message, level, hint) { + const eventId = hint && hint.event_id ? hint.event_id : utils.uuid4(); + + if (!this._client) { + utils.logger.warn('No client configured on scope - will not capture message!'); + return eventId; } - return root + dir; -} -exports.dirname = dirname; -/** JSDoc */ -function basename(path, ext) { - var f = splitPath(path)[2]; - if (ext && f.substr(ext.length * -1) === ext) { - f = f.substr(0, f.length - ext.length); + + const syntheticException = new Error(message); + + this._client.captureMessage( + message, + level, + { + originalException: message, + syntheticException, + ...hint, + event_id: eventId, + }, + this, + ); + + return eventId; + } + + /** + * Captures a manually created event for this scope and sends it to Sentry. + * + * @param exception The event to capture. + * @param hint Optional additional data to attach to the Sentry event. + * @returns the id of the captured event. + */ + captureEvent(event, hint) { + const eventId = hint && hint.event_id ? hint.event_id : utils.uuid4(); + + if (!this._client) { + utils.logger.warn('No client configured on scope - will not capture event!'); + return eventId; } - return f; -} -exports.basename = basename; -//# sourceMappingURL=path.js.map -/***/ }), + this._client.captureEvent(event, { ...hint, event_id: eventId }, this); -/***/ 12486: -/***/ ((__unused_webpack_module, exports) => { + return eventId; + } + + /** + * This will be called on every set call. + */ + _notifyScopeListeners() { + // We need this check for this._notifyingListeners to be able to work on scope during updates + // If this check is not here we'll produce endless recursion when something is done with the scope + // during the callback. + if (!this._notifyingListeners) { + this._notifyingListeners = true; + this._scopeListeners.forEach(callback => { + callback(this); + }); + this._notifyingListeners = false; + } + } +} -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.setPrototypeOf = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties); /** - * setPrototypeOf polyfill using __proto__ + * Get the global scope. + * This scope is applied to _all_ events. */ -// eslint-disable-next-line @typescript-eslint/ban-types -function setProtoOf(obj, proto) { - // @ts-ignore __proto__ does not exist on obj - obj.__proto__ = proto; - return obj; +function getGlobalScope() { + if (!globalScope) { + globalScope = new Scope(); + } + + return globalScope; } + /** - * setPrototypeOf polyfill using mixin + * This is mainly needed for tests. + * DO NOT USE this, as this is an internal API and subject to change. + * @hidden */ -// eslint-disable-next-line @typescript-eslint/ban-types -function mixinProperties(obj, proto) { - for (var prop in proto) { - if (!Object.prototype.hasOwnProperty.call(obj, prop)) { - // @ts-ignore typescript complains about indexing so we remove - obj[prop] = proto[prop]; - } - } - return obj; +function setGlobalScope(scope) { + globalScope = scope; } -//# sourceMappingURL=polyfill.js.map -/***/ }), +function generatePropagationContext() { + return { + traceId: utils.uuid4(), + spanId: utils.uuid4().substring(16), + }; +} -/***/ 76034: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +exports.Scope = Scope; +exports.getGlobalScope = getGlobalScope; +exports.setGlobalScope = setGlobalScope; +//# sourceMappingURL=scope.js.map -Object.defineProperty(exports, "__esModule", ({ value: true })); -var error_1 = __nccwpck_require__(62163); -var syncpromise_1 = __nccwpck_require__(19705); -/** - * Creates an new PromiseBuffer object with the specified limit - * @param limit max number of promises that can be stored in the buffer - */ -function makePromiseBuffer(limit) { - var buffer = []; - function isReady() { - return limit === undefined || buffer.length < limit; - } - /** - * Remove a promise from the queue. - * - * @param task Can be any PromiseLike - * @returns Removed promise. - */ - function remove(task) { - return buffer.splice(buffer.indexOf(task), 1)[0]; - } - /** - * Add a promise (representing an in-flight action) to the queue, and set it to remove itself on fulfillment. - * - * @param taskProducer A function producing any PromiseLike; In previous versions this used to be `task: - * PromiseLike`, but under that model, Promises were instantly created on the call-site and their executor - * functions therefore ran immediately. Thus, even if the buffer was full, the action still happened. By - * requiring the promise to be wrapped in a function, we can defer promise creation until after the buffer - * limit check. - * @returns The original promise. - */ - function add(taskProducer) { - if (!isReady()) { - return syncpromise_1.rejectedSyncPromise(new error_1.SentryError('Not adding Promise due to buffer limit reached.')); - } - // start the task and add its promise to the queue - var task = taskProducer(); - if (buffer.indexOf(task) === -1) { - buffer.push(task); - } - void task - .then(function () { return remove(task); }) - // Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike` - // rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't - // have promises, so TS has to polyfill when down-compiling.) - .then(null, function () { - return remove(task).then(null, function () { - // We have to add another catch here because `remove()` starts a new promise chain. - }); - }); - return task; - } - /** - * Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first. - * - * @param timeout The time, in ms, after which to resolve to `false` if the queue is still non-empty. Passing `0` (or - * not passing anything) will make the promise wait as long as it takes for the queue to drain before resolving to - * `true`. - * @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and - * `false` otherwise - */ - function drain(timeout) { - return new syncpromise_1.SyncPromise(function (resolve, reject) { - var counter = buffer.length; - if (!counter) { - return resolve(true); - } - // wait for `timeout` ms and then resolve to `false` (if not cancelled first) - var capturedSetTimeout = setTimeout(function () { - if (timeout && timeout > 0) { - resolve(false); - } - }, timeout); - // if all promises resolve in time, cancel the timer and resolve to `true` - buffer.forEach(function (item) { - void syncpromise_1.resolvedSyncPromise(item).then(function () { - // eslint-disable-next-line no-plusplus - if (!--counter) { - clearTimeout(capturedSetTimeout); - resolve(true); - } - }, reject); - }); - }); - } - return { - $: buffer, - add: add, - drain: drain, - }; -} -exports.makePromiseBuffer = makePromiseBuffer; -//# sourceMappingURL=promisebuffer.js.map /***/ }), -/***/ 1464: +/***/ 39158: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -exports.DEFAULT_RETRY_AFTER = 60 * 1000; // 60 seconds + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const exports$1 = __nccwpck_require__(74313); +const hub = __nccwpck_require__(18205); + +/** A class object that can instantiate Client objects. */ + /** - * Extracts Retry-After value from the request header or returns default value - * @param header string representation of 'Retry-After' header - * @param now current unix timestamp + * Internal function to create a new SDK client instance. The client is + * installed and then bound to the current scope. * + * @param clientClass The client class to instantiate. + * @param options Options to pass to the client. */ -function parseRetryAfterHeader(header, now) { - if (now === void 0) { now = Date.now(); } - var headerDelay = parseInt("" + header, 10); - if (!isNaN(headerDelay)) { - return headerDelay * 1000; - } - var headerDate = Date.parse("" + header); - if (!isNaN(headerDate)) { - return headerDate - now; +function initAndBind( + clientClass, + options, +) { + if (options.debug === true) { + if (debugBuild.DEBUG_BUILD) { + utils.logger.enable(); + } else { + // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped + utils.consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.'); + }); } - return exports.DEFAULT_RETRY_AFTER; + } + const scope = exports$1.getCurrentScope(); + scope.update(options.initialScope); + + const client = new clientClass(options); + setCurrentClient(client); + initializeClient(client); } -exports.parseRetryAfterHeader = parseRetryAfterHeader; + /** - * Gets the time that given category is disabled until for rate limiting + * Make the given client the current client. */ -function disabledUntil(limits, category) { - return limits[category] || limits.all || 0; +function setCurrentClient(client) { + // eslint-disable-next-line deprecation/deprecation + const hub$1 = hub.getCurrentHub(); + // eslint-disable-next-line deprecation/deprecation + const top = hub$1.getStackTop(); + top.client = client; + top.scope.setClient(client); } -exports.disabledUntil = disabledUntil; + /** - * Checks if a category is rate limited + * Initialize the client for the current scope. + * Make sure to call this after `setCurrentClient()`. */ -function isRateLimited(limits, category, now) { - if (now === void 0) { now = Date.now(); } - return disabledUntil(limits, category) > now; -} -exports.isRateLimited = isRateLimited; -/** - * Update ratelimits from incoming headers. - * Returns true if headers contains a non-empty rate limiting header. - */ -function updateRateLimits(limits, headers, now) { - var e_1, _a, e_2, _b; - if (now === void 0) { now = Date.now(); } - var updatedRateLimits = tslib_1.__assign({}, limits); - // "The name is case-insensitive." - // https://developer.mozilla.org/en-US/docs/Web/API/Headers/get - var rateLimitHeader = headers['x-sentry-rate-limits']; - var retryAfterHeader = headers['retry-after']; - if (rateLimitHeader) { - try { - /** - * rate limit headers are of the form - *
,
,.. - * where each
is of the form - * : : : - * where - * is a delay in seconds - * is the event type(s) (error, transaction, etc) being rate limited and is of the form - * ;;... - * is what's being limited (org, project, or key) - ignored by SDK - * is an arbitrary string like "org_quota" - ignored by SDK - */ - for (var _c = tslib_1.__values(rateLimitHeader.trim().split(',')), _d = _c.next(); !_d.done; _d = _c.next()) { - var limit = _d.value; - var parameters = limit.split(':', 2); - var headerDelay = parseInt(parameters[0], 10); - var delay = (!isNaN(headerDelay) ? headerDelay : 60) * 1000; // 60sec default - if (!parameters[1]) { - updatedRateLimits.all = now + delay; - } - else { - try { - for (var _e = (e_2 = void 0, tslib_1.__values(parameters[1].split(';'))), _f = _e.next(); !_f.done; _f = _e.next()) { - var category = _f.value; - updatedRateLimits[category] = now + delay; - } - } - catch (e_2_1) { e_2 = { error: e_2_1 }; } - finally { - try { - if (_f && !_f.done && (_b = _e.return)) _b.call(_e); - } - finally { if (e_2) throw e_2.error; } - } - } - } - } - catch (e_1_1) { e_1 = { error: e_1_1 }; } - finally { - try { - if (_d && !_d.done && (_a = _c.return)) _a.call(_c); - } - finally { if (e_1) throw e_1.error; } - } - } - else if (retryAfterHeader) { - updatedRateLimits.all = now + parseRetryAfterHeader(retryAfterHeader, now); - } - return updatedRateLimits; +function initializeClient(client) { + if (client.init) { + client.init(); + // TODO v8: Remove this fallback + // eslint-disable-next-line deprecation/deprecation + } else if (client.setupIntegrations) { + // eslint-disable-next-line deprecation/deprecation + client.setupIntegrations(); + } } -exports.updateRateLimits = updateRateLimits; -//# sourceMappingURL=ratelimit.js.map + +exports.initAndBind = initAndBind; +exports.setCurrentClient = setCurrentClient; +//# sourceMappingURL=sdk.js.map + /***/ }), -/***/ 78430: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 44513: +/***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var types_1 = __nccwpck_require__(34105); -var enums_1 = __nccwpck_require__(60663); -function isSupportedSeverity(level) { - return enums_1.SeverityLevels.indexOf(level) !== -1; -} + /** - * Converts a string-based level into a {@link Severity}. + * Use this attribute to represent the source of a span. + * Should be one of: custom, url, route, view, component, task, unknown * - * @param level string representation of Severity - * @returns Severity */ -function severityFromString(level) { - if (level === 'warn') - return types_1.Severity.Warning; - if (isSupportedSeverity(level)) { - return level; - } - return types_1.Severity.Log; -} -exports.severityFromString = severityFromString; -//# sourceMappingURL=severity.js.map +const SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = 'sentry.source'; + +/** + * Use this attribute to represent the sample rate used for a span. + */ +const SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = 'sentry.sample_rate'; + +/** + * Use this attribute to represent the operation of a span. + */ +const SEMANTIC_ATTRIBUTE_SENTRY_OP = 'sentry.op'; + +/** + * Use this attribute to represent the origin of a span. + */ +const SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'sentry.origin'; + +/** + * The id of the profile that this span occured in. + */ +const SEMANTIC_ATTRIBUTE_PROFILE_ID = 'profile_id'; + +exports.SEMANTIC_ATTRIBUTE_PROFILE_ID = SEMANTIC_ATTRIBUTE_PROFILE_ID; +exports.SEMANTIC_ATTRIBUTE_SENTRY_OP = SEMANTIC_ATTRIBUTE_SENTRY_OP; +exports.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN; +exports.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE; +exports.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = SEMANTIC_ATTRIBUTE_SENTRY_SOURCE; +//# sourceMappingURL=semanticAttributes.js.map + /***/ }), -/***/ 60996: +/***/ 19144: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var tslib_1 = __nccwpck_require__(74834); -var STACKTRACE_LIMIT = 50; + +const utils = __nccwpck_require__(57540); +const baseclient = __nccwpck_require__(36950); +const checkin = __nccwpck_require__(31265); +const debugBuild = __nccwpck_require__(93376); +const exports$1 = __nccwpck_require__(74313); +const aggregator = __nccwpck_require__(66327); +const sessionflusher = __nccwpck_require__(48409); +const hubextensions = __nccwpck_require__(44758); +const spanUtils = __nccwpck_require__(98313); +const getRootSpan = __nccwpck_require__(27304); +__nccwpck_require__(14769); +const dynamicSamplingContext = __nccwpck_require__(76248); + /** - * Creates a stack parser with the supplied line parsers - * - * StackFrames are returned in the correct order for Sentry Exception - * frames and with Sentry SDK internal frames removed from the top and bottom - * + * The Sentry Server Runtime Client SDK. */ -function createStackParser() { - var parsers = []; - for (var _i = 0; _i < arguments.length; _i++) { - parsers[_i] = arguments[_i]; +class ServerRuntimeClient + + extends baseclient.BaseClient { + + /** + * Creates a new Edge SDK instance. + * @param options Configuration options for this SDK. + */ + constructor(options) { + // Server clients always support tracing + hubextensions.addTracingExtensions(); + + super(options); + + if (options._experiments && options._experiments['metricsAggregator']) { + this.metricsAggregator = new aggregator.MetricsAggregator(this); } - var sortedParsers = parsers.sort(function (a, b) { return a[0] - b[0]; }).map(function (p) { return p[1]; }); - return function (stack, skipFirst) { - var e_1, _a, e_2, _b; - if (skipFirst === void 0) { skipFirst = 0; } - var frames = []; - try { - for (var _c = tslib_1.__values(stack.split('\n').slice(skipFirst)), _d = _c.next(); !_d.done; _d = _c.next()) { - var line = _d.value; - try { - for (var sortedParsers_1 = (e_2 = void 0, tslib_1.__values(sortedParsers)), sortedParsers_1_1 = sortedParsers_1.next(); !sortedParsers_1_1.done; sortedParsers_1_1 = sortedParsers_1.next()) { - var parser = sortedParsers_1_1.value; - var frame = parser(line); - if (frame) { - frames.push(frame); - break; - } - } - } - catch (e_2_1) { e_2 = { error: e_2_1 }; } - finally { - try { - if (sortedParsers_1_1 && !sortedParsers_1_1.done && (_b = sortedParsers_1.return)) _b.call(sortedParsers_1); - } - finally { if (e_2) throw e_2.error; } - } - } - } - catch (e_1_1) { e_1 = { error: e_1_1 }; } - finally { - try { - if (_d && !_d.done && (_a = _c.return)) _a.call(_c); - } - finally { if (e_1) throw e_1.error; } + } + + /** + * @inheritDoc + */ + eventFromException(exception, hint) { + return utils.resolvedSyncPromise(utils.eventFromUnknownInput(exports$1.getClient(), this._options.stackParser, exception, hint)); + } + + /** + * @inheritDoc + */ + eventFromMessage( + message, + // eslint-disable-next-line deprecation/deprecation + level = 'info', + hint, + ) { + return utils.resolvedSyncPromise( + utils.eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace), + ); + } + + /** + * @inheritDoc + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types + captureException(exception, hint, scope) { + // Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only + // when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload + // sent to the Server only when the `requestHandler` middleware is used + if (this._options.autoSessionTracking && this._sessionFlusher && scope) { + const requestSession = scope.getRequestSession(); + + // Necessary checks to ensure this is code block is executed only within a request + // Should override the status only if `requestSession.status` is `Ok`, which is its initial stage + if (requestSession && requestSession.status === 'ok') { + requestSession.status = 'errored'; + } + } + + return super.captureException(exception, hint, scope); + } + + /** + * @inheritDoc + */ + captureEvent(event, hint, scope) { + // Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only + // when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload + // sent to the Server only when the `requestHandler` middleware is used + if (this._options.autoSessionTracking && this._sessionFlusher && scope) { + const eventType = event.type || 'exception'; + const isException = + eventType === 'exception' && event.exception && event.exception.values && event.exception.values.length > 0; + + // If the event is of type Exception, then a request session should be captured + if (isException) { + const requestSession = scope.getRequestSession(); + + // Ensure that this is happening within the bounds of a request, and make sure not to override + // Session Status if Errored / Crashed + if (requestSession && requestSession.status === 'ok') { + requestSession.status = 'errored'; } - return stripSentryFramesAndReverse(frames); + } + } + + return super.captureEvent(event, hint, scope); + } + + /** + * + * @inheritdoc + */ + close(timeout) { + if (this._sessionFlusher) { + this._sessionFlusher.close(); + } + return super.close(timeout); + } + + /** Method that initialises an instance of SessionFlusher on Client */ + initSessionFlusher() { + const { release, environment } = this._options; + if (!release) { + debugBuild.DEBUG_BUILD && utils.logger.warn('Cannot initialise an instance of SessionFlusher if no release is provided!'); + } else { + this._sessionFlusher = new sessionflusher.SessionFlusher(this, { + release, + environment, + }); + } + } + + /** + * Create a cron monitor check in and send it to Sentry. + * + * @param checkIn An object that describes a check in. + * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want + * to create a monitor automatically when sending a check in. + */ + captureCheckIn(checkIn, monitorConfig, scope) { + const id = 'checkInId' in checkIn && checkIn.checkInId ? checkIn.checkInId : utils.uuid4(); + if (!this._isEnabled()) { + debugBuild.DEBUG_BUILD && utils.logger.warn('SDK not enabled, will not capture checkin.'); + return id; + } + + const options = this.getOptions(); + const { release, environment, tunnel } = options; + + const serializedCheckIn = { + check_in_id: id, + monitor_slug: checkIn.monitorSlug, + status: checkIn.status, + release, + environment, }; -} -exports.createStackParser = createStackParser; -/** - * @hidden - */ -function stripSentryFramesAndReverse(stack) { - if (!stack.length) { - return []; - } - var localStack = stack; - var firstFrameFunction = localStack[0].function || ''; - var lastFrameFunction = localStack[localStack.length - 1].function || ''; - // If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call) - if (firstFrameFunction.indexOf('captureMessage') !== -1 || firstFrameFunction.indexOf('captureException') !== -1) { - localStack = localStack.slice(1); - } - // If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call) - if (lastFrameFunction.indexOf('sentryWrapped') !== -1) { - localStack = localStack.slice(0, -1); - } - // The frame where the crash happened, should be the last entry in the array - return localStack - .slice(0, STACKTRACE_LIMIT) - .map(function (frame) { return (tslib_1.__assign(tslib_1.__assign({}, frame), { filename: frame.filename || localStack[0].filename, function: frame.function || '?' })); }) - .reverse(); -} -exports.stripSentryFramesAndReverse = stripSentryFramesAndReverse; -var defaultFunctionName = ''; -/** - * Safely extract function name from itself - */ -function getFunctionName(fn) { - try { - if (!fn || typeof fn !== 'function') { - return defaultFunctionName; - } - return fn.name || defaultFunctionName; + + if ('duration' in checkIn) { + serializedCheckIn.duration = checkIn.duration; } - catch (e) { - // Just accessing custom props in some Selenium environments - // can cause a "Permission denied" exception (see raven-js#495). - return defaultFunctionName; + + if (monitorConfig) { + serializedCheckIn.monitor_config = { + schedule: monitorConfig.schedule, + checkin_margin: monitorConfig.checkinMargin, + max_runtime: monitorConfig.maxRuntime, + timezone: monitorConfig.timezone, + }; } -} -exports.getFunctionName = getFunctionName; -//# sourceMappingURL=stacktrace.js.map -/***/ }), + const [dynamicSamplingContext, traceContext] = this._getTraceInfoFromScope(scope); + if (traceContext) { + serializedCheckIn.contexts = { + trace: traceContext, + }; + } -/***/ 13707: -/***/ ((__unused_webpack_module, exports) => { + const envelope = checkin.createCheckInEnvelope( + serializedCheckIn, + dynamicSamplingContext, + this.getSdkMetadata(), + tunnel, + this.getDsn(), + ); -Object.defineProperty(exports, "__esModule", ({ value: true })); -/** - * Converts an HTTP status code to sentry status {@link EventStatus}. - * - * @param code number HTTP status code - * @returns EventStatus - */ -function eventStatusFromHttpCode(code) { - if (code >= 200 && code < 300) { - return 'success'; + debugBuild.DEBUG_BUILD && utils.logger.info('Sending checkin:', checkIn.monitorSlug, checkIn.status); + + // _sendEnvelope should not throw + // eslint-disable-next-line @typescript-eslint/no-floating-promises + this._sendEnvelope(envelope); + + return id; + } + + /** + * Method responsible for capturing/ending a request session by calling `incrementSessionStatusCount` to increment + * appropriate session aggregates bucket + */ + _captureRequestSession() { + if (!this._sessionFlusher) { + debugBuild.DEBUG_BUILD && utils.logger.warn('Discarded request mode session because autoSessionTracking option was disabled'); + } else { + this._sessionFlusher.incrementSessionStatusCount(); + } + } + + /** + * @inheritDoc + */ + _prepareEvent( + event, + hint, + scope, + isolationScope, + ) { + if (this._options.platform) { + event.platform = event.platform || this._options.platform; + } + + if (this._options.runtime) { + event.contexts = { + ...event.contexts, + runtime: (event.contexts || {}).runtime || this._options.runtime, + }; + } + + if (this._options.serverName) { + event.server_name = event.server_name || this._options.serverName; } - if (code === 429) { - return 'rate_limit'; + + return super._prepareEvent(event, hint, scope, isolationScope); + } + + /** Extract trace information from scope */ + _getTraceInfoFromScope( + scope, + ) { + if (!scope) { + return [undefined, undefined]; } - if (code >= 400 && code < 500) { - return 'invalid'; + + // eslint-disable-next-line deprecation/deprecation + const span = scope.getSpan(); + if (span) { + const samplingContext = getRootSpan.getRootSpan(span) ? dynamicSamplingContext.getDynamicSamplingContextFromSpan(span) : undefined; + return [samplingContext, spanUtils.spanToTraceContext(span)]; } - if (code >= 500) { - return 'failed'; + + const { traceId, spanId, parentSpanId, dsc } = scope.getPropagationContext(); + const traceContext = { + trace_id: traceId, + span_id: spanId, + parent_span_id: parentSpanId, + }; + if (dsc) { + return [dsc, traceContext]; } - return 'unknown'; + + return [dynamicSamplingContext.getDynamicSamplingContextFromClient(traceId, this, scope), traceContext]; + } } -exports.eventStatusFromHttpCode = eventStatusFromHttpCode; -//# sourceMappingURL=status.js.map + +exports.ServerRuntimeClient = ServerRuntimeClient; +//# sourceMappingURL=server-runtime-client.js.map + /***/ }), -/***/ 17256: +/***/ 14638: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var is_1 = __nccwpck_require__(79409); + +const utils = __nccwpck_require__(57540); + /** - * Truncates given string to the maximum characters count + * Creates a new `Session` object by setting certain default parameters. If optional @param context + * is passed, the passed properties are applied to the session object. * - * @param str An object that contains serializable values - * @param max Maximum number of characters in truncated string (0 = unlimited) - * @returns string Encoded - */ -function truncate(str, max) { - if (max === void 0) { max = 0; } - if (typeof str !== 'string' || max === 0) { - return str; - } - return str.length <= max ? str : str.substr(0, max) + "..."; -} -exports.truncate = truncate; -/** - * This is basically just `trim_line` from - * https://github.com/getsentry/sentry/blob/master/src/sentry/lang/javascript/processor.py#L67 + * @param context (optional) additional properties to be applied to the returned session object * - * @param str An object that contains serializable values - * @param max Maximum number of characters in truncated string - * @returns string Encoded + * @returns a new `Session` object */ -function snipLine(line, colno) { - var newLine = line; - var lineLength = newLine.length; - if (lineLength <= 150) { - return newLine; - } - if (colno > lineLength) { - // eslint-disable-next-line no-param-reassign - colno = lineLength; - } - var start = Math.max(colno - 60, 0); - if (start < 5) { - start = 0; - } - var end = Math.min(start + 140, lineLength); - if (end > lineLength - 5) { - end = lineLength; - } - if (end === lineLength) { - start = Math.max(end - 140, 0); - } - newLine = newLine.slice(start, end); - if (start > 0) { - newLine = "'{snip} " + newLine; - } - if (end < lineLength) { - newLine += ' {snip}'; - } - return newLine; +function makeSession(context) { + // Both timestamp and started are in seconds since the UNIX epoch. + const startingTime = utils.timestampInSeconds(); + + const session = { + sid: utils.uuid4(), + init: true, + timestamp: startingTime, + started: startingTime, + duration: 0, + status: 'ok', + errors: 0, + ignoreDuration: false, + toJSON: () => sessionToJSON(session), + }; + + if (context) { + updateSession(session, context); + } + + return session; } -exports.snipLine = snipLine; + /** - * Join values in array - * @param input array of values to be joined together - * @param delimiter string to be placed in-between values - * @returns Joined values + * Updates a session object with the properties passed in the context. + * + * Note that this function mutates the passed object and returns void. + * (Had to do this instead of returning a new and updated session because closing and sending a session + * makes an update to the session after it was passed to the sending logic. + * @see BaseClient.captureSession ) + * + * @param session the `Session` to update + * @param context the `SessionContext` holding the properties that should be updated in @param session */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function safeJoin(input, delimiter) { - if (!Array.isArray(input)) { - return ''; +// eslint-disable-next-line complexity +function updateSession(session, context = {}) { + if (context.user) { + if (!session.ipAddress && context.user.ip_address) { + session.ipAddress = context.user.ip_address; } - var output = []; - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (var i = 0; i < input.length; i++) { - var value = input[i]; - try { - output.push(String(value)); - } - catch (e) { - output.push('[value cannot be serialized]'); - } + + if (!session.did && !context.did) { + session.did = context.user.id || context.user.email || context.user.username; } - return output.join(delimiter); + } + + session.timestamp = context.timestamp || utils.timestampInSeconds(); + + if (context.abnormal_mechanism) { + session.abnormal_mechanism = context.abnormal_mechanism; + } + + if (context.ignoreDuration) { + session.ignoreDuration = context.ignoreDuration; + } + if (context.sid) { + // Good enough uuid validation. — Kamil + session.sid = context.sid.length === 32 ? context.sid : utils.uuid4(); + } + if (context.init !== undefined) { + session.init = context.init; + } + if (!session.did && context.did) { + session.did = `${context.did}`; + } + if (typeof context.started === 'number') { + session.started = context.started; + } + if (session.ignoreDuration) { + session.duration = undefined; + } else if (typeof context.duration === 'number') { + session.duration = context.duration; + } else { + const duration = session.timestamp - session.started; + session.duration = duration >= 0 ? duration : 0; + } + if (context.release) { + session.release = context.release; + } + if (context.environment) { + session.environment = context.environment; + } + if (!session.ipAddress && context.ipAddress) { + session.ipAddress = context.ipAddress; + } + if (!session.userAgent && context.userAgent) { + session.userAgent = context.userAgent; + } + if (typeof context.errors === 'number') { + session.errors = context.errors; + } + if (context.status) { + session.status = context.status; + } } -exports.safeJoin = safeJoin; + /** - * Checks if the value matches a regex or includes the string - * @param value The string value to be checked against - * @param pattern Either a regex or a string that must be contained in value + * Closes a session by setting its status and updating the session object with it. + * Internally calls `updateSession` to update the passed session object. + * + * Note that this function mutates the passed session (@see updateSession for explanation). + * + * @param session the `Session` object to be closed + * @param status the `SessionStatus` with which the session was closed. If you don't pass a status, + * this function will keep the previously set status, unless it was `'ok'` in which case + * it is changed to `'exited'`. */ -function isMatchingPattern(value, pattern) { - if (!is_1.isString(value)) { - return false; - } - if (is_1.isRegExp(pattern)) { - return pattern.test(value); - } - if (typeof pattern === 'string') { - return value.indexOf(pattern) !== -1; - } - return false; +function closeSession(session, status) { + let context = {}; + if (status) { + context = { status }; + } else if (session.status === 'ok') { + context = { status: 'exited' }; + } + + updateSession(session, context); } -exports.isMatchingPattern = isMatchingPattern; + /** - * Given a string, escape characters which have meaning in the regex grammar, such that the result is safe to feed to - * `new RegExp()`. + * Serializes a passed session object to a JSON object with a slightly different structure. + * This is necessary because the Sentry backend requires a slightly different schema of a session + * than the one the JS SDKs use internally. * - * Based on https://github.com/sindresorhus/escape-string-regexp. Vendored to a) reduce the size by skipping the runtime - * type-checking, and b) ensure it gets down-compiled for old versions of Node (the published package only supports Node - * 12+). + * @param session the session to be converted * - * @param regexString The string to escape - * @returns An version of the string with all special regex characters escaped + * @returns a JSON object of the passed session */ -function escapeStringForRegex(regexString) { - // escape the hyphen separately so we can also replace it with a unicode literal hyphen, to avoid the problems - // discussed in https://github.com/sindresorhus/escape-string-regexp/issues/20. - return regexString.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d'); +function sessionToJSON(session) { + return utils.dropUndefinedKeys({ + sid: `${session.sid}`, + init: session.init, + // Make sure that sec is converted to ms for date constructor + started: new Date(session.started * 1000).toISOString(), + timestamp: new Date(session.timestamp * 1000).toISOString(), + status: session.status, + errors: session.errors, + did: typeof session.did === 'number' || typeof session.did === 'string' ? `${session.did}` : undefined, + duration: session.duration, + abnormal_mechanism: session.abnormal_mechanism, + attrs: { + release: session.release, + environment: session.environment, + ip_address: session.ipAddress, + user_agent: session.userAgent, + }, + }); } -exports.escapeStringForRegex = escapeStringForRegex; -//# sourceMappingURL=string.js.map + +exports.closeSession = closeSession; +exports.makeSession = makeSession; +exports.updateSession = updateSession; +//# sourceMappingURL=session.js.map + /***/ }), -/***/ 64473: +/***/ 48409: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -var flags_1 = __nccwpck_require__(8142); -var global_1 = __nccwpck_require__(16734); -var logger_1 = __nccwpck_require__(29697); + +const utils = __nccwpck_require__(57540); +const exports$1 = __nccwpck_require__(74313); + /** - * Tells whether current environment supports ErrorEvent objects - * {@link supportsErrorEvent}. - * - * @returns Answer to the given question. + * @inheritdoc */ -function supportsErrorEvent() { - try { - new ErrorEvent(''); - return true; - } - catch (e) { - return false; +class SessionFlusher { + + // Cast to any so that it can use Node.js timeout + // eslint-disable-next-line @typescript-eslint/no-explicit-any + + constructor(client, attrs) { + this._client = client; + this.flushTimeout = 60; + this._pendingAggregates = {}; + this._isEnabled = true; + + // Call to setInterval, so that flush is called every 60 seconds. + this._intervalId = setInterval(() => this.flush(), this.flushTimeout * 1000); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (this._intervalId.unref) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + this._intervalId.unref(); } -} -exports.supportsErrorEvent = supportsErrorEvent; -/** - * Tells whether current environment supports DOMError objects - * {@link supportsDOMError}. - * - * @returns Answer to the given question. - */ -function supportsDOMError() { - try { - // Chrome: VM89:1 Uncaught TypeError: Failed to construct 'DOMError': - // 1 argument required, but only 0 present. - // @ts-ignore It really needs 1 argument, not 0. - new DOMError(''); - return true; + this._sessionAttrs = attrs; + } + + /** Checks if `pendingAggregates` has entries, and if it does flushes them by calling `sendSession` */ + flush() { + const sessionAggregates = this.getSessionAggregates(); + if (sessionAggregates.aggregates.length === 0) { + return; } - catch (e) { - return false; + this._pendingAggregates = {}; + this._client.sendSession(sessionAggregates); + } + + /** Massages the entries in `pendingAggregates` and returns aggregated sessions */ + getSessionAggregates() { + const aggregates = Object.keys(this._pendingAggregates).map((key) => { + return this._pendingAggregates[parseInt(key)]; + }); + + const sessionAggregates = { + attrs: this._sessionAttrs, + aggregates, + }; + return utils.dropUndefinedKeys(sessionAggregates); + } + + /** JSDoc */ + close() { + clearInterval(this._intervalId); + this._isEnabled = false; + this.flush(); + } + + /** + * Wrapper function for _incrementSessionStatusCount that checks if the instance of SessionFlusher is enabled then + * fetches the session status of the request from `Scope.getRequestSession().status` on the scope and passes them to + * `_incrementSessionStatusCount` along with the start date + */ + incrementSessionStatusCount() { + if (!this._isEnabled) { + return; } -} -exports.supportsDOMError = supportsDOMError; -/** - * Tells whether current environment supports DOMException objects - * {@link supportsDOMException}. - * - * @returns Answer to the given question. - */ -function supportsDOMException() { - try { - new DOMException(''); - return true; + const scope = exports$1.getCurrentScope(); + const requestSession = scope.getRequestSession(); + + if (requestSession && requestSession.status) { + this._incrementSessionStatusCount(requestSession.status, new Date()); + // This is not entirely necessarily but is added as a safe guard to indicate the bounds of a request and so in + // case captureRequestSession is called more than once to prevent double count + scope.setRequestSession(undefined); + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ } - catch (e) { - return false; + } + + /** + * Increments status bucket in pendingAggregates buffer (internal state) corresponding to status of + * the session received + */ + _incrementSessionStatusCount(status, date) { + // Truncate minutes and seconds on Session Started attribute to have one minute bucket keys + const sessionStartedTrunc = new Date(date).setSeconds(0, 0); + this._pendingAggregates[sessionStartedTrunc] = this._pendingAggregates[sessionStartedTrunc] || {}; + + // corresponds to aggregated sessions in one specific minute bucket + // for example, {"started":"2021-03-16T08:00:00.000Z","exited":4, "errored": 1} + const aggregationCounts = this._pendingAggregates[sessionStartedTrunc]; + if (!aggregationCounts.started) { + aggregationCounts.started = new Date(sessionStartedTrunc).toISOString(); + } + + switch (status) { + case 'errored': + aggregationCounts.errored = (aggregationCounts.errored || 0) + 1; + return aggregationCounts.errored; + case 'ok': + aggregationCounts.exited = (aggregationCounts.exited || 0) + 1; + return aggregationCounts.exited; + default: + aggregationCounts.crashed = (aggregationCounts.crashed || 0) + 1; + return aggregationCounts.crashed; } + } } -exports.supportsDOMException = supportsDOMException; + +exports.SessionFlusher = SessionFlusher; +//# sourceMappingURL=sessionflusher.js.map + + +/***/ }), + +/***/ 67084: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); + /** - * Tells whether current environment supports Fetch API - * {@link supportsFetch}. - * - * @returns Answer to the given question. + * Create envelope from Span item. */ -function supportsFetch() { - if (!('fetch' in global_1.getGlobalObject())) { - return false; - } - try { - new Headers(); - new Request(''); - new Response(); - return true; - } - catch (e) { - return false; - } +function createSpanEnvelope(spans, dsn) { + const headers = { + sent_at: new Date().toISOString(), + }; + + if (dsn) { + headers.dsn = utils.dsnToString(dsn); + } + + const items = spans.map(createSpanItem); + return utils.createEnvelope(headers, items); } -exports.supportsFetch = supportsFetch; -/** - * isNativeFetch checks if the given function is a native implementation of fetch() - */ -// eslint-disable-next-line @typescript-eslint/ban-types -function isNativeFetch(func) { - return func && /^function fetch\(\)\s+\{\s+\[native code\]\s+\}$/.test(func.toString()); + +function createSpanItem(span) { + const spanHeaders = { + type: 'span', + }; + return [spanHeaders, span]; } -exports.isNativeFetch = isNativeFetch; + +exports.createSpanEnvelope = createSpanEnvelope; +//# sourceMappingURL=span.js.map + + +/***/ }), + +/***/ 76248: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); +const constants = __nccwpck_require__(11363); +const exports$1 = __nccwpck_require__(74313); +const getRootSpan = __nccwpck_require__(27304); +const spanUtils = __nccwpck_require__(98313); + /** - * Tells whether current environment supports Fetch API natively - * {@link supportsNativeFetch}. + * Creates a dynamic sampling context from a client. * - * @returns true if `window.fetch` is natively implemented, false otherwise + * Dispatches the `createDsc` lifecycle hook as a side effect. */ -function supportsNativeFetch() { - if (!supportsFetch()) { - return false; - } - var global = global_1.getGlobalObject(); - // Fast path to avoid DOM I/O - // eslint-disable-next-line @typescript-eslint/unbound-method - if (isNativeFetch(global.fetch)) { - return true; - } - // window.fetch is implemented, but is polyfilled or already wrapped (e.g: by a chrome extension) - // so create a "pure" iframe to see if that has native fetch - var result = false; - var doc = global.document; - // eslint-disable-next-line deprecation/deprecation - if (doc && typeof doc.createElement === 'function') { - try { - var sandbox = doc.createElement('iframe'); - sandbox.hidden = true; - doc.head.appendChild(sandbox); - if (sandbox.contentWindow && sandbox.contentWindow.fetch) { - // eslint-disable-next-line @typescript-eslint/unbound-method - result = isNativeFetch(sandbox.contentWindow.fetch); - } - doc.head.removeChild(sandbox); - } - catch (err) { - flags_1.IS_DEBUG_BUILD && - logger_1.logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err); - } - } - return result; +function getDynamicSamplingContextFromClient( + trace_id, + client, + scope, +) { + const options = client.getOptions(); + + const { publicKey: public_key } = client.getDsn() || {}; + // TODO(v8): Remove segment from User + // eslint-disable-next-line deprecation/deprecation + const { segment: user_segment } = (scope && scope.getUser()) || {}; + + const dsc = utils.dropUndefinedKeys({ + environment: options.environment || constants.DEFAULT_ENVIRONMENT, + release: options.release, + user_segment, + public_key, + trace_id, + }) ; + + client.emit && client.emit('createDsc', dsc); + + return dsc; } -exports.supportsNativeFetch = supportsNativeFetch; + /** - * Tells whether current environment supports ReportingObserver API - * {@link supportsReportingObserver}. - * - * @returns Answer to the given question. + * A Span with a frozen dynamic sampling context. */ -function supportsReportingObserver() { - return 'ReportingObserver' in global_1.getGlobalObject(); -} -exports.supportsReportingObserver = supportsReportingObserver; + /** - * Tells whether current environment supports Referrer Policy API - * {@link supportsReferrerPolicy}. + * Creates a dynamic sampling context from a span (and client and scope) * - * @returns Answer to the given question. - */ -function supportsReferrerPolicy() { - // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default' - // (see https://caniuse.com/#feat=referrer-policy), - // it doesn't. And it throws an exception instead of ignoring this parameter... - // REF: https://github.com/getsentry/raven-js/issues/1233 - if (!supportsFetch()) { - return false; - } - try { - new Request('_', { - referrerPolicy: 'origin', - }); - return true; - } - catch (e) { - return false; - } -} -exports.supportsReferrerPolicy = supportsReferrerPolicy; -/** - * Tells whether current environment supports History API - * {@link supportsHistory}. + * @param span the span from which a few values like the root span name and sample rate are extracted. * - * @returns Answer to the given question. + * @returns a dynamic sampling context */ -function supportsHistory() { - // NOTE: in Chrome App environment, touching history.pushState, *even inside - // a try/catch block*, will cause Chrome to output an error to console.error - // borrowed from: https://github.com/angular/angular.js/pull/13945/files - var global = global_1.getGlobalObject(); - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - var chrome = global.chrome; - var isChromePackagedApp = chrome && chrome.app && chrome.app.runtime; - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ - var hasHistoryApi = 'history' in global && !!global.history.pushState && !!global.history.replaceState; - return !isChromePackagedApp && hasHistoryApi; +function getDynamicSamplingContextFromSpan(span) { + const client = exports$1.getClient(); + if (!client) { + return {}; + } + + // passing emit=false here to only emit later once the DSC is actually populated + const dsc = getDynamicSamplingContextFromClient(spanUtils.spanToJSON(span).trace_id || '', client, exports$1.getCurrentScope()); + + // TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext + const txn = getRootSpan.getRootSpan(span) ; + if (!txn) { + return dsc; + } + + // TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext + // For now we need to avoid breaking users who directly created a txn with a DSC, where this field is still set. + // @see Transaction class constructor + const v7FrozenDsc = txn && txn._frozenDynamicSamplingContext; + if (v7FrozenDsc) { + return v7FrozenDsc; + } + + // TODO (v8): Replace txn.metadata with txn.attributes[] + // We can't do this yet because attributes aren't always set yet. + // eslint-disable-next-line deprecation/deprecation + const { sampleRate: maybeSampleRate, source } = txn.metadata; + if (maybeSampleRate != null) { + dsc.sample_rate = `${maybeSampleRate}`; + } + + // We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII + const jsonSpan = spanUtils.spanToJSON(txn); + + // after JSON conversion, txn.name becomes jsonSpan.description + if (source && source !== 'url') { + dsc.transaction = jsonSpan.description; + } + + dsc.sampled = String(spanUtils.spanIsSampled(txn)); + + client.emit && client.emit('createDsc', dsc); + + return dsc; } -exports.supportsHistory = supportsHistory; -//# sourceMappingURL=supports.js.map + +exports.getDynamicSamplingContextFromClient = getDynamicSamplingContextFromClient; +exports.getDynamicSamplingContextFromSpan = getDynamicSamplingContextFromSpan; +//# sourceMappingURL=dynamicSamplingContext.js.map + /***/ }), -/***/ 19705: +/***/ 55448: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); -/* eslint-disable @typescript-eslint/explicit-function-return-type */ -/* eslint-disable @typescript-eslint/typedef */ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -var is_1 = __nccwpck_require__(79409); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const utils$1 = __nccwpck_require__(49194); + +let errorsInstrumented = false; + /** - * Creates a resolved sync promise. - * - * @param value the value to resolve the promise with - * @returns the resolved sync promise + * Configures global error listeners */ -function resolvedSyncPromise(value) { - return new SyncPromise(function (resolve) { - resolve(value); - }); +function registerErrorInstrumentation() { + if (errorsInstrumented) { + return; + } + + errorsInstrumented = true; + utils.addGlobalErrorInstrumentationHandler(errorCallback); + utils.addGlobalUnhandledRejectionInstrumentationHandler(errorCallback); } -exports.resolvedSyncPromise = resolvedSyncPromise; + /** - * Creates a rejected sync promise. - * - * @param value the value to reject the promise with - * @returns the rejected sync promise + * If an error or unhandled promise occurs, we mark the active transaction as failed */ -function rejectedSyncPromise(reason) { - return new SyncPromise(function (_, reject) { - reject(reason); - }); +function errorCallback() { + // eslint-disable-next-line deprecation/deprecation + const activeTransaction = utils$1.getActiveTransaction(); + if (activeTransaction) { + const status = 'internal_error'; + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Transaction: ${status} -> Global error occured`); + activeTransaction.setStatus(status); + } } -exports.rejectedSyncPromise = rejectedSyncPromise; -/** - * Thenable class that behaves like a Promise and follows it's interface - * but is not async internally - */ -var SyncPromise = /** @class */ (function () { - function SyncPromise(executor) { - var _this = this; - this._state = 0 /* PENDING */; - this._handlers = []; - /** JSDoc */ - this._resolve = function (value) { - _this._setResult(1 /* RESOLVED */, value); - }; - /** JSDoc */ - this._reject = function (reason) { - _this._setResult(2 /* REJECTED */, reason); - }; - /** JSDoc */ - this._setResult = function (state, value) { - if (_this._state !== 0 /* PENDING */) { - return; - } - if (is_1.isThenable(value)) { - void value.then(_this._resolve, _this._reject); - return; - } - _this._state = state; - _this._value = value; - _this._executeHandlers(); - }; - /** JSDoc */ - this._executeHandlers = function () { - if (_this._state === 0 /* PENDING */) { - return; - } - var cachedHandlers = _this._handlers.slice(); - _this._handlers = []; - cachedHandlers.forEach(function (handler) { - if (handler[0]) { - return; - } - if (_this._state === 1 /* RESOLVED */) { - // eslint-disable-next-line @typescript-eslint/no-floating-promises - handler[1](_this._value); - } - if (_this._state === 2 /* REJECTED */) { - handler[2](_this._value); - } - handler[0] = true; - }); - }; - try { - executor(this._resolve, this._reject); - } - catch (e) { - this._reject(e); - } - } - /** JSDoc */ - SyncPromise.prototype.then = function (onfulfilled, onrejected) { - var _this = this; - return new SyncPromise(function (resolve, reject) { - _this._handlers.push([ - false, - function (result) { - if (!onfulfilled) { - // TODO: ¯\_(ツ)_/¯ - // TODO: FIXME - resolve(result); - } - else { - try { - resolve(onfulfilled(result)); - } - catch (e) { - reject(e); - } - } - }, - function (reason) { - if (!onrejected) { - reject(reason); - } - else { - try { - resolve(onrejected(reason)); - } - catch (e) { - reject(e); - } - } - }, - ]); - _this._executeHandlers(); - }); - }; - /** JSDoc */ - SyncPromise.prototype.catch = function (onrejected) { - return this.then(function (val) { return val; }, onrejected); - }; - /** JSDoc */ - SyncPromise.prototype.finally = function (onfinally) { - var _this = this; - return new SyncPromise(function (resolve, reject) { - var val; - var isRejected; - return _this.then(function (value) { - isRejected = false; - val = value; - if (onfinally) { - onfinally(); - } - }, function (reason) { - isRejected = true; - val = reason; - if (onfinally) { - onfinally(); - } - }).then(function () { - if (isRejected) { - reject(val); - return; - } - resolve(val); - }); - }); - }; - return SyncPromise; -}()); -exports.SyncPromise = SyncPromise; -//# sourceMappingURL=syncpromise.js.map + +// The function name will be lost when bundling but we need to be able to identify this listener later to maintain the +// node.js default exit behaviour +errorCallback.tag = 'sentry_tracingErrorCallback'; + +exports.registerErrorInstrumentation = registerErrorInstrumentation; +//# sourceMappingURL=errors.js.map + /***/ }), -/***/ 86800: -/***/ ((module, exports, __nccwpck_require__) => { +/***/ 44758: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/* module decorator */ module = __nccwpck_require__.nmd(module); Object.defineProperty(exports, "__esModule", ({ value: true })); -var global_1 = __nccwpck_require__(16734); -var node_1 = __nccwpck_require__(361); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const hub = __nccwpck_require__(18205); +const spanUtils = __nccwpck_require__(98313); +const errors = __nccwpck_require__(55448); +const idletransaction = __nccwpck_require__(46629); +const sampling = __nccwpck_require__(88210); +const transaction = __nccwpck_require__(7827); + +/** Returns all trace headers that are currently on the top scope. */ +// eslint-disable-next-line deprecation/deprecation +function traceHeaders() { + // eslint-disable-next-line deprecation/deprecation + const scope = this.getScope(); + // eslint-disable-next-line deprecation/deprecation + const span = scope.getSpan(); + + return span + ? { + 'sentry-trace': spanUtils.spanToTraceHeader(span), + } + : {}; +} + /** - * A TimestampSource implementation for environments that do not support the Performance Web API natively. + * Creates a new transaction and adds a sampling decision if it doesn't yet have one. + * + * The Hub.startTransaction method delegates to this method to do its work, passing the Hub instance in as `this`, as if + * it had been called on the hub directly. Exists as a separate function so that it can be injected into the class as an + * "extension method." + * + * @param this: The Hub starting the transaction + * @param transactionContext: Data used to configure the transaction + * @param CustomSamplingContext: Optional data to be provided to the `tracesSampler` function (if any) * - * Note that this TimestampSource does not use a monotonic clock. A call to `nowSeconds` may return a timestamp earlier - * than a previously returned value. We do not try to emulate a monotonic behavior in order to facilitate debugging. It - * is more obvious to explain "why does my span have negative duration" than "why my spans have zero duration". + * @returns The new transaction + * + * @see {@link Hub.startTransaction} */ -var dateTimestampSource = { - nowSeconds: function () { return Date.now() / 1000; }, -}; +function _startTransaction( + // eslint-disable-next-line deprecation/deprecation + + transactionContext, + customSamplingContext, +) { + // eslint-disable-next-line deprecation/deprecation + const client = this.getClient(); + const options = (client && client.getOptions()) || {}; + + const configInstrumenter = options.instrumenter || 'sentry'; + const transactionInstrumenter = transactionContext.instrumenter || 'sentry'; + + if (configInstrumenter !== transactionInstrumenter) { + debugBuild.DEBUG_BUILD && + utils.logger.error( + `A transaction was started with instrumenter=\`${transactionInstrumenter}\`, but the SDK is configured with the \`${configInstrumenter}\` instrumenter. +The transaction will not be sampled. Please use the ${configInstrumenter} instrumentation to start transactions.`, + ); + + // eslint-disable-next-line deprecation/deprecation + transactionContext.sampled = false; + } + + // eslint-disable-next-line deprecation/deprecation + let transaction$1 = new transaction.Transaction(transactionContext, this); + transaction$1 = sampling.sampleTransaction(transaction$1, options, { + name: transactionContext.name, + parentSampled: transactionContext.parentSampled, + transactionContext, + attributes: { + // eslint-disable-next-line deprecation/deprecation + ...transactionContext.data, + ...transactionContext.attributes, + }, + ...customSamplingContext, + }); + if (transaction$1.isRecording()) { + transaction$1.initSpanRecorder(options._experiments && (options._experiments.maxSpans )); + } + if (client && client.emit) { + client.emit('startTransaction', transaction$1); + } + return transaction$1; +} + /** - * Returns a wrapper around the native Performance API browser implementation, or undefined for browsers that do not - * support the API. - * - * Wrapping the native API works around differences in behavior from different browsers. + * Create new idle transaction. */ -function getBrowserPerformance() { - var performance = global_1.getGlobalObject().performance; - if (!performance || !performance.now) { - return undefined; - } - // Replace performance.timeOrigin with our own timeOrigin based on Date.now(). - // - // This is a partial workaround for browsers reporting performance.timeOrigin such that performance.timeOrigin + - // performance.now() gives a date arbitrarily in the past. - // - // Additionally, computing timeOrigin in this way fills the gap for browsers where performance.timeOrigin is - // undefined. - // - // The assumption that performance.timeOrigin + performance.now() ~= Date.now() is flawed, but we depend on it to - // interact with data coming out of performance entries. - // - // Note that despite recommendations against it in the spec, browsers implement the Performance API with a clock that - // might stop when the computer is asleep (and perhaps under other circumstances). Such behavior causes - // performance.timeOrigin + performance.now() to have an arbitrary skew over Date.now(). In laptop computers, we have - // observed skews that can be as long as days, weeks or months. - // - // See https://github.com/getsentry/sentry-javascript/issues/2590. - // - // BUG: despite our best intentions, this workaround has its limitations. It mostly addresses timings of pageload - // transactions, but ignores the skew built up over time that can aversely affect timestamps of navigation - // transactions of long-lived web pages. - var timeOrigin = Date.now() - performance.now(); - return { - now: function () { return performance.now(); }, - timeOrigin: timeOrigin, - }; -} -/** - * Returns the native Performance API implementation from Node.js. Returns undefined in old Node.js versions that don't - * implement the API. - */ -function getNodePerformance() { - try { - var perfHooks = node_1.dynamicRequire(module, 'perf_hooks'); - return perfHooks.performance; - } - catch (_) { - return undefined; - } +function startIdleTransaction( + // eslint-disable-next-line deprecation/deprecation + hub, + transactionContext, + idleTimeout, + finalTimeout, + onScope, + customSamplingContext, + heartbeatInterval, + delayAutoFinishUntilSignal = false, +) { + // eslint-disable-next-line deprecation/deprecation + const client = hub.getClient(); + const options = (client && client.getOptions()) || {}; + + // eslint-disable-next-line deprecation/deprecation + let transaction = new idletransaction.IdleTransaction( + transactionContext, + hub, + idleTimeout, + finalTimeout, + heartbeatInterval, + onScope, + delayAutoFinishUntilSignal, + ); + transaction = sampling.sampleTransaction(transaction, options, { + name: transactionContext.name, + parentSampled: transactionContext.parentSampled, + transactionContext, + attributes: { + // eslint-disable-next-line deprecation/deprecation + ...transactionContext.data, + ...transactionContext.attributes, + }, + ...customSamplingContext, + }); + if (transaction.isRecording()) { + transaction.initSpanRecorder(options._experiments && (options._experiments.maxSpans )); + } + if (client && client.emit) { + client.emit('startTransaction', transaction); + } + return transaction; } + /** - * The Performance API implementation for the current platform, if available. - */ -var platformPerformance = node_1.isNodeEnv() ? getNodePerformance() : getBrowserPerformance(); -var timestampSource = platformPerformance === undefined - ? dateTimestampSource - : { - nowSeconds: function () { return (platformPerformance.timeOrigin + platformPerformance.now()) / 1000; }, - }; -/** - * Returns a timestamp in seconds since the UNIX epoch using the Date API. - */ -exports.dateTimestampInSeconds = dateTimestampSource.nowSeconds.bind(dateTimestampSource); -/** - * Returns a timestamp in seconds since the UNIX epoch using either the Performance or Date APIs, depending on the - * availability of the Performance API. - * - * See `usingPerformanceAPI` to test whether the Performance API is used. - * - * BUG: Note that because of how browsers implement the Performance API, the clock might stop when the computer is - * asleep. This creates a skew between `dateTimestampInSeconds` and `timestampInSeconds`. The - * skew can grow to arbitrary amounts like days, weeks or months. - * See https://github.com/getsentry/sentry-javascript/issues/2590. - */ -exports.timestampInSeconds = timestampSource.nowSeconds.bind(timestampSource); -// Re-exported with an old name for backwards-compatibility. -exports.timestampWithMs = exports.timestampInSeconds; -/** - * A boolean that is true when timestampInSeconds uses the Performance API to produce monotonic timestamps. - */ -exports.usingPerformanceAPI = platformPerformance !== undefined; -/** - * The number of milliseconds since the UNIX epoch. This value is only usable in a browser, and only when the - * performance API is available. + * Adds tracing extensions to the global hub. */ -exports.browserPerformanceTimeOrigin = (function () { - // Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or - // performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin - // data as reliable if they are within a reasonable threshold of the current time. - var performance = global_1.getGlobalObject().performance; - if (!performance || !performance.now) { - exports._browserPerformanceTimeOriginMode = 'none'; - return undefined; - } - var threshold = 3600 * 1000; - var performanceNow = performance.now(); - var dateNow = Date.now(); - // if timeOrigin isn't available set delta to threshold so it isn't used - var timeOriginDelta = performance.timeOrigin - ? Math.abs(performance.timeOrigin + performanceNow - dateNow) - : threshold; - var timeOriginIsReliable = timeOriginDelta < threshold; - // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin - // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing. - // Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always - // a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the - // Date API. - // eslint-disable-next-line deprecation/deprecation - var navigationStart = performance.timing && performance.timing.navigationStart; - var hasNavigationStart = typeof navigationStart === 'number'; - // if navigationStart isn't available set delta to threshold so it isn't used - var navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold; - var navigationStartIsReliable = navigationStartDelta < threshold; - if (timeOriginIsReliable || navigationStartIsReliable) { - // Use the more reliable time origin - if (timeOriginDelta <= navigationStartDelta) { - exports._browserPerformanceTimeOriginMode = 'timeOrigin'; - return performance.timeOrigin; - } - else { - exports._browserPerformanceTimeOriginMode = 'navigationStart'; - return navigationStart; - } - } - // Either both timeOrigin and navigationStart are skewed or neither is available, fallback to Date. - exports._browserPerformanceTimeOriginMode = 'dateNow'; - return dateNow; -})(); -//# sourceMappingURL=time.js.map +function addTracingExtensions() { + const carrier = hub.getMainCarrier(); + if (!carrier.__SENTRY__) { + return; + } + carrier.__SENTRY__.extensions = carrier.__SENTRY__.extensions || {}; + if (!carrier.__SENTRY__.extensions.startTransaction) { + carrier.__SENTRY__.extensions.startTransaction = _startTransaction; + } + if (!carrier.__SENTRY__.extensions.traceHeaders) { + carrier.__SENTRY__.extensions.traceHeaders = traceHeaders; + } -/***/ }), + errors.registerErrorInstrumentation(); +} -/***/ 88711: -/***/ ((__unused_webpack_module, exports) => { +exports.addTracingExtensions = addTracingExtensions; +exports.startIdleTransaction = startIdleTransaction; +//# sourceMappingURL=hubextensions.js.map -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.TRACEPARENT_REGEXP = new RegExp('^[ \\t]*' + // whitespace - '([0-9a-f]{32})?' + // trace_id - '-?([0-9a-f]{16})?' + // span_id - '-?([01])?' + // sampled - '[ \\t]*$'); -/** - * Extract transaction context data from a `sentry-trace` header. - * - * @param traceparent Traceparent string - * - * @returns Object containing data from the header, or undefined if traceparent string is malformed - */ -function extractTraceparentData(traceparent) { - var matches = traceparent.match(exports.TRACEPARENT_REGEXP); - if (matches) { - var parentSampled = void 0; - if (matches[3] === '1') { - parentSampled = true; - } - else if (matches[3] === '0') { - parentSampled = false; - } - return { - traceId: matches[1], - parentSampled: parentSampled, - parentSpanId: matches[2], - }; - } - return undefined; -} -exports.extractTraceparentData = extractTraceparentData; -//# sourceMappingURL=tracing.js.map /***/ }), -/***/ 23693: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 46629: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; -/*! - * accepts - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const spanUtils = __nccwpck_require__(98313); +const span = __nccwpck_require__(36283); +const transaction = __nccwpck_require__(7827); +const TRACING_DEFAULTS = { + idleTimeout: 1000, + finalTimeout: 30000, + heartbeatInterval: 5000, +}; -/** - * Module dependencies. - * @private - */ +const FINISH_REASON_TAG = 'finishReason'; -var Negotiator = __nccwpck_require__(12662) -var mime = __nccwpck_require__(20332) +const IDLE_TRANSACTION_FINISH_REASONS = [ + 'heartbeatFailed', + 'idleTimeout', + 'documentHidden', + 'finalTimeout', + 'externalFinish', + 'cancelled', +]; /** - * Module exports. - * @public + * @inheritDoc */ +class IdleTransactionSpanRecorder extends span.SpanRecorder { + constructor( + _pushActivity, + _popActivity, + transactionSpanId, + maxlen, + ) { + super(maxlen);this._pushActivity = _pushActivity;this._popActivity = _popActivity;this.transactionSpanId = transactionSpanId; } -module.exports = Accepts + /** + * @inheritDoc + */ + add(span) { + // We should make sure we do not push and pop activities for + // the transaction that this span recorder belongs to. + if (span.spanContext().spanId !== this.transactionSpanId) { + // We patch span.end() to pop an activity after setting an endTimestamp. + // eslint-disable-next-line @typescript-eslint/unbound-method + const originalEnd = span.end; + span.end = (...rest) => { + this._popActivity(span.spanContext().spanId); + return originalEnd.apply(span, rest); + }; -/** - * Create a new Accepts object for the given req. - * - * @param {object} req - * @public - */ + // We should only push new activities if the span does not have an end timestamp. + if (spanUtils.spanToJSON(span).timestamp === undefined) { + this._pushActivity(span.spanContext().spanId); + } + } -function Accepts (req) { - if (!(this instanceof Accepts)) { - return new Accepts(req) + super.add(span); } - - this.headers = req.headers - this.negotiator = new Negotiator(req) } /** - * Check if the given `type(s)` is acceptable, returning - * the best match when true, otherwise `undefined`, in which - * case you should respond with 406 "Not Acceptable". - * - * The `type` value may be a single mime type string - * such as "application/json", the extension name - * such as "json" or an array `["json", "html", "text/plain"]`. When a list - * or array is given the _best_ match, if any is returned. - * - * Examples: - * - * // Accept: text/html - * this.types('html'); - * // => "html" - * - * // Accept: text/*, application/json - * this.types('html'); - * // => "html" - * this.types('text/html'); - * // => "text/html" - * this.types('json', 'text'); - * // => "json" - * this.types('application/json'); - * // => "application/json" - * - * // Accept: text/*, application/json - * this.types('image/png'); - * this.types('png'); - * // => undefined - * - * // Accept: text/*;q=.5, application/json - * this.types(['html', 'json']); - * this.types('html', 'json'); - * // => "json" - * - * @param {String|Array} types... - * @return {String|Array|Boolean} - * @public + * An IdleTransaction is a transaction that automatically finishes. It does this by tracking child spans as activities. + * You can have multiple IdleTransactions active, but if the `onScope` option is specified, the idle transaction will + * put itself on the scope on creation. */ +class IdleTransaction extends transaction.Transaction { + // Activities store a list of active spans -Accepts.prototype.type = -Accepts.prototype.types = function (types_) { - var types = types_ - - // support flattened arguments - if (types && !Array.isArray(types)) { - types = new Array(arguments.length) - for (var i = 0; i < types.length; i++) { - types[i] = arguments[i] - } - } + // Track state of activities in previous heartbeat - // no types, return all requested types - if (!types || types.length === 0) { - return this.negotiator.mediaTypes() - } + // Amount of times heartbeat has counted. Will cause transaction to finish after 3 beats. - // no accept header, return first given type - if (!this.headers.accept) { - return types[0] - } + // We should not use heartbeat if we finished a transaction - var mimes = types.map(extToMime) - var accepts = this.negotiator.mediaTypes(mimes.filter(validMime)) - var first = accepts[0] + // Idle timeout was canceled and we should finish the transaction with the last span end. - return first - ? types[mimes.indexOf(first)] - : false -} + /** + * Timer that tracks Transaction idleTimeout + */ -/** - * Return accepted encodings or best fit based on `encodings`. - * - * Given `Accept-Encoding: gzip, deflate` - * an array sorted by quality is returned: - * - * ['gzip', 'deflate'] - * - * @param {String|Array} encodings... - * @return {String|Array} - * @public - */ + /** + * @deprecated Transactions will be removed in v8. Use spans instead. + */ + constructor( + transactionContext, + // eslint-disable-next-line deprecation/deprecation + _idleHub, + /** + * The time to wait in ms until the idle transaction will be finished. This timer is started each time + * there are no active spans on this transaction. + */ + _idleTimeout = TRACING_DEFAULTS.idleTimeout, + /** + * The final value in ms that a transaction cannot exceed + */ + _finalTimeout = TRACING_DEFAULTS.finalTimeout, + _heartbeatInterval = TRACING_DEFAULTS.heartbeatInterval, + // Whether or not the transaction should put itself on the scope when it starts and pop itself off when it ends + _onScope = false, + /** + * When set to `true`, will disable the idle timeout (`_idleTimeout` option) and heartbeat mechanisms (`_heartbeatInterval` + * option) until the `sendAutoFinishSignal()` method is called. The final timeout mechanism (`_finalTimeout` option) + * will not be affected by this option, meaning the transaction will definitely be finished when the final timeout is + * reached, no matter what this option is configured to. + * + * Defaults to `false`. + */ + delayAutoFinishUntilSignal = false, + ) { + super(transactionContext, _idleHub);this._idleHub = _idleHub;this._idleTimeout = _idleTimeout;this._finalTimeout = _finalTimeout;this._heartbeatInterval = _heartbeatInterval;this._onScope = _onScope; + this.activities = {}; + this._heartbeatCounter = 0; + this._finished = false; + this._idleTimeoutCanceledPermanently = false; + this._beforeFinishCallbacks = []; + this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[4]; + this._autoFinishAllowed = !delayAutoFinishUntilSignal; -Accepts.prototype.encoding = -Accepts.prototype.encodings = function (encodings_) { - var encodings = encodings_ + if (_onScope) { + // We set the transaction here on the scope so error events pick up the trace + // context and attach it to the error. + debugBuild.DEBUG_BUILD && utils.logger.log(`Setting idle transaction on scope. Span ID: ${this.spanContext().spanId}`); + // eslint-disable-next-line deprecation/deprecation + _idleHub.getScope().setSpan(this); + } - // support flattened arguments - if (encodings && !Array.isArray(encodings)) { - encodings = new Array(arguments.length) - for (var i = 0; i < encodings.length; i++) { - encodings[i] = arguments[i] + if (!delayAutoFinishUntilSignal) { + this._restartIdleTimeout(); } - } - // no encodings, return all requested encodings - if (!encodings || encodings.length === 0) { - return this.negotiator.encodings() + setTimeout(() => { + if (!this._finished) { + this.setStatus('deadline_exceeded'); + this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[3]; + this.end(); + } + }, this._finalTimeout); } - return this.negotiator.encodings(encodings)[0] || false -} - -/** - * Return accepted charsets or best fit based on `charsets`. - * - * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5` - * an array sorted by quality is returned: - * - * ['utf-8', 'utf-7', 'iso-8859-1'] - * - * @param {String|Array} charsets... - * @return {String|Array} - * @public - */ + /** {@inheritDoc} */ + end(endTimestamp) { + const endTimestampInS = spanUtils.spanTimeInputToSeconds(endTimestamp); -Accepts.prototype.charset = -Accepts.prototype.charsets = function (charsets_) { - var charsets = charsets_ + this._finished = true; + this.activities = {}; - // support flattened arguments - if (charsets && !Array.isArray(charsets)) { - charsets = new Array(arguments.length) - for (var i = 0; i < charsets.length; i++) { - charsets[i] = arguments[i] + // eslint-disable-next-line deprecation/deprecation + if (this.op === 'ui.action.click') { + this.setAttribute(FINISH_REASON_TAG, this._finishReason); } - } - - // no charsets, return all requested charsets - if (!charsets || charsets.length === 0) { - return this.negotiator.charsets() - } - - return this.negotiator.charsets(charsets)[0] || false -} - -/** - * Return accepted languages or best fit based on `langs`. - * - * Given `Accept-Language: en;q=0.8, es, pt` - * an array sorted by quality is returned: - * - * ['es', 'pt', 'en'] - * - * @param {String|Array} langs... - * @return {Array|String} - * @public - */ -Accepts.prototype.lang = -Accepts.prototype.langs = -Accepts.prototype.language = -Accepts.prototype.languages = function (languages_) { - var languages = languages_ + // eslint-disable-next-line deprecation/deprecation + if (this.spanRecorder) { + debugBuild.DEBUG_BUILD && + // eslint-disable-next-line deprecation/deprecation + utils.logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestampInS * 1000).toISOString(), this.op); - // support flattened arguments - if (languages && !Array.isArray(languages)) { - languages = new Array(arguments.length) - for (var i = 0; i < languages.length; i++) { - languages[i] = arguments[i] - } - } + for (const callback of this._beforeFinishCallbacks) { + callback(this, endTimestampInS); + } - // no languages, return all requested languages - if (!languages || languages.length === 0) { - return this.negotiator.languages() - } + // eslint-disable-next-line deprecation/deprecation + this.spanRecorder.spans = this.spanRecorder.spans.filter((span) => { + // If we are dealing with the transaction itself, we just return it + if (span.spanContext().spanId === this.spanContext().spanId) { + return true; + } - return this.negotiator.languages(languages)[0] || false -} + // We cancel all pending spans with status "cancelled" to indicate the idle transaction was finished early + if (!spanUtils.spanToJSON(span).timestamp) { + span.setStatus('cancelled'); + span.end(endTimestampInS); + debugBuild.DEBUG_BUILD && + utils.logger.log('[Tracing] cancelling span since transaction ended early', JSON.stringify(span, undefined, 2)); + } -/** - * Convert extnames to mime. - * - * @param {String} type - * @return {String} - * @private - */ + const { start_timestamp: startTime, timestamp: endTime } = spanUtils.spanToJSON(span); + const spanStartedBeforeTransactionFinish = startTime && startTime < endTimestampInS; -function extToMime (type) { - return type.indexOf('/') === -1 - ? mime.lookup(type) - : type -} + // Add a delta with idle timeout so that we prevent false positives + const timeoutWithMarginOfError = (this._finalTimeout + this._idleTimeout) / 1000; + const spanEndedBeforeFinalTimeout = endTime && startTime && endTime - startTime < timeoutWithMarginOfError; -/** - * Check if mime is valid. - * - * @param {String} type - * @return {String} - * @private - */ + if (debugBuild.DEBUG_BUILD) { + const stringifiedSpan = JSON.stringify(span, undefined, 2); + if (!spanStartedBeforeTransactionFinish) { + utils.logger.log('[Tracing] discarding Span since it happened after Transaction was finished', stringifiedSpan); + } else if (!spanEndedBeforeFinalTimeout) { + utils.logger.log('[Tracing] discarding Span since it finished after Transaction final timeout', stringifiedSpan); + } + } -function validMime (type) { - return typeof type === 'string' -} + return spanStartedBeforeTransactionFinish && spanEndedBeforeFinalTimeout; + }); + debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] flushing IdleTransaction'); + } else { + debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] No active IdleTransaction'); + } -/***/ }), + // if `this._onScope` is `true`, the transaction put itself on the scope when it started + if (this._onScope) { + // eslint-disable-next-line deprecation/deprecation + const scope = this._idleHub.getScope(); + // eslint-disable-next-line deprecation/deprecation + if (scope.getTransaction() === this) { + // eslint-disable-next-line deprecation/deprecation + scope.setSpan(undefined); + } + } -/***/ 10803: -/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) { + return super.end(endTimestamp); + } -"use strict"; + /** + * Register a callback function that gets executed before the transaction finishes. + * Useful for cleanup or if you want to add any additional spans based on current context. + * + * This is exposed because users have no other way of running something before an idle transaction + * finishes. + */ + registerBeforeFinishCallback(callback) { + this._beforeFinishCallbacks.push(callback); + } -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -const events_1 = __nccwpck_require__(24434); -const debug_1 = __importDefault(__nccwpck_require__(78382)); -const promisify_1 = __importDefault(__nccwpck_require__(54903)); -const debug = debug_1.default('agent-base'); -function isAgent(v) { - return Boolean(v) && typeof v.addRequest === 'function'; -} -function isSecureEndpoint() { - const { stack } = new Error(); - if (typeof stack !== 'string') - return false; - return stack.split('\n').some(l => l.indexOf('(https.js:') !== -1 || l.indexOf('node:https:') !== -1); -} -function createAgent(callback, opts) { - return new createAgent.Agent(callback, opts); -} -(function (createAgent) { - /** - * Base `http.Agent` implementation. - * No pooling/keep-alive is implemented by default. - * - * @param {Function} callback - * @api public - */ - class Agent extends events_1.EventEmitter { - constructor(callback, _opts) { - super(); - let opts = _opts; - if (typeof callback === 'function') { - this.callback = callback; - } - else if (callback) { - opts = callback; - } - // Timeout for the socket to be returned from the callback - this.timeout = null; - if (opts && typeof opts.timeout === 'number') { - this.timeout = opts.timeout; - } - // These aren't actually used by `agent-base`, but are required - // for the TypeScript definition files in `@types/node` :/ - this.maxFreeSockets = 1; - this.maxSockets = 1; - this.maxTotalSockets = Infinity; - this.sockets = {}; - this.freeSockets = {}; - this.requests = {}; - this.options = {}; - } - get defaultPort() { - if (typeof this.explicitDefaultPort === 'number') { - return this.explicitDefaultPort; - } - return isSecureEndpoint() ? 443 : 80; - } - set defaultPort(v) { - this.explicitDefaultPort = v; - } - get protocol() { - if (typeof this.explicitProtocol === 'string') { - return this.explicitProtocol; - } - return isSecureEndpoint() ? 'https:' : 'http:'; - } - set protocol(v) { - this.explicitProtocol = v; - } - callback(req, opts, fn) { - throw new Error('"agent-base" has no default implementation, you must subclass and override `callback()`'); - } - /** - * Called by node-core's "_http_client.js" module when creating - * a new HTTP request with this Agent instance. - * - * @api public - */ - addRequest(req, _opts) { - const opts = Object.assign({}, _opts); - if (typeof opts.secureEndpoint !== 'boolean') { - opts.secureEndpoint = isSecureEndpoint(); - } - if (opts.host == null) { - opts.host = 'localhost'; - } - if (opts.port == null) { - opts.port = opts.secureEndpoint ? 443 : 80; - } - if (opts.protocol == null) { - opts.protocol = opts.secureEndpoint ? 'https:' : 'http:'; - } - if (opts.host && opts.path) { - // If both a `host` and `path` are specified then it's most - // likely the result of a `url.parse()` call... we need to - // remove the `path` portion so that `net.connect()` doesn't - // attempt to open that as a unix socket file. - delete opts.path; - } - delete opts.agent; - delete opts.hostname; - delete opts._defaultAgent; - delete opts.defaultPort; - delete opts.createConnection; - // Hint to use "Connection: close" - // XXX: non-documented `http` module API :( - req._last = true; - req.shouldKeepAlive = false; - let timedOut = false; - let timeoutId = null; - const timeoutMs = opts.timeout || this.timeout; - const onerror = (err) => { - if (req._hadError) - return; - req.emit('error', err); - // For Safety. Some additional errors might fire later on - // and we need to make sure we don't double-fire the error event. - req._hadError = true; - }; - const ontimeout = () => { - timeoutId = null; - timedOut = true; - const err = new Error(`A "socket" was not created for HTTP request before ${timeoutMs}ms`); - err.code = 'ETIMEOUT'; - onerror(err); - }; - const callbackError = (err) => { - if (timedOut) - return; - if (timeoutId !== null) { - clearTimeout(timeoutId); - timeoutId = null; - } - onerror(err); - }; - const onsocket = (socket) => { - if (timedOut) - return; - if (timeoutId != null) { - clearTimeout(timeoutId); - timeoutId = null; - } - if (isAgent(socket)) { - // `socket` is actually an `http.Agent` instance, so - // relinquish responsibility for this `req` to the Agent - // from here on - debug('Callback returned another Agent instance %o', socket.constructor.name); - socket.addRequest(req, opts); - return; - } - if (socket) { - socket.once('free', () => { - this.freeSocket(socket, opts); - }); - req.onSocket(socket); - return; - } - const err = new Error(`no Duplex stream was returned to agent-base for \`${req.method} ${req.path}\``); - onerror(err); - }; - if (typeof this.callback !== 'function') { - onerror(new Error('`callback` is not defined')); - return; - } - if (!this.promisifiedCallback) { - if (this.callback.length >= 3) { - debug('Converting legacy callback function to promise'); - this.promisifiedCallback = promisify_1.default(this.callback); - } - else { - this.promisifiedCallback = this.callback; - } - } - if (typeof timeoutMs === 'number' && timeoutMs > 0) { - timeoutId = setTimeout(ontimeout, timeoutMs); - } - if ('port' in opts && typeof opts.port !== 'number') { - opts.port = Number(opts.port); - } - try { - debug('Resolving socket for %o request: %o', opts.protocol, `${req.method} ${req.path}`); - Promise.resolve(this.promisifiedCallback(req, opts)).then(onsocket, callbackError); - } - catch (err) { - Promise.reject(err).catch(callbackError); - } - } - freeSocket(socket, opts) { - debug('Freeing socket %o %o', socket.constructor.name, opts); - socket.destroy(); + /** + * @inheritDoc + */ + initSpanRecorder(maxlen) { + // eslint-disable-next-line deprecation/deprecation + if (!this.spanRecorder) { + const pushActivity = (id) => { + if (this._finished) { + return; } - destroy() { - debug('Destroying agent %o', this.constructor.name); + this._pushActivity(id); + }; + const popActivity = (id) => { + if (this._finished) { + return; } - } - createAgent.Agent = Agent; - // So that `instanceof` works correctly - createAgent.prototype = createAgent.Agent.prototype; -})(createAgent || (createAgent = {})); -module.exports = createAgent; -//# sourceMappingURL=index.js.map + this._popActivity(id); + }; -/***/ }), + // eslint-disable-next-line deprecation/deprecation + this.spanRecorder = new IdleTransactionSpanRecorder(pushActivity, popActivity, this.spanContext().spanId, maxlen); -/***/ 54903: -/***/ ((__unused_webpack_module, exports) => { + // Start heartbeat so that transactions do not run forever. + debugBuild.DEBUG_BUILD && utils.logger.log('Starting heartbeat'); + this._pingHeartbeat(); + } + // eslint-disable-next-line deprecation/deprecation + this.spanRecorder.add(this); + } -"use strict"; + /** + * Cancels the existing idle timeout, if there is one. + * @param restartOnChildSpanChange Default is `true`. + * If set to false the transaction will end + * with the last child span. + */ + cancelIdleTimeout( + endTimestamp, + { + restartOnChildSpanChange, + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -function promisify(fn) { - return function (req, opts) { - return new Promise((resolve, reject) => { - fn.call(this, req, opts, (err, rtn) => { - if (err) { - reject(err); - } - else { - resolve(rtn); - } - }); - }); - }; -} -exports["default"] = promisify; -//# sourceMappingURL=promisify.js.map + = { + restartOnChildSpanChange: true, + }, + ) { + this._idleTimeoutCanceledPermanently = restartOnChildSpanChange === false; + if (this._idleTimeoutID) { + clearTimeout(this._idleTimeoutID); + this._idleTimeoutID = undefined; -/***/ }), + if (Object.keys(this.activities).length === 0 && this._idleTimeoutCanceledPermanently) { + this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5]; + this.end(endTimestamp); + } + } + } -/***/ 59683: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Temporary method used to externally set the transaction's `finishReason` + * + * ** WARNING** + * This is for the purpose of experimentation only and will be removed in the near future, do not use! + * + * @internal + * + */ + setFinishReason(reason) { + this._finishReason = reason; + } -"use strict"; + /** + * Permits the IdleTransaction to automatically end itself via the idle timeout and heartbeat mechanisms when the `delayAutoFinishUntilSignal` option was set to `true`. + */ + sendAutoFinishSignal() { + if (!this._autoFinishAllowed) { + debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] Received finish signal for idle transaction.'); + this._restartIdleTimeout(); + this._autoFinishAllowed = true; + } + } -const indentString = __nccwpck_require__(40865); -const cleanStack = __nccwpck_require__(71649); + /** + * Restarts idle timeout, if there is no running idle timeout it will start one. + */ + _restartIdleTimeout(endTimestamp) { + this.cancelIdleTimeout(); + this._idleTimeoutID = setTimeout(() => { + if (!this._finished && Object.keys(this.activities).length === 0) { + this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[1]; + this.end(endTimestamp); + } + }, this._idleTimeout); + } -const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); + /** + * Start tracking a specific activity. + * @param spanId The span id that represents the activity + */ + _pushActivity(spanId) { + this.cancelIdleTimeout(undefined, { restartOnChildSpanChange: !this._idleTimeoutCanceledPermanently }); + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] pushActivity: ${spanId}`); + this.activities[spanId] = true; + debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] new activities count', Object.keys(this.activities).length); + } -class AggregateError extends Error { - constructor(errors) { - if (!Array.isArray(errors)) { - throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); - } + /** + * Remove an activity from usage + * @param spanId The span id that represents the activity + */ + _popActivity(spanId) { + if (this.activities[spanId]) { + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] popActivity ${spanId}`); + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete this.activities[spanId]; + debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] new activities count', Object.keys(this.activities).length); + } - errors = [...errors].map(error => { - if (error instanceof Error) { - return error; - } + if (Object.keys(this.activities).length === 0) { + const endTimestamp = utils.timestampInSeconds(); + if (this._idleTimeoutCanceledPermanently) { + if (this._autoFinishAllowed) { + this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5]; + this.end(endTimestamp); + } + } else { + // We need to add the timeout here to have the real endtimestamp of the transaction + // Remember timestampInSeconds is in seconds, timeout is in ms + this._restartIdleTimeout(endTimestamp + this._idleTimeout / 1000); + } + } + } - if (error !== null && typeof error === 'object') { - // Handle plain error objects with message property and/or possibly other metadata - return Object.assign(new Error(error.message), error); - } + /** + * Checks when entries of this.activities are not changing for 3 beats. + * If this occurs we finish the transaction. + */ + _beat() { + // We should not be running heartbeat if the idle transaction is finished. + if (this._finished) { + return; + } - return new Error(error); - }); + const heartbeatString = Object.keys(this.activities).join(''); - let message = errors - .map(error => { - // The `stack` property is not standardized, so we can't assume it exists - return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error); - }) - .join('\n'); - message = '\n' + indentString(message, 4); - super(message); + if (heartbeatString === this._prevHeartbeatString) { + this._heartbeatCounter++; + } else { + this._heartbeatCounter = 1; + } - this.name = 'AggregateError'; + this._prevHeartbeatString = heartbeatString; - Object.defineProperty(this, '_errors', {value: errors}); - } + if (this._heartbeatCounter >= 3) { + if (this._autoFinishAllowed) { + debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] Transaction finished because of no change for 3 heart beats'); + this.setStatus('deadline_exceeded'); + this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[0]; + this.end(); + } + } else { + this._pingHeartbeat(); + } + } - * [Symbol.iterator]() { - for (const error of this._errors) { - yield error; - } - } + /** + * Pings the heartbeat + */ + _pingHeartbeat() { + debugBuild.DEBUG_BUILD && utils.logger.log(`pinging Heartbeat -> current counter: ${this._heartbeatCounter}`); + setTimeout(() => { + this._beat(); + }, this._heartbeatInterval); + } } -module.exports = AggregateError; +exports.IdleTransaction = IdleTransaction; +exports.IdleTransactionSpanRecorder = IdleTransactionSpanRecorder; +exports.TRACING_DEFAULTS = TRACING_DEFAULTS; +//# sourceMappingURL=idletransaction.js.map /***/ }), -/***/ 35698: -/***/ ((module) => { +/***/ 64599: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +const utils = __nccwpck_require__(49194); /** - * Expose `arrayFlatten`. + * Adds a measurement to the current active transaction. */ -module.exports = arrayFlatten - +function setMeasurement(name, value, unit) { + // eslint-disable-next-line deprecation/deprecation + const transaction = utils.getActiveTransaction(); + if (transaction) { + // eslint-disable-next-line deprecation/deprecation + transaction.setMeasurement(name, value, unit); + } +} + +exports.setMeasurement = setMeasurement; +//# sourceMappingURL=measurement.js.map + + +/***/ }), + +/***/ 88210: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const semanticAttributes = __nccwpck_require__(44513); +const hasTracingEnabled = __nccwpck_require__(7747); +const spanUtils = __nccwpck_require__(98313); + /** - * Recursive flatten function with depth. + * Makes a sampling decision for the given transaction and stores it on the transaction. * - * @param {Array} array - * @param {Array} result - * @param {Number} depth - * @return {Array} + * Called every time a transaction is created. Only transactions which emerge with a `sampled` value of `true` will be + * sent to Sentry. + * + * This method muttes the given `transaction` and will set the `sampled` value on it. + * It returns the same transaction, for convenience. */ -function flattenWithDepth (array, result, depth) { - for (var i = 0; i < array.length; i++) { - var value = array[i] +function sampleTransaction( + transaction, + options, + samplingContext, +) { + // nothing to do if tracing is not enabled + if (!hasTracingEnabled.hasTracingEnabled(options)) { + // eslint-disable-next-line deprecation/deprecation + transaction.sampled = false; + return transaction; + } - if (depth > 0 && Array.isArray(value)) { - flattenWithDepth(value, result, depth - 1) - } else { - result.push(value) - } + // if the user has forced a sampling decision by passing a `sampled` value in their transaction context, go with that + // eslint-disable-next-line deprecation/deprecation + if (transaction.sampled !== undefined) { + // eslint-disable-next-line deprecation/deprecation + transaction.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, Number(transaction.sampled)); + return transaction; + } + + // we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should + // work; prefer the hook if so + let sampleRate; + if (typeof options.tracesSampler === 'function') { + sampleRate = options.tracesSampler(samplingContext); + transaction.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, Number(sampleRate)); + } else if (samplingContext.parentSampled !== undefined) { + sampleRate = samplingContext.parentSampled; + } else if (typeof options.tracesSampleRate !== 'undefined') { + sampleRate = options.tracesSampleRate; + transaction.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, Number(sampleRate)); + } else { + // When `enableTracing === true`, we use a sample rate of 100% + sampleRate = 1; + transaction.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, sampleRate); } - return result + // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The + // only valid values are booleans or numbers between 0 and 1.) + if (!isValidSampleRate(sampleRate)) { + debugBuild.DEBUG_BUILD && utils.logger.warn('[Tracing] Discarding transaction because of invalid sample rate.'); + // eslint-disable-next-line deprecation/deprecation + transaction.sampled = false; + return transaction; + } + + // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped + if (!sampleRate) { + debugBuild.DEBUG_BUILD && + utils.logger.log( + `[Tracing] Discarding transaction because ${ + typeof options.tracesSampler === 'function' + ? 'tracesSampler returned 0 or false' + : 'a negative sampling decision was inherited or tracesSampleRate is set to 0' + }`, + ); + // eslint-disable-next-line deprecation/deprecation + transaction.sampled = false; + return transaction; + } + + // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is + // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false. + // eslint-disable-next-line deprecation/deprecation + transaction.sampled = Math.random() < (sampleRate ); + + // if we're not going to keep it, we're done + // eslint-disable-next-line deprecation/deprecation + if (!transaction.sampled) { + debugBuild.DEBUG_BUILD && + utils.logger.log( + `[Tracing] Discarding transaction because it's not included in the random sample (sampling rate = ${Number( + sampleRate, + )})`, + ); + return transaction; + } + + debugBuild.DEBUG_BUILD && + // eslint-disable-next-line deprecation/deprecation + utils.logger.log(`[Tracing] starting ${transaction.op} transaction - ${spanUtils.spanToJSON(transaction).description}`); + return transaction; } /** - * Recursive flatten function. Omitting depth is slightly faster. - * - * @param {Array} array - * @param {Array} result - * @return {Array} + * Checks the given sample rate to make sure it is valid type and value (a boolean, or a number between 0 and 1). */ -function flattenForever (array, result) { - for (var i = 0; i < array.length; i++) { - var value = array[i] - - if (Array.isArray(value)) { - flattenForever(value, result) - } else { - result.push(value) - } +function isValidSampleRate(rate) { + // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (utils.isNaN(rate) || !(typeof rate === 'number' || typeof rate === 'boolean')) { + debugBuild.DEBUG_BUILD && + utils.logger.warn( + `[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify( + rate, + )} of type ${JSON.stringify(typeof rate)}.`, + ); + return false; } - return result + // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false + if (rate < 0 || rate > 1) { + debugBuild.DEBUG_BUILD && + utils.logger.warn(`[Tracing] Given sample rate is invalid. Sample rate must be between 0 and 1. Got ${rate}.`); + return false; + } + return true; } +exports.isValidSampleRate = isValidSampleRate; +exports.sampleTransaction = sampleTransaction; +//# sourceMappingURL=sampling.js.map + + +/***/ }), + +/***/ 36283: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const metricSummary = __nccwpck_require__(61479); +const semanticAttributes = __nccwpck_require__(44513); +const getRootSpan = __nccwpck_require__(27304); +const spanUtils = __nccwpck_require__(98313); +const spanstatus = __nccwpck_require__(14769); + /** - * Flatten an array, with the ability to define a depth. - * - * @param {Array} array - * @param {Number} depth - * @return {Array} + * Keeps track of finished spans for a given transaction + * @internal + * @hideconstructor + * @hidden */ -function arrayFlatten (array, depth) { - if (depth == null) { - return flattenForever(array, []) +class SpanRecorder { + + constructor(maxlen = 1000) { + this._maxlen = maxlen; + this.spans = []; } - return flattenWithDepth(array, [], depth) + /** + * This is just so that we don't run out of memory while recording a lot + * of spans. At some point we just stop and flush out the start of the + * trace tree (i.e.the first n spans with the smallest + * start_timestamp). + */ + add(span) { + if (this.spans.length > this._maxlen) { + // eslint-disable-next-line deprecation/deprecation + span.spanRecorder = undefined; + } else { + this.spans.push(span); + } + } } +/** + * Span contains all data about a span + */ +class Span { + /** + * Tags for the span. + * @deprecated Use `spanToJSON(span).atttributes` instead. + */ -/***/ }), + /** + * Data for the span. + * @deprecated Use `spanToJSON(span).atttributes` instead. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any -/***/ 25826: -/***/ ((module) => { + /** + * List of spans that were finalized + * + * @deprecated This property will no longer be public. Span recording will be handled internally. + */ -"use strict"; + /** + * @inheritDoc + * @deprecated Use top level `Sentry.getRootSpan()` instead + */ + /** + * The instrumenter that created this span. + * + * TODO (v8): This can probably be replaced by an `instanceOf` check of the span class. + * the instrumenter can only be sentry or otel so we can check the span instance + * to verify which one it is and remove this field entirely. + * + * @deprecated This field will be removed. + */ -/* global SharedArrayBuffer, Atomics */ + /** Epoch timestamp in seconds when the span started. */ -if (typeof SharedArrayBuffer !== 'undefined' && typeof Atomics !== 'undefined') { - const nil = new Int32Array(new SharedArrayBuffer(4)) + /** Epoch timestamp in seconds when the span ended. */ - function sleep (ms) { - // also filters out NaN, non-number types, including empty strings, but allows bigints - const valid = ms > 0 && ms < Infinity - if (valid === false) { - if (typeof ms !== 'number' && typeof ms !== 'bigint') { - throw TypeError('sleep: ms must be a number') - } - throw RangeError('sleep: ms must be a number that is greater than 0 but less than Infinity') + /** Internal keeper of the status */ + + /** + * You should never call the constructor manually, always use `Sentry.startTransaction()` + * or call `startChild()` on an existing span. + * @internal + * @hideconstructor + * @hidden + */ + constructor(spanContext = {}) { + this._traceId = spanContext.traceId || utils.uuid4(); + this._spanId = spanContext.spanId || utils.uuid4().substring(16); + this._startTime = spanContext.startTimestamp || utils.timestampInSeconds(); + // eslint-disable-next-line deprecation/deprecation + this.tags = spanContext.tags ? { ...spanContext.tags } : {}; + // eslint-disable-next-line deprecation/deprecation + this.data = spanContext.data ? { ...spanContext.data } : {}; + // eslint-disable-next-line deprecation/deprecation + this.instrumenter = spanContext.instrumenter || 'sentry'; + + this._attributes = {}; + this.setAttributes({ + [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanContext.origin || 'manual', + [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP]: spanContext.op, + ...spanContext.attributes, + }); + + // eslint-disable-next-line deprecation/deprecation + this._name = spanContext.name || spanContext.description; + + if (spanContext.parentSpanId) { + this._parentSpanId = spanContext.parentSpanId; + } + // We want to include booleans as well here + if ('sampled' in spanContext) { + this._sampled = spanContext.sampled; + } + if (spanContext.status) { + this._status = spanContext.status; } + if (spanContext.endTimestamp) { + this._endTime = spanContext.endTimestamp; + } + if (spanContext.exclusiveTime !== undefined) { + this._exclusiveTime = spanContext.exclusiveTime; + } + this._measurements = spanContext.measurements ? { ...spanContext.measurements } : {}; + } - Atomics.wait(nil, 0, 0, Number(ms)) + // This rule conflicts with another eslint rule :( + /* eslint-disable @typescript-eslint/member-ordering */ + + /** + * An alias for `description` of the Span. + * @deprecated Use `spanToJSON(span).description` instead. + */ + get name() { + return this._name || ''; } - module.exports = sleep -} else { - function sleep (ms) { - // also filters out NaN, non-number types, including empty strings, but allows bigints - const valid = ms > 0 && ms < Infinity - if (valid === false) { - if (typeof ms !== 'number' && typeof ms !== 'bigint') { - throw TypeError('sleep: ms must be a number') - } - throw RangeError('sleep: ms must be a number that is greater than 0 but less than Infinity') - } - const target = Date.now() + Number(ms) - while (target > Date.now()){} + /** + * Update the name of the span. + * @deprecated Use `spanToJSON(span).description` instead. + */ + set name(name) { + this.updateName(name); } - module.exports = sleep + /** + * Get the description of the Span. + * @deprecated Use `spanToJSON(span).description` instead. + */ + get description() { + return this._name; + } -} + /** + * Get the description of the Span. + * @deprecated Use `spanToJSON(span).description` instead. + */ + set description(description) { + this._name = description; + } + /** + * The ID of the trace. + * @deprecated Use `spanContext().traceId` instead. + */ + get traceId() { + return this._traceId; + } -/***/ }), + /** + * The ID of the trace. + * @deprecated You cannot update the traceId of a span after span creation. + */ + set traceId(traceId) { + this._traceId = traceId; + } -/***/ 29922: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * The ID of the span. + * @deprecated Use `spanContext().spanId` instead. + */ + get spanId() { + return this._spanId; + } -var register = __nccwpck_require__(70773); -var addHook = __nccwpck_require__(97477); -var removeHook = __nccwpck_require__(8944); + /** + * The ID of the span. + * @deprecated You cannot update the spanId of a span after span creation. + */ + set spanId(spanId) { + this._spanId = spanId; + } -// bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind; -var bindable = bind.bind(bind); + /** + * @inheritDoc + * + * @deprecated Use `startSpan` functions instead. + */ + set parentSpanId(string) { + this._parentSpanId = string; + } -function bindApi(hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply( - null, - name ? [state, name] : [state] - ); - hook.api = { remove: removeHookRef }; - hook.remove = removeHookRef; - ["before", "error", "after", "wrap"].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind]; - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args); - }); -} + /** + * @inheritDoc + * + * @deprecated Use `spanToJSON(span).parent_span_id` instead. + */ + get parentSpanId() { + return this._parentSpanId; + } -function HookSingular() { - var singularHookName = "h"; - var singularHookState = { - registry: {}, - }; - var singularHook = register.bind(null, singularHookState, singularHookName); - bindApi(singularHook, singularHookState, singularHookName); - return singularHook; -} + /** + * Was this span chosen to be sent as part of the sample? + * @deprecated Use `isRecording()` instead. + */ + get sampled() { + return this._sampled; + } -function HookCollection() { - var state = { - registry: {}, - }; + /** + * Was this span chosen to be sent as part of the sample? + * @deprecated You cannot update the sampling decision of a span after span creation. + */ + set sampled(sampled) { + this._sampled = sampled; + } - var hook = register.bind(null, state); - bindApi(hook, state); + /** + * Attributes for the span. + * @deprecated Use `spanToJSON(span).atttributes` instead. + */ + get attributes() { + return this._attributes; + } - return hook; -} + /** + * Attributes for the span. + * @deprecated Use `setAttributes()` instead. + */ + set attributes(attributes) { + this._attributes = attributes; + } -var collectionHookDeprecationMessageDisplayed = false; -function Hook() { - if (!collectionHookDeprecationMessageDisplayed) { - console.warn( - '[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4' - ); - collectionHookDeprecationMessageDisplayed = true; + /** + * Timestamp in seconds (epoch time) indicating when the span started. + * @deprecated Use `spanToJSON()` instead. + */ + get startTimestamp() { + return this._startTime; } - return HookCollection(); -} -Hook.Singular = HookSingular.bind(); -Hook.Collection = HookCollection.bind(); + /** + * Timestamp in seconds (epoch time) indicating when the span started. + * @deprecated In v8, you will not be able to update the span start time after creation. + */ + set startTimestamp(startTime) { + this._startTime = startTime; + } -module.exports = Hook; -// expose constructors as a named property for TypeScript -module.exports.Hook = Hook; -module.exports.Singular = Hook.Singular; -module.exports.Collection = Hook.Collection; + /** + * Timestamp in seconds when the span ended. + * @deprecated Use `spanToJSON()` instead. + */ + get endTimestamp() { + return this._endTime; + } + + /** + * Timestamp in seconds when the span ended. + * @deprecated Set the end time via `span.end()` instead. + */ + set endTimestamp(endTime) { + this._endTime = endTime; + } + /** + * The status of the span. + * + * @deprecated Use `spanToJSON().status` instead to get the status. + */ + get status() { + return this._status; + } -/***/ }), + /** + * The status of the span. + * + * @deprecated Use `.setStatus()` instead to set or update the status. + */ + set status(status) { + this._status = status; + } -/***/ 97477: -/***/ ((module) => { + /** + * Operation of the span + * + * @deprecated Use `spanToJSON().op` to read the op instead. + */ + get op() { + return this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP] ; + } -module.exports = addHook; + /** + * Operation of the span + * + * @deprecated Use `startSpan()` functions to set or `span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'op') + * to update the span instead. + */ + set op(op) { + this.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP, op); + } -function addHook(state, kind, name, hook) { - var orig = hook; - if (!state.registry[name]) { - state.registry[name] = []; + /** + * The origin of the span, giving context about what created the span. + * + * @deprecated Use `spanToJSON().origin` to read the origin instead. + */ + get origin() { + return this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] ; } - if (kind === "before") { - hook = function (method, options) { - return Promise.resolve() - .then(orig.bind(null, options)) - .then(method.bind(null, options)); - }; + /** + * The origin of the span, giving context about what created the span. + * + * @deprecated Use `startSpan()` functions to set the origin instead. + */ + set origin(origin) { + this.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, origin); } - if (kind === "after") { - hook = function (method, options) { - var result; - return Promise.resolve() - .then(method.bind(null, options)) - .then(function (result_) { - result = result_; - return orig(result, options); - }) - .then(function () { - return result; - }); + /* eslint-enable @typescript-eslint/member-ordering */ + + /** @inheritdoc */ + spanContext() { + const { _spanId: spanId, _traceId: traceId, _sampled: sampled } = this; + return { + spanId, + traceId, + traceFlags: sampled ? spanUtils.TRACE_FLAG_SAMPLED : spanUtils.TRACE_FLAG_NONE, }; } - if (kind === "error") { - hook = function (method, options) { - return Promise.resolve() - .then(method.bind(null, options)) - .catch(function (error) { - return orig(error, options); - }); - }; + /** + * Creates a new `Span` while setting the current `Span.id` as `parentSpanId`. + * Also the `sampled` decision will be inherited. + * + * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead. + */ + startChild( + spanContext, + ) { + const childSpan = new Span({ + ...spanContext, + parentSpanId: this._spanId, + sampled: this._sampled, + traceId: this._traceId, + }); + + // eslint-disable-next-line deprecation/deprecation + childSpan.spanRecorder = this.spanRecorder; + // eslint-disable-next-line deprecation/deprecation + if (childSpan.spanRecorder) { + // eslint-disable-next-line deprecation/deprecation + childSpan.spanRecorder.add(childSpan); + } + + const rootSpan = getRootSpan.getRootSpan(this); + // TODO: still set span.transaction here until we have a more permanent solution + // Probably similarly to the weakmap we hold in node-experimental + // eslint-disable-next-line deprecation/deprecation + childSpan.transaction = rootSpan ; + + if (debugBuild.DEBUG_BUILD && rootSpan) { + const opStr = (spanContext && spanContext.op) || '< unknown op >'; + const nameStr = spanUtils.spanToJSON(childSpan).description || '< unknown name >'; + const idStr = rootSpan.spanContext().spanId; + + const logMessage = `[Tracing] Starting '${opStr}' span on transaction '${nameStr}' (${idStr}).`; + utils.logger.log(logMessage); + this._logMessage = logMessage; + } + + return childSpan; } - state.registry[name].push({ - hook: hook, - orig: orig, - }); -} + /** + * Sets the tag attribute on the current span. + * + * Can also be used to unset a tag, by passing `undefined`. + * + * @param key Tag key + * @param value Tag value + * @deprecated Use `setAttribute()` instead. + */ + setTag(key, value) { + // eslint-disable-next-line deprecation/deprecation + this.tags = { ...this.tags, [key]: value }; + return this; + } + /** + * Sets the data attribute on the current span + * @param key Data key + * @param value Data value + * @deprecated Use `setAttribute()` instead. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + setData(key, value) { + // eslint-disable-next-line deprecation/deprecation + this.data = { ...this.data, [key]: value }; + return this; + } -/***/ }), + /** @inheritdoc */ + setAttribute(key, value) { + if (value === undefined) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete this._attributes[key]; + } else { + this._attributes[key] = value; + } + } -/***/ 70773: -/***/ ((module) => { + /** @inheritdoc */ + setAttributes(attributes) { + Object.keys(attributes).forEach(key => this.setAttribute(key, attributes[key])); + } -module.exports = register; + /** + * @inheritDoc + */ + setStatus(value) { + this._status = value; + return this; + } -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); + /** + * @inheritDoc + * @deprecated Use top-level `setHttpStatus()` instead. + */ + setHttpStatus(httpStatus) { + spanstatus.setHttpStatus(this, httpStatus); + return this; } - if (!options) { - options = {}; + /** + * @inheritdoc + * + * @deprecated Use `.updateName()` instead. + */ + setName(name) { + this.updateName(name); } - if (Array.isArray(name)) { - return name.reverse().reduce(function (callback, name) { - return register.bind(null, state, name, callback, options); - }, method)(); + /** + * @inheritDoc + */ + updateName(name) { + this._name = name; + return this; } - return Promise.resolve().then(function () { - if (!state.registry[name]) { - return method(options); + /** + * @inheritDoc + * + * @deprecated Use `spanToJSON(span).status === 'ok'` instead. + */ + isSuccess() { + return this._status === 'ok'; + } + + /** + * @inheritDoc + * + * @deprecated Use `.end()` instead. + */ + finish(endTimestamp) { + return this.end(endTimestamp); + } + + /** @inheritdoc */ + end(endTimestamp) { + // If already ended, skip + if (this._endTime) { + return; + } + const rootSpan = getRootSpan.getRootSpan(this); + if ( + debugBuild.DEBUG_BUILD && + // Don't call this for transactions + rootSpan && + rootSpan.spanContext().spanId !== this._spanId + ) { + const logMessage = this._logMessage; + if (logMessage) { + utils.logger.log((logMessage ).replace('Starting', 'Finishing')); + } } - return state.registry[name].reduce(function (method, registered) { - return registered.hook.bind(null, method, options); - }, method)(); - }); -} + this._endTime = spanUtils.spanTimeInputToSeconds(endTimestamp); + } + /** + * @inheritDoc + * + * @deprecated Use `spanToTraceHeader()` instead. + */ + toTraceparent() { + return spanUtils.spanToTraceHeader(this); + } -/***/ }), + /** + * @inheritDoc + * + * @deprecated Use `spanToJSON()` or access the fields directly instead. + */ + toContext() { + return utils.dropUndefinedKeys({ + data: this._getData(), + description: this._name, + endTimestamp: this._endTime, + // eslint-disable-next-line deprecation/deprecation + op: this.op, + parentSpanId: this._parentSpanId, + sampled: this._sampled, + spanId: this._spanId, + startTimestamp: this._startTime, + status: this._status, + // eslint-disable-next-line deprecation/deprecation + tags: this.tags, + traceId: this._traceId, + }); + } -/***/ 8944: -/***/ ((module) => { + /** + * @inheritDoc + * + * @deprecated Update the fields directly instead. + */ + updateWithContext(spanContext) { + // eslint-disable-next-line deprecation/deprecation + this.data = spanContext.data || {}; + // eslint-disable-next-line deprecation/deprecation + this._name = spanContext.name || spanContext.description; + this._endTime = spanContext.endTimestamp; + // eslint-disable-next-line deprecation/deprecation + this.op = spanContext.op; + this._parentSpanId = spanContext.parentSpanId; + this._sampled = spanContext.sampled; + this._spanId = spanContext.spanId || this._spanId; + this._startTime = spanContext.startTimestamp || this._startTime; + this._status = spanContext.status; + // eslint-disable-next-line deprecation/deprecation + this.tags = spanContext.tags || {}; + this._traceId = spanContext.traceId || this._traceId; -module.exports = removeHook; + return this; + } -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; + /** + * @inheritDoc + * + * @deprecated Use `spanToTraceContext()` util function instead. + */ + getTraceContext() { + return spanUtils.spanToTraceContext(this); } - var index = state.registry[name] - .map(function (registered) { - return registered.orig; - }) - .indexOf(method); + /** + * Get JSON representation of this span. + * + * @hidden + * @internal This method is purely for internal purposes and should not be used outside + * of SDK code. If you need to get a JSON representation of a span, + * use `spanToJSON(span)` instead. + */ + getSpanJSON() { + return utils.dropUndefinedKeys({ + data: this._getData(), + description: this._name, + op: this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP] , + parent_span_id: this._parentSpanId, + span_id: this._spanId, + start_timestamp: this._startTime, + status: this._status, + // eslint-disable-next-line deprecation/deprecation + tags: Object.keys(this.tags).length > 0 ? this.tags : undefined, + timestamp: this._endTime, + trace_id: this._traceId, + origin: this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] , + _metrics_summary: metricSummary.getMetricSummaryJsonForSpan(this), + profile_id: this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_PROFILE_ID] , + exclusive_time: this._exclusiveTime, + measurements: Object.keys(this._measurements).length > 0 ? this._measurements : undefined, + }); + } - if (index === -1) { - return; + /** @inheritdoc */ + isRecording() { + return !this._endTime && !!this._sampled; } - state.registry[name].splice(index, 1); + /** + * Convert the object to JSON. + * @deprecated Use `spanToJSON(span)` instead. + */ + toJSON() { + return this.getSpanJSON(); + } + + /** + * Get the merged data for this span. + * For now, this combines `data` and `attributes` together, + * until eventually we can ingest `attributes` directly. + */ + _getData() + + { + // eslint-disable-next-line deprecation/deprecation + const { data, _attributes: attributes } = this; + + const hasData = Object.keys(data).length > 0; + const hasAttributes = Object.keys(attributes).length > 0; + + if (!hasData && !hasAttributes) { + return undefined; + } + + if (hasData && hasAttributes) { + return { + ...data, + ...attributes, + }; + } + + return hasData ? data : attributes; + } } +exports.Span = Span; +exports.SpanRecorder = SpanRecorder; +//# sourceMappingURL=span.js.map + /***/ }), -/***/ 40129: -/***/ ((module, exports, __nccwpck_require__) => { +/***/ 14769: +/***/ ((__unused_webpack_module, exports) => { -"use strict"; -/*! - * body-parser - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** The status of an Span. + * + * @deprecated Use string literals - if you require type casting, cast to SpanStatusType type + */ +exports.SpanStatus = void 0; (function (SpanStatus) { + /** The operation completed successfully. */ + const Ok = 'ok'; SpanStatus["Ok"] = Ok; + /** Deadline expired before operation could complete. */ + const DeadlineExceeded = 'deadline_exceeded'; SpanStatus["DeadlineExceeded"] = DeadlineExceeded; + /** 401 Unauthorized (actually does mean unauthenticated according to RFC 7235) */ + const Unauthenticated = 'unauthenticated'; SpanStatus["Unauthenticated"] = Unauthenticated; + /** 403 Forbidden */ + const PermissionDenied = 'permission_denied'; SpanStatus["PermissionDenied"] = PermissionDenied; + /** 404 Not Found. Some requested entity (file or directory) was not found. */ + const NotFound = 'not_found'; SpanStatus["NotFound"] = NotFound; + /** 429 Too Many Requests */ + const ResourceExhausted = 'resource_exhausted'; SpanStatus["ResourceExhausted"] = ResourceExhausted; + /** Client specified an invalid argument. 4xx. */ + const InvalidArgument = 'invalid_argument'; SpanStatus["InvalidArgument"] = InvalidArgument; + /** 501 Not Implemented */ + const Unimplemented = 'unimplemented'; SpanStatus["Unimplemented"] = Unimplemented; + /** 503 Service Unavailable */ + const Unavailable = 'unavailable'; SpanStatus["Unavailable"] = Unavailable; + /** Other/generic 5xx. */ + const InternalError = 'internal_error'; SpanStatus["InternalError"] = InternalError; + /** Unknown. Any non-standard HTTP status code. */ + const UnknownError = 'unknown_error'; SpanStatus["UnknownError"] = UnknownError; + /** The operation was cancelled (typically by the user). */ + const Cancelled = 'cancelled'; SpanStatus["Cancelled"] = Cancelled; + /** Already exists (409) */ + const AlreadyExists = 'already_exists'; SpanStatus["AlreadyExists"] = AlreadyExists; + /** Operation was rejected because the system is not in a state required for the operation's */ + const FailedPrecondition = 'failed_precondition'; SpanStatus["FailedPrecondition"] = FailedPrecondition; + /** The operation was aborted, typically due to a concurrency issue. */ + const Aborted = 'aborted'; SpanStatus["Aborted"] = Aborted; + /** Operation was attempted past the valid range. */ + const OutOfRange = 'out_of_range'; SpanStatus["OutOfRange"] = OutOfRange; + /** Unrecoverable data loss or corruption */ + const DataLoss = 'data_loss'; SpanStatus["DataLoss"] = DataLoss; +})(exports.SpanStatus || (exports.SpanStatus = {})); + +/** + * Converts a HTTP status code into a {@link SpanStatusType}. + * + * @param httpStatus The HTTP response status code. + * @returns The span status or unknown_error. + */ +function getSpanStatusFromHttpCode(httpStatus) { + if (httpStatus < 400 && httpStatus >= 100) { + return 'ok'; + } + + if (httpStatus >= 400 && httpStatus < 500) { + switch (httpStatus) { + case 401: + return 'unauthenticated'; + case 403: + return 'permission_denied'; + case 404: + return 'not_found'; + case 409: + return 'already_exists'; + case 413: + return 'failed_precondition'; + case 429: + return 'resource_exhausted'; + default: + return 'invalid_argument'; + } + } + + if (httpStatus >= 500 && httpStatus < 600) { + switch (httpStatus) { + case 501: + return 'unimplemented'; + case 503: + return 'unavailable'; + case 504: + return 'deadline_exceeded'; + default: + return 'internal_error'; + } + } + return 'unknown_error'; +} /** - * Module dependencies. - * @private + * Converts a HTTP status code into a {@link SpanStatusType}. + * + * @deprecated Use {@link spanStatusFromHttpCode} instead. + * This export will be removed in v8 as the signature contains a typo. + * + * @param httpStatus The HTTP response status code. + * @returns The span status or unknown_error. */ - -var deprecate = __nccwpck_require__(77267)('body-parser') +const spanStatusfromHttpCode = getSpanStatusFromHttpCode; /** - * Cache of loaded parsers. - * @private + * Sets the Http status attributes on the current span based on the http code. + * Additionally, the span's status is updated, depending on the http code. */ +function setHttpStatus(span, httpStatus) { + // TODO (v8): Remove these calls + // Relay does not require us to send the status code as a tag + // For now, just because users might expect it to land as a tag we keep sending it. + // Same with data. + // In v8, we replace both, simply with + // span.setAttribute('http.response.status_code', httpStatus); -var parsers = Object.create(null) + // eslint-disable-next-line deprecation/deprecation + span.setTag('http.status_code', String(httpStatus)); + // eslint-disable-next-line deprecation/deprecation + span.setData('http.response.status_code', httpStatus); -/** - * @typedef Parsers - * @type {function} - * @property {function} json - * @property {function} raw - * @property {function} text - * @property {function} urlencoded - */ + const spanStatus = getSpanStatusFromHttpCode(httpStatus); + if (spanStatus !== 'unknown_error') { + span.setStatus(spanStatus); + } +} -/** - * Module exports. - * @type {Parsers} - */ +exports.getSpanStatusFromHttpCode = getSpanStatusFromHttpCode; +exports.setHttpStatus = setHttpStatus; +exports.spanStatusfromHttpCode = spanStatusfromHttpCode; +//# sourceMappingURL=spanstatus.js.map -exports = module.exports = deprecate.function(bodyParser, - 'bodyParser: use individual json/urlencoded middlewares') -/** - * JSON parser. - * @public - */ +/***/ }), -Object.defineProperty(exports, "json", ({ - configurable: true, - enumerable: true, - get: createParserGetter('json') -})) +/***/ 75150: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/** - * Raw parser. - * @public - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); -Object.defineProperty(exports, "raw", ({ - configurable: true, - enumerable: true, - get: createParserGetter('raw') -})) +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const hub = __nccwpck_require__(18205); +const spanUtils = __nccwpck_require__(98313); +__nccwpck_require__(55448); +__nccwpck_require__(14769); +const dynamicSamplingContext = __nccwpck_require__(76248); +const exports$1 = __nccwpck_require__(74313); +const handleCallbackErrors = __nccwpck_require__(57116); +const hasTracingEnabled = __nccwpck_require__(7747); /** - * Text parser. - * @public + * Wraps a function with a transaction/span and finishes the span after the function is done. + * + * Note that if you have not enabled tracing extensions via `addTracingExtensions` + * or you didn't set `tracesSampleRate`, this function will not generate spans + * and the `span` returned from the callback will be undefined. + * + * This function is meant to be used internally and may break at any time. Use at your own risk. + * + * @internal + * @private + * + * @deprecated Use `startSpan` instead. */ +function trace( + context, + callback, + // eslint-disable-next-line @typescript-eslint/no-empty-function + onError = () => {}, + // eslint-disable-next-line @typescript-eslint/no-empty-function + afterFinish = () => {}, +) { + // eslint-disable-next-line deprecation/deprecation + const hub$1 = hub.getCurrentHub(); + const scope = exports$1.getCurrentScope(); + // eslint-disable-next-line deprecation/deprecation + const parentSpan = scope.getSpan(); + + const spanContext = normalizeContext(context); + const activeSpan = createChildSpanOrTransaction(hub$1, { + parentSpan, + spanContext, + forceTransaction: false, + scope, + }); -Object.defineProperty(exports, "text", ({ - configurable: true, - enumerable: true, - get: createParserGetter('text') -})) - -/** - * URL-encoded parser. - * @public - */ + // eslint-disable-next-line deprecation/deprecation + scope.setSpan(activeSpan); -Object.defineProperty(exports, "urlencoded", ({ - configurable: true, - enumerable: true, - get: createParserGetter('urlencoded') -})) + return handleCallbackErrors.handleCallbackErrors( + () => callback(activeSpan), + error => { + activeSpan && activeSpan.setStatus('internal_error'); + onError(error, activeSpan); + }, + () => { + activeSpan && activeSpan.end(); + // eslint-disable-next-line deprecation/deprecation + scope.setSpan(parentSpan); + afterFinish(); + }, + ); +} /** - * Create a middleware to parse json and urlencoded bodies. + * Wraps a function with a transaction/span and finishes the span after the function is done. + * The created span is the active span and will be used as parent by other spans created inside the function + * and can be accessed via `Sentry.getSpan()`, as long as the function is executed while the scope is active. * - * @param {object} [options] - * @return {function} - * @deprecated - * @public + * If you want to create a span that is not set as active, use {@link startInactiveSpan}. + * + * Note that if you have not enabled tracing extensions via `addTracingExtensions` + * or you didn't set `tracesSampleRate`, this function will not generate spans + * and the `span` returned from the callback will be undefined. */ +function startSpan(context, callback) { + const spanContext = normalizeContext(context); -function bodyParser (options) { - // use default type for parsers - var opts = Object.create(options || null, { - type: { - configurable: true, - enumerable: true, - value: undefined, - writable: true - } - }) + return hub.runWithAsyncContext(() => { + return exports$1.withScope(context.scope, scope => { + // eslint-disable-next-line deprecation/deprecation + const hub$1 = hub.getCurrentHub(); + // eslint-disable-next-line deprecation/deprecation + const parentSpan = scope.getSpan(); - var _urlencoded = exports.urlencoded(opts) - var _json = exports.json(opts) + const shouldSkipSpan = context.onlyIfParent && !parentSpan; + const activeSpan = shouldSkipSpan + ? undefined + : createChildSpanOrTransaction(hub$1, { + parentSpan, + spanContext, + forceTransaction: context.forceTransaction, + scope, + }); - return function bodyParser (req, res, next) { - _json(req, res, function (err) { - if (err) return next(err) - _urlencoded(req, res, next) - }) - } + return handleCallbackErrors.handleCallbackErrors( + () => callback(activeSpan), + () => { + // Only update the span status if it hasn't been changed yet + if (activeSpan) { + const { status } = spanUtils.spanToJSON(activeSpan); + if (!status || status === 'ok') { + activeSpan.setStatus('internal_error'); + } + } + }, + () => activeSpan && activeSpan.end(), + ); + }); + }); } /** - * Create a getter for loading a parser. - * @private + * @deprecated Use {@link startSpan} instead. */ - -function createParserGetter (name) { - return function get () { - return loadParser(name) - } -} +const startActiveSpan = startSpan; /** - * Load a parser module. - * @private + * Similar to `Sentry.startSpan`. Wraps a function with a transaction/span, but does not finish the span + * after the function is done automatically. You'll have to call `span.end()` manually. + * + * The created span is the active span and will be used as parent by other spans created inside the function + * and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active. + * + * Note that if you have not enabled tracing extensions via `addTracingExtensions` + * or you didn't set `tracesSampleRate`, this function will not generate spans + * and the `span` returned from the callback will be undefined. */ +function startSpanManual( + context, + callback, +) { + const spanContext = normalizeContext(context); + + return hub.runWithAsyncContext(() => { + return exports$1.withScope(context.scope, scope => { + // eslint-disable-next-line deprecation/deprecation + const hub$1 = hub.getCurrentHub(); + // eslint-disable-next-line deprecation/deprecation + const parentSpan = scope.getSpan(); + + const shouldSkipSpan = context.onlyIfParent && !parentSpan; + const activeSpan = shouldSkipSpan + ? undefined + : createChildSpanOrTransaction(hub$1, { + parentSpan, + spanContext, + forceTransaction: context.forceTransaction, + scope, + }); -function loadParser (parserName) { - var parser = parsers[parserName] + function finishAndSetSpan() { + activeSpan && activeSpan.end(); + } - if (parser !== undefined) { - return parser - } + return handleCallbackErrors.handleCallbackErrors( + () => callback(activeSpan, finishAndSetSpan), + () => { + // Only update the span status if it hasn't been changed yet, and the span is not yet finished + if (activeSpan && activeSpan.isRecording()) { + const { status } = spanUtils.spanToJSON(activeSpan); + if (!status || status === 'ok') { + activeSpan.setStatus('internal_error'); + } + } + }, + ); + }); + }); +} - // this uses a switch for static require analysis - switch (parserName) { - case 'json': - parser = __nccwpck_require__(39121) - break - case 'raw': - parser = __nccwpck_require__(87661) - break - case 'text': - parser = __nccwpck_require__(49488) - break - case 'urlencoded': - parser = __nccwpck_require__(55514) - break +/** + * Creates a span. This span is not set as active, so will not get automatic instrumentation spans + * as children or be able to be accessed via `Sentry.getSpan()`. + * + * If you want to create a span that is set as active, use {@link startSpan}. + * + * Note that if you have not enabled tracing extensions via `addTracingExtensions` + * or you didn't set `tracesSampleRate` or `tracesSampler`, this function will not generate spans + * and the `span` returned from the callback will be undefined. + */ +function startInactiveSpan(context) { + if (!hasTracingEnabled.hasTracingEnabled()) { + return undefined; } - // store to prevent invoking require() - return (parsers[parserName] = parser) -} - + const spanContext = normalizeContext(context); + // eslint-disable-next-line deprecation/deprecation + const hub$1 = hub.getCurrentHub(); + const parentSpan = context.scope + ? // eslint-disable-next-line deprecation/deprecation + context.scope.getSpan() + : getActiveSpan(); -/***/ }), + const shouldSkipSpan = context.onlyIfParent && !parentSpan; -/***/ 45109: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (shouldSkipSpan) { + return undefined; + } -"use strict"; -/*! - * body-parser - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ + const scope = context.scope || exports$1.getCurrentScope(); + // Even though we don't actually want to make this span active on the current scope, + // we need to make it active on a temporary scope that we use for event processing + // as otherwise, it won't pick the correct span for the event when processing it + const temporaryScope = (scope ).clone(); + return createChildSpanOrTransaction(hub$1, { + parentSpan, + spanContext, + forceTransaction: context.forceTransaction, + scope: temporaryScope, + }); +} /** - * Module dependencies. - * @private + * Returns the currently active span. */ +function getActiveSpan() { + // eslint-disable-next-line deprecation/deprecation + return exports$1.getCurrentScope().getSpan(); +} -var createError = __nccwpck_require__(8927) -var destroy = __nccwpck_require__(14802) -var getBody = __nccwpck_require__(24378) -var iconv = __nccwpck_require__(81241) -var onFinished = __nccwpck_require__(96922) -var unpipe = __nccwpck_require__(77962) -var zlib = __nccwpck_require__(43106) +const continueTrace = ( + { + sentryTrace, + baggage, + } -/** - * Module exports. - */ +, + callback, +) => { + // TODO(v8): Change this function so it doesn't do anything besides setting the propagation context on the current scope: + /* + return withScope((scope) => { + const propagationContext = propagationContextFromHeaders(sentryTrace, baggage); + scope.setPropagationContext(propagationContext); + return callback(); + }) + */ -module.exports = read + const currentScope = exports$1.getCurrentScope(); -/** - * Read a request into a buffer and parse. - * - * @param {object} req - * @param {object} res - * @param {function} next - * @param {function} parse - * @param {function} debug - * @param {object} options - * @private - */ + // eslint-disable-next-line deprecation/deprecation + const { traceparentData, dynamicSamplingContext, propagationContext } = utils.tracingContextFromHeaders( + sentryTrace, + baggage, + ); -function read (req, res, next, parse, debug, options) { - var length - var opts = options - var stream + currentScope.setPropagationContext(propagationContext); - // flag as parsed - req._body = true + if (debugBuild.DEBUG_BUILD && traceparentData) { + utils.logger.log(`[Tracing] Continuing trace ${traceparentData.traceId}.`); + } - // read options - var encoding = opts.encoding !== null - ? opts.encoding - : null - var verify = opts.verify + const transactionContext = { + ...traceparentData, + metadata: utils.dropUndefinedKeys({ + dynamicSamplingContext, + }), + }; - try { - // get the content stream - stream = contentstream(req, debug, opts.inflate) - length = stream.length - stream.length = undefined - } catch (err) { - return next(err) + if (!callback) { + return transactionContext; } - // set raw-body options - opts.length = length - opts.encoding = verify - ? null - : encoding + return hub.runWithAsyncContext(() => { + return callback(transactionContext); + }); +}; - // assert charset is supported - if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { - return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { - charset: encoding.toLowerCase(), - type: 'charset.unsupported' - })) +function createChildSpanOrTransaction( + // eslint-disable-next-line deprecation/deprecation + hub$1, + { + parentSpan, + spanContext, + forceTransaction, + scope, } - // read body - debug('read body') - getBody(stream, opts, function (error, body) { - if (error) { - var _error +, +) { + if (!hasTracingEnabled.hasTracingEnabled()) { + return undefined; + } - if (error.type === 'encoding.unsupported') { - // echo back charset - _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { - charset: encoding.toLowerCase(), - type: 'charset.unsupported' - }) - } else { - // set status code on error - _error = createError(400, error) - } + const isolationScope = hub.getIsolationScope(); - // unpipe from stream and destroy - if (stream !== req) { - unpipe(req) - destroy(stream, true) - } + let span; + if (parentSpan && !forceTransaction) { + // eslint-disable-next-line deprecation/deprecation + span = parentSpan.startChild(spanContext); + } else if (parentSpan) { + // If we forced a transaction but have a parent span, make sure to continue from the parent span, not the scope + const dsc = dynamicSamplingContext.getDynamicSamplingContextFromSpan(parentSpan); + const { traceId, spanId: parentSpanId } = parentSpan.spanContext(); + const sampled = spanUtils.spanIsSampled(parentSpan); - // read off entire request - dump(req, function onfinished () { - next(createError(400, _error)) - }) - return - } + // eslint-disable-next-line deprecation/deprecation + span = hub$1.startTransaction({ + traceId, + parentSpanId, + parentSampled: sampled, + ...spanContext, + metadata: { + dynamicSamplingContext: dsc, + // eslint-disable-next-line deprecation/deprecation + ...spanContext.metadata, + }, + }); + } else { + const { traceId, dsc, parentSpanId, sampled } = { + ...isolationScope.getPropagationContext(), + ...scope.getPropagationContext(), + }; - // verify - if (verify) { - try { - debug('verify body') - verify(req, res, body, encoding) - } catch (err) { - next(createError(403, err, { - body: body, - type: err.type || 'entity.verify.failed' - })) - return - } - } + // eslint-disable-next-line deprecation/deprecation + span = hub$1.startTransaction({ + traceId, + parentSpanId, + parentSampled: sampled, + ...spanContext, + metadata: { + dynamicSamplingContext: dsc, + // eslint-disable-next-line deprecation/deprecation + ...spanContext.metadata, + }, + }); + } - // parse - var str = body - try { - debug('parse body') - str = typeof body !== 'string' && encoding !== null - ? iconv.decode(body, encoding) - : body - req.body = parse(str) - } catch (err) { - next(createError(400, err, { - body: str, - type: err.type || 'entity.parse.failed' - })) - return - } + // We always set this as active span on the scope + // In the case of this being an inactive span, we ensure to pass a detached scope in here in the first place + // But by having this here, we can ensure that the lookup through `getCapturedScopesOnSpan` results in the correct scope & span combo + // eslint-disable-next-line deprecation/deprecation + scope.setSpan(span); - next() - }) + setCapturedScopesOnSpan(span, scope, isolationScope); + + return span; } /** - * Get the content stream of the request. + * This converts StartSpanOptions to TransactionContext. + * For the most part (for now) we accept the same options, + * but some of them need to be transformed. * - * @param {object} req - * @param {function} debug - * @param {boolean} [inflate=true] - * @return {object} - * @api private + * Eventually the StartSpanOptions will be more aligned with OpenTelemetry. */ +function normalizeContext(context) { + if (context.startTime) { + const ctx = { ...context }; + ctx.startTimestamp = spanUtils.spanTimeInputToSeconds(context.startTime); + delete ctx.startTime; + return ctx; + } -function contentstream (req, debug, inflate) { - var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() - var length = req.headers['content-length'] - var stream - - debug('content-encoding "%s"', encoding) + return context; +} - if (inflate === false && encoding !== 'identity') { - throw createError(415, 'content encoding unsupported', { - encoding: encoding, - type: 'encoding.unsupported' - }) - } +const SCOPE_ON_START_SPAN_FIELD = '_sentryScope'; +const ISOLATION_SCOPE_ON_START_SPAN_FIELD = '_sentryIsolationScope'; - switch (encoding) { - case 'deflate': - stream = zlib.createInflate() - debug('inflate body') - req.pipe(stream) - break - case 'gzip': - stream = zlib.createGunzip() - debug('gunzip body') - req.pipe(stream) - break - case 'identity': - stream = req - stream.length = length - break - default: - throw createError(415, 'unsupported content encoding "' + encoding + '"', { - encoding: encoding, - type: 'encoding.unsupported' - }) +function setCapturedScopesOnSpan(span, scope, isolationScope) { + if (span) { + utils.addNonEnumerableProperty(span, ISOLATION_SCOPE_ON_START_SPAN_FIELD, isolationScope); + utils.addNonEnumerableProperty(span, SCOPE_ON_START_SPAN_FIELD, scope); } - - return stream } /** - * Dump the contents of a request. - * - * @param {object} req - * @param {function} callback - * @api private + * Grabs the scope and isolation scope off a span that were active when the span was started. */ - -function dump (req, callback) { - if (onFinished.isFinished(req)) { - callback(null) - } else { - onFinished(req, callback) - req.resume() - } +function getCapturedScopesOnSpan(span) { + return { + scope: (span )[SCOPE_ON_START_SPAN_FIELD], + isolationScope: (span )[ISOLATION_SCOPE_ON_START_SPAN_FIELD], + }; } +exports.continueTrace = continueTrace; +exports.getActiveSpan = getActiveSpan; +exports.getCapturedScopesOnSpan = getCapturedScopesOnSpan; +exports.startActiveSpan = startActiveSpan; +exports.startInactiveSpan = startInactiveSpan; +exports.startSpan = startSpan; +exports.startSpanManual = startSpanManual; +exports.trace = trace; +//# sourceMappingURL=trace.js.map + /***/ }), -/***/ 39121: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 7827: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; -/*! - * body-parser - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const hub = __nccwpck_require__(18205); +const metricSummary = __nccwpck_require__(61479); +const semanticAttributes = __nccwpck_require__(44513); +const spanUtils = __nccwpck_require__(98313); +const dynamicSamplingContext = __nccwpck_require__(76248); +const span = __nccwpck_require__(36283); +const trace = __nccwpck_require__(75150); +/** JSDoc */ +class Transaction extends span.Span { + /** + * The reference to the current hub. + */ + // eslint-disable-next-line deprecation/deprecation -/** - * Module dependencies. - * @private - */ + // DO NOT yet remove this property, it is used in a hack for v7 backwards compatibility. -var bytes = __nccwpck_require__(89015) -var contentType = __nccwpck_require__(22541) -var createError = __nccwpck_require__(8927) -var debug = __nccwpck_require__(66515)('body-parser:json') -var read = __nccwpck_require__(45109) -var typeis = __nccwpck_require__(54693) + /** + * This constructor should never be called manually. Those instrumenting tracing should use + * `Sentry.startTransaction()`, and internal methods should use `hub.startTransaction()`. + * @internal + * @hideconstructor + * @hidden + * + * @deprecated Transactions will be removed in v8. Use spans instead. + */ + // eslint-disable-next-line deprecation/deprecation + constructor(transactionContext, hub$1) { + super(transactionContext); + this._contexts = {}; -/** - * Module exports. - */ + // eslint-disable-next-line deprecation/deprecation + this._hub = hub$1 || hub.getCurrentHub(); -module.exports = json + this._name = transactionContext.name || ''; -/** - * RegExp to match the first non-space in a string. - * - * Allowed whitespace is defined in RFC 7159: - * - * ws = *( - * %x20 / ; Space - * %x09 / ; Horizontal tab - * %x0A / ; Line feed or New line - * %x0D ) ; Carriage return - */ + this._metadata = { + // eslint-disable-next-line deprecation/deprecation + ...transactionContext.metadata, + }; -var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/ // eslint-disable-line no-control-regex + this._trimEnd = transactionContext.trimEnd; -var JSON_SYNTAX_CHAR = '#' -var JSON_SYNTAX_REGEXP = /#+/g + // this is because transactions are also spans, and spans have a transaction pointer + // TODO (v8): Replace this with another way to set the root span + // eslint-disable-next-line deprecation/deprecation + this.transaction = this; -/** - * Create a middleware to parse JSON bodies. - * - * @param {object} [options] - * @return {function} - * @public - */ + // If Dynamic Sampling Context is provided during the creation of the transaction, we freeze it as it usually means + // there is incoming Dynamic Sampling Context. (Either through an incoming request, a baggage meta-tag, or other means) + const incomingDynamicSamplingContext = this._metadata.dynamicSamplingContext; + if (incomingDynamicSamplingContext) { + // We shallow copy this in case anything writes to the original reference of the passed in `dynamicSamplingContext` + this._frozenDynamicSamplingContext = { ...incomingDynamicSamplingContext }; + } + } -function json (options) { - var opts = options || {} + // This sadly conflicts with the getter/setter ordering :( + /* eslint-disable @typescript-eslint/member-ordering */ - var limit = typeof opts.limit !== 'number' - ? bytes.parse(opts.limit || '100kb') - : opts.limit - var inflate = opts.inflate !== false - var reviver = opts.reviver - var strict = opts.strict !== false - var type = opts.type || 'application/json' - var verify = opts.verify || false + /** + * Getter for `name` property. + * @deprecated Use `spanToJSON(span).description` instead. + */ + get name() { + return this._name; + } - if (verify !== false && typeof verify !== 'function') { - throw new TypeError('option verify must be function') + /** + * Setter for `name` property, which also sets `source` as custom. + * @deprecated Use `updateName()` and `setMetadata()` instead. + */ + set name(newName) { + // eslint-disable-next-line deprecation/deprecation + this.setName(newName); } - // create the appropriate type checking function - var shouldParse = typeof type !== 'function' - ? typeChecker(type) - : type + /** + * Get the metadata for this transaction. + * @deprecated Use `spanGetMetadata(transaction)` instead. + */ + get metadata() { + // We merge attributes in for backwards compatibility + return { + // Defaults + // eslint-disable-next-line deprecation/deprecation + source: 'custom', + spanMetadata: {}, - function parse (body) { - if (body.length === 0) { - // special-case empty json body, as it's a common client-side mistake - // TODO: maybe make this configurable or part of "strict" option - return {} - } + // Legacy metadata + ...this._metadata, - if (strict) { - var first = firstchar(body) + // From attributes + ...(this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] && { + source: this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] , + }), + ...(this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE] && { + sampleRate: this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE] , + }), + }; + } - if (first !== '{' && first !== '[') { - debug('strict violation') - throw createStrictSyntaxError(body, first) - } - } + /** + * Update the metadata for this transaction. + * @deprecated Use `spanGetMetadata(transaction)` instead. + */ + set metadata(metadata) { + this._metadata = metadata; + } - try { - debug('parse json') - return JSON.parse(body, reviver) - } catch (e) { - throw normalizeJsonSyntaxError(e, { - message: e.message, - stack: e.stack - }) - } + /* eslint-enable @typescript-eslint/member-ordering */ + + /** + * Setter for `name` property, which also sets `source` on the metadata. + * + * @deprecated Use `.updateName()` and `.setAttribute()` instead. + */ + setName(name, source = 'custom') { + this._name = name; + this.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source); } - return function jsonParser (req, res, next) { - if (req._body) { - debug('body already parsed') - next() - return - } + /** @inheritdoc */ + updateName(name) { + this._name = name; + return this; + } - req.body = req.body || {} + /** + * Attaches SpanRecorder to the span itself + * @param maxlen maximum number of spans that can be recorded + */ + initSpanRecorder(maxlen = 1000) { + // eslint-disable-next-line deprecation/deprecation + if (!this.spanRecorder) { + // eslint-disable-next-line deprecation/deprecation + this.spanRecorder = new span.SpanRecorder(maxlen); + } + // eslint-disable-next-line deprecation/deprecation + this.spanRecorder.add(this); + } - // skip requests without bodies - if (!typeis.hasBody(req)) { - debug('skip empty body') - next() - return + /** + * Set the context of a transaction event. + * @deprecated Use either `.setAttribute()`, or set the context on the scope before creating the transaction. + */ + setContext(key, context) { + if (context === null) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete this._contexts[key]; + } else { + this._contexts[key] = context; } + } - debug('content-type %j', req.headers['content-type']) + /** + * @inheritDoc + * + * @deprecated Use top-level `setMeasurement()` instead. + */ + setMeasurement(name, value, unit = '') { + this._measurements[name] = { value, unit }; + } - // determine if request should be parsed - if (!shouldParse(req)) { - debug('skip parsing') - next() - return - } + /** + * Store metadata on this transaction. + * @deprecated Use attributes or store data on the scope instead. + */ + setMetadata(newMetadata) { + this._metadata = { ...this._metadata, ...newMetadata }; + } - // assert charset per RFC 7159 sec 8.1 - var charset = getCharset(req) || 'utf-8' - if (charset.slice(0, 4) !== 'utf-') { - debug('invalid charset') - next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { - charset: charset, - type: 'charset.unsupported' - })) - return + /** + * @inheritDoc + */ + end(endTimestamp) { + const timestampInS = spanUtils.spanTimeInputToSeconds(endTimestamp); + const transaction = this._finishTransaction(timestampInS); + if (!transaction) { + return undefined; } - - // read - read(req, res, next, parse, debug, { - encoding: charset, - inflate: inflate, - limit: limit, - verify: verify - }) + // eslint-disable-next-line deprecation/deprecation + return this._hub.captureEvent(transaction); } -} -/** - * Create strict violation syntax error matching native error. - * - * @param {string} str - * @param {string} char - * @return {Error} - * @private - */ + /** + * @inheritDoc + */ + toContext() { + // eslint-disable-next-line deprecation/deprecation + const spanContext = super.toContext(); -function createStrictSyntaxError (str, char) { - var index = str.indexOf(char) - var partial = '' + return utils.dropUndefinedKeys({ + ...spanContext, + name: this._name, + trimEnd: this._trimEnd, + }); + } - if (index !== -1) { - partial = str.substring(0, index) + JSON_SYNTAX_CHAR + /** + * @inheritDoc + */ + updateWithContext(transactionContext) { + // eslint-disable-next-line deprecation/deprecation + super.updateWithContext(transactionContext); - for (var i = index + 1; i < str.length; i++) { - partial += JSON_SYNTAX_CHAR + this._name = transactionContext.name || ''; + this._trimEnd = transactionContext.trimEnd; + + return this; + } + + /** + * @inheritdoc + * + * @experimental + * + * @deprecated Use top-level `getDynamicSamplingContextFromSpan` instead. + */ + getDynamicSamplingContext() { + return dynamicSamplingContext.getDynamicSamplingContextFromSpan(this); + } + + /** + * Override the current hub with a new one. + * Used if you want another hub to finish the transaction. + * + * @internal + */ + // eslint-disable-next-line deprecation/deprecation + setHub(hub) { + this._hub = hub; + } + + /** + * Get the profile id of the transaction. + */ + getProfileId() { + if (this._contexts !== undefined && this._contexts['profile'] !== undefined) { + return this._contexts['profile'].profile_id ; } + return undefined; } - try { - JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation') - } catch (e) { - return normalizeJsonSyntaxError(e, { - message: e.message.replace(JSON_SYNTAX_REGEXP, function (placeholder) { - return str.substring(index, index + placeholder.length) + /** + * Finish the transaction & prepare the event to send to Sentry. + */ + _finishTransaction(endTimestamp) { + // This transaction is already finished, so we should not flush it again. + if (this._endTime !== undefined) { + return undefined; + } + + if (!this._name) { + debugBuild.DEBUG_BUILD && utils.logger.warn('Transaction has no name, falling back to ``.'); + this._name = ''; + } + + // just sets the end timestamp + super.end(endTimestamp); + + // eslint-disable-next-line deprecation/deprecation + const client = this._hub.getClient(); + if (client && client.emit) { + client.emit('finishTransaction', this); + } + + if (this._sampled !== true) { + // At this point if `sampled !== true` we want to discard the transaction. + debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.'); + + if (client) { + client.recordDroppedEvent('sample_rate', 'transaction'); + } + + return undefined; + } + + // eslint-disable-next-line deprecation/deprecation + const finishedSpans = this.spanRecorder + ? // eslint-disable-next-line deprecation/deprecation + this.spanRecorder.spans.filter(span => span !== this && spanUtils.spanToJSON(span).timestamp) + : []; + + if (this._trimEnd && finishedSpans.length > 0) { + const endTimes = finishedSpans.map(span => spanUtils.spanToJSON(span).timestamp).filter(Boolean) ; + this._endTime = endTimes.reduce((prev, current) => { + return prev > current ? prev : current; + }); + } + + const { scope: capturedSpanScope, isolationScope: capturedSpanIsolationScope } = trace.getCapturedScopesOnSpan(this); + + // eslint-disable-next-line deprecation/deprecation + const { metadata } = this; + // eslint-disable-next-line deprecation/deprecation + const { source } = metadata; + + const transaction = { + contexts: { + ...this._contexts, + // We don't want to override trace context + trace: spanUtils.spanToTraceContext(this), + }, + // TODO: Pass spans serialized via `spanToJSON()` here instead in v8. + spans: finishedSpans, + start_timestamp: this._startTime, + // eslint-disable-next-line deprecation/deprecation + tags: this.tags, + timestamp: this._endTime, + transaction: this._name, + type: 'transaction', + sdkProcessingMetadata: { + ...metadata, + capturedSpanScope, + capturedSpanIsolationScope, + ...utils.dropUndefinedKeys({ + dynamicSamplingContext: dynamicSamplingContext.getDynamicSamplingContextFromSpan(this), + }), + }, + _metrics_summary: metricSummary.getMetricSummaryJsonForSpan(this), + ...(source && { + transaction_info: { + source, + }, }), - stack: e.stack - }) + }; + + const hasMeasurements = Object.keys(this._measurements).length > 0; + + if (hasMeasurements) { + debugBuild.DEBUG_BUILD && + utils.logger.log( + '[Measurements] Adding measurements to transaction', + JSON.stringify(this._measurements, undefined, 2), + ); + transaction.measurements = this._measurements; + } + + // eslint-disable-next-line deprecation/deprecation + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Finishing ${this.op} transaction: ${this._name}.`); + + return transaction; } } -/** - * Get the first non-whitespace character in a string. - * - * @param {string} str - * @return {function} - * @private - */ +exports.Transaction = Transaction; +//# sourceMappingURL=transaction.js.map -function firstchar (str) { - var match = FIRST_CHAR_REGEXP.exec(str) - return match - ? match[1] - : undefined -} +/***/ }), + +/***/ 49194: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); +const hub = __nccwpck_require__(18205); /** - * Get the charset of a request. + * Grabs active transaction off scope. * - * @param {object} req - * @api private + * @deprecated You should not rely on the transaction, but just use `startSpan()` APIs instead. */ - -function getCharset (req) { - try { - return (contentType.parse(req).parameters.charset || '').toLowerCase() - } catch (e) { - return undefined - } +// eslint-disable-next-line deprecation/deprecation +function getActiveTransaction(maybeHub) { + // eslint-disable-next-line deprecation/deprecation + const hub$1 = maybeHub || hub.getCurrentHub(); + // eslint-disable-next-line deprecation/deprecation + const scope = hub$1.getScope(); + // eslint-disable-next-line deprecation/deprecation + return scope.getTransaction() ; } /** - * Normalize a SyntaxError for JSON.parse. + * The `extractTraceparentData` function and `TRACEPARENT_REGEXP` constant used + * to be declared in this file. It was later moved into `@sentry/utils` as part of a + * move to remove `@sentry/tracing` dependencies from `@sentry/node` (`extractTraceparentData` + * is the only tracing function used by `@sentry/node`). * - * @param {SyntaxError} error - * @param {object} obj - * @return {SyntaxError} + * These exports are kept here for backwards compatability's sake. + * + * See https://github.com/getsentry/sentry-javascript/issues/4642 for more details. + * + * @deprecated Import this function from `@sentry/utils` instead */ +const extractTraceparentData = utils.extractTraceparentData; -function normalizeJsonSyntaxError (error, obj) { - var keys = Object.getOwnPropertyNames(error) +exports.stripUrlQueryAndFragment = utils.stripUrlQueryAndFragment; +exports.extractTraceparentData = extractTraceparentData; +exports.getActiveTransaction = getActiveTransaction; +//# sourceMappingURL=utils.js.map - for (var i = 0; i < keys.length; i++) { - var key = keys[i] - if (key !== 'stack' && key !== 'message') { - delete error[key] - } - } - // replace stack before message for Node.js 0.10 and below - error.stack = obj.stack.replace(error.message, obj.message) - error.message = obj.message +/***/ }), - return error -} +/***/ 91148: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); + +const DEFAULT_TRANSPORT_BUFFER_SIZE = 30; /** - * Get the simple type checker. + * Creates an instance of a Sentry `Transport` * - * @param {string} type - * @return {function} + * @param options + * @param makeRequest */ +function createTransport( + options, + makeRequest, + buffer = utils.makePromiseBuffer( + options.bufferSize || DEFAULT_TRANSPORT_BUFFER_SIZE, + ), +) { + let rateLimits = {}; + const flush = (timeout) => buffer.drain(timeout); + + function send(envelope) { + const filteredEnvelopeItems = []; + + // Drop rate limited items from envelope + utils.forEachEnvelopeItem(envelope, (item, type) => { + const dataCategory = utils.envelopeItemTypeToDataCategory(type); + if (utils.isRateLimited(rateLimits, dataCategory)) { + const event = getEventForEnvelopeItem(item, type); + options.recordDroppedEvent('ratelimit_backoff', dataCategory, event); + } else { + filteredEnvelopeItems.push(item); + } + }); -function typeChecker (type) { - return function checkType (req) { - return Boolean(typeis(req, type)) + // Skip sending if envelope is empty after filtering out rate limited events + if (filteredEnvelopeItems.length === 0) { + return utils.resolvedSyncPromise(); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const filteredEnvelope = utils.createEnvelope(envelope[0], filteredEnvelopeItems ); + + // Creates client report for each item in an envelope + const recordEnvelopeLoss = (reason) => { + utils.forEachEnvelopeItem(filteredEnvelope, (item, type) => { + const event = getEventForEnvelopeItem(item, type); + options.recordDroppedEvent(reason, utils.envelopeItemTypeToDataCategory(type), event); + }); + }; + + const requestTask = () => + makeRequest({ body: utils.serializeEnvelope(filteredEnvelope, options.textEncoder) }).then( + response => { + // We don't want to throw on NOK responses, but we want to at least log them + if (response.statusCode !== undefined && (response.statusCode < 200 || response.statusCode >= 300)) { + debugBuild.DEBUG_BUILD && utils.logger.warn(`Sentry responded with status code ${response.statusCode} to sent event.`); + } + + rateLimits = utils.updateRateLimits(rateLimits, response); + return response; + }, + error => { + recordEnvelopeLoss('network_error'); + throw error; + }, + ); + + return buffer.add(requestTask).then( + result => result, + error => { + if (error instanceof utils.SentryError) { + debugBuild.DEBUG_BUILD && utils.logger.error('Skipped sending event because buffer is full.'); + recordEnvelopeLoss('queue_overflow'); + return utils.resolvedSyncPromise(); + } else { + throw error; + } + }, + ); } + + // We use this to identifify if the transport is the base transport + // TODO (v8): Remove this again as we'll no longer need it + send.__sentry__baseTransport__ = true; + + return { + send, + flush, + }; } +function getEventForEnvelopeItem(item, type) { + if (type !== 'event' && type !== 'transaction') { + return undefined; + } -/***/ }), + return Array.isArray(item) ? (item )[1] : undefined; +} -/***/ 87661: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +exports.DEFAULT_TRANSPORT_BUFFER_SIZE = DEFAULT_TRANSPORT_BUFFER_SIZE; +exports.createTransport = createTransport; +//# sourceMappingURL=base.js.map -"use strict"; -/*! - * body-parser - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ +/***/ }), + +/***/ 47864: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); +const utils = __nccwpck_require__(57540); +const api = __nccwpck_require__(91458); /** - * Module dependencies. + * Gets an event from an envelope. + * + * This is only exported for use in the tests */ +function eventFromEnvelope(env, types) { + let event; -var bytes = __nccwpck_require__(89015) -var debug = __nccwpck_require__(66515)('body-parser:raw') -var read = __nccwpck_require__(45109) -var typeis = __nccwpck_require__(54693) + utils.forEachEnvelopeItem(env, (item, type) => { + if (types.includes(type)) { + event = Array.isArray(item) ? (item )[1] : undefined; + } + // bail out if we found an event + return !!event; + }); + + return event; +} /** - * Module exports. + * Creates a transport that overrides the release on all events. */ +function makeOverrideReleaseTransport( + createTransport, + release, +) { + return options => { + const transport = createTransport(options); -module.exports = raw + return { + ...transport, + send: async (envelope) => { + const event = eventFromEnvelope(envelope, ['event', 'transaction', 'profile', 'replay_event']); + + if (event) { + event.release = release; + } + return transport.send(envelope); + }, + }; + }; +} + +/** Overrides the DSN in the envelope header */ +function overrideDsn(envelope, dsn) { + return utils.createEnvelope( + dsn + ? { + ...envelope[0], + dsn, + } + : envelope[0], + envelope[1], + ); +} /** - * Create a middleware to parse raw bodies. - * - * @param {object} [options] - * @return {function} - * @api public + * Creates a transport that can send events to different DSNs depending on the envelope contents. */ +function makeMultiplexedTransport( + createTransport, + matcher, +) { + return options => { + const fallbackTransport = createTransport(options); + const otherTransports = new Map(); -function raw (options) { - var opts = options || {} + function getTransport(dsn, release) { + // We create a transport for every unique dsn/release combination as there may be code from multiple releases in + // use at the same time + const key = release ? `${dsn}:${release}` : dsn; - var inflate = opts.inflate !== false - var limit = typeof opts.limit !== 'number' - ? bytes.parse(opts.limit || '100kb') - : opts.limit - var type = opts.type || 'application/octet-stream' - var verify = opts.verify || false + let transport = otherTransports.get(key); - if (verify !== false && typeof verify !== 'function') { - throw new TypeError('option verify must be function') - } + if (!transport) { + const validatedDsn = utils.dsnFromString(dsn); + if (!validatedDsn) { + return undefined; + } - // create the appropriate type checking function - var shouldParse = typeof type !== 'function' - ? typeChecker(type) - : type + const url = api.getEnvelopeEndpointWithUrlEncodedAuth(validatedDsn, options.tunnel); - function parse (buf) { - return buf - } + transport = release + ? makeOverrideReleaseTransport(createTransport, release)({ ...options, url }) + : createTransport({ ...options, url }); - return function rawParser (req, res, next) { - if (req._body) { - debug('body already parsed') - next() - return + otherTransports.set(key, transport); + } + + return [dsn, transport]; } - req.body = req.body || {} + async function send(envelope) { + function getEvent(types) { + const eventTypes = types && types.length ? types : ['event']; + return eventFromEnvelope(envelope, eventTypes); + } - // skip requests without bodies - if (!typeis.hasBody(req)) { - debug('skip empty body') - next() - return - } + const transports = matcher({ envelope, getEvent }) + .map(result => { + if (typeof result === 'string') { + return getTransport(result, undefined); + } else { + return getTransport(result.dsn, result.release); + } + }) + .filter((t) => !!t); - debug('content-type %j', req.headers['content-type']) + // If we have no transports to send to, use the fallback transport + if (transports.length === 0) { + // Don't override the DSN in the header for the fallback transport. '' is falsy + transports.push(['', fallbackTransport]); + } - // determine if request should be parsed - if (!shouldParse(req)) { - debug('skip parsing') - next() - return + const results = await Promise.all( + transports.map(([dsn, transport]) => transport.send(overrideDsn(envelope, dsn))), + ); + + return results[0]; } - // read - read(req, res, next, parse, debug, { - encoding: null, - inflate: inflate, - limit: limit, - verify: verify - }) - } -} + async function flush(timeout) { + const promises = [await fallbackTransport.flush(timeout)]; + for (const [, transport] of otherTransports) { + promises.push(await transport.flush(timeout)); + } -/** - * Get the simple type checker. - * - * @param {string} type - * @return {function} - */ + return promises.every(r => r); + } -function typeChecker (type) { - return function checkType (req) { - return Boolean(typeis(req, type)) - } + return { + send, + flush, + }; + }; } +exports.eventFromEnvelope = eventFromEnvelope; +exports.makeMultiplexedTransport = makeMultiplexedTransport; +//# sourceMappingURL=multiplexed.js.map + /***/ }), -/***/ 49488: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 61006: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; -/*! - * body-parser - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(93376); +const MIN_DELAY = 100; // 100 ms +const START_DELAY = 5000; // 5 seconds +const MAX_DELAY = 3.6e6; // 1 hour + +function log(msg, error) { + debugBuild.DEBUG_BUILD && utils.logger.info(`[Offline]: ${msg}`, error); +} /** - * Module dependencies. + * Wraps a transport and stores and retries events when they fail to send. + * + * @param createTransport The transport to wrap. */ +function makeOfflineTransport( + createTransport, +) { + return options => { + const transport = createTransport(options); + const store = options.createStore ? options.createStore(options) : undefined; + + let retryDelay = START_DELAY; + let flushTimer; + + function shouldQueue(env, error, retryDelay) { + // We don't queue Session Replay envelopes because they are: + // - Ordered and Replay relies on the response status to know when they're successfully sent. + // - Likely to fill the queue quickly and block other events from being sent. + // We also want to drop client reports because they can be generated when we retry sending events while offline. + if (utils.envelopeContainsItemType(env, ['replay_event', 'replay_recording', 'client_report'])) { + return false; + } -var bytes = __nccwpck_require__(89015) -var contentType = __nccwpck_require__(22541) -var debug = __nccwpck_require__(66515)('body-parser:text') -var read = __nccwpck_require__(45109) -var typeis = __nccwpck_require__(54693) + if (options.shouldStore) { + return options.shouldStore(env, error, retryDelay); + } -/** - * Module exports. - */ + return true; + } -module.exports = text + function flushIn(delay) { + if (!store) { + return; + } -/** - * Create a middleware to parse text bodies. - * - * @param {object} [options] - * @return {function} - * @api public - */ + if (flushTimer) { + clearTimeout(flushTimer ); + } -function text (options) { - var opts = options || {} + flushTimer = setTimeout(async () => { + flushTimer = undefined; - var defaultCharset = opts.defaultCharset || 'utf-8' - var inflate = opts.inflate !== false - var limit = typeof opts.limit !== 'number' - ? bytes.parse(opts.limit || '100kb') - : opts.limit - var type = opts.type || 'text/plain' - var verify = opts.verify || false + const found = await store.pop(); + if (found) { + log('Attempting to send previously queued event'); + void send(found).catch(e => { + log('Failed to retry sending', e); + }); + } + }, delay) ; - if (verify !== false && typeof verify !== 'function') { - throw new TypeError('option verify must be function') - } + // We need to unref the timer in node.js, otherwise the node process never exit. + if (typeof flushTimer !== 'number' && flushTimer.unref) { + flushTimer.unref(); + } + } - // create the appropriate type checking function - var shouldParse = typeof type !== 'function' - ? typeChecker(type) - : type + function flushWithBackOff() { + if (flushTimer) { + return; + } - function parse (buf) { - return buf - } + flushIn(retryDelay); - return function textParser (req, res, next) { - if (req._body) { - debug('body already parsed') - next() - return + retryDelay = Math.min(retryDelay * 2, MAX_DELAY); } - req.body = req.body || {} + async function send(envelope) { + try { + const result = await transport.send(envelope); - // skip requests without bodies - if (!typeis.hasBody(req)) { - debug('skip empty body') - next() - return - } + let delay = MIN_DELAY; - debug('content-type %j', req.headers['content-type']) + if (result) { + // If there's a retry-after header, use that as the next delay. + if (result.headers && result.headers['retry-after']) { + delay = utils.parseRetryAfterHeader(result.headers['retry-after']); + } // If we have a server error, return now so we don't flush the queue. + else if ((result.statusCode || 0) >= 400) { + return result; + } + } - // determine if request should be parsed - if (!shouldParse(req)) { - debug('skip parsing') - next() - return + flushIn(delay); + retryDelay = START_DELAY; + return result; + } catch (e) { + if (store && (await shouldQueue(envelope, e , retryDelay))) { + await store.insert(envelope); + flushWithBackOff(); + log('Error sending. Event queued', e ); + return {}; + } else { + throw e; + } + } } - // get charset - var charset = getCharset(req) || defaultCharset + if (options.flushAtStartup) { + flushWithBackOff(); + } - // read - read(req, res, next, parse, debug, { - encoding: charset, - inflate: inflate, - limit: limit, - verify: verify - }) - } + return { + send, + flush: t => transport.flush(t), + }; + }; } -/** - * Get the charset of a request. - * - * @param {object} req - * @api private - */ +exports.MIN_DELAY = MIN_DELAY; +exports.START_DELAY = START_DELAY; +exports.makeOfflineTransport = makeOfflineTransport; +//# sourceMappingURL=offline.js.map -function getCharset (req) { - try { - return (contentType.parse(req).parameters.charset || '').toLowerCase() - } catch (e) { - return undefined - } -} + +/***/ }), + +/***/ 87059: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); +const dynamicSamplingContext = __nccwpck_require__(76248); +const getRootSpan = __nccwpck_require__(27304); +const spanUtils = __nccwpck_require__(98313); /** - * Get the simple type checker. - * - * @param {string} type - * @return {function} + * Applies data from the scope to the event and runs all event processors on it. */ +function applyScopeDataToEvent(event, data) { + const { fingerprint, span, breadcrumbs, sdkProcessingMetadata } = data; -function typeChecker (type) { - return function checkType (req) { - return Boolean(typeis(req, type)) + // Apply general data + applyDataToEvent(event, data); + + // We want to set the trace context for normal events only if there isn't already + // a trace context on the event. There is a product feature in place where we link + // errors with transaction and it relies on that. + if (span) { + applySpanToEvent(event, span); } + + applyFingerprintToEvent(event, fingerprint); + applyBreadcrumbsToEvent(event, breadcrumbs); + applySdkMetadataToEvent(event, sdkProcessingMetadata); } +/** Merge data of two scopes together. */ +function mergeScopeData(data, mergeData) { + const { + extra, + tags, + user, + contexts, + level, + sdkProcessingMetadata, + breadcrumbs, + fingerprint, + eventProcessors, + attachments, + propagationContext, + // eslint-disable-next-line deprecation/deprecation + transactionName, + span, + } = mergeData; -/***/ }), + mergeAndOverwriteScopeData(data, 'extra', extra); + mergeAndOverwriteScopeData(data, 'tags', tags); + mergeAndOverwriteScopeData(data, 'user', user); + mergeAndOverwriteScopeData(data, 'contexts', contexts); + mergeAndOverwriteScopeData(data, 'sdkProcessingMetadata', sdkProcessingMetadata); -/***/ 55514: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (level) { + data.level = level; + } -"use strict"; -/*! - * body-parser - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ + if (transactionName) { + // eslint-disable-next-line deprecation/deprecation + data.transactionName = transactionName; + } + if (span) { + data.span = span; + } + if (breadcrumbs.length) { + data.breadcrumbs = [...data.breadcrumbs, ...breadcrumbs]; + } -/** - * Module dependencies. - * @private - */ + if (fingerprint.length) { + data.fingerprint = [...data.fingerprint, ...fingerprint]; + } -var bytes = __nccwpck_require__(89015) -var contentType = __nccwpck_require__(22541) -var createError = __nccwpck_require__(8927) -var debug = __nccwpck_require__(66515)('body-parser:urlencoded') -var deprecate = __nccwpck_require__(77267)('body-parser') -var read = __nccwpck_require__(45109) -var typeis = __nccwpck_require__(54693) + if (eventProcessors.length) { + data.eventProcessors = [...data.eventProcessors, ...eventProcessors]; + } -/** - * Module exports. - */ + if (attachments.length) { + data.attachments = [...data.attachments, ...attachments]; + } -module.exports = urlencoded + data.propagationContext = { ...data.propagationContext, ...propagationContext }; +} /** - * Cache of parser modules. + * Merges certain scope data. Undefined values will overwrite any existing values. + * Exported only for tests. */ +function mergeAndOverwriteScopeData -var parsers = Object.create(null) +(data, prop, mergeVal) { + if (mergeVal && Object.keys(mergeVal).length) { + // Clone object + data[prop] = { ...data[prop] }; + for (const key in mergeVal) { + if (Object.prototype.hasOwnProperty.call(mergeVal, key)) { + data[prop][key] = mergeVal[key]; + } + } + } +} -/** - * Create a middleware to parse urlencoded bodies. - * - * @param {object} [options] - * @return {function} - * @public - */ +function applyDataToEvent(event, data) { + const { + extra, + tags, + user, + contexts, + level, + // eslint-disable-next-line deprecation/deprecation + transactionName, + } = data; -function urlencoded (options) { - var opts = options || {} + const cleanedExtra = utils.dropUndefinedKeys(extra); + if (cleanedExtra && Object.keys(cleanedExtra).length) { + event.extra = { ...cleanedExtra, ...event.extra }; + } - // notice because option default will flip in next major - if (opts.extended === undefined) { - deprecate('undefined extended: provide extended option') + const cleanedTags = utils.dropUndefinedKeys(tags); + if (cleanedTags && Object.keys(cleanedTags).length) { + event.tags = { ...cleanedTags, ...event.tags }; } - var extended = opts.extended !== false - var inflate = opts.inflate !== false - var limit = typeof opts.limit !== 'number' - ? bytes.parse(opts.limit || '100kb') - : opts.limit - var type = opts.type || 'application/x-www-form-urlencoded' - var verify = opts.verify || false - var depth = typeof opts.depth !== 'number' - ? Number(opts.depth || 32) - : opts.depth + const cleanedUser = utils.dropUndefinedKeys(user); + if (cleanedUser && Object.keys(cleanedUser).length) { + event.user = { ...cleanedUser, ...event.user }; + } - if (verify !== false && typeof verify !== 'function') { - throw new TypeError('option verify must be function') + const cleanedContexts = utils.dropUndefinedKeys(contexts); + if (cleanedContexts && Object.keys(cleanedContexts).length) { + event.contexts = { ...cleanedContexts, ...event.contexts }; } - // create the appropriate query parser - var queryparse = extended - ? extendedparser(opts) - : simpleparser(opts) + if (level) { + event.level = level; + } - // create the appropriate type checking function - var shouldParse = typeof type !== 'function' - ? typeChecker(type) - : type - - function parse (body) { - return body.length - ? queryparse(body) - : {} + if (transactionName) { + event.transaction = transactionName; } +} - return function urlencodedParser (req, res, next) { - if (req._body) { - debug('body already parsed') - next() - return - } - - req.body = req.body || {} - - // skip requests without bodies - if (!typeis.hasBody(req)) { - debug('skip empty body') - next() - return - } - - debug('content-type %j', req.headers['content-type']) +function applyBreadcrumbsToEvent(event, breadcrumbs) { + const mergedBreadcrumbs = [...(event.breadcrumbs || []), ...breadcrumbs]; + event.breadcrumbs = mergedBreadcrumbs.length ? mergedBreadcrumbs : undefined; +} - // determine if request should be parsed - if (!shouldParse(req)) { - debug('skip parsing') - next() - return - } +function applySdkMetadataToEvent(event, sdkProcessingMetadata) { + event.sdkProcessingMetadata = { + ...event.sdkProcessingMetadata, + ...sdkProcessingMetadata, + }; +} - // assert charset - var charset = getCharset(req) || 'utf-8' - if (charset !== 'utf-8') { - debug('invalid charset') - next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { - charset: charset, - type: 'charset.unsupported' - })) - return +function applySpanToEvent(event, span) { + event.contexts = { trace: spanUtils.spanToTraceContext(span), ...event.contexts }; + const rootSpan = getRootSpan.getRootSpan(span); + if (rootSpan) { + event.sdkProcessingMetadata = { + dynamicSamplingContext: dynamicSamplingContext.getDynamicSamplingContextFromSpan(span), + ...event.sdkProcessingMetadata, + }; + const transactionName = spanUtils.spanToJSON(rootSpan).description; + if (transactionName) { + event.tags = { transaction: transactionName, ...event.tags }; } - - // read - read(req, res, next, parse, debug, { - debug: debug, - encoding: charset, - inflate: inflate, - limit: limit, - verify: verify, - depth: depth - }) } } /** - * Get the extended query parser. - * - * @param {object} options + * Applies fingerprint from the scope to the event if there's one, + * uses message if there's one instead or get rid of empty fingerprint */ +function applyFingerprintToEvent(event, fingerprint) { + // Make sure it's an array first and we actually have something in place + event.fingerprint = event.fingerprint ? utils.arrayify(event.fingerprint) : []; -function extendedparser (options) { - var parameterLimit = options.parameterLimit !== undefined - ? options.parameterLimit - : 1000 - - var depth = typeof options.depth !== 'number' - ? Number(options.depth || 32) - : options.depth - var parse = parser('qs') - - if (isNaN(parameterLimit) || parameterLimit < 1) { - throw new TypeError('option parameterLimit must be a positive number') + // If we have something on the scope, then merge it with event + if (fingerprint) { + event.fingerprint = event.fingerprint.concat(fingerprint); } - if (isNaN(depth) || depth < 0) { - throw new TypeError('option depth must be a zero or a positive number') + // If we have no data at all, remove empty array default + if (event.fingerprint && !event.fingerprint.length) { + delete event.fingerprint; } +} - if (isFinite(parameterLimit)) { - parameterLimit = parameterLimit | 0 - } +exports.applyScopeDataToEvent = applyScopeDataToEvent; +exports.mergeAndOverwriteScopeData = mergeAndOverwriteScopeData; +exports.mergeScopeData = mergeScopeData; +//# sourceMappingURL=applyScopeDataToEvent.js.map - return function queryparse (body) { - var paramCount = parameterCount(body, parameterLimit) - if (paramCount === undefined) { - debug('too many parameters') - throw createError(413, 'too many parameters', { - type: 'parameters.too.many' - }) - } +/***/ }), - var arrayLimit = Math.max(100, paramCount) +/***/ 27304: +/***/ ((__unused_webpack_module, exports) => { - debug('parse extended urlencoding') - try { - return parse(body, { - allowPrototypes: true, - arrayLimit: arrayLimit, - depth: depth, - strictDepth: true, - parameterLimit: parameterLimit - }) - } catch (err) { - if (err instanceof RangeError) { - throw createError(400, 'The input exceeded the depth', { - type: 'querystring.parse.rangeError' - }) - } else { - throw err - } - } - } +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/** + * Returns the root span of a given span. + * + * As long as we use `Transaction`s internally, the returned root span + * will be a `Transaction` but be aware that this might change in the future. + * + * If the given span has no root span or transaction, `undefined` is returned. + */ +function getRootSpan(span) { + // TODO (v8): Remove this check and just return span + // eslint-disable-next-line deprecation/deprecation + return span.transaction; } +exports.getRootSpan = getRootSpan; +//# sourceMappingURL=getRootSpan.js.map + + +/***/ }), + +/***/ 57116: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); + /** - * Get the charset of a request. + * Wrap a callback function with error handling. + * If an error is thrown, it will be passed to the `onError` callback and re-thrown. * - * @param {object} req - * @api private + * If the return value of the function is a promise, it will be handled with `maybeHandlePromiseRejection`. + * + * If an `onFinally` callback is provided, this will be called when the callback has finished + * - so if it returns a promise, once the promise resolved/rejected, + * else once the callback has finished executing. + * The `onFinally` callback will _always_ be called, no matter if an error was thrown or not. */ +function handleCallbackErrors -function getCharset (req) { +( + fn, + onError, + // eslint-disable-next-line @typescript-eslint/no-empty-function + onFinally = () => {}, +) { + let maybePromiseResult; try { - return (contentType.parse(req).parameters.charset || '').toLowerCase() + maybePromiseResult = fn(); } catch (e) { - return undefined + onError(e); + onFinally(); + throw e; } + + return maybeHandlePromiseRejection(maybePromiseResult, onError, onFinally); } /** - * Count the number of parameters, stopping once limit reached - * - * @param {string} body - * @param {number} limit - * @api private + * Maybe handle a promise rejection. + * This expects to be given a value that _may_ be a promise, or any other value. + * If it is a promise, and it rejects, it will call the `onError` callback. + * Other than this, it will generally return the given value as-is. */ - -function parameterCount (body, limit) { - var count = 0 - var index = 0 - - while ((index = body.indexOf('&', index)) !== -1) { - count++ - index++ - - if (count === limit) { - return undefined - } +function maybeHandlePromiseRejection( + value, + onError, + onFinally, +) { + if (utils.isThenable(value)) { + // @ts-expect-error - the isThenable check returns the "wrong" type here + return value.then( + res => { + onFinally(); + return res; + }, + e => { + onError(e); + onFinally(); + throw e; + }, + ); } - return count + onFinally(); + return value; } -/** - * Get parser for module name dynamically. - * - * @param {string} name - * @return {function} - * @api private - */ +exports.handleCallbackErrors = handleCallbackErrors; +//# sourceMappingURL=handleCallbackErrors.js.map -function parser (name) { - var mod = parsers[name] - if (mod !== undefined) { - return mod.parse - } +/***/ }), - // this uses a switch for static require analysis - switch (name) { - case 'qs': - mod = __nccwpck_require__(91833) - break - case 'querystring': - mod = __nccwpck_require__(83480) - break - } +/***/ 7747: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // store to prevent invoking require() - parsers[name] = mod +Object.defineProperty(exports, "__esModule", ({ value: true })); - return mod.parse -} +const exports$1 = __nccwpck_require__(74313); + +// Treeshakable guard to remove all code related to tracing /** - * Get the simple query parser. + * Determines if tracing is currently enabled. * - * @param {object} options + * Tracing is enabled when at least one of `tracesSampleRate` and `tracesSampler` is defined in the SDK config. */ +function hasTracingEnabled( + maybeOptions, +) { + if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) { + return false; + } -function simpleparser (options) { - var parameterLimit = options.parameterLimit !== undefined - ? options.parameterLimit - : 1000 - var parse = parser('querystring') + const client = exports$1.getClient(); + const options = maybeOptions || (client && client.getOptions()); + return !!options && (options.enableTracing || 'tracesSampleRate' in options || 'tracesSampler' in options); +} - if (isNaN(parameterLimit) || parameterLimit < 1) { - throw new TypeError('option parameterLimit must be a positive number') - } +exports.hasTracingEnabled = hasTracingEnabled; +//# sourceMappingURL=hasTracingEnabled.js.map - if (isFinite(parameterLimit)) { - parameterLimit = parameterLimit | 0 - } - return function queryparse (body) { - var paramCount = parameterCount(body, parameterLimit) +/***/ }), - if (paramCount === undefined) { - debug('too many parameters') - throw createError(413, 'too many parameters', { - type: 'parameters.too.many' - }) - } +/***/ 75227: +/***/ ((__unused_webpack_module, exports) => { - debug('parse urlencoding') - return parse(body, undefined, undefined, { maxKeys: parameterLimit }) - } -} +Object.defineProperty(exports, "__esModule", ({ value: true })); /** - * Get the simple type checker. + * Checks whether given url points to Sentry server + * @param url url to verify * - * @param {string} type - * @return {function} + * TODO(v8): Remove Hub fallback type */ +// eslint-disable-next-line deprecation/deprecation +function isSentryRequestUrl(url, hubOrClient) { + const client = + hubOrClient && isHub(hubOrClient) + ? // eslint-disable-next-line deprecation/deprecation + hubOrClient.getClient() + : hubOrClient; + const dsn = client && client.getDsn(); + const tunnel = client && client.getOptions().tunnel; -function typeChecker (type) { - return function checkType (req) { - return Boolean(typeis(req, type)) - } + return checkDsn(url, dsn) || checkTunnel(url, tunnel); } +function checkTunnel(url, tunnel) { + if (!tunnel) { + return false; + } -/***/ }), - -/***/ 60777: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return removeTrailingSlash(url) === removeTrailingSlash(tunnel); +} -"use strict"; +function checkDsn(url, dsn) { + return dsn ? url.includes(dsn.host) : false; +} +function removeTrailingSlash(str) { + return str[str.length - 1] === '/' ? str.slice(0, -1) : str; +} -var Batcher, Events, parser; -parser = __nccwpck_require__(90651); -Events = __nccwpck_require__(81065); +// eslint-disable-next-line deprecation/deprecation +function isHub(hubOrClient) { + // eslint-disable-next-line deprecation/deprecation + return (hubOrClient ).getClient !== undefined; +} -Batcher = function () { - class Batcher { - constructor(options = {}) { - this.options = options; - parser.load(this.options, this.defaults, this); - this.Events = new Events(this); - this._arr = []; +exports.isSentryRequestUrl = isSentryRequestUrl; +//# sourceMappingURL=isSentryRequestUrl.js.map - this._resetPromise(); - this._lastFlush = Date.now(); - } +/***/ }), - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } +/***/ 70113: +/***/ ((__unused_webpack_module, exports) => { - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); +Object.defineProperty(exports, "__esModule", ({ value: true })); - this._resolve(); +/** + * Tagged template function which returns paramaterized representation of the message + * For example: parameterize`This is a log statement with ${x} and ${y} params`, would return: + * "__sentry_template_string__": 'This is a log statement with %s and %s params', + * "__sentry_template_values__": ['first', 'second'] + * @param strings An array of string values splitted between expressions + * @param values Expressions extracted from template string + * @returns String with template information in __sentry_template_string__ and __sentry_template_values__ properties + */ +function parameterize(strings, ...values) { + const formatted = new String(String.raw(strings, ...values)) ; + formatted.__sentry_template_string__ = strings.join('\x00').replace(/%/g, '%%').replace(/\0/g, '%s'); + formatted.__sentry_template_values__ = values; + return formatted; +} - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } +exports.parameterize = parameterize; +//# sourceMappingURL=parameterize.js.map - add(data) { - var ret; - this._arr.push(data); +/***/ }), - ret = this._promise; +/***/ 57847: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (this._arr.length === this.maxSize) { - this._flush(); - } else if (this.maxTime != null && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - return ret; - } +const utils = __nccwpck_require__(57540); +const constants = __nccwpck_require__(11363); +const eventProcessors = __nccwpck_require__(88807); +const scope = __nccwpck_require__(77226); +const applyScopeDataToEvent = __nccwpck_require__(87059); +const spanUtils = __nccwpck_require__(98313); - } +/** + * This type makes sure that we get either a CaptureContext, OR an EventHint. + * It does not allow mixing them, which could lead to unexpected outcomes, e.g. this is disallowed: + * { user: { id: '123' }, mechanism: { handled: false } } + */ - ; - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise +/** + * Adds common information to events. + * + * The information includes release and environment from `options`, + * breadcrumbs and context (extra, tags and user) from the scope. + * + * Information that is already present in the event is never overwritten. For + * nested objects, such as the context, keys are merged. + * + * Note: This also triggers callbacks for `addGlobalEventProcessor`, but not `beforeSend`. + * + * @param event The original event. + * @param hint May contain additional information about the original exception. + * @param scope A scope containing event metadata. + * @returns A new event with more information. + * @hidden + */ +function prepareEvent( + options, + event, + hint, + scope$1, + client, + isolationScope, +) { + const { normalizeDepth = 3, normalizeMaxBreadth = 1000 } = options; + const prepared = { + ...event, + event_id: event.event_id || hint.event_id || utils.uuid4(), + timestamp: event.timestamp || utils.dateTimestampInSeconds(), }; - return Batcher; -}.call(void 0); - -module.exports = Batcher; + const integrations = hint.integrations || options.integrations.map(i => i.name); -/***/ }), + applyClientOptions(prepared, options); + applyIntegrationsMetadata(prepared, integrations); -/***/ 29263: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // Only put debug IDs onto frames for error events. + if (event.type === undefined) { + applyDebugIds(prepared, options.stackParser); + } -"use strict"; + // If we have scope given to us, use it as the base for further modifications. + // This allows us to prevent unnecessary copying of data if `captureContext` is not provided. + const finalScope = getFinalScope(scope$1, hint.captureContext); + if (hint.mechanism) { + utils.addExceptionMechanism(prepared, hint.mechanism); + } -function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } + const clientEventProcessors = client && client.getEventProcessors ? client.getEventProcessors() : []; -function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } + // This should be the last thing called, since we want that + // {@link Hub.addEventProcessor} gets the finished prepared event. + // Merge scope data together + const data = scope.getGlobalScope().getScopeData(); -function _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest(); } + if (isolationScope) { + const isolationData = isolationScope.getScopeData(); + applyScopeDataToEvent.mergeScopeData(data, isolationData); + } -function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } + if (finalScope) { + const finalScopeData = finalScope.getScopeData(); + applyScopeDataToEvent.mergeScopeData(data, finalScopeData); + } -function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } + const attachments = [...(hint.attachments || []), ...data.attachments]; + if (attachments.length) { + hint.attachments = attachments; + } -function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } + applyScopeDataToEvent.applyScopeDataToEvent(prepared, data); -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + // TODO (v8): Update this order to be: Global > Client > Scope + const eventProcessors$1 = [ + ...clientEventProcessors, + // eslint-disable-next-line deprecation/deprecation + ...eventProcessors.getGlobalEventProcessors(), + // Run scope event processors _after_ all other processors + ...data.eventProcessors, + ]; -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + const result = eventProcessors.notifyEventProcessors(eventProcessors$1, prepared, hint); -var Bottleneck, - DEFAULT_PRIORITY, - Events, - Job, - LocalDatastore, - NUM_PRIORITIES, - Queues, - RedisDatastore, - States, - Sync, - parser, - splice = [].splice; -NUM_PRIORITIES = 10; -DEFAULT_PRIORITY = 5; -parser = __nccwpck_require__(90651); -Queues = __nccwpck_require__(61944); -Job = __nccwpck_require__(73549); -LocalDatastore = __nccwpck_require__(4104); -RedisDatastore = __nccwpck_require__(35068); -Events = __nccwpck_require__(81065); -States = __nccwpck_require__(72878); -Sync = __nccwpck_require__(33923); + return result.then(evt => { + if (evt) { + // We apply the debug_meta field only after all event processors have ran, so that if any event processors modified + // file names (e.g.the RewriteFrames integration) the filename -> debug ID relationship isn't destroyed. + // This should not cause any PII issues, since we're only moving data that is already on the event and not adding + // any new data + applyDebugMeta(evt); + } -Bottleneck = function () { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); + if (typeof normalizeDepth === 'number' && normalizeDepth > 0) { + return normalizeEvent(evt, normalizeDepth, normalizeMaxBreadth); + } + return evt; + }); +} - this._validateOptions(options, invalid); +/** + * Enhances event using the client configuration. + * It takes care of all "static" values like environment, release and `dist`, + * as well as truncating overly long values. + * @param event event instance to be enhanced + */ +function applyClientOptions(event, options) { + const { environment, release, dist, maxValueLength = 250 } = options; - parser.load(options, this.instanceDefaults, this); - this._queues = new Queues(NUM_PRIORITIES); - this._scheduled = {}; - this._states = new States(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events(this); - this._submitLock = new Sync("submit", this.Promise); - this._registerLock = new Sync("register", this.Promise); - storeOptions = parser.load(options, this.storeDefaults, {}); + if (!('environment' in event)) { + event.environment = 'environment' in options ? environment : constants.DEFAULT_ENVIRONMENT; + } - this._store = function () { - if (this.datastore === "redis" || this.datastore === "ioredis" || this.connection != null) { - storeInstanceOptions = parser.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser.load(options, this.localStoreDefaults, {}); - return new LocalDatastore(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }.call(this); + if (event.release === undefined && release !== undefined) { + event.release = release; + } - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); + if (event.dist === undefined && dist !== undefined) { + event.dist = dist; + } - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } + if (event.message) { + event.message = utils.truncate(event.message, maxValueLength); + } - _validateOptions(options, invalid) { - if (!(options != null && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } + const exception = event.exception && event.exception.values && event.exception.values[0]; + if (exception && exception.value) { + exception.value = utils.truncate(exception.value, maxValueLength); + } - ready() { - return this._store.ready; - } + const request = event.request; + if (request && request.url) { + request.url = utils.truncate(request.url, maxValueLength); + } +} - clients() { - return this._store.clients; - } +const debugIdStackParserCache = new WeakMap(); - channel() { - return `b_${this.id}`; - } +/** + * Puts debug IDs into the stack frames of an error event. + */ +function applyDebugIds(event, stackParser) { + const debugIdMap = utils.GLOBAL_OBJ._sentryDebugIds; - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } + if (!debugIdMap) { + return; + } - publish(message) { - return this._store.__publish__(message); - } + let debugIdStackFramesCache; + const cachedDebugIdStackFrameCache = debugIdStackParserCache.get(stackParser); + if (cachedDebugIdStackFrameCache) { + debugIdStackFramesCache = cachedDebugIdStackFrameCache; + } else { + debugIdStackFramesCache = new Map(); + debugIdStackParserCache.set(stackParser, debugIdStackFramesCache); + } - disconnect(flush = true) { - return this._store.__disconnect__(flush); + // Build a map of filename -> debug_id + const filenameDebugIdMap = Object.keys(debugIdMap).reduce((acc, debugIdStackTrace) => { + let parsedStack; + const cachedParsedStack = debugIdStackFramesCache.get(debugIdStackTrace); + if (cachedParsedStack) { + parsedStack = cachedParsedStack; + } else { + parsedStack = stackParser(debugIdStackTrace); + debugIdStackFramesCache.set(debugIdStackTrace, parsedStack); } - chain(_limiter) { - this._limiter = _limiter; - return this; + for (let i = parsedStack.length - 1; i >= 0; i--) { + const stackFrame = parsedStack[i]; + if (stackFrame.filename) { + acc[stackFrame.filename] = debugIdMap[debugIdStackTrace]; + break; + } } + return acc; + }, {}); - queued(priority) { - return this._queues.queued(priority); - } + try { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + event.exception.values.forEach(exception => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + exception.stacktrace.frames.forEach(frame => { + if (frame.filename) { + frame.debug_id = filenameDebugIdMap[frame.filename]; + } + }); + }); + } catch (e) { + // To save bundle size we're just try catching here instead of checking for the existence of all the different objects. + } +} - clusterQueued() { - return this._store.__queued__(); - } +/** + * Moves debug IDs from the stack frames of an error event into the debug_meta field. + */ +function applyDebugMeta(event) { + // Extract debug IDs and filenames from the stack frames on the event. + const filenameDebugIdMap = {}; + try { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + event.exception.values.forEach(exception => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + exception.stacktrace.frames.forEach(frame => { + if (frame.debug_id) { + if (frame.abs_path) { + filenameDebugIdMap[frame.abs_path] = frame.debug_id; + } else if (frame.filename) { + filenameDebugIdMap[frame.filename] = frame.debug_id; + } + delete frame.debug_id; + } + }); + }); + } catch (e) { + // To save bundle size we're just try catching here instead of checking for the existence of all the different objects. + } - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } + if (Object.keys(filenameDebugIdMap).length === 0) { + return; + } - running() { - return this._store.__running__(); - } + // Fill debug_meta information + event.debug_meta = event.debug_meta || {}; + event.debug_meta.images = event.debug_meta.images || []; + const images = event.debug_meta.images; + Object.keys(filenameDebugIdMap).forEach(filename => { + images.push({ + type: 'sourcemap', + code_file: filename, + debug_id: filenameDebugIdMap[filename], + }); + }); +} - done() { - return this._store.__done__(); - } +/** + * This function adds all used integrations to the SDK info in the event. + * @param event The event that will be filled with all integrations. + */ +function applyIntegrationsMetadata(event, integrationNames) { + if (integrationNames.length > 0) { + event.sdk = event.sdk || {}; + event.sdk.integrations = [...(event.sdk.integrations || []), ...integrationNames]; + } +} - jobStatus(id) { - return this._states.jobStatus(id); - } +/** + * Applies `normalize` function on necessary `Event` attributes to make them safe for serialization. + * Normalized keys: + * - `breadcrumbs.data` + * - `user` + * - `contexts` + * - `extra` + * @param event Event + * @returns Normalized event + */ +function normalizeEvent(event, depth, maxBreadth) { + if (!event) { + return null; + } - jobs(status) { - return this._states.statusJobs(status); - } + const normalized = { + ...event, + ...(event.breadcrumbs && { + breadcrumbs: event.breadcrumbs.map(b => ({ + ...b, + ...(b.data && { + data: utils.normalize(b.data, depth, maxBreadth), + }), + })), + }), + ...(event.user && { + user: utils.normalize(event.user, depth, maxBreadth), + }), + ...(event.contexts && { + contexts: utils.normalize(event.contexts, depth, maxBreadth), + }), + ...(event.extra && { + extra: utils.normalize(event.extra, depth, maxBreadth), + }), + }; - counts() { - return this._states.statusCounts(); - } + // event.contexts.trace stores information about a Transaction. Similarly, + // event.spans[] stores information about child Spans. Given that a + // Transaction is conceptually a Span, normalization should apply to both + // Transactions and Spans consistently. + // For now the decision is to skip normalization of Transactions and Spans, + // so this block overwrites the normalized event to add back the original + // Transaction information prior to normalization. + if (event.contexts && event.contexts.trace && normalized.contexts) { + normalized.contexts.trace = event.contexts.trace; - _randomIndex() { - return Math.random().toString(36).slice(2); + // event.contexts.trace.data may contain circular/dangerous data so we need to normalize it + if (event.contexts.trace.data) { + normalized.contexts.trace.data = utils.normalize(event.contexts.trace.data, depth, maxBreadth); } + } - check(weight = 1) { - return this._store.__check__(weight); - } + // event.spans[].data may contain circular/dangerous data so we need to normalize it + if (event.spans) { + normalized.spans = event.spans.map(span => { + const data = spanUtils.spanToJSON(span).data; - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; + if (data) { + // This is a bit weird, as we generally have `Span` instances here, but to be safe we do not assume so + // eslint-disable-next-line deprecation/deprecation + span.data = utils.normalize(data, depth, maxBreadth); } - } - _free(index, job, options, eventInfo) { - var _this = this; + return span; + }); + } - return _asyncToGenerator(function* () { - var e, running; + return normalized; +} - try { - var _ref = yield _this._store.__free__(index, options.weight); +function getFinalScope(scope$1, captureContext) { + if (!captureContext) { + return scope$1; + } - running = _ref.running; + const finalScope = scope$1 ? scope$1.clone() : new scope.Scope(); + finalScope.update(captureContext); + return finalScope; +} - _this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); +/** + * Parse either an `EventHint` directly, or convert a `CaptureContext` to an `EventHint`. + * This is used to allow to update method signatures that used to accept a `CaptureContext` but should now accept an `EventHint`. + */ +function parseEventHintOrCaptureContext( + hint, +) { + if (!hint) { + return undefined; + } - if (running === 0 && _this.empty()) { - return _this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return _this.Events.trigger("error", e); - } - })(); - } + // If you pass a Scope or `() => Scope` as CaptureContext, we just return this as captureContext + if (hintIsScopeOrFunction(hint)) { + return { captureContext: hint }; + } - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function () { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } + if (hintIsScopeContext(hint)) { + return { + captureContext: hint, + }; + } - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; + return hint; +} - if (this.queued() === 0) { - return this.Promise.resolve(null); - } +function hintIsScopeOrFunction( + hint, +) { + return hint instanceof scope.Scope || typeof hint === 'function'; +} - queue = this._queues.getFirst(); +const captureContextKeys = [ + 'user', + 'level', + 'extra', + 'contexts', + 'tags', + 'fingerprint', + 'requestSession', + 'propagationContext', +] ; - var _next2 = next = queue.first(); +function hintIsScopeContext(hint) { + return Object.keys(hint).some(key => captureContextKeys.includes(key )); +} - options = _next2.options; - args = _next2.args; +exports.applyDebugIds = applyDebugIds; +exports.applyDebugMeta = applyDebugMeta; +exports.parseEventHintOrCaptureContext = parseEventHintOrCaptureContext; +exports.prepareEvent = prepareEvent; +//# sourceMappingURL=prepareEvent.js.map - if (capacity != null && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, { - args, - options - }); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({ - success, - wait, - reservoir - }) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, { - success, - args, - options - }); +/***/ }), - if (success) { - queue.shift(); - empty = this.empty(); +/***/ 45229: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (empty) { - this.Events.trigger("empty"); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } +const version = __nccwpck_require__(3206); - this._run(index, next, wait); +/** + * A builder for the SDK metadata in the options for the SDK initialization. + * + * Note: This function is identical to `buildMetadata` in Remix and NextJS and SvelteKit. + * We don't extract it for bundle size reasons. + * @see https://github.com/getsentry/sentry-javascript/pull/7404 + * @see https://github.com/getsentry/sentry-javascript/pull/4196 + * + * If you make changes to this function consider updating the others as well. + * + * @param options SDK options object that gets mutated + * @param names list of package names + */ +function applySdkMetadata(options, name, names = [name], source = 'npm') { + const metadata = options._metadata || {}; - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } + if (!metadata.sdk) { + metadata.sdk = { + name: `sentry.javascript.${name}`, + packages: names.map(name => ({ + name: `${source}:@sentry/${name}`, + version: version.SDK_VERSION, + })), + version: version.SDK_VERSION, + }; + } - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then(drained => { - var newCapacity; + options._metadata = metadata; +} - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch(e => { - return this.Events.trigger("error", e); - }); - } +exports.applySdkMetadata = applySdkMetadata; +//# sourceMappingURL=sdkMetadata.js.map - _dropAllQueued(message) { - return this._queues.shiftAll(function (job) { - return job.doDrop({ - message - }); - }); - } - stop(options = {}) { - var done, waitForExecuting; - options = parser.load(options, this.stopDefaults); +/***/ }), - waitForExecuting = at => { - var finished; +/***/ 98313: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - finished = () => { - var counts; - counts = this._states.counts; - return counts[0] + counts[1] + counts[2] + counts[3] === at; - }; +Object.defineProperty(exports, "__esModule", ({ value: true })); - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; +const utils = __nccwpck_require__(57540); - done = options.dropWaitingJobs ? (this._run = function (index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; +// These are aligned with OpenTelemetry trace flags +const TRACE_FLAG_NONE = 0x0; +const TRACE_FLAG_SAMPLED = 0x1; - for (k in ref) { - v = ref[k]; +/** + * Convert a span to a trace context, which can be sent as the `trace` context in an event. + */ +function spanToTraceContext(span) { + const { spanId: span_id, traceId: trace_id } = span.spanContext(); + const { data, op, parent_span_id, status, tags, origin } = spanToJSON(span); - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } + return utils.dropUndefinedKeys({ + data, + op, + parent_span_id, + span_id, + status, + tags, + trace_id, + origin, + }); +} - this._dropAllQueued(options.dropErrorMessage); +/** + * Convert a Span to a Sentry trace header. + */ +function spanToTraceHeader(span) { + const { traceId, spanId } = span.spanContext(); + const sampled = spanIsSampled(span); + return utils.generateSentryTraceHeader(traceId, spanId, sampled); +} - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); +/** + * Convert a span time input intp a timestamp in seconds. + */ +function spanTimeInputToSeconds(input) { + if (typeof input === 'number') { + return ensureTimestampInSeconds(input); + } - this._receive = function (job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; + if (Array.isArray(input)) { + // See {@link HrTime} for the array-based time format + return input[0] + input[1] / 1e9; + } - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; + if (input instanceof Date) { + return ensureTimestampInSeconds(input.getTime()); + } - return done; - } + return utils.timestampInSeconds(); +} - _addToQueue(job) { - var _this2 = this; +/** + * Converts a timestamp to second, if it was in milliseconds, or keeps it as second. + */ +function ensureTimestampInSeconds(timestamp) { + const isMs = timestamp > 9999999999; + return isMs ? timestamp / 1000 : timestamp; +} - return _asyncToGenerator(function* () { - var args, blocked, error, options, reachedHWM, shifted, strategy; - args = job.args; - options = job.options; +/** + * Convert a span to a JSON representation. + * Note that all fields returned here are optional and need to be guarded against. + * + * Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json). + * This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility. + * And `spanToJSON` needs the Span class from `span.ts` to check here. + * TODO v8: When we remove the deprecated stuff from `span.ts`, we can remove the circular dependency again. + */ +function spanToJSON(span) { + if (spanIsSpanClass(span)) { + return span.getSpanJSON(); + } - try { - var _ref2 = yield _this2._store.__submit__(_this2.queued(), options.weight); + // Fallback: We also check for `.toJSON()` here... + // eslint-disable-next-line deprecation/deprecation + if (typeof span.toJSON === 'function') { + // eslint-disable-next-line deprecation/deprecation + return span.toJSON(); + } - reachedHWM = _ref2.reachedHWM; - blocked = _ref2.blocked; - strategy = _ref2.strategy; - } catch (error1) { - error = error1; + return {}; +} - _this2.Events.trigger("debug", `Could not queue ${options.id}`, { - args, - options, - error - }); +/** + * Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof. + * :( So instead we approximate this by checking if it has the `getSpanJSON` method. + */ +function spanIsSpanClass(span) { + return typeof (span ).getSpanJSON === 'function'; +} - job.doDrop({ - error - }); - return false; - } +/** + * Returns true if a span is sampled. + * In most cases, you should just use `span.isRecording()` instead. + * However, this has a slightly different semantic, as it also returns false if the span is finished. + * So in the case where this distinction is important, use this method. + */ +function spanIsSampled(span) { + // We align our trace flags with the ones OpenTelemetry use + // So we also check for sampled the same way they do. + const { traceFlags } = span.spanContext(); + // eslint-disable-next-line no-bitwise + return Boolean(traceFlags & TRACE_FLAG_SAMPLED); +} - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? _this2._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? _this2._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; +exports.TRACE_FLAG_NONE = TRACE_FLAG_NONE; +exports.TRACE_FLAG_SAMPLED = TRACE_FLAG_SAMPLED; +exports.spanIsSampled = spanIsSampled; +exports.spanTimeInputToSeconds = spanTimeInputToSeconds; +exports.spanToJSON = spanToJSON; +exports.spanToTraceContext = spanToTraceContext; +exports.spanToTraceHeader = spanToTraceHeader; +//# sourceMappingURL=spanUtils.js.map - if (shifted != null) { - shifted.doDrop(); - } - if (shifted == null || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } +/***/ }), - return reachedHWM; - } - } +/***/ 3206: +/***/ ((__unused_webpack_module, exports) => { - job.doQueue(reachedHWM, blocked); +Object.defineProperty(exports, "__esModule", ({ value: true })); - _this2._queues.push(job); +const SDK_VERSION = '7.119.2'; - yield _this2._drainAll(); - return reachedHWM; - })(); - } +exports.SDK_VERSION = SDK_VERSION; +//# sourceMappingURL=version.js.map - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } +/***/ }), - submit(...args) { - var cb, fn, job, options, ref, ref1, task; +/***/ 60679: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (typeof args[0] === "function") { - var _ref3, _ref4, _splice$call, _splice$call2; +Object.defineProperty(exports, "__esModule", ({ value: true })); - ref = args, (_ref3 = ref, _ref4 = _toArray(_ref3), fn = _ref4[0], args = _ref4.slice(1), _ref3), (_splice$call = splice.call(args, -1), _splice$call2 = _slicedToArray(_splice$call, 1), cb = _splice$call2[0], _splice$call); - options = parser.load({}, this.jobDefaults); - } else { - var _ref5, _ref6, _splice$call3, _splice$call4; +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); - ref1 = args, (_ref5 = ref1, _ref6 = _toArray(_ref5), options = _ref6[0], fn = _ref6[1], args = _ref6.slice(2), _ref5), (_splice$call3 = splice.call(args, -1), _splice$call4 = _slicedToArray(_splice$call3, 1), cb = _splice$call4[0], _splice$call3); - options = parser.load(options, this.jobDefaults); - } +const INTEGRATION_NAME = 'CaptureConsole'; - task = (...args) => { - return new this.Promise(function (resolve, reject) { - return fn(...args, function (...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; +const _captureConsoleIntegration = ((options = {}) => { + const levels = options.levels || utils.CONSOLE_LEVELS; - job = new Job(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function (args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function (args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + setup(client) { + if (!('console' in utils.GLOBAL_OBJ)) { + return; + } + + utils.addConsoleInstrumentationHandler(({ args, level }) => { + if (core.getClient() !== client || !levels.includes(level)) { + return; } - }); - return this._receive(job); - } - schedule(...args) { - var job, options, task; + consoleHandler(args, level); + }); + }, + }; +}) ; - if (typeof args[0] === "function") { - var _args = args; +const captureConsoleIntegration = core.defineIntegration(_captureConsoleIntegration); - var _args2 = _toArray(_args); +/** + * Send Console API calls as Sentry Events. + * @deprecated Use `captureConsoleIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const CaptureConsole = core.convertIntegrationFnToClass( + INTEGRATION_NAME, + captureConsoleIntegration, +) - task = _args2[0]; - args = _args2.slice(1); - options = {}; - } else { - var _args3 = args; +; - var _args4 = _toArray(_args3); +function consoleHandler(args, level) { + const captureContext = { + level: utils.severityLevelFromString(level), + extra: { + arguments: args, + }, + }; - options = _args4[0]; - task = _args4[1]; - args = _args4.slice(2); - } + core.withScope(scope => { + scope.addEventProcessor(event => { + event.logger = 'console'; - job = new Job(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + utils.addExceptionMechanism(event, { + handled: false, + type: 'console', + }); - this._receive(job); + return event; + }); - return job.promise; + if (level === 'assert' && args[0] === false) { + const message = `Assertion failed: ${utils.safeJoin(args.slice(1), ' ') || 'console.assert'}`; + scope.setExtra('arguments', args.slice(1)); + core.captureMessage(message, captureContext); + return; } - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - - wrapped = function wrapped(...args) { - return schedule(fn.bind(this), ...args); - }; - - wrapped.withOptions = function (options, ...args) { - return schedule(options, fn, ...args); - }; - - return wrapped; + const error = args.find(arg => arg instanceof Error); + if (level === 'error' && error) { + core.captureException(error, captureContext); + return; } - updateSettings(options = {}) { - var _this3 = this; - - return _asyncToGenerator(function* () { - yield _this3._store.__updateSettings__(parser.overwrite(options, _this3.storeDefaults)); - parser.overwrite(options, _this3.instanceDefaults, _this3); - return _this3; - })(); - } + const message = utils.safeJoin(args, ' '); + core.captureMessage(message, captureContext); + }); +} - currentReservoir() { - return this._store.__currentReservoir__(); - } +exports.CaptureConsole = CaptureConsole; +exports.captureConsoleIntegration = captureConsoleIntegration; +//# sourceMappingURL=captureconsole.js.map - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } - } +/***/ }), - ; - Bottleneck.default = Bottleneck; - Bottleneck.Events = Events; - Bottleneck.version = Bottleneck.prototype.version = (__nccwpck_require__(96701)/* .version */ .r); - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = __nccwpck_require__(88185); - Bottleneck.Group = Bottleneck.prototype.Group = __nccwpck_require__(11213); - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = __nccwpck_require__(28037); - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = __nccwpck_require__(41725); - Bottleneck.Batcher = Bottleneck.prototype.Batcher = __nccwpck_require__(60777); - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY, - weight: 1, - expiration: null, - id: "" - }; - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; - return Bottleneck; -}.call(void 0); +/***/ 18562: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -module.exports = Bottleneck; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); -/***/ 88185: -/***/ ((module) => { +const WINDOW = utils.GLOBAL_OBJ ; -"use strict"; +const DEFAULT_LINES_OF_CONTEXT = 7; +const INTEGRATION_NAME = 'ContextLines'; -var BottleneckError; -BottleneckError = class BottleneckError extends Error {}; -module.exports = BottleneckError; +const _contextLinesIntegration = ((options = {}) => { + const contextLines = options.frameContextLines != null ? options.frameContextLines : DEFAULT_LINES_OF_CONTEXT; -/***/ }), + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(event) { + return addSourceContext(event, contextLines); + }, + }; +}) ; -/***/ 64792: -/***/ ((module) => { +const contextLinesIntegration = core.defineIntegration(_contextLinesIntegration); -"use strict"; +/** + * Collects source context lines around the lines of stackframes pointing to JS embedded in + * the current page's HTML. + * + * This integration DOES NOT work for stack frames pointing to JS files that are loaded by the browser. + * For frames pointing to files, context lines are added during ingestion and symbolication + * by attempting to download the JS files to the Sentry backend. + * + * Use this integration if you have inline JS code in HTML pages that can't be accessed + * by our backend (e.g. due to a login-protected page). + * + * @deprecated Use `contextLinesIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const ContextLines = core.convertIntegrationFnToClass(INTEGRATION_NAME, contextLinesIntegration) +; -var DLList; -DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; +/** + * Processes an event and adds context lines. + */ +function addSourceContext(event, contextLines) { + const doc = WINDOW.document; + const htmlFilename = WINDOW.location && utils.stripUrlQueryAndFragment(WINDOW.location.href); + if (!doc || !htmlFilename) { + return event; } - push(value) { - var node; - this.length++; + const exceptions = event.exception && event.exception.values; + if (!exceptions || !exceptions.length) { + return event; + } - if (typeof this.incr === "function") { - this.incr(); - } + const html = doc.documentElement.innerHTML; + if (!html) { + return event; + } - node = { - value, - prev: this._last, - next: null - }; + const htmlLines = ['', '', ...html.split('\n'), '']; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; + exceptions.forEach(exception => { + const stacktrace = exception.stacktrace; + if (stacktrace && stacktrace.frames) { + stacktrace.frames = stacktrace.frames.map(frame => + applySourceContextToFrame(frame, htmlLines, htmlFilename, contextLines), + ); } + }); - return void 0; + return event; +} + +/** + * Only exported for testing + */ +function applySourceContextToFrame( + frame, + htmlLines, + htmlFilename, + linesOfContext, +) { + if (frame.filename !== htmlFilename || !frame.lineno || !htmlLines.length) { + return frame; } - shift() { - var value; + utils.addContextToFrame(htmlLines, frame, linesOfContext); - if (this._first == null) { - return; - } else { - this.length--; + return frame; +} - if (typeof this.decr === "function") { - this.decr(); - } - } +exports.ContextLines = ContextLines; +exports.applySourceContextToFrame = applySourceContextToFrame; +exports.contextLinesIntegration = contextLinesIntegration; +//# sourceMappingURL=contextlines.js.map - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } +/***/ }), - return value; - } +/***/ 91816: +/***/ ((__unused_webpack_module, exports) => { - first() { - if (this._first != null) { - return this._first.value; - } - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - getArray() { - var node, ref, results; - node = this._first; - results = []; +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +const DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__); - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } +exports.DEBUG_BUILD = DEBUG_BUILD; +//# sourceMappingURL=debug-build.js.map - return results; - } - forEachShift(cb) { - var node; - node = this.shift(); +/***/ }), - while (node != null) { - cb(node), node = this.shift(); - } +/***/ 31757: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - return void 0; - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } +const INTEGRATION_NAME = 'Debug'; - return results; - } +const _debugIntegration = ((options = {}) => { + const _options = { + debugger: false, + stringify: false, + ...options, + }; -}; -module.exports = DLList; + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + setup(client) { + if (!client.on) { + return; + } -/***/ }), + client.on('beforeSendEvent', (event, hint) => { + if (_options.debugger) { + // eslint-disable-next-line no-debugger + debugger; + } -/***/ 81065: -/***/ ((module) => { + /* eslint-disable no-console */ + utils.consoleSandbox(() => { + if (_options.stringify) { + console.log(JSON.stringify(event, null, 2)); + if (hint && Object.keys(hint).length) { + console.log(JSON.stringify(hint, null, 2)); + } + } else { + console.log(event); + if (hint && Object.keys(hint).length) { + console.log(hint); + } + } + }); + /* eslint-enable no-console */ + }); + }, + }; +}) ; -"use strict"; +const debugIntegration = core.defineIntegration(_debugIntegration); +/** + * Integration to debug sent Sentry events. + * This integration should not be used in production. + * + * @deprecated Use `debugIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const Debug = core.convertIntegrationFnToClass(INTEGRATION_NAME, debugIntegration) -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +; -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +exports.Debug = Debug; +exports.debugIntegration = debugIntegration; +//# sourceMappingURL=debug.js.map -var Events; -Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if (this.instance.on != null || this.instance.once != null || this.instance.removeAllListeners != null) { - throw new Error("An Emitter already exists for this object"); - } +/***/ }), - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; +/***/ 27395: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; +Object.defineProperty(exports, "__esModule", ({ value: true })); - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(91816); + +const INTEGRATION_NAME = 'Dedupe'; + +const _dedupeIntegration = (() => { + let previousEvent; + + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(currentEvent) { + // We want to ignore any non-error type events, e.g. transactions or replays + // These should never be deduped, and also not be compared against as _previousEvent. + if (currentEvent.type) { + return currentEvent; } - }; - } - _addListener(name, status, cb) { - var base; + // Juuust in case something goes wrong + try { + if (_shouldDropEvent(currentEvent, previousEvent)) { + debugBuild.DEBUG_BUILD && utils.logger.warn('Event dropped due to being a duplicate of previously captured event.'); + return null; + } + } catch (_oO) {} // eslint-disable-line no-empty - if ((base = this._events)[name] == null) { - base[name] = []; - } + return (previousEvent = currentEvent); + }, + }; +}) ; - this._events[name].push({ - cb, - status - }); +const dedupeIntegration = core.defineIntegration(_dedupeIntegration); - return this.instance; +/** + * Deduplication filter. + * @deprecated Use `dedupeIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const Dedupe = core.convertIntegrationFnToClass(INTEGRATION_NAME, dedupeIntegration) + +; + +/** only exported for tests. */ +function _shouldDropEvent(currentEvent, previousEvent) { + if (!previousEvent) { + return false; } - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } + if (_isSameMessageEvent(currentEvent, previousEvent)) { + return true; } - trigger(name, ...args) { - var _this = this; + if (_isSameExceptionEvent(currentEvent, previousEvent)) { + return true; + } - return _asyncToGenerator(function* () { - var e, promises; + return false; +} - try { - if (name !== "debug") { - _this.trigger("debug", `Event triggered: ${name}`, args); - } +function _isSameMessageEvent(currentEvent, previousEvent) { + const currentMessage = currentEvent.message; + const previousMessage = previousEvent.message; - if (_this._events[name] == null) { - return; - } + // If neither event has a message property, they were both exceptions, so bail out + if (!currentMessage && !previousMessage) { + return false; + } - _this._events[name] = _this._events[name].filter(function (listener) { - return listener.status !== "none"; - }); - promises = _this._events[name].map( - /*#__PURE__*/ - function () { - var _ref = _asyncToGenerator(function* (listener) { - var e, returned; + // If only one event has a stacktrace, but not the other one, they are not the same + if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) { + return false; + } - if (listener.status === "none") { - return; - } + if (currentMessage !== previousMessage) { + return false; + } - if (listener.status === "once") { - listener.status = "none"; - } + if (!_isSameFingerprint(currentEvent, previousEvent)) { + return false; + } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (!_isSameStacktrace(currentEvent, previousEvent)) { + return false; + } - if (typeof (returned != null ? returned.then : void 0) === "function") { - return yield returned; - } else { - return returned; - } - } catch (error) { - e = error; + return true; +} - if (true) { - _this.trigger("error", e); - } +function _isSameExceptionEvent(currentEvent, previousEvent) { + const previousException = _getExceptionFromEvent(previousEvent); + const currentException = _getExceptionFromEvent(currentEvent); - return null; - } - }); + if (!previousException || !currentException) { + return false; + } - return function (_x) { - return _ref.apply(this, arguments); - }; - }()); - return (yield Promise.all(promises)).find(function (x) { - return x != null; - }); - } catch (error) { - e = error; + if (previousException.type !== currentException.type || previousException.value !== currentException.value) { + return false; + } - if (true) { - _this.trigger("error", e); - } + if (!_isSameFingerprint(currentEvent, previousEvent)) { + return false; + } - return null; - } - })(); + if (!_isSameStacktrace(currentEvent, previousEvent)) { + return false; } -}; -module.exports = Events; + return true; +} -/***/ }), +function _isSameStacktrace(currentEvent, previousEvent) { + let currentFrames = _getFramesFromEvent(currentEvent); + let previousFrames = _getFramesFromEvent(previousEvent); -/***/ 11213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // If neither event has a stacktrace, they are assumed to be the same + if (!currentFrames && !previousFrames) { + return true; + } -"use strict"; + // If only one event has a stacktrace, but not the other one, they are not the same + if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) { + return false; + } + currentFrames = currentFrames ; + previousFrames = previousFrames ; -function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } + // If number of frames differ, they are not the same + if (previousFrames.length !== currentFrames.length) { + return false; + } -function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } + // Otherwise, compare the two + for (let i = 0; i < previousFrames.length; i++) { + const frameA = previousFrames[i]; + const frameB = currentFrames[i]; -function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } + if ( + frameA.filename !== frameB.filename || + frameA.lineno !== frameB.lineno || + frameA.colno !== frameB.colno || + frameA.function !== frameB.function + ) { + return false; + } + } -function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } + return true; +} -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +function _isSameFingerprint(currentEvent, previousEvent) { + let currentFingerprint = currentEvent.fingerprint; + let previousFingerprint = previousEvent.fingerprint; -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + // If neither event has a fingerprint, they are assumed to be the same + if (!currentFingerprint && !previousFingerprint) { + return true; + } -var Events, Group, IORedisConnection, RedisConnection, Scripts, parser; -parser = __nccwpck_require__(90651); -Events = __nccwpck_require__(81065); -RedisConnection = __nccwpck_require__(28037); -IORedisConnection = __nccwpck_require__(41725); -Scripts = __nccwpck_require__(65206); + // If only one event has a fingerprint, but not the other one, they are not the same + if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) { + return false; + } -Group = function () { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser.load(this.limiterOptions, this.defaults, this); - this.Events = new Events(this); - this.instances = {}; - this.Bottleneck = __nccwpck_require__(29263); + currentFingerprint = currentFingerprint ; + previousFingerprint = previousFingerprint ; - this._startAutoCleanup(); + // Otherwise, compare the two + try { + return !!(currentFingerprint.join('') === previousFingerprint.join('')); + } catch (_oO) { + return false; + } +} - this.sharedConnection = this.connection != null; +function _getExceptionFromEvent(event) { + return event.exception && event.exception.values && event.exception.values[0]; +} - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection(Object.assign({}, this.limiterOptions, { - Events: this.Events - })); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection(Object.assign({}, this.limiterOptions, { - Events: this.Events - })); - } - } - } +function _getFramesFromEvent(event) { + const exception = event.exception; - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); + if (exception) { + try { + // @ts-expect-error Object could be undefined + return exception.values[0].stacktrace.frames; + } catch (_oO) { + return undefined; } + } + return undefined; +} - deleteKey(key = "") { - var _this = this; +exports.Dedupe = Dedupe; +exports._shouldDropEvent = _shouldDropEvent; +exports.dedupeIntegration = dedupeIntegration; +//# sourceMappingURL=dedupe.js.map - return _asyncToGenerator(function* () { - var deleted, instance; - instance = _this.instances[key]; - if (_this.connection) { - deleted = yield _this.connection.__runCommand__(['del', ...Scripts.allKeys(`${_this.id}-${key}`)]); - } +/***/ }), - if (instance != null) { - delete _this.instances[key]; - yield instance.disconnect(); - } +/***/ 60572: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - return instance != null || deleted > 0; - })(); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(91816); - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } +const INTEGRATION_NAME = 'ExtraErrorData'; - return results; - } +const _extraErrorDataIntegration = ((options = {}) => { + const depth = options.depth || 3; - keys() { - return Object.keys(this.instances); - } + // TODO(v8): Flip the default for this option to true + const captureErrorCause = options.captureErrorCause || false; - clusterKeys() { - var _this2 = this; + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(event, hint) { + return _enhanceEventWithErrorData(event, hint, depth, captureErrorCause); + }, + }; +}) ; - return _asyncToGenerator(function* () { - var cursor, end, found, i, k, keys, len, next, start; +const extraErrorDataIntegration = core.defineIntegration(_extraErrorDataIntegration); - if (_this2.connection == null) { - return _this2.Promise.resolve(_this2.keys()); - } +/** + * Extract additional data for from original exceptions. + * @deprecated Use `extraErrorDataIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const ExtraErrorData = core.convertIntegrationFnToClass( + INTEGRATION_NAME, + extraErrorDataIntegration, +) - keys = []; - cursor = null; - start = `b_${_this2.id}-`.length; - end = "_settings".length; +; - while (cursor !== 0) { - var _ref = yield _this2.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${_this2.id}-*_settings`, "count", 10000]); +function _enhanceEventWithErrorData( + event, + hint = {}, + depth, + captureErrorCause, +) { + if (!hint.originalException || !utils.isError(hint.originalException)) { + return event; + } + const exceptionName = (hint.originalException ).name || hint.originalException.constructor.name; - var _ref2 = _slicedToArray(_ref, 2); + const errorData = _extractErrorData(hint.originalException , captureErrorCause); - next = _ref2[0]; - found = _ref2[1]; - cursor = ~~next; + if (errorData) { + const contexts = { + ...event.contexts, + }; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } + const normalizedErrorData = utils.normalize(errorData, depth); - return keys; - })(); + if (utils.isPlainObject(normalizedErrorData)) { + // We mark the error data as "already normalized" here, because we don't want other normalization procedures to + // potentially truncate the data we just already normalized, with a certain depth setting. + utils.addNonEnumerableProperty(normalizedErrorData, '__sentry_skip_normalization__', true); + contexts[exceptionName] = normalizedErrorData; } - _startAutoCleanup() { - var _this3 = this; + return { + ...event, + contexts, + }; + } - var base; - clearInterval(this.interval); - return typeof (base = this.interval = setInterval( - /*#__PURE__*/ - _asyncToGenerator(function* () { - var e, k, ref, results, time, v; - time = Date.now(); - ref = _this3.instances; - results = []; + return event; +} - for (k in ref) { - v = ref[k]; +/** + * Extract extra information from the Error object + */ +function _extractErrorData(error, captureErrorCause) { + // We are trying to enhance already existing event, so no harm done if it won't succeed + try { + const nativeKeys = [ + 'name', + 'message', + 'stack', + 'line', + 'column', + 'fileName', + 'lineNumber', + 'columnNumber', + 'toJSON', + ]; - try { - if (yield v._store.__groupCheck__(time)) { - results.push(_this3.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } + const extraErrorInfo = {}; - return results; - }), this.timeout / 2)).unref === "function" ? base.unref() : void 0; + // We want only enumerable properties, thus `getOwnPropertyNames` is redundant here, as we filter keys anyway. + for (const key of Object.keys(error)) { + if (nativeKeys.indexOf(key) !== -1) { + continue; + } + const value = error[key]; + extraErrorInfo[key] = utils.isError(value) ? value.toString() : value; } - updateSettings(options = {}) { - parser.overwrite(options, this.defaults, this); - parser.overwrite(options, options, this.limiterOptions); - - if (options.timeout != null) { - return this._startAutoCleanup(); - } + // Error.cause is a standard property that is non enumerable, we therefore need to access it separately. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause + if (captureErrorCause && error.cause !== undefined) { + extraErrorInfo.cause = utils.isError(error.cause) ? error.cause.toString() : error.cause; } - disconnect(flush = true) { - var ref; + // Check if someone attached `toJSON` method to grab even more properties (eg. axios is doing that) + if (typeof error.toJSON === 'function') { + const serializedError = error.toJSON() ; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + for (const key of Object.keys(serializedError)) { + const value = serializedError[key]; + extraErrorInfo[key] = utils.isError(value) ? value.toString() : value; } } + return extraErrorInfo; + } catch (oO) { + debugBuild.DEBUG_BUILD && utils.logger.error('Unable to extract extra data from the Error object:', oO); } - ; - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; - return Group; -}.call(void 0); + return null; +} -module.exports = Group; +exports.ExtraErrorData = ExtraErrorData; +exports.extraErrorDataIntegration = extraErrorDataIntegration; +//# sourceMappingURL=extraerrordata.js.map -/***/ }), -/***/ 41725: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ }), -"use strict"; +/***/ 85539: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +Object.defineProperty(exports, "__esModule", ({ value: true })); -function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(91816); -function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } +const INTEGRATION_NAME = 'HttpClient'; -function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +const _httpClientIntegration = ((options = {}) => { + const _options = { + failedRequestStatusCodes: [[500, 599]], + failedRequestTargets: [/.*/], + ...options, + }; -function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + setup(client) { + _wrapFetch(client, _options); + _wrapXHR(client, _options); + }, + }; +}) ; -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +const httpClientIntegration = core.defineIntegration(_httpClientIntegration); -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +/** + * Create events for failed client side HTTP requests. + * @deprecated Use `httpClientIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const HttpClient = core.convertIntegrationFnToClass(INTEGRATION_NAME, httpClientIntegration) -var Events, IORedisConnection, Scripts, parser; -parser = __nccwpck_require__(90651); -Events = __nccwpck_require__(81065); -Scripts = __nccwpck_require__(65206); +; -IORedisConnection = function () { - class IORedisConnection { - constructor(options = {}) { - parser.load(options, this.defaults, this); +/** + * Interceptor function for fetch requests + * + * @param requestInfo The Fetch API request info + * @param response The Fetch API response + * @param requestInit The request init object + */ +function _fetchResponseHandler( + options, + requestInfo, + response, + requestInit, +) { + if (_shouldCaptureResponse(options, response.status, response.url)) { + const request = _getRequest(requestInfo, requestInit); - if (this.Redis == null) { - this.Redis = eval("require")("ioredis"); // Obfuscated or else Webpack/Angular will try to inline the optional ioredis module. To override this behavior: pass the ioredis module to Bottleneck as the 'Redis' option. - } + let requestHeaders, responseHeaders, requestCookies, responseCookies; - if (this.Events == null) { - this.Events = new Events(this); - } + if (_shouldSendDefaultPii()) { + [{ headers: requestHeaders, cookies: requestCookies }, { headers: responseHeaders, cookies: responseCookies }] = [ + { cookieHeader: 'Cookie', obj: request }, + { cookieHeader: 'Set-Cookie', obj: response }, + ].map(({ cookieHeader, obj }) => { + const headers = _extractFetchHeaders(obj.headers); + let cookies; - this.terminated = false; + try { + const cookieString = headers[cookieHeader] || headers[cookieHeader.toLowerCase()] || undefined; - if (this.clusterNodes != null) { - this.client = new this.Redis.Cluster(this.clusterNodes, this.clientOptions); - this.subscriber = new this.Redis.Cluster(this.clusterNodes, this.clientOptions); - } else if (this.client != null && this.client.duplicate == null) { - this.subscriber = new this.Redis.Cluster(this.client.startupNodes, this.client.options); - } else { - if (this.client == null) { - this.client = new this.Redis(this.clientOptions); + if (cookieString) { + cookies = _parseCookieString(cookieString); + } + } catch (e) { + debugBuild.DEBUG_BUILD && utils.logger.log(`Could not extract cookies from header ${cookieHeader}`); } - this.subscriber = this.client.duplicate(); - } - - this.limiters = {}; - this.ready = this.Promise.all([this._setup(this.client, false), this._setup(this.subscriber, true)]).then(() => { - this._loadScripts(); - return { - client: this.client, - subscriber: this.subscriber + headers, + cookies, }; }); } - _setup(client, sub) { - client.setMaxListeners(0); - return new this.Promise((resolve, reject) => { - client.on("error", e => { - return this.Events.trigger("error", e); - }); + const event = _createEvent({ + url: request.url, + method: request.method, + status: response.status, + requestHeaders, + responseHeaders, + requestCookies, + responseCookies, + }); - if (sub) { - client.on("message", (channel, message) => { - var ref; - return (ref = this.limiters[channel]) != null ? ref._store.onMessage(channel, message) : void 0; - }); - } + core.captureEvent(event); + } +} - if (client.status === "ready") { - return resolve(); - } else { - return client.once("ready", resolve); - } - }); - } +/** + * Interceptor function for XHR requests + * + * @param xhr The XHR request + * @param method The HTTP method + * @param headers The HTTP headers + */ +function _xhrResponseHandler( + options, + xhr, + method, + headers, +) { + if (_shouldCaptureResponse(options, xhr.status, xhr.responseURL)) { + let requestHeaders, responseCookies, responseHeaders; - _loadScripts() { - return Scripts.names.forEach(name => { - return this.client.defineCommand(name, { - lua: Scripts.payload(name) - }); - }); - } + if (_shouldSendDefaultPii()) { + try { + const cookieString = xhr.getResponseHeader('Set-Cookie') || xhr.getResponseHeader('set-cookie') || undefined; - __runCommand__(cmd) { - var _this = this; + if (cookieString) { + responseCookies = _parseCookieString(cookieString); + } + } catch (e) { + debugBuild.DEBUG_BUILD && utils.logger.log('Could not extract cookies from response headers'); + } - return _asyncToGenerator(function* () { - var _, deleted; + try { + responseHeaders = _getXHRResponseHeaders(xhr); + } catch (e) { + debugBuild.DEBUG_BUILD && utils.logger.log('Could not extract headers from response'); + } - yield _this.ready; + requestHeaders = headers; + } - var _ref = yield _this.client.pipeline([cmd]).exec(); + const event = _createEvent({ + url: xhr.responseURL, + method, + status: xhr.status, + requestHeaders, + // Can't access request cookies from XHR + responseHeaders, + responseCookies, + }); - var _ref2 = _slicedToArray(_ref, 1); + core.captureEvent(event); + } +} - var _ref2$ = _slicedToArray(_ref2[0], 2); +/** + * Extracts response size from `Content-Length` header when possible + * + * @param headers + * @returns The response size in bytes or undefined + */ +function _getResponseSizeFromHeaders(headers) { + if (headers) { + const contentLength = headers['Content-Length'] || headers['content-length']; - _ = _ref2$[0]; - deleted = _ref2$[1]; - return deleted; - })(); + if (contentLength) { + return parseInt(contentLength, 10); } + } - __addLimiter__(instance) { - return this.Promise.all([instance.channel(), instance.channel_client()].map(channel => { - return new this.Promise((resolve, reject) => { - return this.subscriber.subscribe(channel, () => { - this.limiters[channel] = instance; - return resolve(); - }); - }); - })); - } + return undefined; +} - __removeLimiter__(instance) { - var _this2 = this; +/** + * Creates an object containing cookies from the given cookie string + * + * @param cookieString The cookie string to parse + * @returns The parsed cookies + */ +function _parseCookieString(cookieString) { + return cookieString.split('; ').reduce((acc, cookie) => { + const [key, value] = cookie.split('='); + acc[key] = value; + return acc; + }, {}); +} - return [instance.channel(), instance.channel_client()].forEach( - /*#__PURE__*/ - function () { - var _ref3 = _asyncToGenerator(function* (channel) { - if (!_this2.terminated) { - yield _this2.subscriber.unsubscribe(channel); - } +/** + * Extracts the headers as an object from the given Fetch API request or response object + * + * @param headers The headers to extract + * @returns The extracted headers as an object + */ +function _extractFetchHeaders(headers) { + const result = {}; - return delete _this2.limiters[channel]; - }); + headers.forEach((value, key) => { + result[key] = value; + }); - return function (_x) { - return _ref3.apply(this, arguments); - }; - }()); - } + return result; +} - __scriptArgs__(name, id, args, cb) { - var keys; - keys = Scripts.keys(name, id); - return [keys.length].concat(keys, args, cb); - } +/** + * Extracts the response headers as an object from the given XHR object + * + * @param xhr The XHR object to extract the response headers from + * @returns The response headers as an object + */ +function _getXHRResponseHeaders(xhr) { + const headers = xhr.getAllResponseHeaders(); - __scriptFn__(name) { - return this.client[name].bind(this.client); - } + if (!headers) { + return {}; + } - disconnect(flush = true) { - var i, k, len, ref; - ref = Object.keys(this.limiters); + return headers.split('\r\n').reduce((acc, line) => { + const [key, value] = line.split(': '); + acc[key] = value; + return acc; + }, {}); +} - for (i = 0, len = ref.length; i < len; i++) { - k = ref[i]; - clearInterval(this.limiters[k]._store.heartbeat); - } +/** + * Checks if the given target url is in the given list of targets + * + * @param target The target url to check + * @returns true if the target url is in the given list of targets, false otherwise + */ +function _isInGivenRequestTargets( + failedRequestTargets, + target, +) { + return failedRequestTargets.some((givenRequestTarget) => { + if (typeof givenRequestTarget === 'string') { + return target.includes(givenRequestTarget); + } - this.limiters = {}; - this.terminated = true; + return givenRequestTarget.test(target); + }); +} - if (flush) { - return this.Promise.all([this.client.quit(), this.subscriber.quit()]); - } else { - this.client.disconnect(); - this.subscriber.disconnect(); - return this.Promise.resolve(); - } +/** + * Checks if the given status code is in the given range + * + * @param status The status code to check + * @returns true if the status code is in the given range, false otherwise + */ +function _isInGivenStatusRanges( + failedRequestStatusCodes, + status, +) { + return failedRequestStatusCodes.some((range) => { + if (typeof range === 'number') { + return range === status; } + return status >= range[0] && status <= range[1]; + }); +} + +/** + * Wraps `fetch` function to capture request and response data + */ +function _wrapFetch(client, options) { + if (!utils.supportsNativeFetch()) { + return; } - ; - IORedisConnection.prototype.datastore = "ioredis"; - IORedisConnection.prototype.defaults = { - Redis: null, - clientOptions: {}, - clusterNodes: null, - client: null, - Promise: Promise, - Events: null - }; - return IORedisConnection; -}.call(void 0); + utils.addFetchInstrumentationHandler(handlerData => { + if (core.getClient() !== client) { + return; + } -module.exports = IORedisConnection; + const { response, args } = handlerData; + const [requestInfo, requestInit] = args ; -/***/ }), + if (!response) { + return; + } -/***/ 73549: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + _fetchResponseHandler(options, requestInfo, response , requestInit); + }); +} -"use strict"; +/** + * Wraps XMLHttpRequest to capture request and response data + */ +function _wrapXHR(client, options) { + if (!('XMLHttpRequest' in utils.GLOBAL_OBJ)) { + return; + } + utils.addXhrInstrumentationHandler(handlerData => { + if (core.getClient() !== client) { + return; + } -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + const xhr = handlerData.xhr ; -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + const sentryXhrData = xhr[utils.SENTRY_XHR_DATA_KEY]; -var BottleneckError, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser; -NUM_PRIORITIES = 10; -DEFAULT_PRIORITY = 5; -parser = __nccwpck_require__(90651); -BottleneckError = __nccwpck_require__(88185); -Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); + if (!sentryXhrData) { + return; + } - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; + const { method, request_headers: headers } = sentryXhrData; + + try { + _xhrResponseHandler(options, xhr, method, headers); + } catch (e) { + debugBuild.DEBUG_BUILD && utils.logger.warn('Error while extracting response event form XHR response', e); } + }); +} - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } +/** + * Checks whether to capture given response as an event + * + * @param status response status code + * @param url response url + */ +function _shouldCaptureResponse(options, status, url) { + return ( + _isInGivenStatusRanges(options.failedRequestStatusCodes, status) && + _isInGivenRequestTargets(options.failedRequestTargets, url) && + !core.isSentryRequestUrl(url, core.getClient()) + ); +} - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; +/** + * Creates a synthetic Sentry event from given response data + * + * @param data response data + * @returns event + */ +function _createEvent(data - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } +) { + const message = `HTTP Client Error with status code: ${data.status}`; - _randomIndex() { - return Math.random().toString(36).slice(2); - } + const event = { + message, + exception: { + values: [ + { + type: 'Error', + value: message, + }, + ], + }, + request: { + url: data.url, + method: data.method, + headers: data.requestHeaders, + cookies: data.requestCookies, + }, + contexts: { + response: { + status_code: data.status, + headers: data.responseHeaders, + cookies: data.responseCookies, + body_size: _getResponseSizeFromHeaders(data.responseHeaders), + }, + }, + }; - doDrop({ - error, - message = "This job has been dropped by Bottleneck" - } = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError(message)); - } + utils.addExceptionMechanism(event, { + type: 'http.client', + handled: false, + }); - this.Events.trigger("dropped", { - args: this.args, - options: this.options, - task: this.task, - promise: this.promise - }); - return true; - } else { - return false; - } - } + return event; +} - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); +function _getRequest(requestInfo, requestInit) { + if (!requestInit && requestInfo instanceof Request) { + return requestInfo; + } - if (!(status === expected || expected === "DONE" && status === null)) { - throw new BottleneckError(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } + // If both are set, we try to construct a new Request with the given arguments + // However, if e.g. the original request has a `body`, this will throw an error because it was already accessed + // In this case, as a fallback, we just use the original request - using both is rather an edge case + if (requestInfo instanceof Request && requestInfo.bodyUsed) { + return requestInfo; } - doReceive() { - this._states.start(this.options.id); + return new Request(requestInfo, requestInit); +} - return this.Events.trigger("received", { - args: this.args, - options: this.options - }); - } +function _shouldSendDefaultPii() { + const client = core.getClient(); + return client ? Boolean(client.getOptions().sendDefaultPii) : false; +} - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); +exports.HttpClient = HttpClient; +exports.httpClientIntegration = httpClientIntegration; +//# sourceMappingURL=httpclient.js.map - this._states.next(this.options.id); - return this.Events.trigger("queued", { - args: this.args, - options: this.options, - reachedHWM, - blocked - }); - } +/***/ }), - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); +/***/ 35322: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - return this.Events.trigger("scheduled", { - args: this.args, - options: this.options - }); - } +const captureconsole = __nccwpck_require__(60679); +const debug = __nccwpck_require__(31757); +const dedupe = __nccwpck_require__(27395); +const extraerrordata = __nccwpck_require__(60572); +const offline = __nccwpck_require__(90717); +const reportingobserver = __nccwpck_require__(53902); +const rewriteframes = __nccwpck_require__(61660); +const sessiontiming = __nccwpck_require__(87460); +const transaction = __nccwpck_require__(766); +const httpclient = __nccwpck_require__(85539); +const contextlines = __nccwpck_require__(18562); + + + +exports.CaptureConsole = captureconsole.CaptureConsole; +exports.captureConsoleIntegration = captureconsole.captureConsoleIntegration; +exports.Debug = debug.Debug; +exports.debugIntegration = debug.debugIntegration; +exports.Dedupe = dedupe.Dedupe; +exports.dedupeIntegration = dedupe.dedupeIntegration; +exports.ExtraErrorData = extraerrordata.ExtraErrorData; +exports.extraErrorDataIntegration = extraerrordata.extraErrorDataIntegration; +exports.Offline = offline.Offline; +exports.ReportingObserver = reportingobserver.ReportingObserver; +exports.reportingObserverIntegration = reportingobserver.reportingObserverIntegration; +exports.RewriteFrames = rewriteframes.RewriteFrames; +exports.rewriteFramesIntegration = rewriteframes.rewriteFramesIntegration; +exports.SessionTiming = sessiontiming.SessionTiming; +exports.sessionTimingIntegration = sessiontiming.sessionTimingIntegration; +exports.Transaction = transaction.Transaction; +exports.HttpClient = httpclient.HttpClient; +exports.httpClientIntegration = httpclient.httpClientIntegration; +exports.ContextLines = contextlines.ContextLines; +exports.contextLinesIntegration = contextlines.contextLinesIntegration; +//# sourceMappingURL=index.js.map - doExecute(chained, clearGlobalState, run, free) { - var _this = this; - return _asyncToGenerator(function* () { - var error, eventInfo, passed; +/***/ }), - if (_this.retryCount === 0) { - _this._assertStatus("RUNNING"); +/***/ 90717: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - _this._states.next(_this.options.id); - } else { - _this._assertStatus("EXECUTING"); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - eventInfo = { - args: _this.args, - options: _this.options, - retryCount: _this.retryCount - }; +const utils = __nccwpck_require__(57540); +const localForage = __nccwpck_require__(40597); +const debugBuild = __nccwpck_require__(91816); - _this.Events.trigger("executing", eventInfo); +const WINDOW = utils.GLOBAL_OBJ ; - try { - passed = yield chained != null ? chained.schedule(_this.options, _this.task, ..._this.args) : _this.task(..._this.args); +/** + * cache offline errors and send when connected + * @deprecated The offline integration has been deprecated in favor of the offline transport wrapper. + * + * http://docs.sentry.io/platforms/javascript/configuration/transports/#offline-caching + */ +class Offline { + /** + * @inheritDoc + */ + static __initStatic() {this.id = 'Offline';} - if (clearGlobalState()) { - _this.doDone(eventInfo); + /** + * @inheritDoc + */ - yield free(_this.options, eventInfo); + /** + * the current hub instance + */ - _this._assertStatus("DONE"); + /** + * maximum number of events to store while offline + */ - return _this._resolve(passed); - } - } catch (error1) { - error = error1; - return _this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - })(); + /** + * event cache + */ + + /** + * @inheritDoc + */ + constructor(options = {}) { + this.name = Offline.id; + + this.maxStoredEvents = options.maxStoredEvents || 30; // set a reasonable default + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + this.offlineEventStore = localForage.createInstance({ + name: 'sentry/offlineEventStore', + }); } - doExpire(clearGlobalState, run, free) { - var error, eventInfo; + /** + * @inheritDoc + */ + setupOnce(addGlobalEventProcessor, getCurrentHub) { + this.hub = getCurrentHub(); - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); + if ('addEventListener' in WINDOW) { + WINDOW.addEventListener('online', () => { + void this._sendEvents().catch(() => { + debugBuild.DEBUG_BUILD && utils.logger.warn('could not send cached events'); + }); + }); } - this._assertStatus("EXECUTING"); + const eventProcessor = event => { + // eslint-disable-next-line deprecation/deprecation + if (this.hub && this.hub.getIntegration(Offline)) { + // cache if we are positively offline + if ('navigator' in WINDOW && 'onLine' in WINDOW.navigator && !WINDOW.navigator.onLine) { + debugBuild.DEBUG_BUILD && utils.logger.log('Event dropped due to being a offline - caching instead'); - eventInfo = { - args: this.args, - options: this.options, - retryCount: this.retryCount + void this._cacheEvent(event) + .then((_event) => this._enforceMaxEvents()) + .catch((_error) => { + debugBuild.DEBUG_BUILD && utils.logger.warn('could not cache event while offline'); + }); + + // return null on success or failure, because being offline will still result in an error + return null; + } + } + + return event; }; - error = new BottleneckError(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - _onFailure(error, eventInfo, clearGlobalState, run, free) { - var _this2 = this; + eventProcessor.id = this.name; + addGlobalEventProcessor(eventProcessor); - return _asyncToGenerator(function* () { - var retry, retryAfter; + // if online now, send any events stored in a previous offline session + if ('navigator' in WINDOW && 'onLine' in WINDOW.navigator && WINDOW.navigator.onLine) { + void this._sendEvents().catch(() => { + debugBuild.DEBUG_BUILD && utils.logger.warn('could not send cached events'); + }); + } + } - if (clearGlobalState()) { - retry = yield _this2.Events.trigger("failed", error, eventInfo); + /** + * cache an event to send later + * @param event an event + */ + async _cacheEvent(event) { + return this.offlineEventStore.setItem(utils.uuid4(), utils.normalize(event)); + } - if (retry != null) { - retryAfter = ~~retry; + /** + * purge excess events if necessary + */ + async _enforceMaxEvents() { + const events = []; - _this2.Events.trigger("retry", `Retrying ${_this2.options.id} after ${retryAfter} ms`, eventInfo); + return this.offlineEventStore + .iterate((event, cacheKey, _index) => { + // aggregate events + events.push({ cacheKey, event }); + }) + .then( + () => + // this promise resolves when the iteration is finished + this._purgeEvents( + // purge all events past maxStoredEvents in reverse chronological order + events + .sort((a, b) => (b.event.timestamp || 0) - (a.event.timestamp || 0)) + .slice(this.maxStoredEvents < events.length ? this.maxStoredEvents : events.length) + .map(event => event.cacheKey), + ), + ) + .catch((_error) => { + debugBuild.DEBUG_BUILD && utils.logger.warn('could not enforce max events'); + }); + } - _this2.retryCount++; - return run(retryAfter); - } else { - _this2.doDone(eventInfo); + /** + * purge event from cache + */ + async _purgeEvent(cacheKey) { + return this.offlineEventStore.removeItem(cacheKey); + } - yield free(_this2.options, eventInfo); + /** + * purge events from cache + */ + async _purgeEvents(cacheKeys) { + // trail with .then to ensure the return type as void and not void|void[] + return Promise.all(cacheKeys.map(cacheKey => this._purgeEvent(cacheKey))).then(); + } - _this2._assertStatus("DONE"); + /** + * send all events + */ + async _sendEvents() { + return this.offlineEventStore.iterate((event, cacheKey, _index) => { + if (this.hub) { + this.hub.captureEvent(event); - return _this2._reject(error); - } + void this._purgeEvent(cacheKey).catch((_error) => { + debugBuild.DEBUG_BUILD && utils.logger.warn('could not purge event from cache'); + }); + } else { + debugBuild.DEBUG_BUILD && utils.logger.warn('no hub found - could not send cached event'); } - })(); + }); } +} Offline.__initStatic(); - doDone(eventInfo) { - this._assertStatus("EXECUTING"); +exports.Offline = Offline; +//# sourceMappingURL=offline.js.map - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } +/***/ }), -}; -module.exports = Job; +/***/ 53902: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/***/ }), +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ 4104: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); -"use strict"; +const WINDOW = utils.GLOBAL_OBJ ; +const INTEGRATION_NAME = 'ReportingObserver'; -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +const SETUP_CLIENTS = new WeakMap(); -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +const _reportingObserverIntegration = ((options = {}) => { + const types = options.types || ['crash', 'deprecation', 'intervention']; -var BottleneckError, LocalDatastore, parser; -parser = __nccwpck_require__(90651); -BottleneckError = __nccwpck_require__(88185); -LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; + /** Handler for the reporting observer. */ + function handler(reports) { + if (!SETUP_CLIENTS.has(core.getClient() )) { + return; + } - this._startHeartbeat(); - } + for (const report of reports) { + core.withScope(scope => { + scope.setExtra('url', report.url); - _startHeartbeat() { - var base; + const label = `ReportingObserver [${report.type}]`; + let details = 'No details available'; - if (this.heartbeat == null && (this.storeOptions.reservoirRefreshInterval != null && this.storeOptions.reservoirRefreshAmount != null || this.storeOptions.reservoirIncreaseInterval != null && this.storeOptions.reservoirIncreaseAmount != null)) { - return typeof (base = this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); + if (report.body) { + // Object.keys doesn't work on ReportBody, as all properties are inheirted + const plainBody - if (this.storeOptions.reservoirRefreshInterval != null && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + = {}; - this.instance._drainAll(this.computeCapacity()); - } + // eslint-disable-next-line guard-for-in + for (const prop in report.body) { + plainBody[prop] = report.body[prop]; + } - if (this.storeOptions.reservoirIncreaseInterval != null && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - var _this$storeOptions = this.storeOptions; - amount = _this$storeOptions.reservoirIncreaseAmount; - maximum = _this$storeOptions.reservoirIncreaseMaximum; - reservoir = _this$storeOptions.reservoir; - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + scope.setExtra('body', plainBody); - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); + if (report.type === 'crash') { + const body = report.body ; + // A fancy way to create a message out of crashId OR reason OR both OR fallback + details = [body.crashId || '', body.reason || ''].join(' ').trim() || details; + } else { + const body = report.body ; + details = body.message || details; } } - }, this.heartbeatInterval)).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); + + core.captureMessage(`${label}: ${details}`); + }); } } - __publish__(message) { - var _this = this; + return { + name: INTEGRATION_NAME, + setupOnce() { + if (!utils.supportsReportingObserver()) { + return; + } - return _asyncToGenerator(function* () { - yield _this.yieldLoop(); - return _this.instance.Events.trigger("message", message.toString()); - })(); - } + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any + const observer = new (WINDOW ).ReportingObserver(handler, { + buffered: true, + types, + }); - __disconnect__(flush) { - var _this2 = this; + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + observer.observe(); + }, - return _asyncToGenerator(function* () { - yield _this2.yieldLoop(); - clearInterval(_this2.heartbeat); - return _this2.Promise.resolve(); - })(); - } + setup(client) { + SETUP_CLIENTS.set(client, true); + }, + }; +}) ; - yieldLoop(t = 0) { - return new this.Promise(function (resolve, reject) { - return setTimeout(resolve, t); - }); - } +const reportingObserverIntegration = core.defineIntegration(_reportingObserverIntegration); - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : 15 * this.storeOptions.minTime || 5000; - } +/** + * Reporting API integration - https://w3c.github.io/reporting/ + * @deprecated Use `reportingObserverIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const ReportingObserver = core.convertIntegrationFnToClass( + INTEGRATION_NAME, + reportingObserverIntegration, +) - __updateSettings__(options) { - var _this3 = this; +; - return _asyncToGenerator(function* () { - yield _this3.yieldLoop(); - parser.overwrite(options, options, _this3.storeOptions); +exports.ReportingObserver = ReportingObserver; +exports.reportingObserverIntegration = reportingObserverIntegration; +//# sourceMappingURL=reportingobserver.js.map - _this3._startHeartbeat(); - _this3.instance._drainAll(_this3.computeCapacity()); +/***/ }), - return true; - })(); - } +/***/ 61660: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - __running__() { - var _this4 = this; +Object.defineProperty(exports, "__esModule", ({ value: true })); - return _asyncToGenerator(function* () { - yield _this4.yieldLoop(); - return _this4._running; - })(); - } +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); + +const INTEGRATION_NAME = 'RewriteFrames'; + +const _rewriteFramesIntegration = ((options = {}) => { + const root = options.root; + const prefix = options.prefix || 'app:///'; + + const iteratee = + options.iteratee || + ((frame) => { + if (!frame.filename) { + return frame; + } + // Determine if this is a Windows frame by checking for a Windows-style prefix such as `C:\` + const isWindowsFrame = + /^[a-zA-Z]:\\/.test(frame.filename) || + // or the presence of a backslash without a forward slash (which are not allowed on Windows) + (frame.filename.includes('\\') && !frame.filename.includes('/')); + // Check if the frame filename begins with `/` + const startsWithSlash = /^\//.test(frame.filename); + if (isWindowsFrame || startsWithSlash) { + const filename = isWindowsFrame + ? frame.filename + .replace(/^[a-zA-Z]:/, '') // remove Windows-style prefix + .replace(/\\/g, '/') // replace all `\\` instances with `/` + : frame.filename; + const base = root ? utils.relative(root, filename) : utils.basename(filename); + frame.filename = `${prefix}${base}`; + } + return frame; + }); - __queued__() { - var _this5 = this; + /** Process an exception event. */ + function _processExceptionsEvent(event) { + try { + return { + ...event, + exception: { + ...event.exception, + // The check for this is performed inside `process` call itself, safe to skip here + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + values: event.exception.values.map(value => ({ + ...value, + ...(value.stacktrace && { stacktrace: _processStacktrace(value.stacktrace) }), + })), + }, + }; + } catch (_oO) { + return event; + } + } - return _asyncToGenerator(function* () { - yield _this5.yieldLoop(); - return _this5.instance.queued(); - })(); + /** Process a stack trace. */ + function _processStacktrace(stacktrace) { + return { + ...stacktrace, + frames: stacktrace && stacktrace.frames && stacktrace.frames.map(f => iteratee(f)), + }; } - __done__() { - var _this6 = this; + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(originalEvent) { + let processedEvent = originalEvent; - return _asyncToGenerator(function* () { - yield _this6.yieldLoop(); - return _this6._done; - })(); - } + if (originalEvent.exception && Array.isArray(originalEvent.exception.values)) { + processedEvent = _processExceptionsEvent(processedEvent); + } - __groupCheck__(time) { - var _this7 = this; + return processedEvent; + }, + }; +}) ; - return _asyncToGenerator(function* () { - yield _this7.yieldLoop(); - return _this7._nextRequest + _this7.timeout < time; - })(); - } +const rewriteFramesIntegration = core.defineIntegration(_rewriteFramesIntegration); - computeCapacity() { - var maxConcurrent, reservoir; - var _this$storeOptions2 = this.storeOptions; - maxConcurrent = _this$storeOptions2.maxConcurrent; - reservoir = _this$storeOptions2.reservoir; +/** + * Rewrite event frames paths. + * @deprecated Use `rewriteFramesIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const RewriteFrames = core.convertIntegrationFnToClass( + INTEGRATION_NAME, + rewriteFramesIntegration, +) - if (maxConcurrent != null && reservoir != null) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } +; - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return capacity == null || weight <= capacity; - } +exports.RewriteFrames = RewriteFrames; +exports.rewriteFramesIntegration = rewriteFramesIntegration; +//# sourceMappingURL=rewriteframes.js.map - __incrementReservoir__(incr) { - var _this8 = this; - return _asyncToGenerator(function* () { - var reservoir; - yield _this8.yieldLoop(); - reservoir = _this8.storeOptions.reservoir += incr; +/***/ }), - _this8.instance._drainAll(_this8.computeCapacity()); +/***/ 87460: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - return reservoir; - })(); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - __currentReservoir__() { - var _this9 = this; +const core = __nccwpck_require__(75442); - return _asyncToGenerator(function* () { - yield _this9.yieldLoop(); - return _this9.storeOptions.reservoir; - })(); - } +const INTEGRATION_NAME = 'SessionTiming'; - isBlocked(now) { - return this._unblockTime >= now; - } +const _sessionTimingIntegration = (() => { + const startTime = Date.now(); - check(weight, now) { - return this.conditionsCheck(weight) && this._nextRequest - now <= 0; - } + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(event) { + const now = Date.now(); - __check__(weight) { - var _this10 = this; + return { + ...event, + extra: { + ...event.extra, + ['session:start']: startTime, + ['session:duration']: now - startTime, + ['session:end']: now, + }, + }; + }, + }; +}) ; - return _asyncToGenerator(function* () { - var now; - yield _this10.yieldLoop(); - now = Date.now(); - return _this10.check(weight, now); - })(); - } +const sessionTimingIntegration = core.defineIntegration(_sessionTimingIntegration); - __register__(index, weight, expiration) { - var _this11 = this; +/** + * This function adds duration since Sentry was initialized till the time event was sent. + * @deprecated Use `sessionTimingIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const SessionTiming = core.convertIntegrationFnToClass( + INTEGRATION_NAME, + sessionTimingIntegration, +) ; - return _asyncToGenerator(function* () { - var now, wait; - yield _this11.yieldLoop(); - now = Date.now(); +exports.SessionTiming = SessionTiming; +exports.sessionTimingIntegration = sessionTimingIntegration; +//# sourceMappingURL=sessiontiming.js.map - if (_this11.conditionsCheck(weight)) { - _this11._running += weight; - if (_this11.storeOptions.reservoir != null) { - _this11.storeOptions.reservoir -= weight; - } +/***/ }), - wait = Math.max(_this11._nextRequest - now, 0); - _this11._nextRequest = now + wait + _this11.storeOptions.minTime; - return { - success: true, - wait, - reservoir: _this11.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - })(); - } +/***/ 766: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - __submit__(queueLength, weight) { - var _this12 = this; +const core = __nccwpck_require__(75442); - return _asyncToGenerator(function* () { - var blocked, now, reachedHWM; - yield _this12.yieldLoop(); +const INTEGRATION_NAME = 'Transaction'; - if (_this12.storeOptions.maxConcurrent != null && weight > _this12.storeOptions.maxConcurrent) { - throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${_this12.storeOptions.maxConcurrent}`); +const transactionIntegration = (() => { + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(event) { + const frames = _getFramesFromEvent(event); + + // use for loop so we don't have to reverse whole frames array + for (let i = frames.length - 1; i >= 0; i--) { + const frame = frames[i]; + + if (frame.in_app === true) { + event.transaction = _getTransaction(frame); + break; + } } - now = Date.now(); - reachedHWM = _this12.storeOptions.highWater != null && queueLength === _this12.storeOptions.highWater && !_this12.check(weight, now); - blocked = _this12.strategyIsBlock() && (reachedHWM || _this12.isBlocked(now)); + return event; + }, + }; +}) ; - if (blocked) { - _this12._unblockTime = now + _this12.computePenalty(); - _this12._nextRequest = _this12._unblockTime + _this12.storeOptions.minTime; +/** + * Add node transaction to the event. + * @deprecated This integration will be removed in v8. + */ +// eslint-disable-next-line deprecation/deprecation +const Transaction = core.convertIntegrationFnToClass(INTEGRATION_NAME, transactionIntegration) - _this12.instance._dropAllQueued(); - } +; - return { - reachedHWM, - blocked, - strategy: _this12.storeOptions.strategy - }; - })(); +function _getFramesFromEvent(event) { + const exception = event.exception && event.exception.values && event.exception.values[0]; + return (exception && exception.stacktrace && exception.stacktrace.frames) || []; +} + +function _getTransaction(frame) { + return frame.module || frame.function ? `${frame.module || '?'}/${frame.function || '?'}` : ''; +} + +exports.Transaction = Transaction; +//# sourceMappingURL=transaction.js.map + + +/***/ }), + +/***/ 93769: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +var { + _optionalChain +} = __nccwpck_require__(57540); + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const domain = __nccwpck_require__(73167); +const core = __nccwpck_require__(75442); + +function getActiveDomain() { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any + return (domain ).active ; +} + +// eslint-disable-next-line deprecation/deprecation +function getCurrentHub() { + const activeDomain = getActiveDomain(); + + // If there's no active domain, just return undefined and the global hub will be used + if (!activeDomain) { + return undefined; } - __free__(index, weight) { - var _this13 = this; + core.ensureHubOnCarrier(activeDomain); - return _asyncToGenerator(function* () { - yield _this13.yieldLoop(); - _this13._running -= weight; - _this13._done += weight; + return core.getHubFromCarrier(activeDomain); +} - _this13.instance._drainAll(_this13.computeCapacity()); +// eslint-disable-next-line deprecation/deprecation +function createNewHub(parent) { + const carrier = {}; + core.ensureHubOnCarrier(carrier, parent); + return core.getHubFromCarrier(carrier); +} - return { - running: _this13._running - }; - })(); +function runWithAsyncContext(callback, options) { + const activeDomain = getActiveDomain(); + + if (activeDomain && _optionalChain([options, 'optionalAccess', _ => _.reuseExisting])) { + // We're already in a domain, so we don't need to create a new one, just call the callback with the current hub + return callback(); } -}; -module.exports = LocalDatastore; + const local = domain.create() ; -/***/ }), + const parentHub = activeDomain ? core.getHubFromCarrier(activeDomain) : undefined; + const newHub = createNewHub(parentHub); + core.setHubOnCarrier(local, newHub); -/***/ 61944: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return local.bind(() => { + return callback(); + })(); +} -"use strict"; +/** + * Sets the async context strategy to use Node.js domains. + */ +function setDomainAsyncContextStrategy() { + core.setAsyncContextStrategy({ getCurrentHub, runWithAsyncContext }); +} +exports.setDomainAsyncContextStrategy = setDomainAsyncContextStrategy; +//# sourceMappingURL=domain.js.map -var DLList, Events, Queues; -DLList = __nccwpck_require__(64792); -Events = __nccwpck_require__(81065); -Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events(this); - this._length = 0; - this._lists = function () { - var j, ref, results; - results = []; +/***/ }), - for (i = j = 1, ref = num_priorities; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { - results.push(new DLList(() => { - return this.incr(); - }, () => { - return this.decr(); - })); - } +/***/ 70589: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - return results; - }.call(this); - } +var { + _optionalChain +} = __nccwpck_require__(57540); - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } +const core = __nccwpck_require__(75442); +const async_hooks = __nccwpck_require__(90290); - push(job) { - return this._lists[job.options.priority].push(job); - } +// eslint-disable-next-line deprecation/deprecation +let asyncStorage; - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } +/** + * Sets the async context strategy to use AsyncLocalStorage which requires Node v12.17.0 or v13.10.0. + */ +function setHooksAsyncContextStrategy() { + if (!asyncStorage) { + // eslint-disable-next-line deprecation/deprecation + asyncStorage = new (async_hooks ).AsyncLocalStorage(); } - shiftAll(fn) { - return this._lists.forEach(function (list) { - return list.forEachShift(fn); - }); + // eslint-disable-next-line deprecation/deprecation + function getCurrentHub() { + return asyncStorage.getStore(); } - getFirst(arr = this._lists) { - var j, len, list; + // eslint-disable-next-line deprecation/deprecation + function createNewHub(parent) { + const carrier = {}; + core.ensureHubOnCarrier(carrier, parent); + return core.getHubFromCarrier(carrier); + } - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; + function runWithAsyncContext(callback, options) { + const existingHub = getCurrentHub(); - if (list.length > 0) { - return list; - } + if (existingHub && _optionalChain([options, 'optionalAccess', _ => _.reuseExisting])) { + // We're already in an async context, so we don't need to create a new one + // just call the callback with the current hub + return callback(); } - return []; - } + const newHub = createNewHub(existingHub); - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); + return asyncStorage.run(newHub, () => { + return callback(); + }); } -}; -module.exports = Queues; + core.setAsyncContextStrategy({ getCurrentHub, runWithAsyncContext }); +} + +exports.setHooksAsyncContextStrategy = setHooksAsyncContextStrategy; +//# sourceMappingURL=hooks.js.map + /***/ }), -/***/ 28037: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 15593: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +const nodeVersion = __nccwpck_require__(85858); +const domain = __nccwpck_require__(93769); +const hooks = __nccwpck_require__(70589); -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +/** + * Sets the correct async context strategy for Node.js + * + * Node.js >= 14 uses AsyncLocalStorage + * Node.js < 14 uses domains + */ +function setNodeAsyncContextStrategy() { + if (nodeVersion.NODE_VERSION.major >= 14) { + hooks.setHooksAsyncContextStrategy(); + } else { + domain.setDomainAsyncContextStrategy(); + } +} -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +exports.setNodeAsyncContextStrategy = setNodeAsyncContextStrategy; +//# sourceMappingURL=index.js.map -var Events, RedisConnection, Scripts, parser; -parser = __nccwpck_require__(90651); -Events = __nccwpck_require__(81065); -Scripts = __nccwpck_require__(65206); -RedisConnection = function () { - class RedisConnection { - constructor(options = {}) { - parser.load(options, this.defaults, this); +/***/ }), - if (this.Redis == null) { - this.Redis = eval("require")("redis"); // Obfuscated or else Webpack/Angular will try to inline the optional redis module. To override this behavior: pass the redis module to Bottleneck as the 'Redis' option. - } +/***/ 69279: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (this.Events == null) { - this.Events = new Events(this); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - this.terminated = false; +const os = __nccwpck_require__(70857); +const util = __nccwpck_require__(39023); +const core = __nccwpck_require__(75442); - if (this.client == null) { - this.client = this.Redis.createClient(this.clientOptions); - } +/** + * The Sentry Node SDK Client. + * + * @see NodeClientOptions for documentation on configuration options. + * @see SentryClient for usage documentation. + */ +class NodeClient extends core.ServerRuntimeClient { + /** + * Creates a new Node SDK instance. + * @param options Configuration options for this SDK. + */ + constructor(options) { + core.applySdkMetadata(options, 'node'); - this.subscriber = this.client.duplicate(); - this.limiters = {}; - this.shas = {}; - this.ready = this.Promise.all([this._setup(this.client, false), this._setup(this.subscriber, true)]).then(() => { - return this._loadScripts(); - }).then(() => { - return { - client: this.client, - subscriber: this.subscriber - }; - }); - } + // Until node supports global TextEncoder in all versions we support, we are forced to pass it from util + options.transportOptions = { + textEncoder: new util.TextEncoder(), + ...options.transportOptions, + }; - _setup(client, sub) { - client.setMaxListeners(0); - return new this.Promise((resolve, reject) => { - client.on("error", e => { - return this.Events.trigger("error", e); - }); + const clientOptions = { + ...options, + platform: 'node', + runtime: { name: 'node', version: global.process.version }, + serverName: options.serverName || global.process.env.SENTRY_NAME || os.hostname(), + }; - if (sub) { - client.on("message", (channel, message) => { - var ref; - return (ref = this.limiters[channel]) != null ? ref._store.onMessage(channel, message) : void 0; - }); - } + super(clientOptions); + } +} - if (client.ready) { - return resolve(); - } else { - return client.once("ready", resolve); - } - }); - } +exports.NodeClient = NodeClient; +//# sourceMappingURL=client.js.map - _loadScript(name) { - return new this.Promise((resolve, reject) => { - var payload; - payload = Scripts.payload(name); - return this.client.multi([["script", "load", payload]]).exec((err, replies) => { - if (err != null) { - return reject(err); - } - this.shas[name] = replies[0]; - return resolve(replies[0]); - }); - }); - } +/***/ }), - _loadScripts() { - return this.Promise.all(Scripts.names.map(k => { - return this._loadScript(k); - })); - } +/***/ 12086: +/***/ ((__unused_webpack_module, exports) => { - __runCommand__(cmd) { - var _this = this; +Object.defineProperty(exports, "__esModule", ({ value: true })); - return _asyncToGenerator(function* () { - yield _this.ready; - return new _this.Promise((resolve, reject) => { - return _this.client.multi([cmd]).exec_atomic(function (err, replies) { - if (err != null) { - return reject(err); - } else { - return resolve(replies[0]); - } - }); - }); - })(); - } +const replacements = [ + ['january', '1'], + ['february', '2'], + ['march', '3'], + ['april', '4'], + ['may', '5'], + ['june', '6'], + ['july', '7'], + ['august', '8'], + ['september', '9'], + ['october', '10'], + ['november', '11'], + ['december', '12'], + ['jan', '1'], + ['feb', '2'], + ['mar', '3'], + ['apr', '4'], + ['may', '5'], + ['jun', '6'], + ['jul', '7'], + ['aug', '8'], + ['sep', '9'], + ['oct', '10'], + ['nov', '11'], + ['dec', '12'], + ['sunday', '0'], + ['monday', '1'], + ['tuesday', '2'], + ['wednesday', '3'], + ['thursday', '4'], + ['friday', '5'], + ['saturday', '6'], + ['sun', '0'], + ['mon', '1'], + ['tue', '2'], + ['wed', '3'], + ['thu', '4'], + ['fri', '5'], + ['sat', '6'], +]; - __addLimiter__(instance) { - return this.Promise.all([instance.channel(), instance.channel_client()].map(channel => { - return new this.Promise((resolve, reject) => { - var handler; +/** + * Replaces names in cron expressions + */ +function replaceCronNames(cronExpression) { + return replacements.reduce( + // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor + (acc, [name, replacement]) => acc.replace(new RegExp(name, 'gi'), replacement), + cronExpression, + ); +} - handler = chan => { - if (chan === channel) { - this.subscriber.removeListener("subscribe", handler); - this.limiters[channel] = instance; - return resolve(); - } - }; +exports.replaceCronNames = replaceCronNames; +//# sourceMappingURL=common.js.map - this.subscriber.on("subscribe", handler); - return this.subscriber.subscribe(channel); - }); - })); - } - __removeLimiter__(instance) { - var _this2 = this; +/***/ }), - return this.Promise.all([instance.channel(), instance.channel_client()].map( - /*#__PURE__*/ - function () { - var _ref = _asyncToGenerator(function* (channel) { - if (!_this2.terminated) { - yield new _this2.Promise((resolve, reject) => { - return _this2.subscriber.unsubscribe(channel, function (err, chan) { - if (err != null) { - return reject(err); - } +/***/ 62711: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (chan === channel) { - return resolve(); - } - }); - }); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - return delete _this2.limiters[channel]; - }); +const core = __nccwpck_require__(75442); +const common = __nccwpck_require__(12086); - return function (_x) { - return _ref.apply(this, arguments); - }; - }())); - } +const ERROR_TEXT = 'Automatic instrumentation of CronJob only supports crontab string'; - __scriptArgs__(name, id, args, cb) { - var keys; - keys = Scripts.keys(name, id); - return [this.shas[name], keys.length].concat(keys, args, cb); - } +/** + * Instruments the `cron` library to send a check-in event to Sentry for each job execution. + * + * ```ts + * import * as Sentry from '@sentry/node'; + * import { CronJob } from 'cron'; + * + * const CronJobWithCheckIn = Sentry.cron.instrumentCron(CronJob, 'my-cron-job'); + * + * // use the constructor + * const job = new CronJobWithCheckIn('* * * * *', () => { + * console.log('You will see this message every minute'); + * }); + * + * // or from + * const job = CronJobWithCheckIn.from({ cronTime: '* * * * *', onTick: () => { + * console.log('You will see this message every minute'); + * }); + * ``` + */ +function instrumentCron(lib, monitorSlug) { + let jobScheduled = false; - __scriptFn__(name) { - return this.client.evalsha.bind(this.client); - } + return new Proxy(lib, { + construct(target, args) { + const [cronTime, onTick, onComplete, start, timeZone, ...rest] = args; - disconnect(flush = true) { - var i, k, len, ref; - ref = Object.keys(this.limiters); + if (typeof cronTime !== 'string') { + throw new Error(ERROR_TEXT); + } - for (i = 0, len = ref.length; i < len; i++) { - k = ref[i]; - clearInterval(this.limiters[k]._store.heartbeat); + if (jobScheduled) { + throw new Error(`A job named '${monitorSlug}' has already been scheduled`); } - this.limiters = {}; - this.terminated = true; - this.client.end(flush); - this.subscriber.end(flush); - return this.Promise.resolve(); - } + jobScheduled = true; - } + const cronString = common.replaceCronNames(cronTime); - ; - RedisConnection.prototype.datastore = "redis"; - RedisConnection.prototype.defaults = { - Redis: null, - clientOptions: {}, - client: null, - Promise: Promise, - Events: null - }; - return RedisConnection; -}.call(void 0); + function monitoredTick(context, onComplete) { + return core.withMonitor( + monitorSlug, + () => { + return onTick(context, onComplete); + }, + { + schedule: { type: 'crontab', value: cronString }, + timezone: timeZone || undefined, + }, + ); + } -module.exports = RedisConnection; + return new target(cronTime, monitoredTick, onComplete, start, timeZone, ...rest); + }, + get(target, prop) { + if (prop === 'from') { + return (param) => { + const { cronTime, onTick, timeZone } = param; -/***/ }), + if (typeof cronTime !== 'string') { + throw new Error(ERROR_TEXT); + } -/***/ 35068: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (jobScheduled) { + throw new Error(`A job named '${monitorSlug}' has already been scheduled`); + } -"use strict"; + jobScheduled = true; + const cronString = common.replaceCronNames(cronTime); -function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } + param.onTick = (context, onComplete) => { + return core.withMonitor( + monitorSlug, + () => { + return onTick(context, onComplete); + }, + { + schedule: { type: 'crontab', value: cronString }, + timezone: timeZone || undefined, + }, + ); + }; -function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } + return target.from(param); + }; + } else { + return target[prop]; + } + }, + }); +} -function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +exports.instrumentCron = instrumentCron; +//# sourceMappingURL=cron.js.map -function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +/***/ }), -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +/***/ 18896: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var BottleneckError, IORedisConnection, RedisConnection, RedisDatastore, parser; -parser = __nccwpck_require__(90651); -BottleneckError = __nccwpck_require__(88185); -RedisConnection = __nccwpck_require__(28037); -IORedisConnection = __nccwpck_require__(41725); -RedisDatastore = class RedisDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.originalId = this.instance.id; - this.clientId = this.instance._randomIndex(); - parser.load(storeInstanceOptions, storeInstanceOptions, this); - this.clients = {}; - this.capacityPriorityCounters = {}; - this.sharedConnection = this.connection != null; +var { + _optionalChain +} = __nccwpck_require__(57540); - if (this.connection == null) { - this.connection = this.instance.datastore === "redis" ? new RedisConnection({ - Redis: this.Redis, - clientOptions: this.clientOptions, - Promise: this.Promise, - Events: this.instance.Events - }) : this.instance.datastore === "ioredis" ? new IORedisConnection({ - Redis: this.Redis, - clientOptions: this.clientOptions, - clusterNodes: this.clusterNodes, - Promise: this.Promise, - Events: this.instance.Events - }) : void 0; - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - this.instance.connection = this.connection; - this.instance.datastore = this.connection.datastore; - this.ready = this.connection.ready.then(clients => { - this.clients = clients; - return this.runScript("init", this.prepareInitSettings(this.clearDatastore)); - }).then(() => { - return this.connection.__addLimiter__(this.instance); - }).then(() => { - return this.runScript("register_client", [this.instance.queued()]); - }).then(() => { - var base; +const core = __nccwpck_require__(75442); +const common = __nccwpck_require__(12086); - if (typeof (base = this.heartbeat = setInterval(() => { - return this.runScript("heartbeat", []).catch(e => { - return this.instance.Events.trigger("error", e); +/** + * Wraps the `node-cron` library with check-in monitoring. + * + * ```ts + * import * as Sentry from "@sentry/node"; + * import cron from "node-cron"; + * + * const cronWithCheckIn = Sentry.cron.instrumentNodeCron(cron); + * + * cronWithCheckIn.schedule( + * "* * * * *", + * () => { + * console.log("running a task every minute"); + * }, + * { name: "my-cron-job" }, + * ); + * ``` + */ +function instrumentNodeCron(lib) { + return new Proxy(lib, { + get(target, prop) { + if (prop === 'schedule' && target.schedule) { + // When 'get' is called for schedule, return a proxied version of the schedule function + return new Proxy(target.schedule, { + apply(target, thisArg, argArray) { + const [expression, , options] = argArray; + + if (!_optionalChain([options, 'optionalAccess', _ => _.name])) { + throw new Error('Missing "name" for scheduled job. A name is required for Sentry check-in monitoring.'); + } + + return core.withMonitor( + options.name, + () => { + return target.apply(thisArg, argArray); + }, + { + schedule: { type: 'crontab', value: common.replaceCronNames(expression) }, + timezone: _optionalChain([options, 'optionalAccess', _2 => _2.timezone]), + }, + ); + }, }); - }, this.heartbeatInterval)).unref === "function") { - base.unref(); + } else { + return target[prop]; } + }, + }); +} - return this.clients; - }); - } +exports.instrumentNodeCron = instrumentNodeCron; +//# sourceMappingURL=node-cron.js.map - __publish__(message) { - var _this = this; - return _asyncToGenerator(function* () { - var client; +/***/ }), - var _ref = yield _this.ready; +/***/ 27505: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - client = _ref.client; - return client.publish(_this.instance.channel(), `message:${message.toString()}`); - })(); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - onMessage(channel, message) { - var _this2 = this; +const core = __nccwpck_require__(75442); +const common = __nccwpck_require__(12086); - return _asyncToGenerator(function* () { - var capacity, counter, data, drained, e, newCapacity, pos, priorityClient, rawCapacity, type; +/** + * Instruments the `node-schedule` library to send a check-in event to Sentry for each job execution. + * + * ```ts + * import * as Sentry from '@sentry/node'; + * import * as schedule from 'node-schedule'; + * + * const scheduleWithCheckIn = Sentry.cron.instrumentNodeSchedule(schedule); + * + * const job = scheduleWithCheckIn.scheduleJob('my-cron-job', '* * * * *', () => { + * console.log('You will see this message every minute'); + * }); + * ``` + */ +function instrumentNodeSchedule(lib) { + return new Proxy(lib, { + get(target, prop) { + if (prop === 'scheduleJob') { + // eslint-disable-next-line @typescript-eslint/unbound-method + return new Proxy(target.scheduleJob, { + apply(target, thisArg, argArray) { + const [nameOrExpression, expressionOrCallback] = argArray; - try { - pos = message.indexOf(":"); - var _ref2 = [message.slice(0, pos), message.slice(pos + 1)]; - type = _ref2[0]; - data = _ref2[1]; + if (typeof nameOrExpression !== 'string' || typeof expressionOrCallback !== 'string') { + throw new Error( + "Automatic instrumentation of 'node-schedule' requires the first parameter of 'scheduleJob' to be a job name string and the second parameter to be a crontab string", + ); + } - if (type === "capacity") { - return yield _this2.instance._drainAll(data.length > 0 ? ~~data : void 0); - } else if (type === "capacity-priority") { - var _data$split = data.split(":"); + const monitorSlug = nameOrExpression; + const expression = expressionOrCallback; + + return core.withMonitor( + monitorSlug, + () => { + return target.apply(thisArg, argArray); + }, + { + schedule: { type: 'crontab', value: common.replaceCronNames(expression) }, + }, + ); + }, + }); + } - var _data$split2 = _slicedToArray(_data$split, 3); + return target[prop]; + }, + }); +} - rawCapacity = _data$split2[0]; - priorityClient = _data$split2[1]; - counter = _data$split2[2]; - capacity = rawCapacity.length > 0 ? ~~rawCapacity : void 0; +exports.instrumentNodeSchedule = instrumentNodeSchedule; +//# sourceMappingURL=node-schedule.js.map - if (priorityClient === _this2.clientId) { - drained = yield _this2.instance._drainAll(capacity); - newCapacity = capacity != null ? capacity - (drained || 0) : ""; - return yield _this2.clients.client.publish(_this2.instance.channel(), `capacity-priority:${newCapacity}::${counter}`); - } else if (priorityClient === "") { - clearTimeout(_this2.capacityPriorityCounters[counter]); - delete _this2.capacityPriorityCounters[counter]; - return _this2.instance._drainAll(capacity); - } else { - return _this2.capacityPriorityCounters[counter] = setTimeout( - /*#__PURE__*/ - _asyncToGenerator(function* () { - var e; - try { - delete _this2.capacityPriorityCounters[counter]; - yield _this2.runScript("blacklist_client", [priorityClient]); - return yield _this2.instance._drainAll(capacity); - } catch (error) { - e = error; - return _this2.instance.Events.trigger("error", e); - } - }), 1000); - } - } else if (type === "message") { - return _this2.instance.Events.trigger("message", data); - } else if (type === "blocked") { - return yield _this2.instance._dropAllQueued(); - } - } catch (error) { - e = error; - return _this2.instance.Events.trigger("error", e); - } - })(); +/***/ }), + +/***/ 96652: +/***/ ((__unused_webpack_module, exports) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +const DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__); + +exports.DEBUG_BUILD = DEBUG_BUILD; +//# sourceMappingURL=debug-build.js.map + + +/***/ }), + +/***/ 82489: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +var { + _optionalChain +} = __nccwpck_require__(57540); + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(96652); +const sdk = __nccwpck_require__(32554); +const trpc = __nccwpck_require__(93343); +const requestDataDeprecated = __nccwpck_require__(2850); + +/** + * Express-compatible tracing handler. + * @see Exposed as `Handlers.tracingHandler` + */ +function tracingHandler() + + { + return function sentryTracingMiddleware( + req, + res, + next, + ) { + const options = _optionalChain([core.getClient, 'call', _ => _(), 'optionalAccess', _2 => _2.getOptions, 'call', _3 => _3()]); + + if ( + !options || + options.instrumenter !== 'sentry' || + _optionalChain([req, 'access', _4 => _4.method, 'optionalAccess', _5 => _5.toUpperCase, 'call', _6 => _6()]) === 'OPTIONS' || + _optionalChain([req, 'access', _7 => _7.method, 'optionalAccess', _8 => _8.toUpperCase, 'call', _9 => _9()]) === 'HEAD' + ) { + return next(); + } + + const sentryTrace = req.headers && utils.isString(req.headers['sentry-trace']) ? req.headers['sentry-trace'] : undefined; + const baggage = _optionalChain([req, 'access', _10 => _10.headers, 'optionalAccess', _11 => _11.baggage]); + if (!core.hasTracingEnabled(options)) { + return next(); + } + + const [name, source] = utils.extractPathForTransaction(req, { path: true, method: true }); + const transaction = core.continueTrace({ sentryTrace, baggage }, ctx => + // TODO: Refactor this to use `startSpan()` + // eslint-disable-next-line deprecation/deprecation + core.startTransaction( + { + name, + op: 'http.server', + origin: 'auto.http.node.tracingHandler', + ...ctx, + data: { + [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, + }, + metadata: { + // eslint-disable-next-line deprecation/deprecation + ...ctx.metadata, + // The request should already have been stored in `scope.sdkProcessingMetadata` (which will become + // `event.sdkProcessingMetadata` the same way the metadata here will) by `sentryRequestMiddleware`, but on the + // off chance someone is using `sentryTracingMiddleware` without `sentryRequestMiddleware`, it doesn't hurt to + // be sure + request: req, + }, + }, + // extra context passed to the tracesSampler + { request: utils.extractRequestData(req) }, + ), + ); + + // We put the transaction on the scope so users can attach children to it + // eslint-disable-next-line deprecation/deprecation + core.getCurrentScope().setSpan(transaction); + + // We also set __sentry_transaction on the response so people can grab the transaction there to add + // spans to it later. + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + (res ).__sentry_transaction = transaction; + + res.once('finish', () => { + // Push `transaction.finish` to the next event loop so open spans have a chance to finish before the transaction + // closes + setImmediate(() => { + // eslint-disable-next-line deprecation/deprecation + utils.addRequestDataToTransaction(transaction, req); + core.setHttpStatus(transaction, res.statusCode); + transaction.end(); + }); + }); + + next(); + }; +} + +/** + * Backwards compatibility shim which can be removed in v8. Forces the given options to follow the + * `AddRequestDataToEventOptions` interface. + * + * TODO (v8): Get rid of this, and stop passing `requestDataOptionsFromExpressHandler` to `setSDKProcessingMetadata`. + */ +function convertReqHandlerOptsToAddReqDataOpts( + reqHandlerOptions = {}, +) { + let addRequestDataOptions; + + if ('include' in reqHandlerOptions) { + addRequestDataOptions = { include: reqHandlerOptions.include }; + } else { + // eslint-disable-next-line deprecation/deprecation + const { ip, request, transaction, user } = reqHandlerOptions ; + + if (ip || request || transaction || user) { + addRequestDataOptions = { include: utils.dropUndefinedKeys({ ip, request, transaction, user }) }; + } } - __disconnect__(flush) { - clearInterval(this.heartbeat); + return addRequestDataOptions; +} - if (this.sharedConnection) { - return this.connection.__removeLimiter__(this.instance); - } else { - return this.connection.disconnect(flush); +/** + * Express compatible request handler. + * @see Exposed as `Handlers.requestHandler` + */ +function requestHandler( + options, +) { + // TODO (v8): Get rid of this + const requestDataOptions = convertReqHandlerOptsToAddReqDataOpts(options); + + const client = core.getClient(); + // Initialise an instance of SessionFlusher on the client when `autoSessionTracking` is enabled and the + // `requestHandler` middleware is used indicating that we are running in SessionAggregates mode + if (client && sdk.isAutoSessionTrackingEnabled(client)) { + client.initSessionFlusher(); + + // If Scope contains a Single mode Session, it is removed in favor of using Session Aggregates mode + const scope = core.getCurrentScope(); + if (scope.getSession()) { + scope.setSession(); } } - runScript(name, args) { - var _this3 = this; + return function sentryRequestMiddleware( + req, + res, + next, + ) { + if (options && options.flushTimeout && options.flushTimeout > 0) { + // eslint-disable-next-line @typescript-eslint/unbound-method + const _end = res.end; + res.end = function (chunk, encoding, cb) { + void core.flush(options.flushTimeout) + .then(() => { + _end.call(this, chunk, encoding, cb); + }) + .then(null, e => { + debugBuild.DEBUG_BUILD && utils.logger.error(e); + _end.call(this, chunk, encoding, cb); + }); + }; + } + core.runWithAsyncContext(() => { + const scope = core.getCurrentScope(); + scope.setSDKProcessingMetadata({ + request: req, + // TODO (v8): Stop passing this + requestDataOptionsFromExpressHandler: requestDataOptions, + }); - return _asyncToGenerator(function* () { - if (!(name === "init" || name === "register_client")) { - yield _this3.ready; + const client = core.getClient(); + if (sdk.isAutoSessionTrackingEnabled(client)) { + // Set `status` of `RequestSession` to Ok, at the beginning of the request + scope.setRequestSession({ status: 'ok' }); } - return new _this3.Promise((resolve, reject) => { - var all_args, arr; - all_args = [Date.now(), _this3.clientId].concat(args); + res.once('finish', () => { + const client = core.getClient(); + if (sdk.isAutoSessionTrackingEnabled(client)) { + setImmediate(() => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (client && (client )._captureRequestSession) { + // Calling _captureRequestSession to capture request session at the end of the request by incrementing + // the correct SessionAggregates bucket i.e. crashed, errored or exited + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + (client )._captureRequestSession(); + } + }); + } + }); + next(); + }); + }; +} - _this3.instance.Events.trigger("debug", `Calling Redis script: ${name}.lua`, all_args); +/** JSDoc */ - arr = _this3.connection.__scriptArgs__(name, _this3.originalId, all_args, function (err, replies) { - if (err != null) { - return reject(err); - } +/** JSDoc */ +function getStatusCodeFromResponse(error) { + const statusCode = error.status || error.statusCode || error.status_code || (error.output && error.output.statusCode); + return statusCode ? parseInt(statusCode , 10) : 500; +} - return resolve(replies); - }); - return _this3.connection.__scriptFn__(name)(...arr); - }).catch(e => { - if (e.message === "SETTINGS_KEY_NOT_FOUND") { - if (name === "heartbeat") { - return _this3.Promise.resolve(); - } else { - return _this3.runScript("init", _this3.prepareInitSettings(false)).then(() => { - return _this3.runScript(name, args); - }); +/** Returns true if response code is internal server error */ +function defaultShouldHandleError(error) { + const status = getStatusCodeFromResponse(error); + return status >= 500; +} + +/** + * Express compatible error handler. + * @see Exposed as `Handlers.errorHandler` + */ +function errorHandler(options + +) + + { + return function sentryErrorMiddleware( + error, + _req, + res, + next, + ) { + const shouldHandleError = (options && options.shouldHandleError) || defaultShouldHandleError; + + if (shouldHandleError(error)) { + core.withScope(_scope => { + // The request should already have been stored in `scope.sdkProcessingMetadata` by `sentryRequestMiddleware`, + // but on the off chance someone is using `sentryErrorMiddleware` without `sentryRequestMiddleware`, it doesn't + // hurt to be sure + _scope.setSDKProcessingMetadata({ request: _req }); + + // For some reason we need to set the transaction on the scope again + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const transaction = (res ).__sentry_transaction ; + if (transaction && !core.getActiveSpan()) { + // eslint-disable-next-line deprecation/deprecation + _scope.setSpan(transaction); + } + + const client = core.getClient(); + if (client && sdk.isAutoSessionTrackingEnabled(client)) { + // Check if the `SessionFlusher` is instantiated on the client to go into this branch that marks the + // `requestSession.status` as `Crashed`, and this check is necessary because the `SessionFlusher` is only + // instantiated when the the`requestHandler` middleware is initialised, which indicates that we should be + // running in SessionAggregates mode + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const isSessionAggregatesMode = (client )._sessionFlusher !== undefined; + if (isSessionAggregatesMode) { + const requestSession = _scope.getRequestSession(); + // If an error bubbles to the `errorHandler`, then this is an unhandled error, and should be reported as a + // Crashed session. The `_requestSession.status` is checked to ensure that this error is happening within + // the bounds of a request, and if so the status is updated + if (requestSession && requestSession.status !== undefined) { + requestSession.status = 'crashed'; + } } - } else if (e.message === "UNKNOWN_CLIENT") { - return _this3.runScript("register_client", [_this3.instance.queued()]).then(() => { - return _this3.runScript(name, args); - }); - } else { - return _this3.Promise.reject(e); } - }); - })(); - } - prepareArray(arr) { - var i, len, results, x; - results = []; + const eventId = core.captureException(error, { mechanism: { type: 'middleware', handled: false } }); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + (res ).sentry = eventId; + next(error); + }); - for (i = 0, len = arr.length; i < len; i++) { - x = arr[i]; - results.push(x != null ? x.toString() : ""); + return; } - return results; - } + next(error); + }; +} - prepareObject(obj) { - var arr, k, v; - arr = []; +/** + * Sentry tRPC middleware that names the handling transaction after the called procedure. + * + * Use the Sentry tRPC middleware in combination with the Sentry server integration, + * e.g. Express Request Handlers or Next.js SDK. + * + * @deprecated Please use the top level export instead: + * ``` + * // OLD + * import * as Sentry from '@sentry/node'; + * Sentry.Handlers.trpcMiddleware(); + * + * // NEW + * import * as Sentry from '@sentry/node'; + * Sentry.trpcMiddleware(); + * ``` + */ +// eslint-disable-next-line deprecation/deprecation +const trpcMiddleware = trpc.trpcMiddleware; - for (k in obj) { - v = obj[k]; - arr.push(k, v != null ? v.toString() : ""); - } +exports.extractRequestData = requestDataDeprecated.extractRequestData; +exports.parseRequest = requestDataDeprecated.parseRequest; +exports.errorHandler = errorHandler; +exports.requestHandler = requestHandler; +exports.tracingHandler = tracingHandler; +exports.trpcMiddleware = trpcMiddleware; +//# sourceMappingURL=handlers.js.map - return arr; - } - prepareInitSettings(clear) { - var args; - args = this.prepareObject(Object.assign({}, this.storeOptions, { - id: this.originalId, - version: this.instance.version, - groupTimeout: this.timeout, - clientTimeout: this.clientTimeout - })); - args.unshift(clear ? 1 : 0, this.instance.version); - return args; - } +/***/ }), - convertBool(b) { - return !!b; - } +/***/ 72454: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - __updateSettings__(options) { - var _this4 = this; +Object.defineProperty(exports, "__esModule", ({ value: true })); - return _asyncToGenerator(function* () { - yield _this4.runScript("update_settings", _this4.prepareObject(options)); - return parser.overwrite(options, options, _this4.storeOptions); - })(); - } +const core = __nccwpck_require__(75442); +const index = __nccwpck_require__(6963); +const client = __nccwpck_require__(69279); +const http = __nccwpck_require__(4121); +const sdk = __nccwpck_require__(32554); +const utils = __nccwpck_require__(57540); +const utils$1 = __nccwpck_require__(19911); +const module$1 = __nccwpck_require__(29968); +const legacy = __nccwpck_require__(31545); +const handlers = __nccwpck_require__(82489); +const index$5 = __nccwpck_require__(20028); +const integrations$1 = __nccwpck_require__(42560); +const integrations = __nccwpck_require__(35322); +const console = __nccwpck_require__(34441); +const onuncaughtexception = __nccwpck_require__(63295); +const onunhandledrejection = __nccwpck_require__(31061); +const modules = __nccwpck_require__(45705); +const contextlines = __nccwpck_require__(73456); +const context = __nccwpck_require__(90079); +const index$1 = __nccwpck_require__(58676); +const spotlight = __nccwpck_require__(38880); +const index$2 = __nccwpck_require__(6008); +const index$3 = __nccwpck_require__(70345); +const index$4 = __nccwpck_require__(12561); +const http$1 = __nccwpck_require__(15842); +const trpc = __nccwpck_require__(93343); +const cron$1 = __nccwpck_require__(62711); +const nodeCron = __nccwpck_require__(18896); +const nodeSchedule = __nccwpck_require__(27505); + +/** + * @deprecated use `createGetModuleFromFilename` instead. + */ +const getModuleFromFilename = module$1.createGetModuleFromFilename(); + +// TODO: Deprecate this once we migrated tracing integrations +const Integrations = { + // eslint-disable-next-line deprecation/deprecation + ...core.Integrations, + ...index$5, + ...integrations$1, +}; - __running__() { - return this.runScript("running", []); - } +/** Methods to instrument cron libraries for Sentry check-ins */ +const cron = { + instrumentCron: cron$1.instrumentCron, + instrumentNodeCron: nodeCron.instrumentNodeCron, + instrumentNodeSchedule: nodeSchedule.instrumentNodeSchedule, +}; - __queued__() { - return this.runScript("queued", []); - } +exports.Hub = core.Hub; +exports.SDK_VERSION = core.SDK_VERSION; +exports.SEMANTIC_ATTRIBUTE_SENTRY_OP = core.SEMANTIC_ATTRIBUTE_SENTRY_OP; +exports.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN; +exports.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = core.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE; +exports.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE; +exports.Scope = core.Scope; +exports.addBreadcrumb = core.addBreadcrumb; +exports.addEventProcessor = core.addEventProcessor; +exports.addGlobalEventProcessor = core.addGlobalEventProcessor; +exports.addIntegration = core.addIntegration; +exports.captureCheckIn = core.captureCheckIn; +exports.captureEvent = core.captureEvent; +exports.captureException = core.captureException; +exports.captureMessage = core.captureMessage; +exports.captureSession = core.captureSession; +exports.close = core.close; +exports.configureScope = core.configureScope; +exports.continueTrace = core.continueTrace; +exports.createTransport = core.createTransport; +exports.endSession = core.endSession; +exports.extractTraceparentData = core.extractTraceparentData; +exports.flush = core.flush; +exports.functionToStringIntegration = core.functionToStringIntegration; +exports.getActiveSpan = core.getActiveSpan; +exports.getActiveTransaction = core.getActiveTransaction; +exports.getClient = core.getClient; +exports.getCurrentHub = core.getCurrentHub; +exports.getCurrentScope = core.getCurrentScope; +exports.getGlobalScope = core.getGlobalScope; +exports.getHubFromCarrier = core.getHubFromCarrier; +exports.getIsolationScope = core.getIsolationScope; +exports.getSpanStatusFromHttpCode = core.getSpanStatusFromHttpCode; +exports.inboundFiltersIntegration = core.inboundFiltersIntegration; +exports.isInitialized = core.isInitialized; +exports.lastEventId = core.lastEventId; +exports.linkedErrorsIntegration = core.linkedErrorsIntegration; +exports.makeMain = core.makeMain; +exports.metrics = core.metrics; +exports.parameterize = core.parameterize; +exports.requestDataIntegration = core.requestDataIntegration; +exports.runWithAsyncContext = core.runWithAsyncContext; +exports.setContext = core.setContext; +exports.setCurrentClient = core.setCurrentClient; +exports.setExtra = core.setExtra; +exports.setExtras = core.setExtras; +exports.setHttpStatus = core.setHttpStatus; +exports.setMeasurement = core.setMeasurement; +exports.setTag = core.setTag; +exports.setTags = core.setTags; +exports.setUser = core.setUser; +exports.spanStatusfromHttpCode = core.spanStatusfromHttpCode; +exports.startActiveSpan = core.startActiveSpan; +exports.startInactiveSpan = core.startInactiveSpan; +exports.startSession = core.startSession; +exports.startSpan = core.startSpan; +exports.startSpanManual = core.startSpanManual; +exports.startTransaction = core.startTransaction; +exports.trace = core.trace; +exports.withActiveSpan = core.withActiveSpan; +exports.withIsolationScope = core.withIsolationScope; +exports.withMonitor = core.withMonitor; +exports.withScope = core.withScope; +exports.autoDiscoverNodePerformanceMonitoringIntegrations = index.autoDiscoverNodePerformanceMonitoringIntegrations; +exports.NodeClient = client.NodeClient; +exports.makeNodeTransport = http.makeNodeTransport; +exports.defaultIntegrations = sdk.defaultIntegrations; +exports.defaultStackParser = sdk.defaultStackParser; +exports.getDefaultIntegrations = sdk.getDefaultIntegrations; +exports.getSentryRelease = sdk.getSentryRelease; +exports.init = sdk.init; +exports.DEFAULT_USER_INCLUDES = utils.DEFAULT_USER_INCLUDES; +exports.addRequestDataToEvent = utils.addRequestDataToEvent; +exports.extractRequestData = utils.extractRequestData; +exports.deepReadDirSync = utils$1.deepReadDirSync; +exports.createGetModuleFromFilename = module$1.createGetModuleFromFilename; +exports.enableAnrDetection = legacy.enableAnrDetection; +exports.Handlers = handlers; +exports.captureConsoleIntegration = integrations.captureConsoleIntegration; +exports.debugIntegration = integrations.debugIntegration; +exports.dedupeIntegration = integrations.dedupeIntegration; +exports.extraErrorDataIntegration = integrations.extraErrorDataIntegration; +exports.httpClientIntegration = integrations.httpClientIntegration; +exports.reportingObserverIntegration = integrations.reportingObserverIntegration; +exports.rewriteFramesIntegration = integrations.rewriteFramesIntegration; +exports.sessionTimingIntegration = integrations.sessionTimingIntegration; +exports.consoleIntegration = console.consoleIntegration; +exports.onUncaughtExceptionIntegration = onuncaughtexception.onUncaughtExceptionIntegration; +exports.onUnhandledRejectionIntegration = onunhandledrejection.onUnhandledRejectionIntegration; +exports.modulesIntegration = modules.modulesIntegration; +exports.contextLinesIntegration = contextlines.contextLinesIntegration; +exports.nodeContextIntegration = context.nodeContextIntegration; +exports.localVariablesIntegration = index$1.localVariablesIntegration; +exports.spotlightIntegration = spotlight.spotlightIntegration; +exports.anrIntegration = index$2.anrIntegration; +exports.hapiErrorPlugin = index$3.hapiErrorPlugin; +exports.hapiIntegration = index$3.hapiIntegration; +exports.Undici = index$4.Undici; +exports.nativeNodeFetchintegration = index$4.nativeNodeFetchintegration; +exports.Http = http$1.Http; +exports.httpIntegration = http$1.httpIntegration; +exports.trpcMiddleware = trpc.trpcMiddleware; +exports.Integrations = Integrations; +exports.cron = cron; +exports.getModuleFromFilename = getModuleFromFilename; +//# sourceMappingURL=index.js.map - __done__() { - return this.runScript("done", []); - } - __groupCheck__() { - var _this5 = this; +/***/ }), - return _asyncToGenerator(function* () { - return _this5.convertBool((yield _this5.runScript("group_check", []))); - })(); - } +/***/ 6008: +/***/ ((module, exports, __nccwpck_require__) => { - __incrementReservoir__(incr) { - return this.runScript("increment_reservoir", [incr]); - } +/* module decorator */ module = __nccwpck_require__.nmd(module); +var { + _optionalChain, + _optionalChainDelete +} = __nccwpck_require__(57540); - __currentReservoir__() { - return this.runScript("current_reservoir", []); +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const url = __nccwpck_require__(87016); +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const nodeVersion = __nccwpck_require__(85858); +const workerScript = __nccwpck_require__(33894); + +const DEFAULT_INTERVAL = 50; +const DEFAULT_HANG_THRESHOLD = 5000; + +function log(message, ...args) { + utils.logger.log(`[ANR] ${message}`, ...args); +} + +function globalWithScopeFetchFn() { + return utils.GLOBAL_OBJ; +} + +/** Fetches merged scope data */ +function getScopeData() { + const scope = core.getGlobalScope().getScopeData(); + core.mergeScopeData(scope, core.getIsolationScope().getScopeData()); + core.mergeScopeData(scope, core.getCurrentScope().getScopeData()); + + // We remove attachments because they likely won't serialize well as json + scope.attachments = []; + // We can't serialize event processor functions + scope.eventProcessors = []; + + return scope; +} + +/** + * We need to use dynamicRequire because worker_threads is not available in node < v12 and webpack error will when + * targeting those versions + */ +function getWorkerThreads() { + return utils.dynamicRequire(module, 'worker_threads'); +} + +/** + * Gets contexts by calling all event processors. This relies on being called after all integrations are setup + */ +async function getContexts(client) { + let event = { message: 'ANR' }; + const eventHint = {}; + + for (const processor of client.getEventProcessors()) { + if (event === null) break; + event = await processor(event, eventHint); } - __check__(weight) { - var _this6 = this; + return _optionalChain([event, 'optionalAccess', _2 => _2.contexts]) || {}; +} - return _asyncToGenerator(function* () { - return _this6.convertBool((yield _this6.runScript("check", _this6.prepareArray([weight])))); - })(); +const INTEGRATION_NAME = 'Anr'; + +const _anrIntegration = ((options = {}) => { + if (nodeVersion.NODE_VERSION.major < 16 || (nodeVersion.NODE_VERSION.major === 16 && nodeVersion.NODE_VERSION.minor < 17)) { + throw new Error('ANR detection requires Node 16.17.0 or later'); } - __register__(index, weight, expiration) { - var _this7 = this; + let worker; + let client; - return _asyncToGenerator(function* () { - var reservoir, success, wait; + // Hookup the scope fetch function to the global object so that it can be called from the worker thread via the + // debugger when it pauses + const gbl = globalWithScopeFetchFn(); + gbl.__SENTRY_GET_SCOPES__ = getScopeData; - var _ref4 = yield _this7.runScript("register", _this7.prepareArray([index, weight, expiration])); + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + startWorker: () => { + if (worker) { + return; + } - var _ref5 = _slicedToArray(_ref4, 3); + if (client) { + worker = _startWorker(client, options); + } + }, + stopWorker: () => { + if (worker) { + // eslint-disable-next-line @typescript-eslint/no-floating-promises + worker.then(stop => { + stop(); + worker = undefined; + }); + } + }, + setup(initClient) { + client = initClient; - success = _ref5[0]; - wait = _ref5[1]; - reservoir = _ref5[2]; - return { - success: _this7.convertBool(success), - wait, - reservoir - }; - })(); - } + // setImmediate is used to ensure that all other integrations have had their setup called first. + // This allows us to call into all integrations to fetch the full context + setImmediate(() => this.startWorker()); + }, + } ; +}) ; - __submit__(queueLength, weight) { - var _this8 = this; +const anrIntegration = core.defineIntegration(_anrIntegration) ; - return _asyncToGenerator(function* () { - var blocked, e, maxConcurrent, overweight, reachedHWM, strategy; +/** + * Starts a thread to detect App Not Responding (ANR) events + * + * ANR detection requires Node 16.17.0 or later + * + * @deprecated Use `anrIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const Anr = core.convertIntegrationFnToClass(INTEGRATION_NAME, anrIntegration) - try { - var _ref6 = yield _this8.runScript("submit", _this8.prepareArray([queueLength, weight])); +; - var _ref7 = _slicedToArray(_ref6, 3); +// eslint-disable-next-line deprecation/deprecation - reachedHWM = _ref7[0]; - blocked = _ref7[1]; - strategy = _ref7[2]; - return { - reachedHWM: _this8.convertBool(reachedHWM), - blocked: _this8.convertBool(blocked), - strategy - }; - } catch (error) { - e = error; +/** + * Starts the ANR worker thread + */ +async function _startWorker( + client, + integrationOptions, +) { + const dsn = client.getDsn(); - if (e.message.indexOf("OVERWEIGHT") === 0) { - var _e$message$split = e.message.split(":"); + if (!dsn) { + return () => { + // + }; + } - var _e$message$split2 = _slicedToArray(_e$message$split, 3); + const contexts = await getContexts(client); - overweight = _e$message$split2[0]; - weight = _e$message$split2[1]; - maxConcurrent = _e$message$split2[2]; - throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${maxConcurrent}`); - } else { - throw e; - } - } - })(); + // These will not be accurate if sent later from the worker thread + _optionalChainDelete([contexts, 'access', _3 => _3.app, 'optionalAccess', _4 => delete _4.app_memory]); + _optionalChainDelete([contexts, 'access', _5 => _5.device, 'optionalAccess', _6 => delete _6.free_memory]); + + const initOptions = client.getOptions(); + + const sdkMetadata = client.getSdkMetadata() || {}; + if (sdkMetadata.sdk) { + sdkMetadata.sdk.integrations = initOptions.integrations.map(i => i.name); } - __free__(index, weight) { - var _this9 = this; + const options = { + debug: utils.logger.isEnabled(), + dsn, + environment: initOptions.environment || 'production', + release: initOptions.release, + dist: initOptions.dist, + sdkMetadata, + appRootPath: integrationOptions.appRootPath, + pollInterval: integrationOptions.pollInterval || DEFAULT_INTERVAL, + anrThreshold: integrationOptions.anrThreshold || DEFAULT_HANG_THRESHOLD, + captureStackTrace: !!integrationOptions.captureStackTrace, + staticTags: integrationOptions.staticTags || {}, + contexts, + }; - return _asyncToGenerator(function* () { - var running; - running = yield _this9.runScript("free", _this9.prepareArray([index])); - return { - running - }; - })(); + if (options.captureStackTrace) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const inspector = __nccwpck_require__(50264); + if (!inspector.url()) { + inspector.open(0); + } } -}; -module.exports = RedisDatastore; + const { Worker } = getWorkerThreads(); + + const worker = new Worker(new url.URL(`data:application/javascript;base64,${workerScript.base64WorkerScript}`), { + workerData: options, + }); + + process.on('exit', () => { + // eslint-disable-next-line @typescript-eslint/no-floating-promises + worker.terminate(); + }); + + const timer = setInterval(() => { + try { + const currentSession = core.getCurrentScope().getSession(); + // We need to copy the session object and remove the toJSON method so it can be sent to the worker + // serialized without making it a SerializedSession + const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined; + // message the worker to tell it the main event loop is still running + worker.postMessage({ session }); + } catch (_) { + // + } + }, options.pollInterval); + // Timer should not block exit + timer.unref(); + + worker.on('message', (msg) => { + if (msg === 'session-ended') { + log('ANR event sent from ANR worker. Clearing session in this thread.'); + core.getCurrentScope().setSession(undefined); + } + }); + + worker.once('error', (err) => { + clearInterval(timer); + log('ANR worker error', err); + }); + + worker.once('exit', (code) => { + clearInterval(timer); + log('ANR worker exit', code); + }); + + // Ensure this thread can't block app exit + worker.unref(); + + return () => { + // eslint-disable-next-line @typescript-eslint/no-floating-promises + worker.terminate(); + clearInterval(timer); + }; +} + +exports.Anr = Anr; +exports.anrIntegration = anrIntegration; +//# sourceMappingURL=index.js.map + /***/ }), -/***/ 65206: +/***/ 31545: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +const core = __nccwpck_require__(75442); +const index = __nccwpck_require__(6008); -var headers, lua, templates; -lua = __nccwpck_require__(79583); -headers = { - refs: lua["refs.lua"], - validate_keys: lua["validate_keys.lua"], - validate_client: lua["validate_client.lua"], - refresh_expiration: lua["refresh_expiration.lua"], - process_tick: lua["process_tick.lua"], - conditions_check: lua["conditions_check.lua"], - get_time: lua["get_time.lua"] -}; - -exports.allKeys = function (id) { - return [ - /* - HASH - */ - `b_${id}_settings`, - /* - HASH - job index -> weight - */ - `b_${id}_job_weights`, - /* - ZSET - job index -> expiration - */ - `b_${id}_job_expirations`, - /* - HASH - job index -> client - */ - `b_${id}_job_clients`, - /* - ZSET - client -> sum running - */ - `b_${id}_client_running`, - /* - HASH - client -> num queued - */ - `b_${id}_client_num_queued`, - /* - ZSET - client -> last job registered - */ - `b_${id}_client_last_registered`, - /* - ZSET - client -> last seen - */ - `b_${id}_client_last_seen`]; -}; +// TODO (v8): Remove this entire file and the `enableAnrDetection` export -templates = { - init: { - keys: exports.allKeys, - headers: ["process_tick"], - refresh_expiration: true, - code: lua["init.lua"] - }, - group_check: { - keys: exports.allKeys, - headers: [], - refresh_expiration: false, - code: lua["group_check.lua"] - }, - register_client: { - keys: exports.allKeys, - headers: ["validate_keys"], - refresh_expiration: false, - code: lua["register_client.lua"] - }, - blacklist_client: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client"], - refresh_expiration: false, - code: lua["blacklist_client.lua"] - }, - heartbeat: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client", "process_tick"], - refresh_expiration: false, - code: lua["heartbeat.lua"] - }, - update_settings: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client", "process_tick"], - refresh_expiration: true, - code: lua["update_settings.lua"] - }, - running: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client", "process_tick"], - refresh_expiration: false, - code: lua["running.lua"] - }, - queued: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client"], - refresh_expiration: false, - code: lua["queued.lua"] - }, - done: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client", "process_tick"], - refresh_expiration: false, - code: lua["done.lua"] - }, - check: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client", "process_tick", "conditions_check"], - refresh_expiration: false, - code: lua["check.lua"] - }, - submit: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client", "process_tick", "conditions_check"], - refresh_expiration: true, - code: lua["submit.lua"] - }, - register: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client", "process_tick", "conditions_check"], - refresh_expiration: true, - code: lua["register.lua"] - }, - free: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client", "process_tick"], - refresh_expiration: true, - code: lua["free.lua"] - }, - current_reservoir: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client", "process_tick"], - refresh_expiration: false, - code: lua["current_reservoir.lua"] - }, - increment_reservoir: { - keys: exports.allKeys, - headers: ["validate_keys", "validate_client", "process_tick"], - refresh_expiration: true, - code: lua["increment_reservoir.lua"] - } -}; -exports.names = Object.keys(templates); +/** + * @deprecated Use the `Anr` integration instead. + * + * ```ts + * import * as Sentry from '@sentry/node'; + * + * Sentry.init({ + * dsn: '__DSN__', + * integrations: [new Sentry.Integrations.Anr({ captureStackTrace: true })], + * }); + * ``` + */ +function enableAnrDetection(options) { + const client = core.getClient() ; + // eslint-disable-next-line deprecation/deprecation + const integration = new index.Anr(options); + integration.setup(client); + return Promise.resolve(); +} -exports.keys = function (name, id) { - return templates[name].keys(id); -}; +exports.enableAnrDetection = enableAnrDetection; +//# sourceMappingURL=legacy.js.map -exports.payload = function (name) { - var template; - template = templates[name]; - return Array.prototype.concat(headers.refs, template.headers.map(function (h) { - return headers[h]; - }), template.refresh_expiration ? headers.refresh_expiration : "", template.code).join("\n"); -}; /***/ }), -/***/ 72878: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 33894: +/***/ ((__unused_webpack_module, exports) => { -"use strict"; +/*! @sentry/node 7.119.2 (9211bd4) | https://github.com/getsentry/sentry-javascript */ +exports.base64WorkerScript="aW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJ2luc3BlY3Rvcic7CmltcG9ydCB7IHdvcmtlckRhdGEsIHBhcmVudFBvcnQgfSBmcm9tICd3b3JrZXJfdGhyZWFkcyc7CmltcG9ydCB7IHBvc2l4LCBzZXAgfSBmcm9tICdwYXRoJzsKaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJzsKaW1wb3J0ICogYXMgaHR0cHMgZnJvbSAnaHR0cHMnOwppbXBvcnQgeyBSZWFkYWJsZSB9IGZyb20gJ3N0cmVhbSc7CmltcG9ydCB7IFVSTCB9IGZyb20gJ3VybCc7CmltcG9ydCB7IGNyZWF0ZUd6aXAgfSBmcm9tICd6bGliJzsKaW1wb3J0ICogYXMgbmV0IGZyb20gJ25ldCc7CmltcG9ydCAqIGFzIHRscyBmcm9tICd0bHMnOwoKLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC91bmJvdW5kLW1ldGhvZApjb25zdCBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIG9uZSBvZiBhIGZldyBFcnJvciBvciBFcnJvci1saWtlCiAqIHtAbGluayBpc0Vycm9yfS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzRXJyb3Iod2F0KSB7CiAgc3dpdGNoIChvYmplY3RUb1N0cmluZy5jYWxsKHdhdCkpIHsKICAgIGNhc2UgJ1tvYmplY3QgRXJyb3JdJzoKICAgIGNhc2UgJ1tvYmplY3QgRXhjZXB0aW9uXSc6CiAgICBjYXNlICdbb2JqZWN0IERPTUV4Y2VwdGlvbl0nOgogICAgICByZXR1cm4gdHJ1ZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBpc0luc3RhbmNlT2Yod2F0LCBFcnJvcik7CiAgfQp9Ci8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSBpcyBhbiBpbnN0YW5jZSBvZiB0aGUgZ2l2ZW4gYnVpbHQtaW4gY2xhc3MuCiAqCiAqIEBwYXJhbSB3YXQgVGhlIHZhbHVlIHRvIGJlIGNoZWNrZWQKICogQHBhcmFtIGNsYXNzTmFtZQogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc0J1aWx0aW4od2F0LCBjbGFzc05hbWUpIHsKICByZXR1cm4gb2JqZWN0VG9TdHJpbmcuY2FsbCh3YXQpID09PSBgW29iamVjdCAke2NsYXNzTmFtZX1dYDsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhIHN0cmluZwogKiB7QGxpbmsgaXNTdHJpbmd9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNTdHJpbmcod2F0KSB7CiAgcmV0dXJuIGlzQnVpbHRpbih3YXQsICdTdHJpbmcnKTsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhbiBvYmplY3QgbGl0ZXJhbCwgb3IgYSBjbGFzcyBpbnN0YW5jZS4KICoge0BsaW5rIGlzUGxhaW5PYmplY3R9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh3YXQpIHsKICByZXR1cm4gaXNCdWlsdGluKHdhdCwgJ09iamVjdCcpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIEV2ZW50IGluc3RhbmNlCiAqIHtAbGluayBpc0V2ZW50fS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzRXZlbnQod2F0KSB7CiAgcmV0dXJuIHR5cGVvZiBFdmVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNJbnN0YW5jZU9mKHdhdCwgRXZlbnQpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIEVsZW1lbnQgaW5zdGFuY2UKICoge0BsaW5rIGlzRWxlbWVudH0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc0VsZW1lbnQod2F0KSB7CiAgcmV0dXJuIHR5cGVvZiBFbGVtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpc0luc3RhbmNlT2Yod2F0LCBFbGVtZW50KTsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlIGhhcyBhIHRoZW4gZnVuY3Rpb24uCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKi8KZnVuY3Rpb24gaXNUaGVuYWJsZSh3YXQpIHsKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzCiAgcmV0dXJuIEJvb2xlYW4od2F0ICYmIHdhdC50aGVuICYmIHR5cGVvZiB3YXQudGhlbiA9PT0gJ2Z1bmN0aW9uJyk7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgYSBTeW50aGV0aWNFdmVudAogKiB7QGxpbmsgaXNTeW50aGV0aWNFdmVudH0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1N5bnRoZXRpY0V2ZW50KHdhdCkgewogIHJldHVybiBpc1BsYWluT2JqZWN0KHdhdCkgJiYgJ25hdGl2ZUV2ZW50JyBpbiB3YXQgJiYgJ3ByZXZlbnREZWZhdWx0JyBpbiB3YXQgJiYgJ3N0b3BQcm9wYWdhdGlvbicgaW4gd2F0Owp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUgaXMgTmFOCiAqIHtAbGluayBpc05hTn0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc05hTiQxKHdhdCkgewogIHJldHVybiB0eXBlb2Ygd2F0ID09PSAnbnVtYmVyJyAmJiB3YXQgIT09IHdhdDsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhbiBpbnN0YW5jZSBvZiBwcm92aWRlZCBjb25zdHJ1Y3Rvci4KICoge0BsaW5rIGlzSW5zdGFuY2VPZn0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcGFyYW0gYmFzZSBBIGNvbnN0cnVjdG9yIHRvIGJlIHVzZWQgaW4gYSBjaGVjay4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNJbnN0YW5jZU9mKHdhdCwgYmFzZSkgewogIHRyeSB7CiAgICByZXR1cm4gd2F0IGluc3RhbmNlb2YgYmFzZTsKICB9IGNhdGNoIChfZSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhIFZ1ZSBWaWV3TW9kZWwuCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1Z1ZVZpZXdNb2RlbCh3YXQpIHsKICAvLyBOb3QgdXNpbmcgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyBiZWNhdXNlIGluIFZ1ZSAzIGl0IHdvdWxkIHJlYWQgdGhlIGluc3RhbmNlJ3MgU3ltYm9sKFN5bWJvbC50b1N0cmluZ1RhZykgcHJvcGVydHkuCiAgcmV0dXJuICEhKHR5cGVvZiB3YXQgPT09ICdvYmplY3QnICYmIHdhdCAhPT0gbnVsbCAmJiAoKHdhdCApLl9faXNWdWUgfHwgKHdhdCApLl9pc1Z1ZSkpOwp9CgovKiogSW50ZXJuYWwgZ2xvYmFsIHdpdGggY29tbW9uIHByb3BlcnRpZXMgYW5kIFNlbnRyeSBleHRlbnNpb25zICAqLwoKLy8gVGhlIGNvZGUgYmVsb3cgZm9yICdpc0dsb2JhbE9iaicgYW5kICdHTE9CQUxfT0JKJyB3YXMgY29waWVkIGZyb20gY29yZS1qcyBiZWZvcmUgbW9kaWZpY2F0aW9uCi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2Jsb2IvMWI5NDRkZjU1MjgyY2RjOTljOTBkYjVmNDllYjBiNmVkYTJjYzBhMy9wYWNrYWdlcy9jb3JlLWpzL2ludGVybmFscy9nbG9iYWwuanMKLy8gY29yZS1qcyBoYXMgdGhlIGZvbGxvd2luZyBsaWNlbmNlOgovLwovLyBDb3B5cmlnaHQgKGMpIDIwMTQtMjAyMiBEZW5pcyBQdXNoa2FyZXYKLy8KLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQovLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAovLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci8vCi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgovLwovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgovLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgovLyBUSEUgU09GVFdBUkUuCgovKiogUmV0dXJucyAnb2JqJyBpZiBpdCdzIHRoZSBnbG9iYWwgb2JqZWN0LCBvdGhlcndpc2UgcmV0dXJucyB1bmRlZmluZWQgKi8KZnVuY3Rpb24gaXNHbG9iYWxPYmoob2JqKSB7CiAgcmV0dXJuIG9iaiAmJiBvYmouTWF0aCA9PSBNYXRoID8gb2JqIDogdW5kZWZpbmVkOwp9CgovKiogR2V0J3MgdGhlIGdsb2JhbCBvYmplY3QgZm9yIHRoZSBjdXJyZW50IEphdmFTY3JpcHQgcnVudGltZSAqLwpjb25zdCBHTE9CQUxfT0JKID0KICAodHlwZW9mIGdsb2JhbFRoaXMgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmooZ2xvYmFsVGhpcykpIHx8CiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscwogICh0eXBlb2Ygd2luZG93ID09ICdvYmplY3QnICYmIGlzR2xvYmFsT2JqKHdpbmRvdykpIHx8CiAgKHR5cGVvZiBzZWxmID09ICdvYmplY3QnICYmIGlzR2xvYmFsT2JqKHNlbGYpKSB8fAogICh0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGlzR2xvYmFsT2JqKGdsb2JhbCkpIHx8CiAgKGZ1bmN0aW9uICgpIHsKICAgIHJldHVybiB0aGlzOwogIH0pKCkgfHwKICB7fTsKCi8qKgogKiBAZGVwcmVjYXRlZCBVc2UgR0xPQkFMX09CSiBpbnN0ZWFkIG9yIFdJTkRPVyBmcm9tIEBzZW50cnkvYnJvd3Nlci4gVGhpcyB3aWxsIGJlIHJlbW92ZWQgaW4gdjgKICovCmZ1bmN0aW9uIGdldEdsb2JhbE9iamVjdCgpIHsKICByZXR1cm4gR0xPQkFMX09CSiA7Cn0KCi8qKgogKiBSZXR1cm5zIGEgZ2xvYmFsIHNpbmdsZXRvbiBjb250YWluZWQgaW4gdGhlIGdsb2JhbCBgX19TRU5UUllfX2Agb2JqZWN0LgogKgogKiBJZiB0aGUgc2luZ2xldG9uIGRvZXNuJ3QgYWxyZWFkeSBleGlzdCBpbiBgX19TRU5UUllfX2AsIGl0IHdpbGwgYmUgY3JlYXRlZCB1c2luZyB0aGUgZ2l2ZW4gZmFjdG9yeQogKiBmdW5jdGlvbiBhbmQgYWRkZWQgdG8gdGhlIGBfX1NFTlRSWV9fYCBvYmplY3QuCiAqCiAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGdsb2JhbCBzaW5nbGV0b24gb24gX19TRU5UUllfXwogKiBAcGFyYW0gY3JlYXRvciBjcmVhdG9yIEZhY3RvcnkgZnVuY3Rpb24gdG8gY3JlYXRlIHRoZSBzaW5nbGV0b24gaWYgaXQgZG9lc24ndCBhbHJlYWR5IGV4aXN0IG9uIGBfX1NFTlRSWV9fYAogKiBAcGFyYW0gb2JqIChPcHRpb25hbCkgVGhlIGdsb2JhbCBvYmplY3Qgb24gd2hpY2ggdG8gbG9vayBmb3IgYF9fU0VOVFJZX19gLCBpZiBub3QgYEdMT0JBTF9PQkpgJ3MgcmV0dXJuIHZhbHVlCiAqIEByZXR1cm5zIHRoZSBzaW5nbGV0b24KICovCmZ1bmN0aW9uIGdldEdsb2JhbFNpbmdsZXRvbihuYW1lLCBjcmVhdG9yLCBvYmopIHsKICBjb25zdCBnYmwgPSAob2JqIHx8IEdMT0JBTF9PQkopIDsKICBjb25zdCBfX1NFTlRSWV9fID0gKGdibC5fX1NFTlRSWV9fID0gZ2JsLl9fU0VOVFJZX18gfHwge30pOwogIGNvbnN0IHNpbmdsZXRvbiA9IF9fU0VOVFJZX19bbmFtZV0gfHwgKF9fU0VOVFJZX19bbmFtZV0gPSBjcmVhdG9yKCkpOwogIHJldHVybiBzaW5nbGV0b247Cn0KCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgpjb25zdCBXSU5ET1cgPSBnZXRHbG9iYWxPYmplY3QoKTsKCmNvbnN0IERFRkFVTFRfTUFYX1NUUklOR19MRU5HVEggPSA4MDsKCi8qKgogKiBHaXZlbiBhIGNoaWxkIERPTSBlbGVtZW50LCByZXR1cm5zIGEgcXVlcnktc2VsZWN0b3Igc3RhdGVtZW50IGRlc2NyaWJpbmcgdGhhdAogKiBhbmQgaXRzIGFuY2VzdG9ycwogKiBlLmcuIFtIVE1MRWxlbWVudF0gPT4gYm9keSA+IGRpdiA+IGlucHV0I2Zvby5idG5bbmFtZT1iYXpdCiAqIEByZXR1cm5zIGdlbmVyYXRlZCBET00gcGF0aAogKi8KZnVuY3Rpb24gaHRtbFRyZWVBc1N0cmluZygKICBlbGVtLAogIG9wdGlvbnMgPSB7fSwKKSB7CiAgaWYgKCFlbGVtKSB7CiAgICByZXR1cm4gJzx1bmtub3duPic7CiAgfQoKICAvLyB0cnkvY2F0Y2ggYm90aDoKICAvLyAtIGFjY2Vzc2luZyBldmVudC50YXJnZXQgKHNlZSBnZXRzZW50cnkvcmF2ZW4tanMjODM4LCAjNzY4KQogIC8vIC0gYGh0bWxUcmVlQXNTdHJpbmdgIGJlY2F1c2UgaXQncyBjb21wbGV4LCBhbmQganVzdCBhY2Nlc3NpbmcgdGhlIERPTSBpbmNvcnJlY3RseQogIC8vIC0gY2FuIHRocm93IGFuIGV4Y2VwdGlvbiBpbiBzb21lIGNpcmN1bXN0YW5jZXMuCiAgdHJ5IHsKICAgIGxldCBjdXJyZW50RWxlbSA9IGVsZW0gOwogICAgY29uc3QgTUFYX1RSQVZFUlNFX0hFSUdIVCA9IDU7CiAgICBjb25zdCBvdXQgPSBbXTsKICAgIGxldCBoZWlnaHQgPSAwOwogICAgbGV0IGxlbiA9IDA7CiAgICBjb25zdCBzZXBhcmF0b3IgPSAnID4gJzsKICAgIGNvbnN0IHNlcExlbmd0aCA9IHNlcGFyYXRvci5sZW5ndGg7CiAgICBsZXQgbmV4dFN0cjsKICAgIGNvbnN0IGtleUF0dHJzID0gQXJyYXkuaXNBcnJheShvcHRpb25zKSA/IG9wdGlvbnMgOiBvcHRpb25zLmtleUF0dHJzOwogICAgY29uc3QgbWF4U3RyaW5nTGVuZ3RoID0gKCFBcnJheS5pc0FycmF5KG9wdGlvbnMpICYmIG9wdGlvbnMubWF4U3RyaW5nTGVuZ3RoKSB8fCBERUZBVUxUX01BWF9TVFJJTkdfTEVOR1RIOwoKICAgIHdoaWxlIChjdXJyZW50RWxlbSAmJiBoZWlnaHQrKyA8IE1BWF9UUkFWRVJTRV9IRUlHSFQpIHsKICAgICAgbmV4dFN0ciA9IF9odG1sRWxlbWVudEFzU3RyaW5nKGN1cnJlbnRFbGVtLCBrZXlBdHRycyk7CiAgICAgIC8vIGJhaWwgb3V0IGlmCiAgICAgIC8vIC0gbmV4dFN0ciBpcyB0aGUgJ2h0bWwnIGVsZW1lbnQKICAgICAgLy8gLSB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgdGhhdCB3b3VsZCBiZSBjcmVhdGVkIGV4Y2VlZHMgbWF4U3RyaW5nTGVuZ3RoCiAgICAgIC8vICAgKGlnbm9yZSB0aGlzIGxpbWl0IGlmIHdlIGFyZSBvbiB0aGUgZmlyc3QgaXRlcmF0aW9uKQogICAgICBpZiAobmV4dFN0ciA9PT0gJ2h0bWwnIHx8IChoZWlnaHQgPiAxICYmIGxlbiArIG91dC5sZW5ndGggKiBzZXBMZW5ndGggKyBuZXh0U3RyLmxlbmd0aCA+PSBtYXhTdHJpbmdMZW5ndGgpKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICAgIG91dC5wdXNoKG5leHRTdHIpOwoKICAgICAgbGVuICs9IG5leHRTdHIubGVuZ3RoOwogICAgICBjdXJyZW50RWxlbSA9IGN1cnJlbnRFbGVtLnBhcmVudE5vZGU7CiAgICB9CgogICAgcmV0dXJuIG91dC5yZXZlcnNlKCkuam9pbihzZXBhcmF0b3IpOwogIH0gY2F0Y2ggKF9vTykgewogICAgcmV0dXJuICc8dW5rbm93bj4nOwogIH0KfQoKLyoqCiAqIFJldHVybnMgYSBzaW1wbGUsIHF1ZXJ5LXNlbGVjdG9yIHJlcHJlc2VudGF0aW9uIG9mIGEgRE9NIGVsZW1lbnQKICogZS5nLiBbSFRNTEVsZW1lbnRdID0+IGlucHV0I2Zvby5idG5bbmFtZT1iYXpdCiAqIEByZXR1cm5zIGdlbmVyYXRlZCBET00gcGF0aAogKi8KZnVuY3Rpb24gX2h0bWxFbGVtZW50QXNTdHJpbmcoZWwsIGtleUF0dHJzKSB7CiAgY29uc3QgZWxlbSA9IGVsCgo7CgogIGNvbnN0IG91dCA9IFtdOwogIGxldCBjbGFzc05hbWU7CiAgbGV0IGNsYXNzZXM7CiAgbGV0IGtleTsKICBsZXQgYXR0cjsKICBsZXQgaTsKCiAgaWYgKCFlbGVtIHx8ICFlbGVtLnRhZ05hbWUpIHsKICAgIHJldHVybiAnJzsKICB9CgogIC8vIEB0cy1leHBlY3QtZXJyb3IgV0lORE9XIGhhcyBIVE1MRWxlbWVudAogIGlmIChXSU5ET1cuSFRNTEVsZW1lbnQpIHsKICAgIC8vIElmIHVzaW5nIHRoZSBjb21wb25lbnQgbmFtZSBhbm5vdGF0aW9uIHBsdWdpbiwgdGhpcyB2YWx1ZSBtYXkgYmUgYXZhaWxhYmxlIG9uIHRoZSBET00gbm9kZQogICAgaWYgKGVsZW0gaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiBlbGVtLmRhdGFzZXQgJiYgZWxlbS5kYXRhc2V0WydzZW50cnlDb21wb25lbnQnXSkgewogICAgICByZXR1cm4gZWxlbS5kYXRhc2V0WydzZW50cnlDb21wb25lbnQnXTsKICAgIH0KICB9CgogIG91dC5wdXNoKGVsZW0udGFnTmFtZS50b0xvd2VyQ2FzZSgpKTsKCiAgLy8gUGFpcnMgb2YgYXR0cmlidXRlIGtleXMgZGVmaW5lZCBpbiBgc2VyaWFsaXplQXR0cmlidXRlYCBhbmQgdGhlaXIgdmFsdWVzIG9uIGVsZW1lbnQuCiAgY29uc3Qga2V5QXR0clBhaXJzID0KICAgIGtleUF0dHJzICYmIGtleUF0dHJzLmxlbmd0aAogICAgICA/IGtleUF0dHJzLmZpbHRlcihrZXlBdHRyID0+IGVsZW0uZ2V0QXR0cmlidXRlKGtleUF0dHIpKS5tYXAoa2V5QXR0ciA9PiBba2V5QXR0ciwgZWxlbS5nZXRBdHRyaWJ1dGUoa2V5QXR0cildKQogICAgICA6IG51bGw7CgogIGlmIChrZXlBdHRyUGFpcnMgJiYga2V5QXR0clBhaXJzLmxlbmd0aCkgewogICAga2V5QXR0clBhaXJzLmZvckVhY2goa2V5QXR0clBhaXIgPT4gewogICAgICBvdXQucHVzaChgWyR7a2V5QXR0clBhaXJbMF19PSIke2tleUF0dHJQYWlyWzFdfSJdYCk7CiAgICB9KTsKICB9IGVsc2UgewogICAgaWYgKGVsZW0uaWQpIHsKICAgICAgb3V0LnB1c2goYCMke2VsZW0uaWR9YCk7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdAogICAgY2xhc3NOYW1lID0gZWxlbS5jbGFzc05hbWU7CiAgICBpZiAoY2xhc3NOYW1lICYmIGlzU3RyaW5nKGNsYXNzTmFtZSkpIHsKICAgICAgY2xhc3NlcyA9IGNsYXNzTmFtZS5zcGxpdCgvXHMrLyk7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBjbGFzc2VzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgb3V0LnB1c2goYC4ke2NsYXNzZXNbaV19YCk7CiAgICAgIH0KICAgIH0KICB9CiAgY29uc3QgYWxsb3dlZEF0dHJzID0gWydhcmlhLWxhYmVsJywgJ3R5cGUnLCAnbmFtZScsICd0aXRsZScsICdhbHQnXTsKICBmb3IgKGkgPSAwOyBpIDwgYWxsb3dlZEF0dHJzLmxlbmd0aDsgaSsrKSB7CiAgICBrZXkgPSBhbGxvd2VkQXR0cnNbaV07CiAgICBhdHRyID0gZWxlbS5nZXRBdHRyaWJ1dGUoa2V5KTsKICAgIGlmIChhdHRyKSB7CiAgICAgIG91dC5wdXNoKGBbJHtrZXl9PSIke2F0dHJ9Il1gKTsKICAgIH0KICB9CiAgcmV0dXJuIG91dC5qb2luKCcnKTsKfQoKLyoqCiAqIFRoaXMgc2VydmVzIGFzIGEgYnVpbGQgdGltZSBmbGFnIHRoYXQgd2lsbCBiZSB0cnVlIGJ5IGRlZmF1bHQsIGJ1dCBmYWxzZSBpbiBub24tZGVidWcgYnVpbGRzIG9yIGlmIHVzZXJzIHJlcGxhY2UgYF9fU0VOVFJZX0RFQlVHX19gIGluIHRoZWlyIGdlbmVyYXRlZCBjb2RlLgogKgogKiBBVFRFTlRJT046IFRoaXMgY29uc3RhbnQgbXVzdCBuZXZlciBjcm9zcyBwYWNrYWdlIGJvdW5kYXJpZXMgKGkuZS4gYmUgZXhwb3J0ZWQpIHRvIGd1YXJhbnRlZSB0aGF0IGl0IGNhbiBiZSB1c2VkIGZvciB0cmVlIHNoYWtpbmcuCiAqLwpjb25zdCBERUJVR19CVUlMRCQxID0gKHR5cGVvZiBfX1NFTlRSWV9ERUJVR19fID09PSAndW5kZWZpbmVkJyB8fCBfX1NFTlRSWV9ERUJVR19fKTsKCi8qKiBQcmVmaXggZm9yIGxvZ2dpbmcgc3RyaW5ncyAqLwpjb25zdCBQUkVGSVggPSAnU2VudHJ5IExvZ2dlciAnOwoKY29uc3QgQ09OU09MRV9MRVZFTFMgPSBbCiAgJ2RlYnVnJywKICAnaW5mbycsCiAgJ3dhcm4nLAogICdlcnJvcicsCiAgJ2xvZycsCiAgJ2Fzc2VydCcsCiAgJ3RyYWNlJywKXSA7CgovKiogVGhpcyBtYXkgYmUgbXV0YXRlZCBieSB0aGUgY29uc29sZSBpbnN0cnVtZW50YXRpb24uICovCmNvbnN0IG9yaWdpbmFsQ29uc29sZU1ldGhvZHMKCiA9IHt9OwoKLyoqIEpTRG9jICovCgovKioKICogVGVtcG9yYXJpbHkgZGlzYWJsZSBzZW50cnkgY29uc29sZSBpbnN0cnVtZW50YXRpb25zLgogKgogKiBAcGFyYW0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZ2FpbnN0IHRoZSBvcmlnaW5hbCBgY29uc29sZWAgbWVzc2FnZXMKICogQHJldHVybnMgVGhlIHJlc3VsdHMgb2YgdGhlIGNhbGxiYWNrCiAqLwpmdW5jdGlvbiBjb25zb2xlU2FuZGJveChjYWxsYmFjaykgewogIGlmICghKCdjb25zb2xlJyBpbiBHTE9CQUxfT0JKKSkgewogICAgcmV0dXJuIGNhbGxiYWNrKCk7CiAgfQoKICBjb25zdCBjb25zb2xlID0gR0xPQkFMX09CSi5jb25zb2xlIDsKICBjb25zdCB3cmFwcGVkRnVuY3MgPSB7fTsKCiAgY29uc3Qgd3JhcHBlZExldmVscyA9IE9iamVjdC5rZXlzKG9yaWdpbmFsQ29uc29sZU1ldGhvZHMpIDsKCiAgLy8gUmVzdG9yZSBhbGwgd3JhcHBlZCBjb25zb2xlIG1ldGhvZHMKICB3cmFwcGVkTGV2ZWxzLmZvckVhY2gobGV2ZWwgPT4gewogICAgY29uc3Qgb3JpZ2luYWxDb25zb2xlTWV0aG9kID0gb3JpZ2luYWxDb25zb2xlTWV0aG9kc1tsZXZlbF0gOwogICAgd3JhcHBlZEZ1bmNzW2xldmVsXSA9IGNvbnNvbGVbbGV2ZWxdIDsKICAgIGNvbnNvbGVbbGV2ZWxdID0gb3JpZ2luYWxDb25zb2xlTWV0aG9kOwogIH0pOwoKICB0cnkgewogICAgcmV0dXJuIGNhbGxiYWNrKCk7CiAgfSBmaW5hbGx5IHsKICAgIC8vIFJldmVydCByZXN0b3JhdGlvbiB0byB3cmFwcGVkIHN0YXRlCiAgICB3cmFwcGVkTGV2ZWxzLmZvckVhY2gobGV2ZWwgPT4gewogICAgICBjb25zb2xlW2xldmVsXSA9IHdyYXBwZWRGdW5jc1tsZXZlbF0gOwogICAgfSk7CiAgfQp9CgpmdW5jdGlvbiBtYWtlTG9nZ2VyKCkgewogIGxldCBlbmFibGVkID0gZmFsc2U7CiAgY29uc3QgbG9nZ2VyID0gewogICAgZW5hYmxlOiAoKSA9PiB7CiAgICAgIGVuYWJsZWQgPSB0cnVlOwogICAgfSwKICAgIGRpc2FibGU6ICgpID0+IHsKICAgICAgZW5hYmxlZCA9IGZhbHNlOwogICAgfSwKICAgIGlzRW5hYmxlZDogKCkgPT4gZW5hYmxlZCwKICB9OwoKICBpZiAoREVCVUdfQlVJTEQkMSkgewogICAgQ09OU09MRV9MRVZFTFMuZm9yRWFjaChuYW1lID0+IHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkKICAgICAgbG9nZ2VyW25hbWVdID0gKC4uLmFyZ3MpID0+IHsKICAgICAgICBpZiAoZW5hYmxlZCkgewogICAgICAgICAgY29uc29sZVNhbmRib3goKCkgPT4gewogICAgICAgICAgICBHTE9CQUxfT0JKLmNvbnNvbGVbbmFtZV0oYCR7UFJFRklYfVske25hbWV9XTpgLCAuLi5hcmdzKTsKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfTsKICAgIH0pOwogIH0gZWxzZSB7CiAgICBDT05TT0xFX0xFVkVMUy5mb3JFYWNoKG5hbWUgPT4gewogICAgICBsb2dnZXJbbmFtZV0gPSAoKSA9PiB1bmRlZmluZWQ7CiAgICB9KTsKICB9CgogIHJldHVybiBsb2dnZXIgOwp9Cgpjb25zdCBsb2dnZXIgPSBtYWtlTG9nZ2VyKCk7CgovKioKICogUmVuZGVycyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgRHNuLgogKgogKiBCeSBkZWZhdWx0LCB0aGlzIHdpbGwgcmVuZGVyIHRoZSBwdWJsaWMgcmVwcmVzZW50YXRpb24gd2l0aG91dCB0aGUgcGFzc3dvcmQKICogY29tcG9uZW50LiBUbyBnZXQgdGhlIGRlcHJlY2F0ZWQgcHJpdmF0ZSByZXByZXNlbnRhdGlvbiwgc2V0IGB3aXRoUGFzc3dvcmRgCiAqIHRvIHRydWUuCiAqCiAqIEBwYXJhbSB3aXRoUGFzc3dvcmQgV2hlbiBzZXQgdG8gdHJ1ZSwgdGhlIHBhc3N3b3JkIHdpbGwgYmUgaW5jbHVkZWQuCiAqLwpmdW5jdGlvbiBkc25Ub1N0cmluZyhkc24sIHdpdGhQYXNzd29yZCA9IGZhbHNlKSB7CiAgY29uc3QgeyBob3N0LCBwYXRoLCBwYXNzLCBwb3J0LCBwcm9qZWN0SWQsIHByb3RvY29sLCBwdWJsaWNLZXkgfSA9IGRzbjsKICByZXR1cm4gKAogICAgYCR7cHJvdG9jb2x9Oi8vJHtwdWJsaWNLZXl9JHt3aXRoUGFzc3dvcmQgJiYgcGFzcyA/IGA6JHtwYXNzfWAgOiAnJ31gICsKICAgIGBAJHtob3N0fSR7cG9ydCA/IGA6JHtwb3J0fWAgOiAnJ30vJHtwYXRoID8gYCR7cGF0aH0vYCA6IHBhdGh9JHtwcm9qZWN0SWR9YAogICk7Cn0KCi8qKiBBbiBlcnJvciBlbWl0dGVkIGJ5IFNlbnRyeSBTREtzIGFuZCByZWxhdGVkIHV0aWxpdGllcy4gKi8KY2xhc3MgU2VudHJ5RXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgLyoqIERpc3BsYXkgbmFtZSBvZiB0aGlzIGVycm9yIGluc3RhbmNlLiAqLwoKICAgY29uc3RydWN0b3IoIG1lc3NhZ2UsIGxvZ0xldmVsID0gJ3dhcm4nKSB7CiAgICBzdXBlcihtZXNzYWdlKTt0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlOwogICAgdGhpcy5uYW1lID0gbmV3LnRhcmdldC5wcm90b3R5cGUuY29uc3RydWN0b3IubmFtZTsKICAgIC8vIFRoaXMgc2V0cyB0aGUgcHJvdG90eXBlIHRvIGJlIGBFcnJvcmAsIG5vdCBgU2VudHJ5RXJyb3JgLiBJdCdzIHVuY2xlYXIgd2h5IHdlIGRvIHRoaXMsIGJ1dCBjb21tZW50aW5nIHRoaXMgbGluZQogICAgLy8gb3V0IGNhdXNlcyB2YXJpb3VzIChzZWVtaW5nbHkgdG90YWxseSB1bnJlbGF0ZWQpIHBsYXl3cmlnaHQgdGVzdHMgY29uc2lzdGVudGx5IHRpbWUgb3V0LiBGWUksIHRoaXMgbWFrZXMKICAgIC8vIGluc3RhbmNlcyBvZiBgU2VudHJ5RXJyb3JgIGZhaWwgYG9iaiBpbnN0YW5jZW9mIFNlbnRyeUVycm9yYCBjaGVja3MuCiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgbmV3LnRhcmdldC5wcm90b3R5cGUpOwogICAgdGhpcy5sb2dMZXZlbCA9IGxvZ0xldmVsOwogIH0KfQoKLyoqCiAqIEVuY29kZXMgZ2l2ZW4gb2JqZWN0IGludG8gdXJsLWZyaWVuZGx5IGZvcm1hdAogKgogKiBAcGFyYW0gb2JqZWN0IEFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIHNlcmlhbGl6YWJsZSB2YWx1ZXMKICogQHJldHVybnMgc3RyaW5nIEVuY29kZWQKICovCmZ1bmN0aW9uIHVybEVuY29kZShvYmplY3QpIHsKICByZXR1cm4gT2JqZWN0LmtleXMob2JqZWN0KQogICAgLm1hcChrZXkgPT4gYCR7ZW5jb2RlVVJJQ29tcG9uZW50KGtleSl9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KG9iamVjdFtrZXldKX1gKQogICAgLmpvaW4oJyYnKTsKfQoKLyoqCiAqIFRyYW5zZm9ybXMgYW55IGBFcnJvcmAgb3IgYEV2ZW50YCBpbnRvIGEgcGxhaW4gb2JqZWN0IHdpdGggYWxsIG9mIHRoZWlyIGVudW1lcmFibGUgcHJvcGVydGllcywgYW5kIHNvbWUgb2YgdGhlaXIKICogbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBhdHRhY2hlZC4KICoKICogQHBhcmFtIHZhbHVlIEluaXRpYWwgc291cmNlIHRoYXQgd2UgaGF2ZSB0byB0cmFuc2Zvcm0gaW4gb3JkZXIgZm9yIGl0IHRvIGJlIHVzYWJsZSBieSB0aGUgc2VyaWFsaXplcgogKiBAcmV0dXJucyBBbiBFdmVudCBvciBFcnJvciB0dXJuZWQgaW50byBhbiBvYmplY3QgLSBvciB0aGUgdmFsdWUgYXJndXJtZW50IGl0c2VsZiwgd2hlbiB2YWx1ZSBpcyBuZWl0aGVyIGFuIEV2ZW50IG5vcgogKiAgYW4gRXJyb3IuCiAqLwpmdW5jdGlvbiBjb252ZXJ0VG9QbGFpbk9iamVjdCgKICB2YWx1ZSwKKQoKIHsKICBpZiAoaXNFcnJvcih2YWx1ZSkpIHsKICAgIHJldHVybiB7CiAgICAgIG1lc3NhZ2U6IHZhbHVlLm1lc3NhZ2UsCiAgICAgIG5hbWU6IHZhbHVlLm5hbWUsCiAgICAgIHN0YWNrOiB2YWx1ZS5zdGFjaywKICAgICAgLi4uZ2V0T3duUHJvcGVydGllcyh2YWx1ZSksCiAgICB9OwogIH0gZWxzZSBpZiAoaXNFdmVudCh2YWx1ZSkpIHsKICAgIGNvbnN0IG5ld09iagoKID0gewogICAgICB0eXBlOiB2YWx1ZS50eXBlLAogICAgICB0YXJnZXQ6IHNlcmlhbGl6ZUV2ZW50VGFyZ2V0KHZhbHVlLnRhcmdldCksCiAgICAgIGN1cnJlbnRUYXJnZXQ6IHNlcmlhbGl6ZUV2ZW50VGFyZ2V0KHZhbHVlLmN1cnJlbnRUYXJnZXQpLAogICAgICAuLi5nZXRPd25Qcm9wZXJ0aWVzKHZhbHVlKSwKICAgIH07CgogICAgaWYgKHR5cGVvZiBDdXN0b21FdmVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNJbnN0YW5jZU9mKHZhbHVlLCBDdXN0b21FdmVudCkpIHsKICAgICAgbmV3T2JqLmRldGFpbCA9IHZhbHVlLmRldGFpbDsKICAgIH0KCiAgICByZXR1cm4gbmV3T2JqOwogIH0gZWxzZSB7CiAgICByZXR1cm4gdmFsdWU7CiAgfQp9CgovKiogQ3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGFyZ2V0IG9mIGFuIGBFdmVudGAgb2JqZWN0ICovCmZ1bmN0aW9uIHNlcmlhbGl6ZUV2ZW50VGFyZ2V0KHRhcmdldCkgewogIHRyeSB7CiAgICByZXR1cm4gaXNFbGVtZW50KHRhcmdldCkgPyBodG1sVHJlZUFzU3RyaW5nKHRhcmdldCkgOiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodGFyZ2V0KTsKICB9IGNhdGNoIChfb08pIHsKICAgIHJldHVybiAnPHVua25vd24+JzsKICB9Cn0KCi8qKiBGaWx0ZXJzIG91dCBhbGwgYnV0IGFuIG9iamVjdCdzIG93biBwcm9wZXJ0aWVzICovCmZ1bmN0aW9uIGdldE93blByb3BlcnRpZXMob2JqKSB7CiAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIG9iaiAhPT0gbnVsbCkgewogICAgY29uc3QgZXh0cmFjdGVkUHJvcHMgPSB7fTsKICAgIGZvciAoY29uc3QgcHJvcGVydHkgaW4gb2JqKSB7CiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wZXJ0eSkpIHsKICAgICAgICBleHRyYWN0ZWRQcm9wc1twcm9wZXJ0eV0gPSAob2JqIClbcHJvcGVydHldOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gZXh0cmFjdGVkUHJvcHM7CiAgfSBlbHNlIHsKICAgIHJldHVybiB7fTsKICB9Cn0KCi8qKgogKiBHaXZlbiBhbnkgb2JqZWN0LCByZXR1cm4gYSBuZXcgb2JqZWN0IGhhdmluZyByZW1vdmVkIGFsbCBmaWVsZHMgd2hvc2UgdmFsdWUgd2FzIGB1bmRlZmluZWRgLgogKiBXb3JrcyByZWN1cnNpdmVseSBvbiBvYmplY3RzIGFuZCBhcnJheXMuCiAqCiAqIEF0dGVudGlvbjogVGhpcyBmdW5jdGlvbiBrZWVwcyBjaXJjdWxhciByZWZlcmVuY2VzIGluIHRoZSByZXR1cm5lZCBvYmplY3QuCiAqLwpmdW5jdGlvbiBkcm9wVW5kZWZpbmVkS2V5cyhpbnB1dFZhbHVlKSB7CiAgLy8gVGhpcyBtYXAga2VlcHMgdHJhY2sgb2Ygd2hhdCBhbHJlYWR5IHZpc2l0ZWQgbm9kZXMgbWFwIHRvLgogIC8vIE91ciBTZXQgLSBiYXNlZCBtZW1vQnVpbGRlciBkb2Vzbid0IHdvcmsgaGVyZSBiZWNhdXNlIHdlIHdhbnQgdG8gdGhlIG91dHB1dCBvYmplY3QgdG8gaGF2ZSB0aGUgc2FtZSBjaXJjdWxhcgogIC8vIHJlZmVyZW5jZXMgYXMgdGhlIGlucHV0IG9iamVjdC4KICBjb25zdCBtZW1vaXphdGlvbk1hcCA9IG5ldyBNYXAoKTsKCiAgLy8gVGhpcyBmdW5jdGlvbiBqdXN0IHByb3hpZXMgYF9kcm9wVW5kZWZpbmVkS2V5c2AgdG8ga2VlcCB0aGUgYG1lbW9CdWlsZGVyYCBvdXQgb2YgdGhpcyBmdW5jdGlvbidzIEFQSQogIHJldHVybiBfZHJvcFVuZGVmaW5lZEtleXMoaW5wdXRWYWx1ZSwgbWVtb2l6YXRpb25NYXApOwp9CgpmdW5jdGlvbiBfZHJvcFVuZGVmaW5lZEtleXMoaW5wdXRWYWx1ZSwgbWVtb2l6YXRpb25NYXApIHsKICBpZiAoaXNQb2pvKGlucHV0VmFsdWUpKSB7CiAgICAvLyBJZiB0aGlzIG5vZGUgaGFzIGFscmVhZHkgYmVlbiB2aXNpdGVkIGR1ZSB0byBhIGNpcmN1bGFyIHJlZmVyZW5jZSwgcmV0dXJuIHRoZSBvYmplY3QgaXQgd2FzIG1hcHBlZCB0byBpbiB0aGUgbmV3IG9iamVjdAogICAgY29uc3QgbWVtb1ZhbCA9IG1lbW9pemF0aW9uTWFwLmdldChpbnB1dFZhbHVlKTsKICAgIGlmIChtZW1vVmFsICE9PSB1bmRlZmluZWQpIHsKICAgICAgcmV0dXJuIG1lbW9WYWwgOwogICAgfQoKICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307CiAgICAvLyBTdG9yZSB0aGUgbWFwcGluZyBvZiB0aGlzIHZhbHVlIGluIGNhc2Ugd2UgdmlzaXQgaXQgYWdhaW4sIGluIGNhc2Ugb2YgY2lyY3VsYXIgZGF0YQogICAgbWVtb2l6YXRpb25NYXAuc2V0KGlucHV0VmFsdWUsIHJldHVyblZhbHVlKTsKCiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhpbnB1dFZhbHVlKSkgewogICAgICBpZiAodHlwZW9mIGlucHV0VmFsdWVba2V5XSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICByZXR1cm5WYWx1ZVtrZXldID0gX2Ryb3BVbmRlZmluZWRLZXlzKGlucHV0VmFsdWVba2V5XSwgbWVtb2l6YXRpb25NYXApOwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJldHVyblZhbHVlIDsKICB9CgogIGlmIChBcnJheS5pc0FycmF5KGlucHV0VmFsdWUpKSB7CiAgICAvLyBJZiB0aGlzIG5vZGUgaGFzIGFscmVhZHkgYmVlbiB2aXNpdGVkIGR1ZSB0byBhIGNpcmN1bGFyIHJlZmVyZW5jZSwgcmV0dXJuIHRoZSBhcnJheSBpdCB3YXMgbWFwcGVkIHRvIGluIHRoZSBuZXcgb2JqZWN0CiAgICBjb25zdCBtZW1vVmFsID0gbWVtb2l6YXRpb25NYXAuZ2V0KGlucHV0VmFsdWUpOwogICAgaWYgKG1lbW9WYWwgIT09IHVuZGVmaW5lZCkgewogICAgICByZXR1cm4gbWVtb1ZhbCA7CiAgICB9CgogICAgY29uc3QgcmV0dXJuVmFsdWUgPSBbXTsKICAgIC8vIFN0b3JlIHRoZSBtYXBwaW5nIG9mIHRoaXMgdmFsdWUgaW4gY2FzZSB3ZSB2aXNpdCBpdCBhZ2FpbiwgaW4gY2FzZSBvZiBjaXJjdWxhciBkYXRhCiAgICBtZW1vaXphdGlvbk1hcC5zZXQoaW5wdXRWYWx1ZSwgcmV0dXJuVmFsdWUpOwoKICAgIGlucHV0VmFsdWUuZm9yRWFjaCgoaXRlbSkgPT4gewogICAgICByZXR1cm5WYWx1ZS5wdXNoKF9kcm9wVW5kZWZpbmVkS2V5cyhpdGVtLCBtZW1vaXphdGlvbk1hcCkpOwogICAgfSk7CgogICAgcmV0dXJuIHJldHVyblZhbHVlIDsKICB9CgogIHJldHVybiBpbnB1dFZhbHVlOwp9CgpmdW5jdGlvbiBpc1Bvam8oaW5wdXQpIHsKICBpZiAoIWlzUGxhaW5PYmplY3QoaW5wdXQpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICB0cnkgewogICAgY29uc3QgbmFtZSA9IChPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5wdXQpICkuY29uc3RydWN0b3IubmFtZTsKICAgIHJldHVybiAhbmFtZSB8fCBuYW1lID09PSAnT2JqZWN0JzsKICB9IGNhdGNoIChlKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9Cn0KCi8qKgogKiBEb2VzIHRoaXMgZmlsZW5hbWUgbG9vayBsaWtlIGl0J3MgcGFydCBvZiB0aGUgYXBwIGNvZGU/CiAqLwpmdW5jdGlvbiBmaWxlbmFtZUlzSW5BcHAoZmlsZW5hbWUsIGlzTmF0aXZlID0gZmFsc2UpIHsKICBjb25zdCBpc0ludGVybmFsID0KICAgIGlzTmF0aXZlIHx8CiAgICAoZmlsZW5hbWUgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgaXQncyBhbiBhYnNvbHV0ZSBsaW51eCBwYXRoCiAgICAgICFmaWxlbmFtZS5zdGFydHNXaXRoKCcvJykgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgaXQncyBhbiBhYnNvbHV0ZSB3aW5kb3dzIHBhdGgKICAgICAgIWZpbGVuYW1lLm1hdGNoKC9eW0EtWl06LykgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgdGhlIHBhdGggaXMgc3RhcnRpbmcgd2l0aCBhIGRvdAogICAgICAhZmlsZW5hbWUuc3RhcnRzV2l0aCgnLicpICYmCiAgICAgIC8vIEl0J3Mgbm90IGludGVybmFsIGlmIHRoZSBmcmFtZSBoYXMgYSBwcm90b2NvbC4gSW4gbm9kZSwgdGhpcyBpcyB1c3VhbGx5IHRoZSBjYXNlIGlmIHRoZSBmaWxlIGdvdCBwcmUtcHJvY2Vzc2VkIHdpdGggYSBidW5kbGVyIGxpa2Ugd2VicGFjawogICAgICAhZmlsZW5hbWUubWF0Y2goL15bYS16QS1aXShbYS16QS1aMC05LlwtK10pKjpcL1wvLykpOyAvLyBTY2hlbWEgZnJvbTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM2NDE3ODIKCiAgLy8gaW5fYXBwIGlzIGFsbCB0aGF0J3Mgbm90IGFuIGludGVybmFsIE5vZGUgZnVuY3Rpb24gb3IgYSBtb2R1bGUgd2l0aGluIG5vZGVfbW9kdWxlcwogIC8vIG5vdGUgdGhhdCBpc05hdGl2ZSBhcHBlYXJzIHRvIHJldHVybiB0cnVlIGV2ZW4gZm9yIG5vZGUgY29yZSBsaWJyYXJpZXMKICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9yYXZlbi1ub2RlL2lzc3Vlcy8xNzYKCiAgcmV0dXJuICFpc0ludGVybmFsICYmIGZpbGVuYW1lICE9PSB1bmRlZmluZWQgJiYgIWZpbGVuYW1lLmluY2x1ZGVzKCdub2RlX21vZHVsZXMvJyk7Cn0KCmNvbnN0IFNUQUNLVFJBQ0VfRlJBTUVfTElNSVQgPSA1MDsKY29uc3QgU1RSSVBfRlJBTUVfUkVHRVhQID0gL2NhcHR1cmVNZXNzYWdlfGNhcHR1cmVFeGNlcHRpb24vOwoKLyoqCiAqIFJlbW92ZXMgU2VudHJ5IGZyYW1lcyBmcm9tIHRoZSB0b3AgYW5kIGJvdHRvbSBvZiB0aGUgc3RhY2sgaWYgcHJlc2VudCBhbmQgZW5mb3JjZXMgYSBsaW1pdCBvZiBtYXggbnVtYmVyIG9mIGZyYW1lcy4KICogQXNzdW1lcyBzdGFjayBpbnB1dCBpcyBvcmRlcmVkIGZyb20gdG9wIHRvIGJvdHRvbSBhbmQgcmV0dXJucyB0aGUgcmV2ZXJzZSByZXByZXNlbnRhdGlvbiBzbyBjYWxsIHNpdGUgb2YgdGhlCiAqIGZ1bmN0aW9uIHRoYXQgY2F1c2VkIHRoZSBjcmFzaCBpcyB0aGUgbGFzdCBmcmFtZSBpbiB0aGUgYXJyYXkuCiAqIEBoaWRkZW4KICovCmZ1bmN0aW9uIHN0cmlwU2VudHJ5RnJhbWVzQW5kUmV2ZXJzZShzdGFjaykgewogIGlmICghc3RhY2subGVuZ3RoKSB7CiAgICByZXR1cm4gW107CiAgfQoKICBjb25zdCBsb2NhbFN0YWNrID0gQXJyYXkuZnJvbShzdGFjayk7CgogIC8vIElmIHN0YWNrIHN0YXJ0cyB3aXRoIG9uZSBvZiBvdXIgQVBJIGNhbGxzLCByZW1vdmUgaXQgKHN0YXJ0cywgbWVhbmluZyBpdCdzIHRoZSB0b3Agb2YgdGhlIHN0YWNrIC0gYWthIGxhc3QgY2FsbCkKICBpZiAoL3NlbnRyeVdyYXBwZWQvLnRlc3QobG9jYWxTdGFja1tsb2NhbFN0YWNrLmxlbmd0aCAtIDFdLmZ1bmN0aW9uIHx8ICcnKSkgewogICAgbG9jYWxTdGFjay5wb3AoKTsKICB9CgogIC8vIFJldmVyc2luZyBpbiB0aGUgbWlkZGxlIG9mIHRoZSBwcm9jZWR1cmUgYWxsb3dzIHVzIHRvIGp1c3QgcG9wIHRoZSB2YWx1ZXMgb2ZmIHRoZSBzdGFjawogIGxvY2FsU3RhY2sucmV2ZXJzZSgpOwoKICAvLyBJZiBzdGFjayBlbmRzIHdpdGggb25lIG9mIG91ciBpbnRlcm5hbCBBUEkgY2FsbHMsIHJlbW92ZSBpdCAoZW5kcywgbWVhbmluZyBpdCdzIHRoZSBib3R0b20gb2YgdGhlIHN0YWNrIC0gYWthIHRvcC1tb3N0IGNhbGwpCiAgaWYgKFNUUklQX0ZSQU1FX1JFR0VYUC50ZXN0KGxvY2FsU3RhY2tbbG9jYWxTdGFjay5sZW5ndGggLSAxXS5mdW5jdGlvbiB8fCAnJykpIHsKICAgIGxvY2FsU3RhY2sucG9wKCk7CgogICAgLy8gV2hlbiB1c2luZyBzeW50aGV0aWMgZXZlbnRzLCB3ZSB3aWxsIGhhdmUgYSAyIGxldmVscyBkZWVwIHN0YWNrLCBhcyBgbmV3IEVycm9yKCdTZW50cnkgc3ludGhldGljRXhjZXB0aW9uJylgCiAgICAvLyBpcyBwcm9kdWNlZCB3aXRoaW4gdGhlIGh1YiBpdHNlbGYsIG1ha2luZyBpdDoKICAgIC8vCiAgICAvLyAgIFNlbnRyeS5jYXB0dXJlRXhjZXB0aW9uKCkKICAgIC8vICAgZ2V0Q3VycmVudEh1YigpLmNhcHR1cmVFeGNlcHRpb24oKQogICAgLy8KICAgIC8vIGluc3RlYWQgb2YganVzdCB0aGUgdG9wIGBTZW50cnlgIGNhbGwgaXRzZWxmLgogICAgLy8gVGhpcyBmb3JjZXMgdXMgdG8gcG9zc2libHkgc3RyaXAgYW4gYWRkaXRpb25hbCBmcmFtZSBpbiB0aGUgZXhhY3Qgc2FtZSB3YXMgYXMgYWJvdmUuCiAgICBpZiAoU1RSSVBfRlJBTUVfUkVHRVhQLnRlc3QobG9jYWxTdGFja1tsb2NhbFN0YWNrLmxlbmd0aCAtIDFdLmZ1bmN0aW9uIHx8ICcnKSkgewogICAgICBsb2NhbFN0YWNrLnBvcCgpOwogICAgfQogIH0KCiAgcmV0dXJuIGxvY2FsU3RhY2suc2xpY2UoMCwgU1RBQ0tUUkFDRV9GUkFNRV9MSU1JVCkubWFwKGZyYW1lID0+ICh7CiAgICAuLi5mcmFtZSwKICAgIGZpbGVuYW1lOiBmcmFtZS5maWxlbmFtZSB8fCBsb2NhbFN0YWNrW2xvY2FsU3RhY2subGVuZ3RoIC0gMV0uZmlsZW5hbWUsCiAgICBmdW5jdGlvbjogZnJhbWUuZnVuY3Rpb24gfHwgJz8nLAogIH0pKTsKfQoKY29uc3QgZGVmYXVsdEZ1bmN0aW9uTmFtZSA9ICc8YW5vbnltb3VzPic7CgovKioKICogU2FmZWx5IGV4dHJhY3QgZnVuY3Rpb24gbmFtZSBmcm9tIGl0c2VsZgogKi8KZnVuY3Rpb24gZ2V0RnVuY3Rpb25OYW1lKGZuKSB7CiAgdHJ5IHsKICAgIGlmICghZm4gfHwgdHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7CiAgICAgIHJldHVybiBkZWZhdWx0RnVuY3Rpb25OYW1lOwogICAgfQogICAgcmV0dXJuIGZuLm5hbWUgfHwgZGVmYXVsdEZ1bmN0aW9uTmFtZTsKICB9IGNhdGNoIChlKSB7CiAgICAvLyBKdXN0IGFjY2Vzc2luZyBjdXN0b20gcHJvcHMgaW4gc29tZSBTZWxlbml1bSBlbnZpcm9ubWVudHMKICAgIC8vIGNhbiBjYXVzZSBhICJQZXJtaXNzaW9uIGRlbmllZCIgZXhjZXB0aW9uIChzZWUgcmF2ZW4tanMjNDk1KS4KICAgIHJldHVybiBkZWZhdWx0RnVuY3Rpb25OYW1lOwogIH0KfQoKLyoqCiAqIFVVSUQ0IGdlbmVyYXRvcgogKgogKiBAcmV0dXJucyBzdHJpbmcgR2VuZXJhdGVkIFVVSUQ0LgogKi8KZnVuY3Rpb24gdXVpZDQoKSB7CiAgY29uc3QgZ2JsID0gR0xPQkFMX09CSiA7CiAgY29uc3QgY3J5cHRvID0gZ2JsLmNyeXB0byB8fCBnYmwubXNDcnlwdG87CgogIGxldCBnZXRSYW5kb21CeXRlID0gKCkgPT4gTWF0aC5yYW5kb20oKSAqIDE2OwogIHRyeSB7CiAgICBpZiAoY3J5cHRvICYmIGNyeXB0by5yYW5kb21VVUlEKSB7CiAgICAgIHJldHVybiBjcnlwdG8ucmFuZG9tVVVJRCgpLnJlcGxhY2UoLy0vZywgJycpOwogICAgfQogICAgaWYgKGNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7CiAgICAgIGdldFJhbmRvbUJ5dGUgPSAoKSA9PiB7CiAgICAgICAgLy8gY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBtaWdodCByZXR1cm4gdW5kZWZpbmVkIGluc3RlYWQgb2YgdGhlIHR5cGVkIGFycmF5CiAgICAgICAgLy8gaW4gb2xkIENocm9taXVtIHZlcnNpb25zIChlLmcuIDIzLjAuMTIzNS4wICgxNTE0MjIpKQogICAgICAgIC8vIEhvd2V2ZXIsIGB0eXBlZEFycmF5YCBpcyBzdGlsbCBmaWxsZWQgaW4tcGxhY2UuCiAgICAgICAgLy8gQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQ3J5cHRvL2dldFJhbmRvbVZhbHVlcyN0eXBlZGFycmF5CiAgICAgICAgY29uc3QgdHlwZWRBcnJheSA9IG5ldyBVaW50OEFycmF5KDEpOwogICAgICAgIGNyeXB0by5nZXRSYW5kb21WYWx1ZXModHlwZWRBcnJheSk7CiAgICAgICAgcmV0dXJuIHR5cGVkQXJyYXlbMF07CiAgICAgIH07CiAgICB9CiAgfSBjYXRjaCAoXykgewogICAgLy8gc29tZSBydW50aW1lcyBjYW4gY3Jhc2ggaW52b2tpbmcgY3J5cHRvCiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3NlbnRyeS1qYXZhc2NyaXB0L2lzc3Vlcy84OTM1CiAgfQoKICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwNTAzNC9ob3ctdG8tY3JlYXRlLWEtZ3VpZC11dWlkLWluLWphdmFzY3JpcHQvMjExNzUyMyMyMTE3NTIzCiAgLy8gQ29uY2F0ZW5hdGluZyB0aGUgZm9sbG93aW5nIG51bWJlcnMgYXMgc3RyaW5ncyByZXN1bHRzIGluICcxMDAwMDAwMDEwMDA0MDAwODAwMDEwMDAwMDAwMDAwMCcKICByZXR1cm4gKChbMWU3XSApICsgMWUzICsgNGUzICsgOGUzICsgMWUxMSkucmVwbGFjZSgvWzAxOF0vZywgYyA9PgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWJpdHdpc2UKICAgICgoYyApIF4gKChnZXRSYW5kb21CeXRlKCkgJiAxNSkgPj4gKChjICkgLyA0KSkpLnRvU3RyaW5nKDE2KSwKICApOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIGlucHV0IGlzIGFscmVhZHkgYW4gYXJyYXksIGFuZCBpZiBpdCBpc24ndCwgd3JhcHMgaXQgaW4gb25lLgogKgogKiBAcGFyYW0gbWF5YmVBcnJheSBJbnB1dCB0byB0dXJuIGludG8gYW4gYXJyYXksIGlmIG5lY2Vzc2FyeQogKiBAcmV0dXJucyBUaGUgaW5wdXQsIGlmIGFscmVhZHkgYW4gYXJyYXksIG9yIGFuIGFycmF5IHdpdGggdGhlIGlucHV0IGFzIHRoZSBvbmx5IGVsZW1lbnQsIGlmIG5vdAogKi8KZnVuY3Rpb24gYXJyYXlpZnkobWF5YmVBcnJheSkgewogIHJldHVybiBBcnJheS5pc0FycmF5KG1heWJlQXJyYXkpID8gbWF5YmVBcnJheSA6IFttYXliZUFycmF5XTsKfQoKLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzICovCi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi8KCi8qKgogKiBIZWxwZXIgdG8gZGVjeWNsZSBqc29uIG9iamVjdHMKICovCmZ1bmN0aW9uIG1lbW9CdWlsZGVyKCkgewogIGNvbnN0IGhhc1dlYWtTZXQgPSB0eXBlb2YgV2Vha1NldCA9PT0gJ2Z1bmN0aW9uJzsKICBjb25zdCBpbm5lciA9IGhhc1dlYWtTZXQgPyBuZXcgV2Vha1NldCgpIDogW107CiAgZnVuY3Rpb24gbWVtb2l6ZShvYmopIHsKICAgIGlmIChoYXNXZWFrU2V0KSB7CiAgICAgIGlmIChpbm5lci5oYXMob2JqKSkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlubmVyLmFkZChvYmopOwogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3ByZWZlci1mb3Itb2YKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5uZXIubGVuZ3RoOyBpKyspIHsKICAgICAgY29uc3QgdmFsdWUgPSBpbm5lcltpXTsKICAgICAgaWYgKHZhbHVlID09PSBvYmopIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgfQogICAgaW5uZXIucHVzaChvYmopOwogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgZnVuY3Rpb24gdW5tZW1vaXplKG9iaikgewogICAgaWYgKGhhc1dlYWtTZXQpIHsKICAgICAgaW5uZXIuZGVsZXRlKG9iaik7CiAgICB9IGVsc2UgewogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlubmVyLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgaWYgKGlubmVyW2ldID09PSBvYmopIHsKICAgICAgICAgIGlubmVyLnNwbGljZShpLCAxKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICByZXR1cm4gW21lbW9pemUsIHVubWVtb2l6ZV07Cn0KCi8qKgogKiBSZWN1cnNpdmVseSBub3JtYWxpemVzIHRoZSBnaXZlbiBvYmplY3QuCiAqCiAqIC0gQ3JlYXRlcyBhIGNvcHkgdG8gcHJldmVudCBvcmlnaW5hbCBpbnB1dCBtdXRhdGlvbgogKiAtIFNraXBzIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMKICogLSBXaGVuIHN0cmluZ2lmeWluZywgY2FsbHMgYHRvSlNPTmAgaWYgaW1wbGVtZW50ZWQKICogLSBSZW1vdmVzIGNpcmN1bGFyIHJlZmVyZW5jZXMKICogLSBUcmFuc2xhdGVzIG5vbi1zZXJpYWxpemFibGUgdmFsdWVzIChgdW5kZWZpbmVkYC9gTmFOYC9mdW5jdGlvbnMpIHRvIHNlcmlhbGl6YWJsZSBmb3JtYXQKICogLSBUcmFuc2xhdGVzIGtub3duIGdsb2JhbCBvYmplY3RzL2NsYXNzZXMgdG8gYSBzdHJpbmcgcmVwcmVzZW50YXRpb25zCiAqIC0gVGFrZXMgY2FyZSBvZiBgRXJyb3JgIG9iamVjdCBzZXJpYWxpemF0aW9uCiAqIC0gT3B0aW9uYWxseSBsaW1pdHMgZGVwdGggb2YgZmluYWwgb3V0cHV0CiAqIC0gT3B0aW9uYWxseSBsaW1pdHMgbnVtYmVyIG9mIHByb3BlcnRpZXMvZWxlbWVudHMgaW5jbHVkZWQgaW4gYW55IHNpbmdsZSBvYmplY3QvYXJyYXkKICoKICogQHBhcmFtIGlucHV0IFRoZSBvYmplY3QgdG8gYmUgbm9ybWFsaXplZC4KICogQHBhcmFtIGRlcHRoIFRoZSBtYXggZGVwdGggdG8gd2hpY2ggdG8gbm9ybWFsaXplIHRoZSBvYmplY3QuIChBbnl0aGluZyBkZWVwZXIgc3RyaW5naWZpZWQgd2hvbGUuKQogKiBAcGFyYW0gbWF4UHJvcGVydGllcyBUaGUgbWF4IG51bWJlciBvZiBlbGVtZW50cyBvciBwcm9wZXJ0aWVzIHRvIGJlIGluY2x1ZGVkIGluIGFueSBzaW5nbGUgYXJyYXkgb3IKICogb2JqZWN0IGluIHRoZSBub3JtYWxsaXplZCBvdXRwdXQuCiAqIEByZXR1cm5zIEEgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBvYmplY3QsIG9yIGAiKipub24tc2VyaWFsaXphYmxlKioiYCBpZiBhbnkgZXJyb3JzIGFyZSB0aHJvd24gZHVyaW5nIG5vcm1hbGl6YXRpb24uCiAqLwovLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQpmdW5jdGlvbiBub3JtYWxpemUoaW5wdXQsIGRlcHRoID0gMTAwLCBtYXhQcm9wZXJ0aWVzID0gK0luZmluaXR5KSB7CiAgdHJ5IHsKICAgIC8vIHNpbmNlIHdlJ3JlIGF0IHRoZSBvdXRlcm1vc3QgbGV2ZWwsIHdlIGRvbid0IHByb3ZpZGUgYSBrZXkKICAgIHJldHVybiB2aXNpdCgnJywgaW5wdXQsIGRlcHRoLCBtYXhQcm9wZXJ0aWVzKTsKICB9IGNhdGNoIChlcnIpIHsKICAgIHJldHVybiB7IEVSUk9SOiBgKipub24tc2VyaWFsaXphYmxlKiogKCR7ZXJyfSlgIH07CiAgfQp9CgovKioKICogVmlzaXRzIGEgbm9kZSB0byBwZXJmb3JtIG5vcm1hbGl6YXRpb24gb24gaXQKICoKICogQHBhcmFtIGtleSBUaGUga2V5IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIG5vZGUKICogQHBhcmFtIHZhbHVlIFRoZSBub2RlIHRvIGJlIHZpc2l0ZWQKICogQHBhcmFtIGRlcHRoIE9wdGlvbmFsIG51bWJlciBpbmRpY2F0aW5nIHRoZSBtYXhpbXVtIHJlY3Vyc2lvbiBkZXB0aAogKiBAcGFyYW0gbWF4UHJvcGVydGllcyBPcHRpb25hbCBtYXhpbXVtIG51bWJlciBvZiBwcm9wZXJ0aWVzL2VsZW1lbnRzIGluY2x1ZGVkIGluIGFueSBzaW5nbGUgb2JqZWN0L2FycmF5CiAqIEBwYXJhbSBtZW1vIE9wdGlvbmFsIE1lbW8gY2xhc3MgaGFuZGxpbmcgZGVjeWNsaW5nCiAqLwpmdW5jdGlvbiB2aXNpdCgKICBrZXksCiAgdmFsdWUsCiAgZGVwdGggPSArSW5maW5pdHksCiAgbWF4UHJvcGVydGllcyA9ICtJbmZpbml0eSwKICBtZW1vID0gbWVtb0J1aWxkZXIoKSwKKSB7CiAgY29uc3QgW21lbW9pemUsIHVubWVtb2l6ZV0gPSBtZW1vOwoKICAvLyBHZXQgdGhlIHNpbXBsZSBjYXNlcyBvdXQgb2YgdGhlIHdheSBmaXJzdAogIGlmICgKICAgIHZhbHVlID09IG51bGwgfHwgLy8gdGhpcyBtYXRjaGVzIG51bGwgYW5kIHVuZGVmaW5lZCAtPiBlcWVxIG5vdCBlcWVxZXEKICAgIChbJ251bWJlcicsICdib29sZWFuJywgJ3N0cmluZyddLmluY2x1ZGVzKHR5cGVvZiB2YWx1ZSkgJiYgIWlzTmFOJDEodmFsdWUpKQogICkgewogICAgcmV0dXJuIHZhbHVlIDsKICB9CgogIGNvbnN0IHN0cmluZ2lmaWVkID0gc3RyaW5naWZ5VmFsdWUoa2V5LCB2YWx1ZSk7CgogIC8vIEFueXRoaW5nIHdlIGNvdWxkIHBvdGVudGlhbGx5IGRpZyBpbnRvIG1vcmUgKG9iamVjdHMgb3IgYXJyYXlzKSB3aWxsIGhhdmUgY29tZSBiYWNrIGFzIGAiW29iamVjdCBYWFhYXSJgLgogIC8vIEV2ZXJ5dGhpbmcgZWxzZSB3aWxsIGhhdmUgYWxyZWFkeSBiZWVuIHNlcmlhbGl6ZWQsIHNvIGlmIHdlIGRvbid0IHNlZSB0aGF0IHBhdHRlcm4sIHdlJ3JlIGRvbmUuCiAgaWYgKCFzdHJpbmdpZmllZC5zdGFydHNXaXRoKCdbb2JqZWN0ICcpKSB7CiAgICByZXR1cm4gc3RyaW5naWZpZWQ7CiAgfQoKICAvLyBGcm9tIGhlcmUgb24sIHdlIGNhbiBhc3NlcnQgdGhhdCBgdmFsdWVgIGlzIGVpdGhlciBhbiBvYmplY3Qgb3IgYW4gYXJyYXkuCgogIC8vIERvIG5vdCBub3JtYWxpemUgb2JqZWN0cyB0aGF0IHdlIGtub3cgaGF2ZSBhbHJlYWR5IGJlZW4gbm9ybWFsaXplZC4gQXMgYSBnZW5lcmFsIHJ1bGUsIHRoZQogIC8vICJfX3NlbnRyeV9za2lwX25vcm1hbGl6YXRpb25fXyIgcHJvcGVydHkgc2hvdWxkIG9ubHkgYmUgdXNlZCBzcGFyaW5nbHkgYW5kIG9ubHkgc2hvdWxkIG9ubHkgYmUgc2V0IG9uIG9iamVjdHMgdGhhdAogIC8vIGhhdmUgYWxyZWFkeSBiZWVuIG5vcm1hbGl6ZWQuCiAgaWYgKCh2YWx1ZSApWydfX3NlbnRyeV9za2lwX25vcm1hbGl6YXRpb25fXyddKSB7CiAgICByZXR1cm4gdmFsdWUgOwogIH0KCiAgLy8gV2UgY2FuIHNldCBgX19zZW50cnlfb3ZlcnJpZGVfbm9ybWFsaXphdGlvbl9kZXB0aF9fYCBvbiBhbiBvYmplY3QgdG8gZW5zdXJlIHRoYXQgZnJvbSB0aGVyZQogIC8vIFdlIGtlZXAgYSBjZXJ0YWluIGFtb3VudCBvZiBkZXB0aC4KICAvLyBUaGlzIHNob3VsZCBiZSB1c2VkIHNwYXJpbmdseSwgZS5nLiB3ZSB1c2UgaXQgZm9yIHRoZSByZWR1eCBpbnRlZ3JhdGlvbiB0byBlbnN1cmUgd2UgZ2V0IGEgY2VydGFpbiBhbW91bnQgb2Ygc3RhdGUuCiAgY29uc3QgcmVtYWluaW5nRGVwdGggPQogICAgdHlwZW9mICh2YWx1ZSApWydfX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX18nXSA9PT0gJ251bWJlcicKICAgICAgPyAoKHZhbHVlIClbJ19fc2VudHJ5X292ZXJyaWRlX25vcm1hbGl6YXRpb25fZGVwdGhfXyddICkKICAgICAgOiBkZXB0aDsKCiAgLy8gV2UncmUgYWxzbyBkb25lIGlmIHdlJ3ZlIHJlYWNoZWQgdGhlIG1heCBkZXB0aAogIGlmIChyZW1haW5pbmdEZXB0aCA9PT0gMCkgewogICAgLy8gQXQgdGhpcyBwb2ludCB3ZSBrbm93IGBzZXJpYWxpemVkYCBpcyBhIHN0cmluZyBvZiB0aGUgZm9ybSBgIltvYmplY3QgWFhYWF0iYC4gQ2xlYW4gaXQgdXAgc28gaXQncyBqdXN0IGAiW1hYWFhdImAuCiAgICByZXR1cm4gc3RyaW5naWZpZWQucmVwbGFjZSgnb2JqZWN0ICcsICcnKTsKICB9CgogIC8vIElmIHdlJ3ZlIGFscmVhZHkgdmlzaXRlZCB0aGlzIGJyYW5jaCwgYmFpbCBvdXQsIGFzIGl0J3MgY2lyY3VsYXIgcmVmZXJlbmNlLiBJZiBub3QsIG5vdGUgdGhhdCB3ZSdyZSBzZWVpbmcgaXQgbm93LgogIGlmIChtZW1vaXplKHZhbHVlKSkgewogICAgcmV0dXJuICdbQ2lyY3VsYXIgfl0nOwogIH0KCiAgLy8gSWYgdGhlIHZhbHVlIGhhcyBhIGB0b0pTT05gIG1ldGhvZCwgd2UgY2FsbCBpdCB0byBleHRyYWN0IG1vcmUgaW5mb3JtYXRpb24KICBjb25zdCB2YWx1ZVdpdGhUb0pTT04gPSB2YWx1ZSA7CiAgaWYgKHZhbHVlV2l0aFRvSlNPTiAmJiB0eXBlb2YgdmFsdWVXaXRoVG9KU09OLnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykgewogICAgdHJ5IHsKICAgICAgY29uc3QganNvblZhbHVlID0gdmFsdWVXaXRoVG9KU09OLnRvSlNPTigpOwogICAgICAvLyBXZSBuZWVkIHRvIG5vcm1hbGl6ZSB0aGUgcmV0dXJuIHZhbHVlIG9mIGAudG9KU09OKClgIGluIGNhc2UgaXQgaGFzIGNpcmN1bGFyIHJlZmVyZW5jZXMKICAgICAgcmV0dXJuIHZpc2l0KCcnLCBqc29uVmFsdWUsIHJlbWFpbmluZ0RlcHRoIC0gMSwgbWF4UHJvcGVydGllcywgbWVtbyk7CiAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgLy8gcGFzcyAoVGhlIGJ1aWx0LWluIGB0b0pTT05gIGZhaWxlZCwgYnV0IHdlIGNhbiBzdGlsbCB0cnkgdG8gZG8gaXQgb3Vyc2VsdmVzKQogICAgfQogIH0KCiAgLy8gQXQgdGhpcyBwb2ludCB3ZSBrbm93IHdlIGVpdGhlciBoYXZlIGFuIG9iamVjdCBvciBhbiBhcnJheSwgd2UgaGF2ZW4ndCBzZWVuIGl0IGJlZm9yZSwgYW5kIHdlJ3JlIGdvaW5nIHRvIHJlY3Vyc2UKICAvLyBiZWNhdXNlIHdlIGhhdmVuJ3QgeWV0IHJlYWNoZWQgdGhlIG1heCBkZXB0aC4gQ3JlYXRlIGFuIGFjY3VtdWxhdG9yIHRvIGhvbGQgdGhlIHJlc3VsdHMgb2YgdmlzaXRpbmcgZWFjaAogIC8vIHByb3BlcnR5L2VudHJ5LCBhbmQga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIGl0ZW1zIHdlIGFkZCB0byBpdC4KICBjb25zdCBub3JtYWxpemVkID0gKEFycmF5LmlzQXJyYXkodmFsdWUpID8gW10gOiB7fSkgOwogIGxldCBudW1BZGRlZCA9IDA7CgogIC8vIEJlZm9yZSB3ZSBiZWdpbiwgY29udmVydGBFcnJvcmAgYW5kYEV2ZW50YCBpbnN0YW5jZXMgaW50byBwbGFpbiBvYmplY3RzLCBzaW5jZSBzb21lIG9mIGVhY2ggb2YgdGhlaXIgcmVsZXZhbnQKICAvLyBwcm9wZXJ0aWVzIGFyZSBub24tZW51bWVyYWJsZSBhbmQgb3RoZXJ3aXNlIHdvdWxkIGdldCBtaXNzZWQuCiAgY29uc3QgdmlzaXRhYmxlID0gY29udmVydFRvUGxhaW5PYmplY3QodmFsdWUgKTsKCiAgZm9yIChjb25zdCB2aXNpdEtleSBpbiB2aXNpdGFibGUpIHsKICAgIC8vIEF2b2lkIGl0ZXJhdGluZyBvdmVyIGZpZWxkcyBpbiB0aGUgcHJvdG90eXBlIGlmIHRoZXkndmUgc29tZWhvdyBiZWVuIGV4cG9zZWQgdG8gZW51bWVyYXRpb24uCiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh2aXNpdGFibGUsIHZpc2l0S2V5KSkgewogICAgICBjb250aW51ZTsKICAgIH0KCiAgICBpZiAobnVtQWRkZWQgPj0gbWF4UHJvcGVydGllcykgewogICAgICBub3JtYWxpemVkW3Zpc2l0S2V5XSA9ICdbTWF4UHJvcGVydGllcyB+XSc7CiAgICAgIGJyZWFrOwogICAgfQoKICAgIC8vIFJlY3Vyc2l2ZWx5IHZpc2l0IGFsbCB0aGUgY2hpbGQgbm9kZXMKICAgIGNvbnN0IHZpc2l0VmFsdWUgPSB2aXNpdGFibGVbdmlzaXRLZXldOwogICAgbm9ybWFsaXplZFt2aXNpdEtleV0gPSB2aXNpdCh2aXNpdEtleSwgdmlzaXRWYWx1ZSwgcmVtYWluaW5nRGVwdGggLSAxLCBtYXhQcm9wZXJ0aWVzLCBtZW1vKTsKCiAgICBudW1BZGRlZCsrOwogIH0KCiAgLy8gT25jZSB3ZSd2ZSB2aXNpdGVkIGFsbCB0aGUgYnJhbmNoZXMsIHJlbW92ZSB0aGUgcGFyZW50IGZyb20gbWVtbyBzdG9yYWdlCiAgdW5tZW1vaXplKHZhbHVlKTsKCiAgLy8gUmV0dXJuIGFjY3VtdWxhdGVkIHZhbHVlcwogIHJldHVybiBub3JtYWxpemVkOwp9CgovKiBlc2xpbnQtZGlzYWJsZSBjb21wbGV4aXR5ICovCi8qKgogKiBTdHJpbmdpZnkgdGhlIGdpdmVuIHZhbHVlLiBIYW5kbGVzIHZhcmlvdXMga25vd24gc3BlY2lhbCB2YWx1ZXMgYW5kIHR5cGVzLgogKgogKiBOb3QgbWVhbnQgdG8gYmUgdXNlZCBvbiBzaW1wbGUgcHJpbWl0aXZlcyB3aGljaCBhbHJlYWR5IGhhdmUgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24sIGFzIGl0IHdpbGwsIGZvciBleGFtcGxlLCB0dXJuCiAqIHRoZSBudW1iZXIgMTIzMSBpbnRvICJbT2JqZWN0IE51bWJlcl0iLCBub3Igb24gYG51bGxgLCBhcyBpdCB3aWxsIHRocm93LgogKgogKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIHN0cmluZ2lmeQogKiBAcmV0dXJucyBBIHN0cmluZ2lmaWVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiB2YWx1ZQogKi8KZnVuY3Rpb24gc3RyaW5naWZ5VmFsdWUoCiAga2V5LAogIC8vIHRoaXMgdHlwZSBpcyBhIHRpbnkgYml0IG9mIGEgY2hlYXQsIHNpbmNlIHRoaXMgZnVuY3Rpb24gZG9lcyBoYW5kbGUgTmFOICh3aGljaCBpcyB0ZWNobmljYWxseSBhIG51bWJlciksIGJ1dCBmb3IKICAvLyBvdXIgaW50ZXJuYWwgdXNlLCBpdCdsbCBkbwogIHZhbHVlLAopIHsKICB0cnkgewogICAgaWYgKGtleSA9PT0gJ2RvbWFpbicgJiYgdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiAodmFsdWUgKS5fZXZlbnRzKSB7CiAgICAgIHJldHVybiAnW0RvbWFpbl0nOwogICAgfQoKICAgIGlmIChrZXkgPT09ICdkb21haW5FbWl0dGVyJykgewogICAgICByZXR1cm4gJ1tEb21haW5FbWl0dGVyXSc7CiAgICB9CgogICAgLy8gSXQncyBzYWZlIHRvIHVzZSBgZ2xvYmFsYCwgYHdpbmRvd2AsIGFuZCBgZG9jdW1lbnRgIGhlcmUgaW4gdGhpcyBtYW5uZXIsIGFzIHdlIGFyZSBhc3NlcnRpbmcgdXNpbmcgYHR5cGVvZmAgZmlyc3QKICAgIC8vIHdoaWNoIHdvbid0IHRocm93IGlmIHRoZXkgYXJlIG5vdCBwcmVzZW50LgoKICAgIGlmICh0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSA9PT0gZ2xvYmFsKSB7CiAgICAgIHJldHVybiAnW0dsb2JhbF0nOwogICAgfQoKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLWdsb2JhbHMKICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSA9PT0gd2luZG93KSB7CiAgICAgIHJldHVybiAnW1dpbmRvd10nOwogICAgfQoKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLWdsb2JhbHMKICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlID09PSBkb2N1bWVudCkgewogICAgICByZXR1cm4gJ1tEb2N1bWVudF0nOwogICAgfQoKICAgIGlmIChpc1Z1ZVZpZXdNb2RlbCh2YWx1ZSkpIHsKICAgICAgcmV0dXJuICdbVnVlVmlld01vZGVsXSc7CiAgICB9CgogICAgLy8gUmVhY3QncyBTeW50aGV0aWNFdmVudCB0aGluZ3kKICAgIGlmIChpc1N5bnRoZXRpY0V2ZW50KHZhbHVlKSkgewogICAgICByZXR1cm4gJ1tTeW50aGV0aWNFdmVudF0nOwogICAgfQoKICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmIHZhbHVlICE9PSB2YWx1ZSkgewogICAgICByZXR1cm4gJ1tOYU5dJzsKICAgIH0KCiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7CiAgICAgIHJldHVybiBgW0Z1bmN0aW9uOiAke2dldEZ1bmN0aW9uTmFtZSh2YWx1ZSl9XWA7CiAgICB9CgogICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N5bWJvbCcpIHsKICAgICAgcmV0dXJuIGBbJHtTdHJpbmcodmFsdWUpfV1gOwogICAgfQoKICAgIC8vIHN0cmluZ2lmaWVkIEJpZ0ludHMgYXJlIGluZGlzdGluZ3Vpc2hhYmxlIGZyb20gcmVndWxhciBudW1iZXJzLCBzbyB3ZSBuZWVkIHRvIGxhYmVsIHRoZW0gdG8gYXZvaWQgY29uZnVzaW9uCiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYmlnaW50JykgewogICAgICByZXR1cm4gYFtCaWdJbnQ6ICR7U3RyaW5nKHZhbHVlKX1dYDsKICAgIH0KCiAgICAvLyBOb3cgdGhhdCB3ZSd2ZSBrbm9ja2VkIG91dCBhbGwgdGhlIHNwZWNpYWwgY2FzZXMgYW5kIHRoZSBwcmltaXRpdmVzLCBhbGwgd2UgaGF2ZSBsZWZ0IGFyZSBvYmplY3RzLiBTaW1wbHkgY2FzdGluZwogICAgLy8gdGhlbSB0byBzdHJpbmdzIG1lYW5zIHRoYXQgaW5zdGFuY2VzIG9mIGNsYXNzZXMgd2hpY2ggaGF2ZW4ndCBkZWZpbmVkIHRoZWlyIGB0b1N0cmluZ1RhZ2Agd2lsbCBqdXN0IGNvbWUgb3V0IGFzCiAgICAvLyBgIltvYmplY3QgT2JqZWN0XSJgLiBJZiB3ZSBpbnN0ZWFkIGxvb2sgYXQgdGhlIGNvbnN0cnVjdG9yJ3MgbmFtZSAod2hpY2ggaXMgdGhlIHNhbWUgYXMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzKSwKICAgIC8vIHdlIGNhbiBtYWtlIHN1cmUgdGhhdCBvbmx5IHBsYWluIG9iamVjdHMgY29tZSBvdXQgdGhhdCB3YXkuCiAgICBjb25zdCBvYmpOYW1lID0gZ2V0Q29uc3RydWN0b3JOYW1lKHZhbHVlKTsKCiAgICAvLyBIYW5kbGUgSFRNTCBFbGVtZW50cwogICAgaWYgKC9eSFRNTChcdyopRWxlbWVudCQvLnRlc3Qob2JqTmFtZSkpIHsKICAgICAgcmV0dXJuIGBbSFRNTEVsZW1lbnQ6ICR7b2JqTmFtZX1dYDsKICAgIH0KCiAgICByZXR1cm4gYFtvYmplY3QgJHtvYmpOYW1lfV1gOwogIH0gY2F0Y2ggKGVycikgewogICAgcmV0dXJuIGAqKm5vbi1zZXJpYWxpemFibGUqKiAoJHtlcnJ9KWA7CiAgfQp9Ci8qIGVzbGludC1lbmFibGUgY29tcGxleGl0eSAqLwoKZnVuY3Rpb24gZ2V0Q29uc3RydWN0b3JOYW1lKHZhbHVlKSB7CiAgY29uc3QgcHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHZhbHVlKTsKCiAgcmV0dXJuIHByb3RvdHlwZSA/IHByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lIDogJ251bGwgcHJvdG90eXBlJzsKfQoKLyoqCiAqIE5vcm1hbGl6ZXMgVVJMcyBpbiBleGNlcHRpb25zIGFuZCBzdGFja3RyYWNlcyB0byBhIGJhc2UgcGF0aCBzbyBTZW50cnkgY2FuIGZpbmdlcnByaW50CiAqIGFjcm9zcyBwbGF0Zm9ybXMgYW5kIHdvcmtpbmcgZGlyZWN0b3J5LgogKgogKiBAcGFyYW0gdXJsIFRoZSBVUkwgdG8gYmUgbm9ybWFsaXplZC4KICogQHBhcmFtIGJhc2VQYXRoIFRoZSBhcHBsaWNhdGlvbiBiYXNlIHBhdGguCiAqIEByZXR1cm5zIFRoZSBub3JtYWxpemVkIFVSTC4KICovCmZ1bmN0aW9uIG5vcm1hbGl6ZVVybFRvQmFzZSh1cmwsIGJhc2VQYXRoKSB7CiAgY29uc3QgZXNjYXBlZEJhc2UgPSBiYXNlUGF0aAogICAgLy8gQmFja3NsYXNoIHRvIGZvcndhcmQKICAgIC5yZXBsYWNlKC9cXC9nLCAnLycpCiAgICAvLyBFc2NhcGUgUmVnRXhwIHNwZWNpYWwgY2hhcmFjdGVycwogICAgLnJlcGxhY2UoL1t8XFx7fSgpW1xdXiQrKj8uXS9nLCAnXFwkJicpOwoKICBsZXQgbmV3VXJsID0gdXJsOwogIHRyeSB7CiAgICBuZXdVcmwgPSBkZWNvZGVVUkkodXJsKTsKICB9IGNhdGNoIChfT28pIHsKICAgIC8vIFNvbWV0aW1lIHRoaXMgYnJlYWtzCiAgfQogIHJldHVybiAoCiAgICBuZXdVcmwKICAgICAgLnJlcGxhY2UoL1xcL2csICcvJykKICAgICAgLnJlcGxhY2UoL3dlYnBhY2s6XC8/L2csICcnKSAvLyBSZW1vdmUgaW50ZXJtZWRpYXRlIGJhc2UgcGF0aAogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHNlbnRyeS1pbnRlcm5hbC9zZGsvbm8tcmVnZXhwLWNvbnN0cnVjdG9yCiAgICAgIC5yZXBsYWNlKG5ldyBSZWdFeHAoYChmaWxlOi8vKT8vKiR7ZXNjYXBlZEJhc2V9LypgLCAnaWcnKSwgJ2FwcDovLy8nKQogICk7Cn0KCi8vIFNsaWdodGx5IG1vZGlmaWVkIChubyBJRTggc3VwcG9ydCwgRVM2KSBhbmQgdHJhbnNjcmliZWQgdG8gVHlwZVNjcmlwdAoKLy8gU3BsaXQgYSBmaWxlbmFtZSBpbnRvIFtyb290LCBkaXIsIGJhc2VuYW1lLCBleHRdLCB1bml4IHZlcnNpb24KLy8gJ3Jvb3QnIGlzIGp1c3QgYSBzbGFzaCwgb3Igbm90aGluZy4KY29uc3Qgc3BsaXRQYXRoUmUgPSAvXihcUys6XFx8XC8/KShbXHNcU10qPykoKD86XC57MSwyfXxbXi9cXF0rP3wpKFwuW14uL1xcXSp8KSkoPzpbL1xcXSopJC87Ci8qKiBKU0RvYyAqLwpmdW5jdGlvbiBzcGxpdFBhdGgoZmlsZW5hbWUpIHsKICAvLyBUcnVuY2F0ZSBmaWxlcyBuYW1lcyBncmVhdGVyIHRoYW4gMTAyNCBjaGFyYWN0ZXJzIHRvIGF2b2lkIHJlZ2V4IGRvcwogIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvcHVsbC84NzM3I2Rpc2N1c3Npb25fcjEyODU3MTkxNzIKICBjb25zdCB0cnVuY2F0ZWQgPSBmaWxlbmFtZS5sZW5ndGggPiAxMDI0ID8gYDx0cnVuY2F0ZWQ+JHtmaWxlbmFtZS5zbGljZSgtMTAyNCl9YCA6IGZpbGVuYW1lOwogIGNvbnN0IHBhcnRzID0gc3BsaXRQYXRoUmUuZXhlYyh0cnVuY2F0ZWQpOwogIHJldHVybiBwYXJ0cyA/IHBhcnRzLnNsaWNlKDEpIDogW107Cn0KCi8qKiBKU0RvYyAqLwpmdW5jdGlvbiBkaXJuYW1lKHBhdGgpIHsKICBjb25zdCByZXN1bHQgPSBzcGxpdFBhdGgocGF0aCk7CiAgY29uc3Qgcm9vdCA9IHJlc3VsdFswXTsKICBsZXQgZGlyID0gcmVzdWx0WzFdOwoKICBpZiAoIXJvb3QgJiYgIWRpcikgewogICAgLy8gTm8gZGlybmFtZSB3aGF0c29ldmVyCiAgICByZXR1cm4gJy4nOwogIH0KCiAgaWYgKGRpcikgewogICAgLy8gSXQgaGFzIGEgZGlybmFtZSwgc3RyaXAgdHJhaWxpbmcgc2xhc2gKICAgIGRpciA9IGRpci5zbGljZSgwLCBkaXIubGVuZ3RoIC0gMSk7CiAgfQoKICByZXR1cm4gcm9vdCArIGRpcjsKfQoKLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L2V4cGxpY2l0LWZ1bmN0aW9uLXJldHVybi10eXBlICovCgovKiogU3luY1Byb21pc2UgaW50ZXJuYWwgc3RhdGVzICovCnZhciBTdGF0ZXM7IChmdW5jdGlvbiAoU3RhdGVzKSB7CiAgLyoqIFBlbmRpbmcgKi8KICBjb25zdCBQRU5ESU5HID0gMDsgU3RhdGVzW1N0YXRlc1siUEVORElORyJdID0gUEVORElOR10gPSAiUEVORElORyI7CiAgLyoqIFJlc29sdmVkIC8gT0sgKi8KICBjb25zdCBSRVNPTFZFRCA9IDE7IFN0YXRlc1tTdGF0ZXNbIlJFU09MVkVEIl0gPSBSRVNPTFZFRF0gPSAiUkVTT0xWRUQiOwogIC8qKiBSZWplY3RlZCAvIEVycm9yICovCiAgY29uc3QgUkVKRUNURUQgPSAyOyBTdGF0ZXNbU3RhdGVzWyJSRUpFQ1RFRCJdID0gUkVKRUNURURdID0gIlJFSkVDVEVEIjsKfSkoU3RhdGVzIHx8IChTdGF0ZXMgPSB7fSkpOwoKLy8gT3ZlcmxvYWRzIHNvIHdlIGNhbiBjYWxsIHJlc29sdmVkU3luY1Byb21pc2Ugd2l0aG91dCBhcmd1bWVudHMgYW5kIGdlbmVyaWMgYXJndW1lbnQKCi8qKgogKiBDcmVhdGVzIGEgcmVzb2x2ZWQgc3luYyBwcm9taXNlLgogKgogKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIHRvIHJlc29sdmUgdGhlIHByb21pc2Ugd2l0aAogKiBAcmV0dXJucyB0aGUgcmVzb2x2ZWQgc3luYyBwcm9taXNlCiAqLwpmdW5jdGlvbiByZXNvbHZlZFN5bmNQcm9taXNlKHZhbHVlKSB7CiAgcmV0dXJuIG5ldyBTeW5jUHJvbWlzZShyZXNvbHZlID0+IHsKICAgIHJlc29sdmUodmFsdWUpOwogIH0pOwp9CgovKioKICogQ3JlYXRlcyBhIHJlamVjdGVkIHN5bmMgcHJvbWlzZS4KICoKICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byByZWplY3QgdGhlIHByb21pc2Ugd2l0aAogKiBAcmV0dXJucyB0aGUgcmVqZWN0ZWQgc3luYyBwcm9taXNlCiAqLwpmdW5jdGlvbiByZWplY3RlZFN5bmNQcm9taXNlKHJlYXNvbikgewogIHJldHVybiBuZXcgU3luY1Byb21pc2UoKF8sIHJlamVjdCkgPT4gewogICAgcmVqZWN0KHJlYXNvbik7CiAgfSk7Cn0KCi8qKgogKiBUaGVuYWJsZSBjbGFzcyB0aGF0IGJlaGF2ZXMgbGlrZSBhIFByb21pc2UgYW5kIGZvbGxvd3MgaXQncyBpbnRlcmZhY2UKICogYnV0IGlzIG5vdCBhc3luYyBpbnRlcm5hbGx5CiAqLwpjbGFzcyBTeW5jUHJvbWlzZSB7CgogICBjb25zdHJ1Y3RvcigKICAgIGV4ZWN1dG9yLAogICkge1N5bmNQcm9taXNlLnByb3RvdHlwZS5fX2luaXQuY2FsbCh0aGlzKTtTeW5jUHJvbWlzZS5wcm90b3R5cGUuX19pbml0Mi5jYWxsKHRoaXMpO1N5bmNQcm9taXNlLnByb3RvdHlwZS5fX2luaXQzLmNhbGwodGhpcyk7U3luY1Byb21pc2UucHJvdG90eXBlLl9faW5pdDQuY2FsbCh0aGlzKTsKICAgIHRoaXMuX3N0YXRlID0gU3RhdGVzLlBFTkRJTkc7CiAgICB0aGlzLl9oYW5kbGVycyA9IFtdOwoKICAgIHRyeSB7CiAgICAgIGV4ZWN1dG9yKHRoaXMuX3Jlc29sdmUsIHRoaXMuX3JlamVjdCk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHRoaXMuX3JlamVjdChlKTsKICAgIH0KICB9CgogIC8qKiBKU0RvYyAqLwogICB0aGVuKAogICAgb25mdWxmaWxsZWQsCiAgICBvbnJlamVjdGVkLAogICkgewogICAgcmV0dXJuIG5ldyBTeW5jUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAgIHRoaXMuX2hhbmRsZXJzLnB1c2goWwogICAgICAgIGZhbHNlLAogICAgICAgIHJlc3VsdCA9PiB7CiAgICAgICAgICBpZiAoIW9uZnVsZmlsbGVkKSB7CiAgICAgICAgICAgIC8vIFRPRE86IMKvXF8o44OEKV8vwq8KICAgICAgICAgICAgLy8gVE9ETzogRklYTUUKICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQgKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgcmVzb2x2ZShvbmZ1bGZpbGxlZChyZXN1bHQpKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgIHJlamVjdChlKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVhc29uID0+IHsKICAgICAgICAgIGlmICghb25yZWplY3RlZCkgewogICAgICAgICAgICByZWplY3QocmVhc29uKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgcmVzb2x2ZShvbnJlamVjdGVkKHJlYXNvbikpOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgcmVqZWN0KGUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgXSk7CiAgICAgIHRoaXMuX2V4ZWN1dGVIYW5kbGVycygpOwogICAgfSk7CiAgfQoKICAvKiogSlNEb2MgKi8KICAgY2F0Y2goCiAgICBvbnJlamVjdGVkLAogICkgewogICAgcmV0dXJuIHRoaXMudGhlbih2YWwgPT4gdmFsLCBvbnJlamVjdGVkKTsKICB9CgogIC8qKiBKU0RvYyAqLwogICBmaW5hbGx5KG9uZmluYWxseSkgewogICAgcmV0dXJuIG5ldyBTeW5jUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAgIGxldCB2YWw7CiAgICAgIGxldCBpc1JlamVjdGVkOwoKICAgICAgcmV0dXJuIHRoaXMudGhlbigKICAgICAgICB2YWx1ZSA9PiB7CiAgICAgICAgICBpc1JlamVjdGVkID0gZmFsc2U7CiAgICAgICAgICB2YWwgPSB2YWx1ZTsKICAgICAgICAgIGlmIChvbmZpbmFsbHkpIHsKICAgICAgICAgICAgb25maW5hbGx5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICByZWFzb24gPT4gewogICAgICAgICAgaXNSZWplY3RlZCA9IHRydWU7CiAgICAgICAgICB2YWwgPSByZWFzb247CiAgICAgICAgICBpZiAob25maW5hbGx5KSB7CiAgICAgICAgICAgIG9uZmluYWxseSgpOwogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICkudGhlbigoKSA9PiB7CiAgICAgICAgaWYgKGlzUmVqZWN0ZWQpIHsKICAgICAgICAgIHJlamVjdCh2YWwpOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcmVzb2x2ZSh2YWwgKTsKICAgICAgfSk7CiAgICB9KTsKICB9CgogIC8qKiBKU0RvYyAqLwogICAgX19pbml0KCkge3RoaXMuX3Jlc29sdmUgPSAodmFsdWUpID0+IHsKICAgIHRoaXMuX3NldFJlc3VsdChTdGF0ZXMuUkVTT0xWRUQsIHZhbHVlKTsKICB9O30KCiAgLyoqIEpTRG9jICovCiAgICBfX2luaXQyKCkge3RoaXMuX3JlamVjdCA9IChyZWFzb24pID0+IHsKICAgIHRoaXMuX3NldFJlc3VsdChTdGF0ZXMuUkVKRUNURUQsIHJlYXNvbik7CiAgfTt9CgogIC8qKiBKU0RvYyAqLwogICAgX19pbml0MygpIHt0aGlzLl9zZXRSZXN1bHQgPSAoc3RhdGUsIHZhbHVlKSA9PiB7CiAgICBpZiAodGhpcy5fc3RhdGUgIT09IFN0YXRlcy5QRU5ESU5HKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoaXNUaGVuYWJsZSh2YWx1ZSkpIHsKICAgICAgdm9pZCAodmFsdWUgKS50aGVuKHRoaXMuX3Jlc29sdmUsIHRoaXMuX3JlamVjdCk7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICB0aGlzLl9zdGF0ZSA9IHN0YXRlOwogICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTsKCiAgICB0aGlzLl9leGVjdXRlSGFuZGxlcnMoKTsKICB9O30KCiAgLyoqIEpTRG9jICovCiAgICBfX2luaXQ0KCkge3RoaXMuX2V4ZWN1dGVIYW5kbGVycyA9ICgpID0+IHsKICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gU3RhdGVzLlBFTkRJTkcpIHsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIGNvbnN0IGNhY2hlZEhhbmRsZXJzID0gdGhpcy5faGFuZGxlcnMuc2xpY2UoKTsKICAgIHRoaXMuX2hhbmRsZXJzID0gW107CgogICAgY2FjaGVkSGFuZGxlcnMuZm9yRWFjaChoYW5kbGVyID0+IHsKICAgICAgaWYgKGhhbmRsZXJbMF0pIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gU3RhdGVzLlJFU09MVkVEKSB7CiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1mbG9hdGluZy1wcm9taXNlcwogICAgICAgIGhhbmRsZXJbMV0odGhpcy5fdmFsdWUgKTsKICAgICAgfQoKICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSBTdGF0ZXMuUkVKRUNURUQpIHsKICAgICAgICBoYW5kbGVyWzJdKHRoaXMuX3ZhbHVlKTsKICAgICAgfQoKICAgICAgaGFuZGxlclswXSA9IHRydWU7CiAgICB9KTsKICB9O30KfQoKLyoqCiAqIENyZWF0ZXMgYW4gbmV3IFByb21pc2VCdWZmZXIgb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBsaW1pdAogKiBAcGFyYW0gbGltaXQgbWF4IG51bWJlciBvZiBwcm9taXNlcyB0aGF0IGNhbiBiZSBzdG9yZWQgaW4gdGhlIGJ1ZmZlcgogKi8KZnVuY3Rpb24gbWFrZVByb21pc2VCdWZmZXIobGltaXQpIHsKICBjb25zdCBidWZmZXIgPSBbXTsKCiAgZnVuY3Rpb24gaXNSZWFkeSgpIHsKICAgIHJldHVybiBsaW1pdCA9PT0gdW5kZWZpbmVkIHx8IGJ1ZmZlci5sZW5ndGggPCBsaW1pdDsKICB9CgogIC8qKgogICAqIFJlbW92ZSBhIHByb21pc2UgZnJvbSB0aGUgcXVldWUuCiAgICoKICAgKiBAcGFyYW0gdGFzayBDYW4gYmUgYW55IFByb21pc2VMaWtlPFQ+CiAgICogQHJldHVybnMgUmVtb3ZlZCBwcm9taXNlLgogICAqLwogIGZ1bmN0aW9uIHJlbW92ZSh0YXNrKSB7CiAgICByZXR1cm4gYnVmZmVyLnNwbGljZShidWZmZXIuaW5kZXhPZih0YXNrKSwgMSlbMF07CiAgfQoKICAvKioKICAgKiBBZGQgYSBwcm9taXNlIChyZXByZXNlbnRpbmcgYW4gaW4tZmxpZ2h0IGFjdGlvbikgdG8gdGhlIHF1ZXVlLCBhbmQgc2V0IGl0IHRvIHJlbW92ZSBpdHNlbGYgb24gZnVsZmlsbG1lbnQuCiAgICoKICAgKiBAcGFyYW0gdGFza1Byb2R1Y2VyIEEgZnVuY3Rpb24gcHJvZHVjaW5nIGFueSBQcm9taXNlTGlrZTxUPjsgSW4gcHJldmlvdXMgdmVyc2lvbnMgdGhpcyB1c2VkIHRvIGJlIGB0YXNrOgogICAqICAgICAgICBQcm9taXNlTGlrZTxUPmAsIGJ1dCB1bmRlciB0aGF0IG1vZGVsLCBQcm9taXNlcyB3ZXJlIGluc3RhbnRseSBjcmVhdGVkIG9uIHRoZSBjYWxsLXNpdGUgYW5kIHRoZWlyIGV4ZWN1dG9yCiAgICogICAgICAgIGZ1bmN0aW9ucyB0aGVyZWZvcmUgcmFuIGltbWVkaWF0ZWx5LiBUaHVzLCBldmVuIGlmIHRoZSBidWZmZXIgd2FzIGZ1bGwsIHRoZSBhY3Rpb24gc3RpbGwgaGFwcGVuZWQuIEJ5CiAgICogICAgICAgIHJlcXVpcmluZyB0aGUgcHJvbWlzZSB0byBiZSB3cmFwcGVkIGluIGEgZnVuY3Rpb24sIHdlIGNhbiBkZWZlciBwcm9taXNlIGNyZWF0aW9uIHVudGlsIGFmdGVyIHRoZSBidWZmZXIKICAgKiAgICAgICAgbGltaXQgY2hlY2suCiAgICogQHJldHVybnMgVGhlIG9yaWdpbmFsIHByb21pc2UuCiAgICovCiAgZnVuY3Rpb24gYWRkKHRhc2tQcm9kdWNlcikgewogICAgaWYgKCFpc1JlYWR5KCkpIHsKICAgICAgcmV0dXJuIHJlamVjdGVkU3luY1Byb21pc2UobmV3IFNlbnRyeUVycm9yKCdOb3QgYWRkaW5nIFByb21pc2UgYmVjYXVzZSBidWZmZXIgbGltaXQgd2FzIHJlYWNoZWQuJykpOwogICAgfQoKICAgIC8vIHN0YXJ0IHRoZSB0YXNrIGFuZCBhZGQgaXRzIHByb21pc2UgdG8gdGhlIHF1ZXVlCiAgICBjb25zdCB0YXNrID0gdGFza1Byb2R1Y2VyKCk7CiAgICBpZiAoYnVmZmVyLmluZGV4T2YodGFzaykgPT09IC0xKSB7CiAgICAgIGJ1ZmZlci5wdXNoKHRhc2spOwogICAgfQogICAgdm9pZCB0YXNrCiAgICAgIC50aGVuKCgpID0+IHJlbW92ZSh0YXNrKSkKICAgICAgLy8gVXNlIGB0aGVuKG51bGwsIHJlamVjdGlvbkhhbmRsZXIpYCByYXRoZXIgdGhhbiBgY2F0Y2gocmVqZWN0aW9uSGFuZGxlcilgIHNvIHRoYXQgd2UgY2FuIHVzZSBgUHJvbWlzZUxpa2VgCiAgICAgIC8vIHJhdGhlciB0aGFuIGBQcm9taXNlYC4gYFByb21pc2VMaWtlYCBkb2Vzbid0IGhhdmUgYSBgLmNhdGNoYCBtZXRob2QsIG1ha2luZyBpdHMgcG9seWZpbGwgc21hbGxlci4gKEVTNSBkaWRuJ3QKICAgICAgLy8gaGF2ZSBwcm9taXNlcywgc28gVFMgaGFzIHRvIHBvbHlmaWxsIHdoZW4gZG93bi1jb21waWxpbmcuKQogICAgICAudGhlbihudWxsLCAoKSA9PgogICAgICAgIHJlbW92ZSh0YXNrKS50aGVuKG51bGwsICgpID0+IHsKICAgICAgICAgIC8vIFdlIGhhdmUgdG8gYWRkIGFub3RoZXIgY2F0Y2ggaGVyZSBiZWNhdXNlIGByZW1vdmUoKWAgc3RhcnRzIGEgbmV3IHByb21pc2UgY2hhaW4uCiAgICAgICAgfSksCiAgICAgICk7CiAgICByZXR1cm4gdGFzazsKICB9CgogIC8qKgogICAqIFdhaXQgZm9yIGFsbCBwcm9taXNlcyBpbiB0aGUgcXVldWUgdG8gcmVzb2x2ZSBvciBmb3IgdGltZW91dCB0byBleHBpcmUsIHdoaWNoZXZlciBjb21lcyBmaXJzdC4KICAgKgogICAqIEBwYXJhbSB0aW1lb3V0IFRoZSB0aW1lLCBpbiBtcywgYWZ0ZXIgd2hpY2ggdG8gcmVzb2x2ZSB0byBgZmFsc2VgIGlmIHRoZSBxdWV1ZSBpcyBzdGlsbCBub24tZW1wdHkuIFBhc3NpbmcgYDBgIChvcgogICAqIG5vdCBwYXNzaW5nIGFueXRoaW5nKSB3aWxsIG1ha2UgdGhlIHByb21pc2Ugd2FpdCBhcyBsb25nIGFzIGl0IHRha2VzIGZvciB0aGUgcXVldWUgdG8gZHJhaW4gYmVmb3JlIHJlc29sdmluZyB0bwogICAqIGB0cnVlYC4KICAgKiBAcmV0dXJucyBBIHByb21pc2Ugd2hpY2ggd2lsbCByZXNvbHZlIHRvIGB0cnVlYCBpZiB0aGUgcXVldWUgaXMgYWxyZWFkeSBlbXB0eSBvciBkcmFpbnMgYmVmb3JlIHRoZSB0aW1lb3V0LCBhbmQKICAgKiBgZmFsc2VgIG90aGVyd2lzZQogICAqLwogIGZ1bmN0aW9uIGRyYWluKHRpbWVvdXQpIHsKICAgIHJldHVybiBuZXcgU3luY1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgICBsZXQgY291bnRlciA9IGJ1ZmZlci5sZW5ndGg7CgogICAgICBpZiAoIWNvdW50ZXIpIHsKICAgICAgICByZXR1cm4gcmVzb2x2ZSh0cnVlKTsKICAgICAgfQoKICAgICAgLy8gd2FpdCBmb3IgYHRpbWVvdXRgIG1zIGFuZCB0aGVuIHJlc29sdmUgdG8gYGZhbHNlYCAoaWYgbm90IGNhbmNlbGxlZCBmaXJzdCkKICAgICAgY29uc3QgY2FwdHVyZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7CiAgICAgICAgaWYgKHRpbWVvdXQgJiYgdGltZW91dCA+IDApIHsKICAgICAgICAgIHJlc29sdmUoZmFsc2UpOwogICAgICAgIH0KICAgICAgfSwgdGltZW91dCk7CgogICAgICAvLyBpZiBhbGwgcHJvbWlzZXMgcmVzb2x2ZSBpbiB0aW1lLCBjYW5jZWwgdGhlIHRpbWVyIGFuZCByZXNvbHZlIHRvIGB0cnVlYAogICAgICBidWZmZXIuZm9yRWFjaChpdGVtID0+IHsKICAgICAgICB2b2lkIHJlc29sdmVkU3luY1Byb21pc2UoaXRlbSkudGhlbigoKSA9PiB7CiAgICAgICAgICBpZiAoIS0tY291bnRlcikgewogICAgICAgICAgICBjbGVhclRpbWVvdXQoY2FwdHVyZWRTZXRUaW1lb3V0KTsKICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTsKICAgICAgICAgIH0KICAgICAgICB9LCByZWplY3QpOwogICAgICB9KTsKICAgIH0pOwogIH0KCiAgcmV0dXJuIHsKICAgICQ6IGJ1ZmZlciwKICAgIGFkZCwKICAgIGRyYWluLAogIH07Cn0KCmNvbnN0IE9ORV9TRUNPTkRfSU5fTVMgPSAxMDAwOwoKLyoqCiAqIEEgcGFydGlhbCBkZWZpbml0aW9uIG9mIHRoZSBbUGVyZm9ybWFuY2UgV2ViIEFQSV17QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1BlcmZvcm1hbmNlfQogKiBmb3IgYWNjZXNzaW5nIGEgaGlnaC1yZXNvbHV0aW9uIG1vbm90b25pYyBjbG9jay4KICovCgovKioKICogUmV0dXJucyBhIHRpbWVzdGFtcCBpbiBzZWNvbmRzIHNpbmNlIHRoZSBVTklYIGVwb2NoIHVzaW5nIHRoZSBEYXRlIEFQSS4KICoKICogVE9ETyh2OCk6IFJldHVybiB0eXBlIHNob3VsZCBiZSByb3VuZGVkLgogKi8KZnVuY3Rpb24gZGF0ZVRpbWVzdGFtcEluU2Vjb25kcygpIHsKICByZXR1cm4gRGF0ZS5ub3coKSAvIE9ORV9TRUNPTkRfSU5fTVM7Cn0KCi8qKgogKiBSZXR1cm5zIGEgd3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBQZXJmb3JtYW5jZSBBUEkgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiwgb3IgdW5kZWZpbmVkIGZvciBicm93c2VycyB0aGF0IGRvIG5vdAogKiBzdXBwb3J0IHRoZSBBUEkuCiAqCiAqIFdyYXBwaW5nIHRoZSBuYXRpdmUgQVBJIHdvcmtzIGFyb3VuZCBkaWZmZXJlbmNlcyBpbiBiZWhhdmlvciBmcm9tIGRpZmZlcmVudCBicm93c2Vycy4KICovCmZ1bmN0aW9uIGNyZWF0ZVVuaXhUaW1lc3RhbXBJblNlY29uZHNGdW5jKCkgewogIGNvbnN0IHsgcGVyZm9ybWFuY2UgfSA9IEdMT0JBTF9PQkogOwogIGlmICghcGVyZm9ybWFuY2UgfHwgIXBlcmZvcm1hbmNlLm5vdykgewogICAgcmV0dXJuIGRhdGVUaW1lc3RhbXBJblNlY29uZHM7CiAgfQoKICAvLyBTb21lIGJyb3dzZXIgYW5kIGVudmlyb25tZW50cyBkb24ndCBoYXZlIGEgdGltZU9yaWdpbiwgc28gd2UgZmFsbGJhY2sgdG8KICAvLyB1c2luZyBEYXRlLm5vdygpIHRvIGNvbXB1dGUgdGhlIHN0YXJ0aW5nIHRpbWUuCiAgY29uc3QgYXBwcm94U3RhcnRpbmdUaW1lT3JpZ2luID0gRGF0ZS5ub3coKSAtIHBlcmZvcm1hbmNlLm5vdygpOwogIGNvbnN0IHRpbWVPcmlnaW4gPSBwZXJmb3JtYW5jZS50aW1lT3JpZ2luID09IHVuZGVmaW5lZCA/IGFwcHJveFN0YXJ0aW5nVGltZU9yaWdpbiA6IHBlcmZvcm1hbmNlLnRpbWVPcmlnaW47CgogIC8vIHBlcmZvcm1hbmNlLm5vdygpIGlzIGEgbW9ub3RvbmljIGNsb2NrLCB3aGljaCBtZWFucyBpdCBzdGFydHMgYXQgMCB3aGVuIHRoZSBwcm9jZXNzIGJlZ2lucy4gVG8gZ2V0IHRoZSBjdXJyZW50CiAgLy8gd2FsbCBjbG9jayB0aW1lIChhY3R1YWwgVU5JWCB0aW1lc3RhbXApLCB3ZSBuZWVkIHRvIGFkZCB0aGUgc3RhcnRpbmcgdGltZSBvcmlnaW4gYW5kIHRoZSBjdXJyZW50IHRpbWUgZWxhcHNlZC4KICAvLwogIC8vIFRPRE86IFRoaXMgZG9lcyBub3QgYWNjb3VudCBmb3IgdGhlIGNhc2Ugd2hlcmUgdGhlIG1vbm90b25pYyBjbG9jayB0aGF0IHBvd2VycyBwZXJmb3JtYW5jZS5ub3coKSBkcmlmdHMgZnJvbSB0aGUKICAvLyB3YWxsIGNsb2NrIHRpbWUsIHdoaWNoIGNhdXNlcyB0aGUgcmV0dXJuZWQgdGltZXN0YW1wIHRvIGJlIGluYWNjdXJhdGUuIFdlIHNob3VsZCBpbnZlc3RpZ2F0ZSBob3cgdG8gZGV0ZWN0IGFuZAogIC8vIGNvcnJlY3QgZm9yIHRoaXMuCiAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3NlbnRyeS1qYXZhc2NyaXB0L2lzc3Vlcy8yNTkwCiAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vbWRuL2NvbnRlbnQvaXNzdWVzLzQ3MTMKICAvLyBTZWU6IGh0dHBzOi8vZGV2LnRvL25vYW1yL3doZW4tYS1taWxsaXNlY29uZC1pcy1ub3QtYS1taWxsaXNlY29uZC0zaDYKICByZXR1cm4gKCkgPT4gewogICAgcmV0dXJuICh0aW1lT3JpZ2luICsgcGVyZm9ybWFuY2Uubm93KCkpIC8gT05FX1NFQ09ORF9JTl9NUzsKICB9Owp9CgovKioKICogUmV0dXJucyBhIHRpbWVzdGFtcCBpbiBzZWNvbmRzIHNpbmNlIHRoZSBVTklYIGVwb2NoIHVzaW5nIGVpdGhlciB0aGUgUGVyZm9ybWFuY2Ugb3IgRGF0ZSBBUElzLCBkZXBlbmRpbmcgb24gdGhlCiAqIGF2YWlsYWJpbGl0eSBvZiB0aGUgUGVyZm9ybWFuY2UgQVBJLgogKgogKiBCVUc6IE5vdGUgdGhhdCBiZWNhdXNlIG9mIGhvdyBicm93c2VycyBpbXBsZW1lbnQgdGhlIFBlcmZvcm1hbmNlIEFQSSwgdGhlIGNsb2NrIG1pZ2h0IHN0b3Agd2hlbiB0aGUgY29tcHV0ZXIgaXMKICogYXNsZWVwLiBUaGlzIGNyZWF0ZXMgYSBza2V3IGJldHdlZW4gYGRhdGVUaW1lc3RhbXBJblNlY29uZHNgIGFuZCBgdGltZXN0YW1wSW5TZWNvbmRzYC4gVGhlCiAqIHNrZXcgY2FuIGdyb3cgdG8gYXJiaXRyYXJ5IGFtb3VudHMgbGlrZSBkYXlzLCB3ZWVrcyBvciBtb250aHMuCiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3NlbnRyeS1qYXZhc2NyaXB0L2lzc3Vlcy8yNTkwLgogKi8KY29uc3QgdGltZXN0YW1wSW5TZWNvbmRzID0gY3JlYXRlVW5peFRpbWVzdGFtcEluU2Vjb25kc0Z1bmMoKTsKCi8qKgogKiBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZSB0aGUgVU5JWCBlcG9jaC4gVGhpcyB2YWx1ZSBpcyBvbmx5IHVzYWJsZSBpbiBhIGJyb3dzZXIsIGFuZCBvbmx5IHdoZW4gdGhlCiAqIHBlcmZvcm1hbmNlIEFQSSBpcyBhdmFpbGFibGUuCiAqLwooKCkgPT4gewogIC8vIFVuZm9ydHVuYXRlbHkgYnJvd3NlcnMgbWF5IHJlcG9ydCBhbiBpbmFjY3VyYXRlIHRpbWUgb3JpZ2luIGRhdGEsIHRocm91Z2ggZWl0aGVyIHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gb3IKICAvLyBwZXJmb3JtYW5jZS50aW1pbmcubmF2aWdhdGlvblN0YXJ0LCB3aGljaCByZXN1bHRzIGluIHBvb3IgcmVzdWx0cyBpbiBwZXJmb3JtYW5jZSBkYXRhLiBXZSBvbmx5IHRyZWF0IHRpbWUgb3JpZ2luCiAgLy8gZGF0YSBhcyByZWxpYWJsZSBpZiB0aGV5IGFyZSB3aXRoaW4gYSByZWFzb25hYmxlIHRocmVzaG9sZCBvZiB0aGUgY3VycmVudCB0aW1lLgoKICBjb25zdCB7IHBlcmZvcm1hbmNlIH0gPSBHTE9CQUxfT0JKIDsKICBpZiAoIXBlcmZvcm1hbmNlIHx8ICFwZXJmb3JtYW5jZS5ub3cpIHsKICAgIHJldHVybiB1bmRlZmluZWQ7CiAgfQoKICBjb25zdCB0aHJlc2hvbGQgPSAzNjAwICogMTAwMDsKICBjb25zdCBwZXJmb3JtYW5jZU5vdyA9IHBlcmZvcm1hbmNlLm5vdygpOwogIGNvbnN0IGRhdGVOb3cgPSBEYXRlLm5vdygpOwoKICAvLyBpZiB0aW1lT3JpZ2luIGlzbid0IGF2YWlsYWJsZSBzZXQgZGVsdGEgdG8gdGhyZXNob2xkIHNvIGl0IGlzbid0IHVzZWQKICBjb25zdCB0aW1lT3JpZ2luRGVsdGEgPSBwZXJmb3JtYW5jZS50aW1lT3JpZ2luCiAgICA/IE1hdGguYWJzKHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gKyBwZXJmb3JtYW5jZU5vdyAtIGRhdGVOb3cpCiAgICA6IHRocmVzaG9sZDsKICBjb25zdCB0aW1lT3JpZ2luSXNSZWxpYWJsZSA9IHRpbWVPcmlnaW5EZWx0YSA8IHRocmVzaG9sZDsKCiAgLy8gV2hpbGUgcGVyZm9ybWFuY2UudGltaW5nLm5hdmlnYXRpb25TdGFydCBpcyBkZXByZWNhdGVkIGluIGZhdm9yIG9mIHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4sIHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4KICAvLyBpcyBub3QgYXMgd2lkZWx5IHN1cHBvcnRlZC4gTmFtZWx5LCBwZXJmb3JtYW5jZS50aW1lT3JpZ2luIGlzIHVuZGVmaW5lZCBpbiBTYWZhcmkgYXMgb2Ygd3JpdGluZy4KICAvLyBBbHNvIGFzIG9mIHdyaXRpbmcsIHBlcmZvcm1hbmNlLnRpbWluZyBpcyBub3QgYXZhaWxhYmxlIGluIFdlYiBXb3JrZXJzIGluIG1haW5zdHJlYW0gYnJvd3NlcnMsIHNvIGl0IGlzIG5vdCBhbHdheXMKICAvLyBhIHZhbGlkIGZhbGxiYWNrLiBJbiB0aGUgYWJzZW5jZSBvZiBhbiBpbml0aWFsIHRpbWUgcHJvdmlkZWQgYnkgdGhlIGJyb3dzZXIsIGZhbGxiYWNrIHRvIHRoZSBjdXJyZW50IHRpbWUgZnJvbSB0aGUKICAvLyBEYXRlIEFQSS4KICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICBjb25zdCBuYXZpZ2F0aW9uU3RhcnQgPSBwZXJmb3JtYW5jZS50aW1pbmcgJiYgcGVyZm9ybWFuY2UudGltaW5nLm5hdmlnYXRpb25TdGFydDsKICBjb25zdCBoYXNOYXZpZ2F0aW9uU3RhcnQgPSB0eXBlb2YgbmF2aWdhdGlvblN0YXJ0ID09PSAnbnVtYmVyJzsKICAvLyBpZiBuYXZpZ2F0aW9uU3RhcnQgaXNuJ3QgYXZhaWxhYmxlIHNldCBkZWx0YSB0byB0aHJlc2hvbGQgc28gaXQgaXNuJ3QgdXNlZAogIGNvbnN0IG5hdmlnYXRpb25TdGFydERlbHRhID0gaGFzTmF2aWdhdGlvblN0YXJ0ID8gTWF0aC5hYnMobmF2aWdhdGlvblN0YXJ0ICsgcGVyZm9ybWFuY2VOb3cgLSBkYXRlTm93KSA6IHRocmVzaG9sZDsKICBjb25zdCBuYXZpZ2F0aW9uU3RhcnRJc1JlbGlhYmxlID0gbmF2aWdhdGlvblN0YXJ0RGVsdGEgPCB0aHJlc2hvbGQ7CgogIGlmICh0aW1lT3JpZ2luSXNSZWxpYWJsZSB8fCBuYXZpZ2F0aW9uU3RhcnRJc1JlbGlhYmxlKSB7CiAgICAvLyBVc2UgdGhlIG1vcmUgcmVsaWFibGUgdGltZSBvcmlnaW4KICAgIGlmICh0aW1lT3JpZ2luRGVsdGEgPD0gbmF2aWdhdGlvblN0YXJ0RGVsdGEpIHsKICAgICAgcmV0dXJuIHBlcmZvcm1hbmNlLnRpbWVPcmlnaW47CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gbmF2aWdhdGlvblN0YXJ0OwogICAgfQogIH0KICByZXR1cm4gZGF0ZU5vdzsKfSkoKTsKCi8qKgogKiBDcmVhdGVzIGFuIGVudmVsb3BlLgogKiBNYWtlIHN1cmUgdG8gYWx3YXlzIGV4cGxpY2l0bHkgcHJvdmlkZSB0aGUgZ2VuZXJpYyB0byB0aGlzIGZ1bmN0aW9uCiAqIHNvIHRoYXQgdGhlIGVudmVsb3BlIHR5cGVzIHJlc29sdmUgY29ycmVjdGx5LgogKi8KZnVuY3Rpb24gY3JlYXRlRW52ZWxvcGUoaGVhZGVycywgaXRlbXMgPSBbXSkgewogIHJldHVybiBbaGVhZGVycywgaXRlbXNdIDsKfQoKLyoqCiAqIENvbnZlbmllbmNlIGZ1bmN0aW9uIHRvIGxvb3AgdGhyb3VnaCB0aGUgaXRlbXMgYW5kIGl0ZW0gdHlwZXMgb2YgYW4gZW52ZWxvcGUuCiAqIChUaGlzIGZ1bmN0aW9uIHdhcyBtb3N0bHkgY3JlYXRlZCBiZWNhdXNlIHdvcmtpbmcgd2l0aCBlbnZlbG9wZSB0eXBlcyBpcyBwYWluZnVsIGF0IHRoZSBtb21lbnQpCiAqCiAqIElmIHRoZSBjYWxsYmFjayByZXR1cm5zIHRydWUsIHRoZSByZXN0IG9mIHRoZSBpdGVtcyB3aWxsIGJlIHNraXBwZWQuCiAqLwpmdW5jdGlvbiBmb3JFYWNoRW52ZWxvcGVJdGVtKAogIGVudmVsb3BlLAogIGNhbGxiYWNrLAopIHsKICBjb25zdCBlbnZlbG9wZUl0ZW1zID0gZW52ZWxvcGVbMV07CgogIGZvciAoY29uc3QgZW52ZWxvcGVJdGVtIG9mIGVudmVsb3BlSXRlbXMpIHsKICAgIGNvbnN0IGVudmVsb3BlSXRlbVR5cGUgPSBlbnZlbG9wZUl0ZW1bMF0udHlwZTsKICAgIGNvbnN0IHJlc3VsdCA9IGNhbGxiYWNrKGVudmVsb3BlSXRlbSwgZW52ZWxvcGVJdGVtVHlwZSk7CgogICAgaWYgKHJlc3VsdCkgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICB9CgogIHJldHVybiBmYWxzZTsKfQoKLyoqCiAqIEVuY29kZSBhIHN0cmluZyB0byBVVEY4LgogKi8KZnVuY3Rpb24gZW5jb2RlVVRGOChpbnB1dCwgdGV4dEVuY29kZXIpIHsKICBjb25zdCB1dGY4ID0gdGV4dEVuY29kZXIgfHwgbmV3IFRleHRFbmNvZGVyKCk7CiAgcmV0dXJuIHV0ZjguZW5jb2RlKGlucHV0KTsKfQoKLyoqCiAqIFNlcmlhbGl6ZXMgYW4gZW52ZWxvcGUuCiAqLwpmdW5jdGlvbiBzZXJpYWxpemVFbnZlbG9wZShlbnZlbG9wZSwgdGV4dEVuY29kZXIpIHsKICBjb25zdCBbZW52SGVhZGVycywgaXRlbXNdID0gZW52ZWxvcGU7CgogIC8vIEluaXRpYWxseSB3ZSBjb25zdHJ1Y3Qgb3VyIGVudmVsb3BlIGFzIGEgc3RyaW5nIGFuZCBvbmx5IGNvbnZlcnQgdG8gYmluYXJ5IGNodW5rcyBpZiB3ZSBlbmNvdW50ZXIgYmluYXJ5IGRhdGEKICBsZXQgcGFydHMgPSBKU09OLnN0cmluZ2lmeShlbnZIZWFkZXJzKTsKCiAgZnVuY3Rpb24gYXBwZW5kKG5leHQpIHsKICAgIGlmICh0eXBlb2YgcGFydHMgPT09ICdzdHJpbmcnKSB7CiAgICAgIHBhcnRzID0gdHlwZW9mIG5leHQgPT09ICdzdHJpbmcnID8gcGFydHMgKyBuZXh0IDogW2VuY29kZVVURjgocGFydHMsIHRleHRFbmNvZGVyKSwgbmV4dF07CiAgICB9IGVsc2UgewogICAgICBwYXJ0cy5wdXNoKHR5cGVvZiBuZXh0ID09PSAnc3RyaW5nJyA/IGVuY29kZVVURjgobmV4dCwgdGV4dEVuY29kZXIpIDogbmV4dCk7CiAgICB9CiAgfQoKICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHsKICAgIGNvbnN0IFtpdGVtSGVhZGVycywgcGF5bG9hZF0gPSBpdGVtOwoKICAgIGFwcGVuZChgXG4ke0pTT04uc3RyaW5naWZ5KGl0ZW1IZWFkZXJzKX1cbmApOwoKICAgIGlmICh0eXBlb2YgcGF5bG9hZCA9PT0gJ3N0cmluZycgfHwgcGF5bG9hZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsKICAgICAgYXBwZW5kKHBheWxvYWQpOwogICAgfSBlbHNlIHsKICAgICAgbGV0IHN0cmluZ2lmaWVkUGF5bG9hZDsKICAgICAgdHJ5IHsKICAgICAgICBzdHJpbmdpZmllZFBheWxvYWQgPSBKU09OLnN0cmluZ2lmeShwYXlsb2FkKTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIC8vIEluIGNhc2UsIGRlc3BpdGUgYWxsIG91ciBlZmZvcnRzIHRvIGtlZXAgYHBheWxvYWRgIGNpcmN1bGFyLWRlcGVuZGVuY3ktZnJlZSwgYEpTT04uc3RyaW5pZnkoKWAgc3RpbGwKICAgICAgICAvLyBmYWlscywgd2UgdHJ5IGFnYWluIGFmdGVyIG5vcm1hbGl6aW5nIGl0IGFnYWluIHdpdGggaW5maW5pdGUgbm9ybWFsaXphdGlvbiBkZXB0aC4gVGhpcyBvZiBjb3Vyc2UgaGFzIGEKICAgICAgICAvLyBwZXJmb3JtYW5jZSBpbXBhY3QgYnV0IGluIHRoaXMgY2FzZSBhIHBlcmZvcm1hbmNlIGhpdCBpcyBiZXR0ZXIgdGhhbiB0aHJvd2luZy4KICAgICAgICBzdHJpbmdpZmllZFBheWxvYWQgPSBKU09OLnN0cmluZ2lmeShub3JtYWxpemUocGF5bG9hZCkpOwogICAgICB9CiAgICAgIGFwcGVuZChzdHJpbmdpZmllZFBheWxvYWQpOwogICAgfQogIH0KCiAgcmV0dXJuIHR5cGVvZiBwYXJ0cyA9PT0gJ3N0cmluZycgPyBwYXJ0cyA6IGNvbmNhdEJ1ZmZlcnMocGFydHMpOwp9CgpmdW5jdGlvbiBjb25jYXRCdWZmZXJzKGJ1ZmZlcnMpIHsKICBjb25zdCB0b3RhbExlbmd0aCA9IGJ1ZmZlcnMucmVkdWNlKChhY2MsIGJ1ZikgPT4gYWNjICsgYnVmLmxlbmd0aCwgMCk7CgogIGNvbnN0IG1lcmdlZCA9IG5ldyBVaW50OEFycmF5KHRvdGFsTGVuZ3RoKTsKICBsZXQgb2Zmc2V0ID0gMDsKICBmb3IgKGNvbnN0IGJ1ZmZlciBvZiBidWZmZXJzKSB7CiAgICBtZXJnZWQuc2V0KGJ1ZmZlciwgb2Zmc2V0KTsKICAgIG9mZnNldCArPSBidWZmZXIubGVuZ3RoOwogIH0KCiAgcmV0dXJuIG1lcmdlZDsKfQoKY29uc3QgSVRFTV9UWVBFX1RPX0RBVEFfQ0FURUdPUllfTUFQID0gewogIHNlc3Npb246ICdzZXNzaW9uJywKICBzZXNzaW9uczogJ3Nlc3Npb24nLAogIGF0dGFjaG1lbnQ6ICdhdHRhY2htZW50JywKICB0cmFuc2FjdGlvbjogJ3RyYW5zYWN0aW9uJywKICBldmVudDogJ2Vycm9yJywKICBjbGllbnRfcmVwb3J0OiAnaW50ZXJuYWwnLAogIHVzZXJfcmVwb3J0OiAnZGVmYXVsdCcsCiAgcHJvZmlsZTogJ3Byb2ZpbGUnLAogIHJlcGxheV9ldmVudDogJ3JlcGxheScsCiAgcmVwbGF5X3JlY29yZGluZzogJ3JlcGxheScsCiAgY2hlY2tfaW46ICdtb25pdG9yJywKICBmZWVkYmFjazogJ2ZlZWRiYWNrJywKICBzcGFuOiAnc3BhbicsCiAgc3RhdHNkOiAnbWV0cmljX2J1Y2tldCcsCn07CgovKioKICogTWFwcyB0aGUgdHlwZSBvZiBhbiBlbnZlbG9wZSBpdGVtIHRvIGEgZGF0YSBjYXRlZ29yeS4KICovCmZ1bmN0aW9uIGVudmVsb3BlSXRlbVR5cGVUb0RhdGFDYXRlZ29yeSh0eXBlKSB7CiAgcmV0dXJuIElURU1fVFlQRV9UT19EQVRBX0NBVEVHT1JZX01BUFt0eXBlXTsKfQoKLyoqIEV4dHJhY3RzIHRoZSBtaW5pbWFsIFNESyBpbmZvIGZyb20gdGhlIG1ldGFkYXRhIG9yIGFuIGV2ZW50cyAqLwpmdW5jdGlvbiBnZXRTZGtNZXRhZGF0YUZvckVudmVsb3BlSGVhZGVyKG1ldGFkYXRhT3JFdmVudCkgewogIGlmICghbWV0YWRhdGFPckV2ZW50IHx8ICFtZXRhZGF0YU9yRXZlbnQuc2RrKSB7CiAgICByZXR1cm47CiAgfQogIGNvbnN0IHsgbmFtZSwgdmVyc2lvbiB9ID0gbWV0YWRhdGFPckV2ZW50LnNkazsKICByZXR1cm4geyBuYW1lLCB2ZXJzaW9uIH07Cn0KCi8qKgogKiBDcmVhdGVzIGV2ZW50IGVudmVsb3BlIGhlYWRlcnMsIGJhc2VkIG9uIGV2ZW50LCBzZGsgaW5mbyBhbmQgdHVubmVsCiAqIE5vdGU6IFRoaXMgZnVuY3Rpb24gd2FzIGV4dHJhY3RlZCBmcm9tIHRoZSBjb3JlIHBhY2thZ2UgdG8gbWFrZSBpdCBhdmFpbGFibGUgaW4gUmVwbGF5CiAqLwpmdW5jdGlvbiBjcmVhdGVFdmVudEVudmVsb3BlSGVhZGVycygKICBldmVudCwKICBzZGtJbmZvLAogIHR1bm5lbCwKICBkc24sCikgewogIGNvbnN0IGR5bmFtaWNTYW1wbGluZ0NvbnRleHQgPSBldmVudC5zZGtQcm9jZXNzaW5nTWV0YWRhdGEgJiYgZXZlbnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLmR5bmFtaWNTYW1wbGluZ0NvbnRleHQ7CiAgcmV0dXJuIHsKICAgIGV2ZW50X2lkOiBldmVudC5ldmVudF9pZCAsCiAgICBzZW50X2F0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksCiAgICAuLi4oc2RrSW5mbyAmJiB7IHNkazogc2RrSW5mbyB9KSwKICAgIC4uLighIXR1bm5lbCAmJiBkc24gJiYgeyBkc246IGRzblRvU3RyaW5nKGRzbikgfSksCiAgICAuLi4oZHluYW1pY1NhbXBsaW5nQ29udGV4dCAmJiB7CiAgICAgIHRyYWNlOiBkcm9wVW5kZWZpbmVkS2V5cyh7IC4uLmR5bmFtaWNTYW1wbGluZ0NvbnRleHQgfSksCiAgICB9KSwKICB9Owp9CgovLyBJbnRlbnRpb25hbGx5IGtlZXBpbmcgdGhlIGtleSBicm9hZCwgYXMgd2UgZG9uJ3Qga25vdyBmb3Igc3VyZSB3aGF0IHJhdGUgbGltaXQgaGVhZGVycyBnZXQgcmV0dXJuZWQgZnJvbSBiYWNrZW5kCgpjb25zdCBERUZBVUxUX1JFVFJZX0FGVEVSID0gNjAgKiAxMDAwOyAvLyA2MCBzZWNvbmRzCgovKioKICogRXh0cmFjdHMgUmV0cnktQWZ0ZXIgdmFsdWUgZnJvbSB0aGUgcmVxdWVzdCBoZWFkZXIgb3IgcmV0dXJucyBkZWZhdWx0IHZhbHVlCiAqIEBwYXJhbSBoZWFkZXIgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mICdSZXRyeS1BZnRlcicgaGVhZGVyCiAqIEBwYXJhbSBub3cgY3VycmVudCB1bml4IHRpbWVzdGFtcAogKgogKi8KZnVuY3Rpb24gcGFyc2VSZXRyeUFmdGVySGVhZGVyKGhlYWRlciwgbm93ID0gRGF0ZS5ub3coKSkgewogIGNvbnN0IGhlYWRlckRlbGF5ID0gcGFyc2VJbnQoYCR7aGVhZGVyfWAsIDEwKTsKICBpZiAoIWlzTmFOKGhlYWRlckRlbGF5KSkgewogICAgcmV0dXJuIGhlYWRlckRlbGF5ICogMTAwMDsKICB9CgogIGNvbnN0IGhlYWRlckRhdGUgPSBEYXRlLnBhcnNlKGAke2hlYWRlcn1gKTsKICBpZiAoIWlzTmFOKGhlYWRlckRhdGUpKSB7CiAgICByZXR1cm4gaGVhZGVyRGF0ZSAtIG5vdzsKICB9CgogIHJldHVybiBERUZBVUxUX1JFVFJZX0FGVEVSOwp9CgovKioKICogR2V0cyB0aGUgdGltZSB0aGF0IHRoZSBnaXZlbiBjYXRlZ29yeSBpcyBkaXNhYmxlZCB1bnRpbCBmb3IgcmF0ZSBsaW1pdGluZy4KICogSW4gY2FzZSBubyBjYXRlZ29yeS1zcGVjaWZpYyBsaW1pdCBpcyBzZXQgYnV0IGEgZ2VuZXJhbCByYXRlIGxpbWl0IGFjcm9zcyBhbGwgY2F0ZWdvcmllcyBpcyBhY3RpdmUsCiAqIHRoYXQgdGltZSBpcyByZXR1cm5lZC4KICoKICogQHJldHVybiB0aGUgdGltZSBpbiBtcyB0aGF0IHRoZSBjYXRlZ29yeSBpcyBkaXNhYmxlZCB1bnRpbCBvciAwIGlmIHRoZXJlJ3Mgbm8gYWN0aXZlIHJhdGUgbGltaXQuCiAqLwpmdW5jdGlvbiBkaXNhYmxlZFVudGlsKGxpbWl0cywgZGF0YUNhdGVnb3J5KSB7CiAgcmV0dXJuIGxpbWl0c1tkYXRhQ2F0ZWdvcnldIHx8IGxpbWl0cy5hbGwgfHwgMDsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIGNhdGVnb3J5IGlzIHJhdGUgbGltaXRlZAogKi8KZnVuY3Rpb24gaXNSYXRlTGltaXRlZChsaW1pdHMsIGRhdGFDYXRlZ29yeSwgbm93ID0gRGF0ZS5ub3coKSkgewogIHJldHVybiBkaXNhYmxlZFVudGlsKGxpbWl0cywgZGF0YUNhdGVnb3J5KSA+IG5vdzsKfQoKLyoqCiAqIFVwZGF0ZSByYXRlbGltaXRzIGZyb20gaW5jb21pbmcgaGVhZGVycy4KICoKICogQHJldHVybiB0aGUgdXBkYXRlZCBSYXRlTGltaXRzIG9iamVjdC4KICovCmZ1bmN0aW9uIHVwZGF0ZVJhdGVMaW1pdHMoCiAgbGltaXRzLAogIHsgc3RhdHVzQ29kZSwgaGVhZGVycyB9LAogIG5vdyA9IERhdGUubm93KCksCikgewogIGNvbnN0IHVwZGF0ZWRSYXRlTGltaXRzID0gewogICAgLi4ubGltaXRzLAogIH07CgogIC8vICJUaGUgbmFtZSBpcyBjYXNlLWluc2Vuc2l0aXZlLiIKICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSGVhZGVycy9nZXQKICBjb25zdCByYXRlTGltaXRIZWFkZXIgPSBoZWFkZXJzICYmIGhlYWRlcnNbJ3gtc2VudHJ5LXJhdGUtbGltaXRzJ107CiAgY29uc3QgcmV0cnlBZnRlckhlYWRlciA9IGhlYWRlcnMgJiYgaGVhZGVyc1sncmV0cnktYWZ0ZXInXTsKCiAgaWYgKHJhdGVMaW1pdEhlYWRlcikgewogICAgLyoqCiAgICAgKiByYXRlIGxpbWl0IGhlYWRlcnMgYXJlIG9mIHRoZSBmb3JtCiAgICAgKiAgICAgPGhlYWRlcj4sPGhlYWRlcj4sLi4KICAgICAqIHdoZXJlIGVhY2ggPGhlYWRlcj4gaXMgb2YgdGhlIGZvcm0KICAgICAqICAgICA8cmV0cnlfYWZ0ZXI+OiA8Y2F0ZWdvcmllcz46IDxzY29wZT46IDxyZWFzb25fY29kZT46IDxuYW1lc3BhY2VzPgogICAgICogd2hlcmUKICAgICAqICAgICA8cmV0cnlfYWZ0ZXI+IGlzIGEgZGVsYXkgaW4gc2Vjb25kcwogICAgICogICAgIDxjYXRlZ29yaWVzPiBpcyB0aGUgZXZlbnQgdHlwZShzKSAoZXJyb3IsIHRyYW5zYWN0aW9uLCBldGMpIGJlaW5nIHJhdGUgbGltaXRlZCBhbmQgaXMgb2YgdGhlIGZvcm0KICAgICAqICAgICAgICAgPGNhdGVnb3J5Pjs8Y2F0ZWdvcnk+Oy4uLgogICAgICogICAgIDxzY29wZT4gaXMgd2hhdCdzIGJlaW5nIGxpbWl0ZWQgKG9yZywgcHJvamVjdCwgb3Iga2V5KSAtIGlnbm9yZWQgYnkgU0RLCiAgICAgKiAgICAgPHJlYXNvbl9jb2RlPiBpcyBhbiBhcmJpdHJhcnkgc3RyaW5nIGxpa2UgIm9yZ19xdW90YSIgLSBpZ25vcmVkIGJ5IFNESwogICAgICogICAgIDxuYW1lc3BhY2VzPiBTZW1pY29sb24tc2VwYXJhdGVkIGxpc3Qgb2YgbWV0cmljIG5hbWVzcGFjZSBpZGVudGlmaWVycy4gRGVmaW5lcyB3aGljaCBuYW1lc3BhY2Uocykgd2lsbCBiZSBhZmZlY3RlZC4KICAgICAqICAgICAgICAgT25seSBwcmVzZW50IGlmIHJhdGUgbGltaXQgYXBwbGllcyB0byB0aGUgbWV0cmljX2J1Y2tldCBkYXRhIGNhdGVnb3J5LgogICAgICovCiAgICBmb3IgKGNvbnN0IGxpbWl0IG9mIHJhdGVMaW1pdEhlYWRlci50cmltKCkuc3BsaXQoJywnKSkgewogICAgICBjb25zdCBbcmV0cnlBZnRlciwgY2F0ZWdvcmllcywgLCAsIG5hbWVzcGFjZXNdID0gbGltaXQuc3BsaXQoJzonLCA1KTsKICAgICAgY29uc3QgaGVhZGVyRGVsYXkgPSBwYXJzZUludChyZXRyeUFmdGVyLCAxMCk7CiAgICAgIGNvbnN0IGRlbGF5ID0gKCFpc05hTihoZWFkZXJEZWxheSkgPyBoZWFkZXJEZWxheSA6IDYwKSAqIDEwMDA7IC8vIDYwc2VjIGRlZmF1bHQKICAgICAgaWYgKCFjYXRlZ29yaWVzKSB7CiAgICAgICAgdXBkYXRlZFJhdGVMaW1pdHMuYWxsID0gbm93ICsgZGVsYXk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZm9yIChjb25zdCBjYXRlZ29yeSBvZiBjYXRlZ29yaWVzLnNwbGl0KCc7JykpIHsKICAgICAgICAgIGlmIChjYXRlZ29yeSA9PT0gJ21ldHJpY19idWNrZXQnKSB7CiAgICAgICAgICAgIC8vIG5hbWVzcGFjZXMgd2lsbCBiZSBwcmVzZW50IHdoZW4gY2F0ZWdvcnkgPT09ICdtZXRyaWNfYnVja2V0JwogICAgICAgICAgICBpZiAoIW5hbWVzcGFjZXMgfHwgbmFtZXNwYWNlcy5zcGxpdCgnOycpLmluY2x1ZGVzKCdjdXN0b20nKSkgewogICAgICAgICAgICAgIHVwZGF0ZWRSYXRlTGltaXRzW2NhdGVnb3J5XSA9IG5vdyArIGRlbGF5OwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB1cGRhdGVkUmF0ZUxpbWl0c1tjYXRlZ29yeV0gPSBub3cgKyBkZWxheTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKHJldHJ5QWZ0ZXJIZWFkZXIpIHsKICAgIHVwZGF0ZWRSYXRlTGltaXRzLmFsbCA9IG5vdyArIHBhcnNlUmV0cnlBZnRlckhlYWRlcihyZXRyeUFmdGVySGVhZGVyLCBub3cpOwogIH0gZWxzZSBpZiAoc3RhdHVzQ29kZSA9PT0gNDI5KSB7CiAgICB1cGRhdGVkUmF0ZUxpbWl0cy5hbGwgPSBub3cgKyA2MCAqIDEwMDA7CiAgfQoKICByZXR1cm4gdXBkYXRlZFJhdGVMaW1pdHM7Cn0KCi8qKgogKiBBIG5vZGUuanMgd2F0Y2hkb2cgdGltZXIKICogQHBhcmFtIHBvbGxJbnRlcnZhbCBUaGUgaW50ZXJ2YWwgdGhhdCB3ZSBleHBlY3QgdG8gZ2V0IHBvbGxlZCBhdAogKiBAcGFyYW0gYW5yVGhyZXNob2xkIFRoZSB0aHJlc2hvbGQgZm9yIHdoZW4gd2UgY29uc2lkZXIgQU5SCiAqIEBwYXJhbSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gY2FsbCBmb3IgQU5SCiAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIGBwb2xsYCBhbmQgYGVuYWJsZWRgIGZ1bmN0aW9ucyB7QGxpbmsgV2F0Y2hkb2dSZXR1cm59CiAqLwpmdW5jdGlvbiB3YXRjaGRvZ1RpbWVyKAogIGNyZWF0ZVRpbWVyLAogIHBvbGxJbnRlcnZhbCwKICBhbnJUaHJlc2hvbGQsCiAgY2FsbGJhY2ssCikgewogIGNvbnN0IHRpbWVyID0gY3JlYXRlVGltZXIoKTsKICBsZXQgdHJpZ2dlcmVkID0gZmFsc2U7CiAgbGV0IGVuYWJsZWQgPSB0cnVlOwoKICBzZXRJbnRlcnZhbCgoKSA9PiB7CiAgICBjb25zdCBkaWZmTXMgPSB0aW1lci5nZXRUaW1lTXMoKTsKCiAgICBpZiAodHJpZ2dlcmVkID09PSBmYWxzZSAmJiBkaWZmTXMgPiBwb2xsSW50ZXJ2YWwgKyBhbnJUaHJlc2hvbGQpIHsKICAgICAgdHJpZ2dlcmVkID0gdHJ1ZTsKICAgICAgaWYgKGVuYWJsZWQpIHsKICAgICAgICBjYWxsYmFjaygpOwogICAgICB9CiAgICB9CgogICAgaWYgKGRpZmZNcyA8IHBvbGxJbnRlcnZhbCArIGFuclRocmVzaG9sZCkgewogICAgICB0cmlnZ2VyZWQgPSBmYWxzZTsKICAgIH0KICB9LCAyMCk7CgogIHJldHVybiB7CiAgICBwb2xsOiAoKSA9PiB7CiAgICAgIHRpbWVyLnJlc2V0KCk7CiAgICB9LAogICAgZW5hYmxlZDogKHN0YXRlKSA9PiB7CiAgICAgIGVuYWJsZWQgPSBzdGF0ZTsKICAgIH0sCiAgfTsKfQoKLy8gdHlwZXMgY29waWVkIGZyb20gaW5zcGVjdG9yLmQudHMKCi8qKgogKiBDb252ZXJ0cyBEZWJ1Z2dlci5DYWxsRnJhbWUgdG8gU2VudHJ5IFN0YWNrRnJhbWUKICovCmZ1bmN0aW9uIGNhbGxGcmFtZVRvU3RhY2tGcmFtZSgKICBmcmFtZSwKICB1cmwsCiAgZ2V0TW9kdWxlRnJvbUZpbGVuYW1lLAopIHsKICBjb25zdCBmaWxlbmFtZSA9IHVybCA/IHVybC5yZXBsYWNlKC9eZmlsZTpcL1wvLywgJycpIDogdW5kZWZpbmVkOwoKICAvLyBDYWxsRnJhbWUgcm93L2NvbCBhcmUgMCBiYXNlZCwgd2hlcmVhcyBTdGFja0ZyYW1lIGFyZSAxIGJhc2VkCiAgY29uc3QgY29sbm8gPSBmcmFtZS5sb2NhdGlvbi5jb2x1bW5OdW1iZXIgPyBmcmFtZS5sb2NhdGlvbi5jb2x1bW5OdW1iZXIgKyAxIDogdW5kZWZpbmVkOwogIGNvbnN0IGxpbmVubyA9IGZyYW1lLmxvY2F0aW9uLmxpbmVOdW1iZXIgPyBmcmFtZS5sb2NhdGlvbi5saW5lTnVtYmVyICsgMSA6IHVuZGVmaW5lZDsKCiAgcmV0dXJuIGRyb3BVbmRlZmluZWRLZXlzKHsKICAgIGZpbGVuYW1lLAogICAgbW9kdWxlOiBnZXRNb2R1bGVGcm9tRmlsZW5hbWUoZmlsZW5hbWUpLAogICAgZnVuY3Rpb246IGZyYW1lLmZ1bmN0aW9uTmFtZSB8fCAnPycsCiAgICBjb2xubywKICAgIGxpbmVubywKICAgIGluX2FwcDogZmlsZW5hbWUgPyBmaWxlbmFtZUlzSW5BcHAoZmlsZW5hbWUpIDogdW5kZWZpbmVkLAogIH0pOwp9CgovKioKICogVGhpcyBzZXJ2ZXMgYXMgYSBidWlsZCB0aW1lIGZsYWcgdGhhdCB3aWxsIGJlIHRydWUgYnkgZGVmYXVsdCwgYnV0IGZhbHNlIGluIG5vbi1kZWJ1ZyBidWlsZHMgb3IgaWYgdXNlcnMgcmVwbGFjZSBgX19TRU5UUllfREVCVUdfX2AgaW4gdGhlaXIgZ2VuZXJhdGVkIGNvZGUuCiAqCiAqIEFUVEVOVElPTjogVGhpcyBjb25zdGFudCBtdXN0IG5ldmVyIGNyb3NzIHBhY2thZ2UgYm91bmRhcmllcyAoaS5lLiBiZSBleHBvcnRlZCkgdG8gZ3VhcmFudGVlIHRoYXQgaXQgY2FuIGJlIHVzZWQgZm9yIHRyZWUgc2hha2luZy4KICovCmNvbnN0IERFQlVHX0JVSUxEID0gKHR5cGVvZiBfX1NFTlRSWV9ERUJVR19fID09PSAndW5kZWZpbmVkJyB8fCBfX1NFTlRSWV9ERUJVR19fKTsKCmNvbnN0IERFRkFVTFRfRU5WSVJPTk1FTlQgPSAncHJvZHVjdGlvbic7CgovKioKICogUmV0dXJucyB0aGUgZ2xvYmFsIGV2ZW50IHByb2Nlc3NvcnMuCiAqIEBkZXByZWNhdGVkIEdsb2JhbCBldmVudCBwcm9jZXNzb3JzIHdpbGwgYmUgcmVtb3ZlZCBpbiB2OC4KICovCmZ1bmN0aW9uIGdldEdsb2JhbEV2ZW50UHJvY2Vzc29ycygpIHsKICByZXR1cm4gZ2V0R2xvYmFsU2luZ2xldG9uKCdnbG9iYWxFdmVudFByb2Nlc3NvcnMnLCAoKSA9PiBbXSk7Cn0KCi8qKgogKiBQcm9jZXNzIGFuIGFycmF5IG9mIGV2ZW50IHByb2Nlc3NvcnMsIHJldHVybmluZyB0aGUgcHJvY2Vzc2VkIGV2ZW50IChvciBgbnVsbGAgaWYgdGhlIGV2ZW50IHdhcyBkcm9wcGVkKS4KICovCmZ1bmN0aW9uIG5vdGlmeUV2ZW50UHJvY2Vzc29ycygKICBwcm9jZXNzb3JzLAogIGV2ZW50LAogIGhpbnQsCiAgaW5kZXggPSAwLAopIHsKICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgIGNvbnN0IHByb2Nlc3NvciA9IHByb2Nlc3NvcnNbaW5kZXhdOwogICAgaWYgKGV2ZW50ID09PSBudWxsIHx8IHR5cGVvZiBwcm9jZXNzb3IgIT09ICdmdW5jdGlvbicpIHsKICAgICAgcmVzb2x2ZShldmVudCk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCByZXN1bHQgPSBwcm9jZXNzb3IoeyAuLi5ldmVudCB9LCBoaW50KSA7CgogICAgICBERUJVR19CVUlMRCAmJiBwcm9jZXNzb3IuaWQgJiYgcmVzdWx0ID09PSBudWxsICYmIGxvZ2dlci5sb2coYEV2ZW50IHByb2Nlc3NvciAiJHtwcm9jZXNzb3IuaWR9IiBkcm9wcGVkIGV2ZW50YCk7CgogICAgICBpZiAoaXNUaGVuYWJsZShyZXN1bHQpKSB7CiAgICAgICAgdm9pZCByZXN1bHQKICAgICAgICAgIC50aGVuKGZpbmFsID0+IG5vdGlmeUV2ZW50UHJvY2Vzc29ycyhwcm9jZXNzb3JzLCBmaW5hbCwgaGludCwgaW5kZXggKyAxKS50aGVuKHJlc29sdmUpKQogICAgICAgICAgLnRoZW4obnVsbCwgcmVqZWN0KTsKICAgICAgfSBlbHNlIHsKICAgICAgICB2b2lkIG5vdGlmeUV2ZW50UHJvY2Vzc29ycyhwcm9jZXNzb3JzLCByZXN1bHQsIGhpbnQsIGluZGV4ICsgMSkKICAgICAgICAgIC50aGVuKHJlc29sdmUpCiAgICAgICAgICAudGhlbihudWxsLCByZWplY3QpOwogICAgICB9CiAgICB9CiAgfSk7Cn0KCi8qKgogKiBDcmVhdGVzIGEgbmV3IGBTZXNzaW9uYCBvYmplY3QgYnkgc2V0dGluZyBjZXJ0YWluIGRlZmF1bHQgcGFyYW1ldGVycy4gSWYgb3B0aW9uYWwgQHBhcmFtIGNvbnRleHQKICogaXMgcGFzc2VkLCB0aGUgcGFzc2VkIHByb3BlcnRpZXMgYXJlIGFwcGxpZWQgdG8gdGhlIHNlc3Npb24gb2JqZWN0LgogKgogKiBAcGFyYW0gY29udGV4dCAob3B0aW9uYWwpIGFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBiZSBhcHBsaWVkIHRvIHRoZSByZXR1cm5lZCBzZXNzaW9uIG9iamVjdAogKgogKiBAcmV0dXJucyBhIG5ldyBgU2Vzc2lvbmAgb2JqZWN0CiAqLwpmdW5jdGlvbiBtYWtlU2Vzc2lvbihjb250ZXh0KSB7CiAgLy8gQm90aCB0aW1lc3RhbXAgYW5kIHN0YXJ0ZWQgYXJlIGluIHNlY29uZHMgc2luY2UgdGhlIFVOSVggZXBvY2guCiAgY29uc3Qgc3RhcnRpbmdUaW1lID0gdGltZXN0YW1wSW5TZWNvbmRzKCk7CgogIGNvbnN0IHNlc3Npb24gPSB7CiAgICBzaWQ6IHV1aWQ0KCksCiAgICBpbml0OiB0cnVlLAogICAgdGltZXN0YW1wOiBzdGFydGluZ1RpbWUsCiAgICBzdGFydGVkOiBzdGFydGluZ1RpbWUsCiAgICBkdXJhdGlvbjogMCwKICAgIHN0YXR1czogJ29rJywKICAgIGVycm9yczogMCwKICAgIGlnbm9yZUR1cmF0aW9uOiBmYWxzZSwKICAgIHRvSlNPTjogKCkgPT4gc2Vzc2lvblRvSlNPTihzZXNzaW9uKSwKICB9OwoKICBpZiAoY29udGV4dCkgewogICAgdXBkYXRlU2Vzc2lvbihzZXNzaW9uLCBjb250ZXh0KTsKICB9CgogIHJldHVybiBzZXNzaW9uOwp9CgovKioKICogVXBkYXRlcyBhIHNlc3Npb24gb2JqZWN0IHdpdGggdGhlIHByb3BlcnRpZXMgcGFzc2VkIGluIHRoZSBjb250ZXh0LgogKgogKiBOb3RlIHRoYXQgdGhpcyBmdW5jdGlvbiBtdXRhdGVzIHRoZSBwYXNzZWQgb2JqZWN0IGFuZCByZXR1cm5zIHZvaWQuCiAqIChIYWQgdG8gZG8gdGhpcyBpbnN0ZWFkIG9mIHJldHVybmluZyBhIG5ldyBhbmQgdXBkYXRlZCBzZXNzaW9uIGJlY2F1c2UgY2xvc2luZyBhbmQgc2VuZGluZyBhIHNlc3Npb24KICogbWFrZXMgYW4gdXBkYXRlIHRvIHRoZSBzZXNzaW9uIGFmdGVyIGl0IHdhcyBwYXNzZWQgdG8gdGhlIHNlbmRpbmcgbG9naWMuCiAqIEBzZWUgQmFzZUNsaWVudC5jYXB0dXJlU2Vzc2lvbiApCiAqCiAqIEBwYXJhbSBzZXNzaW9uIHRoZSBgU2Vzc2lvbmAgdG8gdXBkYXRlCiAqIEBwYXJhbSBjb250ZXh0IHRoZSBgU2Vzc2lvbkNvbnRleHRgIGhvbGRpbmcgdGhlIHByb3BlcnRpZXMgdGhhdCBzaG91bGQgYmUgdXBkYXRlZCBpbiBAcGFyYW0gc2Vzc2lvbgogKi8KLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbXBsZXhpdHkKZnVuY3Rpb24gdXBkYXRlU2Vzc2lvbihzZXNzaW9uLCBjb250ZXh0ID0ge30pIHsKICBpZiAoY29udGV4dC51c2VyKSB7CiAgICBpZiAoIXNlc3Npb24uaXBBZGRyZXNzICYmIGNvbnRleHQudXNlci5pcF9hZGRyZXNzKSB7CiAgICAgIHNlc3Npb24uaXBBZGRyZXNzID0gY29udGV4dC51c2VyLmlwX2FkZHJlc3M7CiAgICB9CgogICAgaWYgKCFzZXNzaW9uLmRpZCAmJiAhY29udGV4dC5kaWQpIHsKICAgICAgc2Vzc2lvbi5kaWQgPSBjb250ZXh0LnVzZXIuaWQgfHwgY29udGV4dC51c2VyLmVtYWlsIHx8IGNvbnRleHQudXNlci51c2VybmFtZTsKICAgIH0KICB9CgogIHNlc3Npb24udGltZXN0YW1wID0gY29udGV4dC50aW1lc3RhbXAgfHwgdGltZXN0YW1wSW5TZWNvbmRzKCk7CgogIGlmIChjb250ZXh0LmFibm9ybWFsX21lY2hhbmlzbSkgewogICAgc2Vzc2lvbi5hYm5vcm1hbF9tZWNoYW5pc20gPSBjb250ZXh0LmFibm9ybWFsX21lY2hhbmlzbTsKICB9CgogIGlmIChjb250ZXh0Lmlnbm9yZUR1cmF0aW9uKSB7CiAgICBzZXNzaW9uLmlnbm9yZUR1cmF0aW9uID0gY29udGV4dC5pZ25vcmVEdXJhdGlvbjsKICB9CiAgaWYgKGNvbnRleHQuc2lkKSB7CiAgICAvLyBHb29kIGVub3VnaCB1dWlkIHZhbGlkYXRpb24uIOKAlCBLYW1pbAogICAgc2Vzc2lvbi5zaWQgPSBjb250ZXh0LnNpZC5sZW5ndGggPT09IDMyID8gY29udGV4dC5zaWQgOiB1dWlkNCgpOwogIH0KICBpZiAoY29udGV4dC5pbml0ICE9PSB1bmRlZmluZWQpIHsKICAgIHNlc3Npb24uaW5pdCA9IGNvbnRleHQuaW5pdDsKICB9CiAgaWYgKCFzZXNzaW9uLmRpZCAmJiBjb250ZXh0LmRpZCkgewogICAgc2Vzc2lvbi5kaWQgPSBgJHtjb250ZXh0LmRpZH1gOwogIH0KICBpZiAodHlwZW9mIGNvbnRleHQuc3RhcnRlZCA9PT0gJ251bWJlcicpIHsKICAgIHNlc3Npb24uc3RhcnRlZCA9IGNvbnRleHQuc3RhcnRlZDsKICB9CiAgaWYgKHNlc3Npb24uaWdub3JlRHVyYXRpb24pIHsKICAgIHNlc3Npb24uZHVyYXRpb24gPSB1bmRlZmluZWQ7CiAgfSBlbHNlIGlmICh0eXBlb2YgY29udGV4dC5kdXJhdGlvbiA9PT0gJ251bWJlcicpIHsKICAgIHNlc3Npb24uZHVyYXRpb24gPSBjb250ZXh0LmR1cmF0aW9uOwogIH0gZWxzZSB7CiAgICBjb25zdCBkdXJhdGlvbiA9IHNlc3Npb24udGltZXN0YW1wIC0gc2Vzc2lvbi5zdGFydGVkOwogICAgc2Vzc2lvbi5kdXJhdGlvbiA9IGR1cmF0aW9uID49IDAgPyBkdXJhdGlvbiA6IDA7CiAgfQogIGlmIChjb250ZXh0LnJlbGVhc2UpIHsKICAgIHNlc3Npb24ucmVsZWFzZSA9IGNvbnRleHQucmVsZWFzZTsKICB9CiAgaWYgKGNvbnRleHQuZW52aXJvbm1lbnQpIHsKICAgIHNlc3Npb24uZW52aXJvbm1lbnQgPSBjb250ZXh0LmVudmlyb25tZW50OwogIH0KICBpZiAoIXNlc3Npb24uaXBBZGRyZXNzICYmIGNvbnRleHQuaXBBZGRyZXNzKSB7CiAgICBzZXNzaW9uLmlwQWRkcmVzcyA9IGNvbnRleHQuaXBBZGRyZXNzOwogIH0KICBpZiAoIXNlc3Npb24udXNlckFnZW50ICYmIGNvbnRleHQudXNlckFnZW50KSB7CiAgICBzZXNzaW9uLnVzZXJBZ2VudCA9IGNvbnRleHQudXNlckFnZW50OwogIH0KICBpZiAodHlwZW9mIGNvbnRleHQuZXJyb3JzID09PSAnbnVtYmVyJykgewogICAgc2Vzc2lvbi5lcnJvcnMgPSBjb250ZXh0LmVycm9yczsKICB9CiAgaWYgKGNvbnRleHQuc3RhdHVzKSB7CiAgICBzZXNzaW9uLnN0YXR1cyA9IGNvbnRleHQuc3RhdHVzOwogIH0KfQoKLyoqCiAqIENsb3NlcyBhIHNlc3Npb24gYnkgc2V0dGluZyBpdHMgc3RhdHVzIGFuZCB1cGRhdGluZyB0aGUgc2Vzc2lvbiBvYmplY3Qgd2l0aCBpdC4KICogSW50ZXJuYWxseSBjYWxscyBgdXBkYXRlU2Vzc2lvbmAgdG8gdXBkYXRlIHRoZSBwYXNzZWQgc2Vzc2lvbiBvYmplY3QuCiAqCiAqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIG11dGF0ZXMgdGhlIHBhc3NlZCBzZXNzaW9uIChAc2VlIHVwZGF0ZVNlc3Npb24gZm9yIGV4cGxhbmF0aW9uKS4KICoKICogQHBhcmFtIHNlc3Npb24gdGhlIGBTZXNzaW9uYCBvYmplY3QgdG8gYmUgY2xvc2VkCiAqIEBwYXJhbSBzdGF0dXMgdGhlIGBTZXNzaW9uU3RhdHVzYCB3aXRoIHdoaWNoIHRoZSBzZXNzaW9uIHdhcyBjbG9zZWQuIElmIHlvdSBkb24ndCBwYXNzIGEgc3RhdHVzLAogKiAgICAgICAgICAgICAgIHRoaXMgZnVuY3Rpb24gd2lsbCBrZWVwIHRoZSBwcmV2aW91c2x5IHNldCBzdGF0dXMsIHVubGVzcyBpdCB3YXMgYCdvaydgIGluIHdoaWNoIGNhc2UKICogICAgICAgICAgICAgICBpdCBpcyBjaGFuZ2VkIHRvIGAnZXhpdGVkJ2AuCiAqLwpmdW5jdGlvbiBjbG9zZVNlc3Npb24oc2Vzc2lvbiwgc3RhdHVzKSB7CiAgbGV0IGNvbnRleHQgPSB7fTsKICBpZiAoc3RhdHVzKSB7CiAgICBjb250ZXh0ID0geyBzdGF0dXMgfTsKICB9IGVsc2UgaWYgKHNlc3Npb24uc3RhdHVzID09PSAnb2snKSB7CiAgICBjb250ZXh0ID0geyBzdGF0dXM6ICdleGl0ZWQnIH07CiAgfQoKICB1cGRhdGVTZXNzaW9uKHNlc3Npb24sIGNvbnRleHQpOwp9CgovKioKICogU2VyaWFsaXplcyBhIHBhc3NlZCBzZXNzaW9uIG9iamVjdCB0byBhIEpTT04gb2JqZWN0IHdpdGggYSBzbGlnaHRseSBkaWZmZXJlbnQgc3RydWN0dXJlLgogKiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHRoZSBTZW50cnkgYmFja2VuZCByZXF1aXJlcyBhIHNsaWdodGx5IGRpZmZlcmVudCBzY2hlbWEgb2YgYSBzZXNzaW9uCiAqIHRoYW4gdGhlIG9uZSB0aGUgSlMgU0RLcyB1c2UgaW50ZXJuYWxseS4KICoKICogQHBhcmFtIHNlc3Npb24gdGhlIHNlc3Npb24gdG8gYmUgY29udmVydGVkCiAqCiAqIEByZXR1cm5zIGEgSlNPTiBvYmplY3Qgb2YgdGhlIHBhc3NlZCBzZXNzaW9uCiAqLwpmdW5jdGlvbiBzZXNzaW9uVG9KU09OKHNlc3Npb24pIHsKICByZXR1cm4gZHJvcFVuZGVmaW5lZEtleXMoewogICAgc2lkOiBgJHtzZXNzaW9uLnNpZH1gLAogICAgaW5pdDogc2Vzc2lvbi5pbml0LAogICAgLy8gTWFrZSBzdXJlIHRoYXQgc2VjIGlzIGNvbnZlcnRlZCB0byBtcyBmb3IgZGF0ZSBjb25zdHJ1Y3RvcgogICAgc3RhcnRlZDogbmV3IERhdGUoc2Vzc2lvbi5zdGFydGVkICogMTAwMCkudG9JU09TdHJpbmcoKSwKICAgIHRpbWVzdGFtcDogbmV3IERhdGUoc2Vzc2lvbi50aW1lc3RhbXAgKiAxMDAwKS50b0lTT1N0cmluZygpLAogICAgc3RhdHVzOiBzZXNzaW9uLnN0YXR1cywKICAgIGVycm9yczogc2Vzc2lvbi5lcnJvcnMsCiAgICBkaWQ6IHR5cGVvZiBzZXNzaW9uLmRpZCA9PT0gJ251bWJlcicgfHwgdHlwZW9mIHNlc3Npb24uZGlkID09PSAnc3RyaW5nJyA/IGAke3Nlc3Npb24uZGlkfWAgOiB1bmRlZmluZWQsCiAgICBkdXJhdGlvbjogc2Vzc2lvbi5kdXJhdGlvbiwKICAgIGFibm9ybWFsX21lY2hhbmlzbTogc2Vzc2lvbi5hYm5vcm1hbF9tZWNoYW5pc20sCiAgICBhdHRyczogewogICAgICByZWxlYXNlOiBzZXNzaW9uLnJlbGVhc2UsCiAgICAgIGVudmlyb25tZW50OiBzZXNzaW9uLmVudmlyb25tZW50LAogICAgICBpcF9hZGRyZXNzOiBzZXNzaW9uLmlwQWRkcmVzcywKICAgICAgdXNlcl9hZ2VudDogc2Vzc2lvbi51c2VyQWdlbnQsCiAgICB9LAogIH0pOwp9Cgpjb25zdCBUUkFDRV9GTEFHX1NBTVBMRUQgPSAweDE7CgovKioKICogQ29udmVydCBhIHNwYW4gdG8gYSB0cmFjZSBjb250ZXh0LCB3aGljaCBjYW4gYmUgc2VudCBhcyB0aGUgYHRyYWNlYCBjb250ZXh0IGluIGFuIGV2ZW50LgogKi8KZnVuY3Rpb24gc3BhblRvVHJhY2VDb250ZXh0KHNwYW4pIHsKICBjb25zdCB7IHNwYW5JZDogc3Bhbl9pZCwgdHJhY2VJZDogdHJhY2VfaWQgfSA9IHNwYW4uc3BhbkNvbnRleHQoKTsKICBjb25zdCB7IGRhdGEsIG9wLCBwYXJlbnRfc3Bhbl9pZCwgc3RhdHVzLCB0YWdzLCBvcmlnaW4gfSA9IHNwYW5Ub0pTT04oc3Bhbik7CgogIHJldHVybiBkcm9wVW5kZWZpbmVkS2V5cyh7CiAgICBkYXRhLAogICAgb3AsCiAgICBwYXJlbnRfc3Bhbl9pZCwKICAgIHNwYW5faWQsCiAgICBzdGF0dXMsCiAgICB0YWdzLAogICAgdHJhY2VfaWQsCiAgICBvcmlnaW4sCiAgfSk7Cn0KCi8qKgogKiBDb252ZXJ0IGEgc3BhbiB0byBhIEpTT04gcmVwcmVzZW50YXRpb24uCiAqIE5vdGUgdGhhdCBhbGwgZmllbGRzIHJldHVybmVkIGhlcmUgYXJlIG9wdGlvbmFsIGFuZCBuZWVkIHRvIGJlIGd1YXJkZWQgYWdhaW5zdC4KICoKICogTm90ZTogQmVjYXVzZSBvZiB0aGlzLCB3ZSBjdXJyZW50bHkgaGF2ZSBhIGNpcmN1bGFyIHR5cGUgZGVwZW5kZW5jeSAod2hpY2ggd2Ugb3B0ZWQgb3V0IG9mIGluIHBhY2thZ2UuanNvbikuCiAqIFRoaXMgaXMgbm90IGF2b2lkYWJsZSBhcyB3ZSBuZWVkIGBzcGFuVG9KU09OYCBpbiBgc3BhblV0aWxzLnRzYCwgd2hpY2ggaW4gdHVybiBpcyBuZWVkZWQgYnkgYHNwYW4udHNgIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS4KICogQW5kIGBzcGFuVG9KU09OYCBuZWVkcyB0aGUgU3BhbiBjbGFzcyBmcm9tIGBzcGFuLnRzYCB0byBjaGVjayBoZXJlLgogKiBUT0RPIHY4OiBXaGVuIHdlIHJlbW92ZSB0aGUgZGVwcmVjYXRlZCBzdHVmZiBmcm9tIGBzcGFuLnRzYCwgd2UgY2FuIHJlbW92ZSB0aGUgY2lyY3VsYXIgZGVwZW5kZW5jeSBhZ2Fpbi4KICovCmZ1bmN0aW9uIHNwYW5Ub0pTT04oc3BhbikgewogIGlmIChzcGFuSXNTcGFuQ2xhc3Moc3BhbikpIHsKICAgIHJldHVybiBzcGFuLmdldFNwYW5KU09OKCk7CiAgfQoKICAvLyBGYWxsYmFjazogV2UgYWxzbyBjaGVjayBmb3IgYC50b0pTT04oKWAgaGVyZS4uLgogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogIGlmICh0eXBlb2Ygc3Bhbi50b0pTT04gPT09ICdmdW5jdGlvbicpIHsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgcmV0dXJuIHNwYW4udG9KU09OKCk7CiAgfQoKICByZXR1cm4ge307Cn0KCi8qKgogKiBTYWRseSwgZHVlIHRvIGNpcmN1bGFyIGRlcGVuZGVuY3kgY2hlY2tzIHdlIGNhbm5vdCBhY3R1YWxseSBpbXBvcnQgdGhlIFNwYW4gY2xhc3MgaGVyZSBhbmQgY2hlY2sgZm9yIGluc3RhbmNlb2YuCiAqIDooIFNvIGluc3RlYWQgd2UgYXBwcm94aW1hdGUgdGhpcyBieSBjaGVja2luZyBpZiBpdCBoYXMgdGhlIGBnZXRTcGFuSlNPTmAgbWV0aG9kLgogKi8KZnVuY3Rpb24gc3BhbklzU3BhbkNsYXNzKHNwYW4pIHsKICByZXR1cm4gdHlwZW9mIChzcGFuICkuZ2V0U3BhbkpTT04gPT09ICdmdW5jdGlvbic7Cn0KCi8qKgogKiBSZXR1cm5zIHRydWUgaWYgYSBzcGFuIGlzIHNhbXBsZWQuCiAqIEluIG1vc3QgY2FzZXMsIHlvdSBzaG91bGQganVzdCB1c2UgYHNwYW4uaXNSZWNvcmRpbmcoKWAgaW5zdGVhZC4KICogSG93ZXZlciwgdGhpcyBoYXMgYSBzbGlnaHRseSBkaWZmZXJlbnQgc2VtYW50aWMsIGFzIGl0IGFsc28gcmV0dXJucyBmYWxzZSBpZiB0aGUgc3BhbiBpcyBmaW5pc2hlZC4KICogU28gaW4gdGhlIGNhc2Ugd2hlcmUgdGhpcyBkaXN0aW5jdGlvbiBpcyBpbXBvcnRhbnQsIHVzZSB0aGlzIG1ldGhvZC4KICovCmZ1bmN0aW9uIHNwYW5Jc1NhbXBsZWQoc3BhbikgewogIC8vIFdlIGFsaWduIG91ciB0cmFjZSBmbGFncyB3aXRoIHRoZSBvbmVzIE9wZW5UZWxlbWV0cnkgdXNlCiAgLy8gU28gd2UgYWxzbyBjaGVjayBmb3Igc2FtcGxlZCB0aGUgc2FtZSB3YXkgdGhleSBkby4KICBjb25zdCB7IHRyYWNlRmxhZ3MgfSA9IHNwYW4uc3BhbkNvbnRleHQoKTsKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZQogIHJldHVybiBCb29sZWFuKHRyYWNlRmxhZ3MgJiBUUkFDRV9GTEFHX1NBTVBMRUQpOwp9CgovKioKICogR2V0IHRoZSBjdXJyZW50bHkgYWN0aXZlIGNsaWVudC4KICovCmZ1bmN0aW9uIGdldENsaWVudCgpIHsKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICByZXR1cm4gZ2V0Q3VycmVudEh1YigpLmdldENsaWVudCgpOwp9CgovKioKICogR2V0IHRoZSBjdXJyZW50bHkgYWN0aXZlIHNjb3BlLgogKi8KZnVuY3Rpb24gZ2V0Q3VycmVudFNjb3BlKCkgewogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogIHJldHVybiBnZXRDdXJyZW50SHViKCkuZ2V0U2NvcGUoKTsKfQoKLyoqCiAqIFJldHVybnMgdGhlIHJvb3Qgc3BhbiBvZiBhIGdpdmVuIHNwYW4uCiAqCiAqIEFzIGxvbmcgYXMgd2UgdXNlIGBUcmFuc2FjdGlvbmBzIGludGVybmFsbHksIHRoZSByZXR1cm5lZCByb290IHNwYW4KICogd2lsbCBiZSBhIGBUcmFuc2FjdGlvbmAgYnV0IGJlIGF3YXJlIHRoYXQgdGhpcyBtaWdodCBjaGFuZ2UgaW4gdGhlIGZ1dHVyZS4KICoKICogSWYgdGhlIGdpdmVuIHNwYW4gaGFzIG5vIHJvb3Qgc3BhbiBvciB0cmFuc2FjdGlvbiwgYHVuZGVmaW5lZGAgaXMgcmV0dXJuZWQuCiAqLwpmdW5jdGlvbiBnZXRSb290U3BhbihzcGFuKSB7CiAgLy8gVE9ETyAodjgpOiBSZW1vdmUgdGhpcyBjaGVjayBhbmQganVzdCByZXR1cm4gc3BhbgogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogIHJldHVybiBzcGFuLnRyYW5zYWN0aW9uOwp9CgovKioKICogQ3JlYXRlcyBhIGR5bmFtaWMgc2FtcGxpbmcgY29udGV4dCBmcm9tIGEgY2xpZW50LgogKgogKiBEaXNwYXRjaGVzIHRoZSBgY3JlYXRlRHNjYCBsaWZlY3ljbGUgaG9vayBhcyBhIHNpZGUgZWZmZWN0LgogKi8KZnVuY3Rpb24gZ2V0RHluYW1pY1NhbXBsaW5nQ29udGV4dEZyb21DbGllbnQoCiAgdHJhY2VfaWQsCiAgY2xpZW50LAogIHNjb3BlLAopIHsKICBjb25zdCBvcHRpb25zID0gY2xpZW50LmdldE9wdGlvbnMoKTsKCiAgY29uc3QgeyBwdWJsaWNLZXk6IHB1YmxpY19rZXkgfSA9IGNsaWVudC5nZXREc24oKSB8fCB7fTsKICAvLyBUT0RPKHY4KTogUmVtb3ZlIHNlZ21lbnQgZnJvbSBVc2VyCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgY29uc3QgeyBzZWdtZW50OiB1c2VyX3NlZ21lbnQgfSA9IChzY29wZSAmJiBzY29wZS5nZXRVc2VyKCkpIHx8IHt9OwoKICBjb25zdCBkc2MgPSBkcm9wVW5kZWZpbmVkS2V5cyh7CiAgICBlbnZpcm9ubWVudDogb3B0aW9ucy5lbnZpcm9ubWVudCB8fCBERUZBVUxUX0VOVklST05NRU5ULAogICAgcmVsZWFzZTogb3B0aW9ucy5yZWxlYXNlLAogICAgdXNlcl9zZWdtZW50LAogICAgcHVibGljX2tleSwKICAgIHRyYWNlX2lkLAogIH0pIDsKCiAgY2xpZW50LmVtaXQgJiYgY2xpZW50LmVtaXQoJ2NyZWF0ZURzYycsIGRzYyk7CgogIHJldHVybiBkc2M7Cn0KCi8qKgogKiBBIFNwYW4gd2l0aCBhIGZyb3plbiBkeW5hbWljIHNhbXBsaW5nIGNvbnRleHQuCiAqLwoKLyoqCiAqIENyZWF0ZXMgYSBkeW5hbWljIHNhbXBsaW5nIGNvbnRleHQgZnJvbSBhIHNwYW4gKGFuZCBjbGllbnQgYW5kIHNjb3BlKQogKgogKiBAcGFyYW0gc3BhbiB0aGUgc3BhbiBmcm9tIHdoaWNoIGEgZmV3IHZhbHVlcyBsaWtlIHRoZSByb290IHNwYW4gbmFtZSBhbmQgc2FtcGxlIHJhdGUgYXJlIGV4dHJhY3RlZC4KICoKICogQHJldHVybnMgYSBkeW5hbWljIHNhbXBsaW5nIGNvbnRleHQKICovCmZ1bmN0aW9uIGdldER5bmFtaWNTYW1wbGluZ0NvbnRleHRGcm9tU3BhbihzcGFuKSB7CiAgY29uc3QgY2xpZW50ID0gZ2V0Q2xpZW50KCk7CiAgaWYgKCFjbGllbnQpIHsKICAgIHJldHVybiB7fTsKICB9CgogIC8vIHBhc3NpbmcgZW1pdD1mYWxzZSBoZXJlIHRvIG9ubHkgZW1pdCBsYXRlciBvbmNlIHRoZSBEU0MgaXMgYWN0dWFsbHkgcG9wdWxhdGVkCiAgY29uc3QgZHNjID0gZ2V0RHluYW1pY1NhbXBsaW5nQ29udGV4dEZyb21DbGllbnQoc3BhblRvSlNPTihzcGFuKS50cmFjZV9pZCB8fCAnJywgY2xpZW50LCBnZXRDdXJyZW50U2NvcGUoKSk7CgogIC8vIFRPRE8gKHY4KTogUmVtb3ZlIHY3RnJvemVuRHNjIGFzIGEgVHJhbnNhY3Rpb24gd2lsbCBubyBsb25nZXIgaGF2ZSBfZnJvemVuRHluYW1pY1NhbXBsaW5nQ29udGV4dAogIGNvbnN0IHR4biA9IGdldFJvb3RTcGFuKHNwYW4pIDsKICBpZiAoIXR4bikgewogICAgcmV0dXJuIGRzYzsKICB9CgogIC8vIFRPRE8gKHY4KTogUmVtb3ZlIHY3RnJvemVuRHNjIGFzIGEgVHJhbnNhY3Rpb24gd2lsbCBubyBsb25nZXIgaGF2ZSBfZnJvemVuRHluYW1pY1NhbXBsaW5nQ29udGV4dAogIC8vIEZvciBub3cgd2UgbmVlZCB0byBhdm9pZCBicmVha2luZyB1c2VycyB3aG8gZGlyZWN0bHkgY3JlYXRlZCBhIHR4biB3aXRoIGEgRFNDLCB3aGVyZSB0aGlzIGZpZWxkIGlzIHN0aWxsIHNldC4KICAvLyBAc2VlIFRyYW5zYWN0aW9uIGNsYXNzIGNvbnN0cnVjdG9yCiAgY29uc3QgdjdGcm96ZW5Ec2MgPSB0eG4gJiYgdHhuLl9mcm96ZW5EeW5hbWljU2FtcGxpbmdDb250ZXh0OwogIGlmICh2N0Zyb3plbkRzYykgewogICAgcmV0dXJuIHY3RnJvemVuRHNjOwogIH0KCiAgLy8gVE9ETyAodjgpOiBSZXBsYWNlIHR4bi5tZXRhZGF0YSB3aXRoIHR4bi5hdHRyaWJ1dGVzW10KICAvLyBXZSBjYW4ndCBkbyB0aGlzIHlldCBiZWNhdXNlIGF0dHJpYnV0ZXMgYXJlbid0IGFsd2F5cyBzZXQgeWV0LgogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogIGNvbnN0IHsgc2FtcGxlUmF0ZTogbWF5YmVTYW1wbGVSYXRlLCBzb3VyY2UgfSA9IHR4bi5tZXRhZGF0YTsKICBpZiAobWF5YmVTYW1wbGVSYXRlICE9IG51bGwpIHsKICAgIGRzYy5zYW1wbGVfcmF0ZSA9IGAke21heWJlU2FtcGxlUmF0ZX1gOwogIH0KCiAgLy8gV2UgZG9uJ3Qgd2FudCB0byBoYXZlIGEgdHJhbnNhY3Rpb24gbmFtZSBpbiB0aGUgRFNDIGlmIHRoZSBzb3VyY2UgaXMgInVybCIgYmVjYXVzZSBVUkxzIG1pZ2h0IGNvbnRhaW4gUElJCiAgY29uc3QganNvblNwYW4gPSBzcGFuVG9KU09OKHR4bik7CgogIC8vIGFmdGVyIEpTT04gY29udmVyc2lvbiwgdHhuLm5hbWUgYmVjb21lcyBqc29uU3Bhbi5kZXNjcmlwdGlvbgogIGlmIChzb3VyY2UgJiYgc291cmNlICE9PSAndXJsJykgewogICAgZHNjLnRyYW5zYWN0aW9uID0ganNvblNwYW4uZGVzY3JpcHRpb247CiAgfQoKICBkc2Muc2FtcGxlZCA9IFN0cmluZyhzcGFuSXNTYW1wbGVkKHR4bikpOwoKICBjbGllbnQuZW1pdCAmJiBjbGllbnQuZW1pdCgnY3JlYXRlRHNjJywgZHNjKTsKCiAgcmV0dXJuIGRzYzsKfQoKLyoqCiAqIEFwcGxpZXMgZGF0YSBmcm9tIHRoZSBzY29wZSB0byB0aGUgZXZlbnQgYW5kIHJ1bnMgYWxsIGV2ZW50IHByb2Nlc3NvcnMgb24gaXQuCiAqLwpmdW5jdGlvbiBhcHBseVNjb3BlRGF0YVRvRXZlbnQoZXZlbnQsIGRhdGEpIHsKICBjb25zdCB7IGZpbmdlcnByaW50LCBzcGFuLCBicmVhZGNydW1icywgc2RrUHJvY2Vzc2luZ01ldGFkYXRhIH0gPSBkYXRhOwoKICAvLyBBcHBseSBnZW5lcmFsIGRhdGEKICBhcHBseURhdGFUb0V2ZW50KGV2ZW50LCBkYXRhKTsKCiAgLy8gV2Ugd2FudCB0byBzZXQgdGhlIHRyYWNlIGNvbnRleHQgZm9yIG5vcm1hbCBldmVudHMgb25seSBpZiB0aGVyZSBpc24ndCBhbHJlYWR5CiAgLy8gYSB0cmFjZSBjb250ZXh0IG9uIHRoZSBldmVudC4gVGhlcmUgaXMgYSBwcm9kdWN0IGZlYXR1cmUgaW4gcGxhY2Ugd2hlcmUgd2UgbGluawogIC8vIGVycm9ycyB3aXRoIHRyYW5zYWN0aW9uIGFuZCBpdCByZWxpZXMgb24gdGhhdC4KICBpZiAoc3BhbikgewogICAgYXBwbHlTcGFuVG9FdmVudChldmVudCwgc3Bhbik7CiAgfQoKICBhcHBseUZpbmdlcnByaW50VG9FdmVudChldmVudCwgZmluZ2VycHJpbnQpOwogIGFwcGx5QnJlYWRjcnVtYnNUb0V2ZW50KGV2ZW50LCBicmVhZGNydW1icyk7CiAgYXBwbHlTZGtNZXRhZGF0YVRvRXZlbnQoZXZlbnQsIHNka1Byb2Nlc3NpbmdNZXRhZGF0YSk7Cn0KCmZ1bmN0aW9uIGFwcGx5RGF0YVRvRXZlbnQoZXZlbnQsIGRhdGEpIHsKICBjb25zdCB7CiAgICBleHRyYSwKICAgIHRhZ3MsCiAgICB1c2VyLAogICAgY29udGV4dHMsCiAgICBsZXZlbCwKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgdHJhbnNhY3Rpb25OYW1lLAogIH0gPSBkYXRhOwoKICBjb25zdCBjbGVhbmVkRXh0cmEgPSBkcm9wVW5kZWZpbmVkS2V5cyhleHRyYSk7CiAgaWYgKGNsZWFuZWRFeHRyYSAmJiBPYmplY3Qua2V5cyhjbGVhbmVkRXh0cmEpLmxlbmd0aCkgewogICAgZXZlbnQuZXh0cmEgPSB7IC4uLmNsZWFuZWRFeHRyYSwgLi4uZXZlbnQuZXh0cmEgfTsKICB9CgogIGNvbnN0IGNsZWFuZWRUYWdzID0gZHJvcFVuZGVmaW5lZEtleXModGFncyk7CiAgaWYgKGNsZWFuZWRUYWdzICYmIE9iamVjdC5rZXlzKGNsZWFuZWRUYWdzKS5sZW5ndGgpIHsKICAgIGV2ZW50LnRhZ3MgPSB7IC4uLmNsZWFuZWRUYWdzLCAuLi5ldmVudC50YWdzIH07CiAgfQoKICBjb25zdCBjbGVhbmVkVXNlciA9IGRyb3BVbmRlZmluZWRLZXlzKHVzZXIpOwogIGlmIChjbGVhbmVkVXNlciAmJiBPYmplY3Qua2V5cyhjbGVhbmVkVXNlcikubGVuZ3RoKSB7CiAgICBldmVudC51c2VyID0geyAuLi5jbGVhbmVkVXNlciwgLi4uZXZlbnQudXNlciB9OwogIH0KCiAgY29uc3QgY2xlYW5lZENvbnRleHRzID0gZHJvcFVuZGVmaW5lZEtleXMoY29udGV4dHMpOwogIGlmIChjbGVhbmVkQ29udGV4dHMgJiYgT2JqZWN0LmtleXMoY2xlYW5lZENvbnRleHRzKS5sZW5ndGgpIHsKICAgIGV2ZW50LmNvbnRleHRzID0geyAuLi5jbGVhbmVkQ29udGV4dHMsIC4uLmV2ZW50LmNvbnRleHRzIH07CiAgfQoKICBpZiAobGV2ZWwpIHsKICAgIGV2ZW50LmxldmVsID0gbGV2ZWw7CiAgfQoKICBpZiAodHJhbnNhY3Rpb25OYW1lKSB7CiAgICBldmVudC50cmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uTmFtZTsKICB9Cn0KCmZ1bmN0aW9uIGFwcGx5QnJlYWRjcnVtYnNUb0V2ZW50KGV2ZW50LCBicmVhZGNydW1icykgewogIGNvbnN0IG1lcmdlZEJyZWFkY3J1bWJzID0gWy4uLihldmVudC5icmVhZGNydW1icyB8fCBbXSksIC4uLmJyZWFkY3J1bWJzXTsKICBldmVudC5icmVhZGNydW1icyA9IG1lcmdlZEJyZWFkY3J1bWJzLmxlbmd0aCA/IG1lcmdlZEJyZWFkY3J1bWJzIDogdW5kZWZpbmVkOwp9CgpmdW5jdGlvbiBhcHBseVNka01ldGFkYXRhVG9FdmVudChldmVudCwgc2RrUHJvY2Vzc2luZ01ldGFkYXRhKSB7CiAgZXZlbnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhID0gewogICAgLi4uZXZlbnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLAogICAgLi4uc2RrUHJvY2Vzc2luZ01ldGFkYXRhLAogIH07Cn0KCmZ1bmN0aW9uIGFwcGx5U3BhblRvRXZlbnQoZXZlbnQsIHNwYW4pIHsKICBldmVudC5jb250ZXh0cyA9IHsgdHJhY2U6IHNwYW5Ub1RyYWNlQ29udGV4dChzcGFuKSwgLi4uZXZlbnQuY29udGV4dHMgfTsKICBjb25zdCByb290U3BhbiA9IGdldFJvb3RTcGFuKHNwYW4pOwogIGlmIChyb290U3BhbikgewogICAgZXZlbnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhID0gewogICAgICBkeW5hbWljU2FtcGxpbmdDb250ZXh0OiBnZXREeW5hbWljU2FtcGxpbmdDb250ZXh0RnJvbVNwYW4oc3BhbiksCiAgICAgIC4uLmV2ZW50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YSwKICAgIH07CiAgICBjb25zdCB0cmFuc2FjdGlvbk5hbWUgPSBzcGFuVG9KU09OKHJvb3RTcGFuKS5kZXNjcmlwdGlvbjsKICAgIGlmICh0cmFuc2FjdGlvbk5hbWUpIHsKICAgICAgZXZlbnQudGFncyA9IHsgdHJhbnNhY3Rpb246IHRyYW5zYWN0aW9uTmFtZSwgLi4uZXZlbnQudGFncyB9OwogICAgfQogIH0KfQoKLyoqCiAqIEFwcGxpZXMgZmluZ2VycHJpbnQgZnJvbSB0aGUgc2NvcGUgdG8gdGhlIGV2ZW50IGlmIHRoZXJlJ3Mgb25lLAogKiB1c2VzIG1lc3NhZ2UgaWYgdGhlcmUncyBvbmUgaW5zdGVhZCBvciBnZXQgcmlkIG9mIGVtcHR5IGZpbmdlcnByaW50CiAqLwpmdW5jdGlvbiBhcHBseUZpbmdlcnByaW50VG9FdmVudChldmVudCwgZmluZ2VycHJpbnQpIHsKICAvLyBNYWtlIHN1cmUgaXQncyBhbiBhcnJheSBmaXJzdCBhbmQgd2UgYWN0dWFsbHkgaGF2ZSBzb21ldGhpbmcgaW4gcGxhY2UKICBldmVudC5maW5nZXJwcmludCA9IGV2ZW50LmZpbmdlcnByaW50ID8gYXJyYXlpZnkoZXZlbnQuZmluZ2VycHJpbnQpIDogW107CgogIC8vIElmIHdlIGhhdmUgc29tZXRoaW5nIG9uIHRoZSBzY29wZSwgdGhlbiBtZXJnZSBpdCB3aXRoIGV2ZW50CiAgaWYgKGZpbmdlcnByaW50KSB7CiAgICBldmVudC5maW5nZXJwcmludCA9IGV2ZW50LmZpbmdlcnByaW50LmNvbmNhdChmaW5nZXJwcmludCk7CiAgfQoKICAvLyBJZiB3ZSBoYXZlIG5vIGRhdGEgYXQgYWxsLCByZW1vdmUgZW1wdHkgYXJyYXkgZGVmYXVsdAogIGlmIChldmVudC5maW5nZXJwcmludCAmJiAhZXZlbnQuZmluZ2VycHJpbnQubGVuZ3RoKSB7CiAgICBkZWxldGUgZXZlbnQuZmluZ2VycHJpbnQ7CiAgfQp9CgovKioKICogRGVmYXVsdCB2YWx1ZSBmb3IgbWF4aW11bSBudW1iZXIgb2YgYnJlYWRjcnVtYnMgYWRkZWQgdG8gYW4gZXZlbnQuCiAqLwpjb25zdCBERUZBVUxUX01BWF9CUkVBRENSVU1CUyA9IDEwMDsKCi8qKgogKiBIb2xkcyBhZGRpdGlvbmFsIGV2ZW50IGluZm9ybWF0aW9uLiB7QGxpbmsgU2NvcGUuYXBwbHlUb0V2ZW50fSB3aWxsIGJlCiAqIGNhbGxlZCBieSB0aGUgY2xpZW50IGJlZm9yZSBhbiBldmVudCB3aWxsIGJlIHNlbnQuCiAqLwpjbGFzcyBTY29wZSAgewogIC8qKiBGbGFnIGlmIG5vdGlmeWluZyBpcyBoYXBwZW5pbmcuICovCgogIC8qKiBDYWxsYmFjayBmb3IgY2xpZW50IHRvIHJlY2VpdmUgc2NvcGUgY2hhbmdlcy4gKi8KCiAgLyoqIENhbGxiYWNrIGxpc3QgdGhhdCB3aWxsIGJlIGNhbGxlZCBhZnRlciB7QGxpbmsgYXBwbHlUb0V2ZW50fS4gKi8KCiAgLyoqIEFycmF5IG9mIGJyZWFkY3J1bWJzLiAqLwoKICAvKiogVXNlciAqLwoKICAvKiogVGFncyAqLwoKICAvKiogRXh0cmEgKi8KCiAgLyoqIENvbnRleHRzICovCgogIC8qKiBBdHRhY2htZW50cyAqLwoKICAvKiogUHJvcGFnYXRpb24gQ29udGV4dCBmb3IgZGlzdHJpYnV0ZWQgdHJhY2luZyAqLwoKICAvKioKICAgKiBBIHBsYWNlIHRvIHN0YXNoIGRhdGEgd2hpY2ggaXMgbmVlZGVkIGF0IHNvbWUgcG9pbnQgaW4gdGhlIFNESydzIGV2ZW50IHByb2Nlc3NpbmcgcGlwZWxpbmUgYnV0IHdoaWNoIHNob3VsZG4ndCBnZXQKICAgKiBzZW50IHRvIFNlbnRyeQogICAqLwoKICAvKiogRmluZ2VycHJpbnQgKi8KCiAgLyoqIFNldmVyaXR5ICovCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCgogIC8qKgogICAqIFRyYW5zYWN0aW9uIE5hbWUKICAgKi8KCiAgLyoqIFNwYW4gKi8KCiAgLyoqIFNlc3Npb24gKi8KCiAgLyoqIFJlcXVlc3QgTW9kZSBTZXNzaW9uIFN0YXR1cyAqLwoKICAvKiogVGhlIGNsaWVudCBvbiB0aGlzIHNjb3BlICovCgogIC8vIE5PVEU6IEFueSBmaWVsZCB3aGljaCBnZXRzIGFkZGVkIGhlcmUgc2hvdWxkIGdldCBhZGRlZCBub3Qgb25seSB0byB0aGUgY29uc3RydWN0b3IgYnV0IGFsc28gdG8gdGhlIGBjbG9uZWAgbWV0aG9kLgoKICAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLl9ub3RpZnlpbmdMaXN0ZW5lcnMgPSBmYWxzZTsKICAgIHRoaXMuX3Njb3BlTGlzdGVuZXJzID0gW107CiAgICB0aGlzLl9ldmVudFByb2Nlc3NvcnMgPSBbXTsKICAgIHRoaXMuX2JyZWFkY3J1bWJzID0gW107CiAgICB0aGlzLl9hdHRhY2htZW50cyA9IFtdOwogICAgdGhpcy5fdXNlciA9IHt9OwogICAgdGhpcy5fdGFncyA9IHt9OwogICAgdGhpcy5fZXh0cmEgPSB7fTsKICAgIHRoaXMuX2NvbnRleHRzID0ge307CiAgICB0aGlzLl9zZGtQcm9jZXNzaW5nTWV0YWRhdGEgPSB7fTsKICAgIHRoaXMuX3Byb3BhZ2F0aW9uQ29udGV4dCA9IGdlbmVyYXRlUHJvcGFnYXRpb25Db250ZXh0KCk7CiAgfQoKICAvKioKICAgKiBJbmhlcml0IHZhbHVlcyBmcm9tIHRoZSBwYXJlbnQgc2NvcGUuCiAgICogQGRlcHJlY2F0ZWQgVXNlIGBzY29wZS5jbG9uZSgpYCBhbmQgYG5ldyBTY29wZSgpYCBpbnN0ZWFkLgogICAqLwogICBzdGF0aWMgY2xvbmUoc2NvcGUpIHsKICAgIHJldHVybiBzY29wZSA/IHNjb3BlLmNsb25lKCkgOiBuZXcgU2NvcGUoKTsKICB9CgogIC8qKgogICAqIENsb25lIHRoaXMgc2NvcGUgaW5zdGFuY2UuCiAgICovCiAgIGNsb25lKCkgewogICAgY29uc3QgbmV3U2NvcGUgPSBuZXcgU2NvcGUoKTsKICAgIG5ld1Njb3BlLl9icmVhZGNydW1icyA9IFsuLi50aGlzLl9icmVhZGNydW1ic107CiAgICBuZXdTY29wZS5fdGFncyA9IHsgLi4udGhpcy5fdGFncyB9OwogICAgbmV3U2NvcGUuX2V4dHJhID0geyAuLi50aGlzLl9leHRyYSB9OwogICAgbmV3U2NvcGUuX2NvbnRleHRzID0geyAuLi50aGlzLl9jb250ZXh0cyB9OwogICAgbmV3U2NvcGUuX3VzZXIgPSB0aGlzLl91c2VyOwogICAgbmV3U2NvcGUuX2xldmVsID0gdGhpcy5fbGV2ZWw7CiAgICBuZXdTY29wZS5fc3BhbiA9IHRoaXMuX3NwYW47CiAgICBuZXdTY29wZS5fc2Vzc2lvbiA9IHRoaXMuX3Nlc3Npb247CiAgICBuZXdTY29wZS5fdHJhbnNhY3Rpb25OYW1lID0gdGhpcy5fdHJhbnNhY3Rpb25OYW1lOwogICAgbmV3U2NvcGUuX2ZpbmdlcnByaW50ID0gdGhpcy5fZmluZ2VycHJpbnQ7CiAgICBuZXdTY29wZS5fZXZlbnRQcm9jZXNzb3JzID0gWy4uLnRoaXMuX2V2ZW50UHJvY2Vzc29yc107CiAgICBuZXdTY29wZS5fcmVxdWVzdFNlc3Npb24gPSB0aGlzLl9yZXF1ZXN0U2Vzc2lvbjsKICAgIG5ld1Njb3BlLl9hdHRhY2htZW50cyA9IFsuLi50aGlzLl9hdHRhY2htZW50c107CiAgICBuZXdTY29wZS5fc2RrUHJvY2Vzc2luZ01ldGFkYXRhID0geyAuLi50aGlzLl9zZGtQcm9jZXNzaW5nTWV0YWRhdGEgfTsKICAgIG5ld1Njb3BlLl9wcm9wYWdhdGlvbkNvbnRleHQgPSB7IC4uLnRoaXMuX3Byb3BhZ2F0aW9uQ29udGV4dCB9OwogICAgbmV3U2NvcGUuX2NsaWVudCA9IHRoaXMuX2NsaWVudDsKCiAgICByZXR1cm4gbmV3U2NvcGU7CiAgfQoKICAvKiogVXBkYXRlIHRoZSBjbGllbnQgb24gdGhlIHNjb3BlLiAqLwogICBzZXRDbGllbnQoY2xpZW50KSB7CiAgICB0aGlzLl9jbGllbnQgPSBjbGllbnQ7CiAgfQoKICAvKioKICAgKiBHZXQgdGhlIGNsaWVudCBhc3NpZ25lZCB0byB0aGlzIHNjb3BlLgogICAqCiAgICogSXQgaXMgZ2VuZXJhbGx5IHJlY29tbWVuZGVkIHRvIHVzZSB0aGUgZ2xvYmFsIGZ1bmN0aW9uIGBTZW50cnkuZ2V0Q2xpZW50KClgIGluc3RlYWQsIHVubGVzcyB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmcuCiAgICovCiAgIGdldENsaWVudCgpIHsKICAgIHJldHVybiB0aGlzLl9jbGllbnQ7CiAgfQoKICAvKioKICAgKiBBZGQgaW50ZXJuYWwgb24gY2hhbmdlIGxpc3RlbmVyLiBVc2VkIGZvciBzdWIgU0RLcyB0aGF0IG5lZWQgdG8gc3RvcmUgdGhlIHNjb3BlLgogICAqIEBoaWRkZW4KICAgKi8KICAgYWRkU2NvcGVMaXN0ZW5lcihjYWxsYmFjaykgewogICAgdGhpcy5fc2NvcGVMaXN0ZW5lcnMucHVzaChjYWxsYmFjayk7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqLwogICBhZGRFdmVudFByb2Nlc3NvcihjYWxsYmFjaykgewogICAgdGhpcy5fZXZlbnRQcm9jZXNzb3JzLnB1c2goY2FsbGJhY2spOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqLwogICBzZXRVc2VyKHVzZXIpIHsKICAgIC8vIElmIG51bGwgaXMgcGFzc2VkIHdlIHdhbnQgdG8gdW5zZXQgZXZlcnl0aGluZywgYnV0IHN0aWxsIGRlZmluZSBrZXlzLAogICAgLy8gc28gdGhhdCBsYXRlciBkb3duIGluIHRoZSBwaXBlbGluZSBhbnkgZXhpc3RpbmcgdmFsdWVzIGFyZSBjbGVhcmVkLgogICAgdGhpcy5fdXNlciA9IHVzZXIgfHwgewogICAgICBlbWFpbDogdW5kZWZpbmVkLAogICAgICBpZDogdW5kZWZpbmVkLAogICAgICBpcF9hZGRyZXNzOiB1bmRlZmluZWQsCiAgICAgIHNlZ21lbnQ6IHVuZGVmaW5lZCwKICAgICAgdXNlcm5hbWU6IHVuZGVmaW5lZCwKICAgIH07CgogICAgaWYgKHRoaXMuX3Nlc3Npb24pIHsKICAgICAgdXBkYXRlU2Vzc2lvbih0aGlzLl9zZXNzaW9uLCB7IHVzZXIgfSk7CiAgICB9CgogICAgdGhpcy5fbm90aWZ5U2NvcGVMaXN0ZW5lcnMoKTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKi8KICAgZ2V0VXNlcigpIHsKICAgIHJldHVybiB0aGlzLl91c2VyOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKi8KICAgZ2V0UmVxdWVzdFNlc3Npb24oKSB7CiAgICByZXR1cm4gdGhpcy5fcmVxdWVzdFNlc3Npb247CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqLwogICBzZXRSZXF1ZXN0U2Vzc2lvbihyZXF1ZXN0U2Vzc2lvbikgewogICAgdGhpcy5fcmVxdWVzdFNlc3Npb24gPSByZXF1ZXN0U2Vzc2lvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKi8KICAgc2V0VGFncyh0YWdzKSB7CiAgICB0aGlzLl90YWdzID0gewogICAgICAuLi50aGlzLl90YWdzLAogICAgICAuLi50YWdzLAogICAgfTsKICAgIHRoaXMuX25vdGlmeVNjb3BlTGlzdGVuZXJzKCk7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICovCiAgIHNldFRhZyhrZXksIHZhbHVlKSB7CiAgICB0aGlzLl90YWdzID0geyAuLi50aGlzLl90YWdzLCBba2V5XTogdmFsdWUgfTsKICAgIHRoaXMuX25vdGlmeVNjb3BlTGlzdGVuZXJzKCk7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICovCiAgIHNldEV4dHJhcyhleHRyYXMpIHsKICAgIHRoaXMuX2V4dHJhID0gewogICAgICAuLi50aGlzLl9leHRyYSwKICAgICAgLi4uZXh0cmFzLAogICAgfTsKICAgIHRoaXMuX25vdGlmeVNjb3BlTGlzdGVuZXJzKCk7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICovCiAgIHNldEV4dHJhKGtleSwgZXh0cmEpIHsKICAgIHRoaXMuX2V4dHJhID0geyAuLi50aGlzLl9leHRyYSwgW2tleV06IGV4dHJhIH07CiAgICB0aGlzLl9ub3RpZnlTY29wZUxpc3RlbmVycygpOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqLwogICBzZXRGaW5nZXJwcmludChmaW5nZXJwcmludCkgewogICAgdGhpcy5fZmluZ2VycHJpbnQgPSBmaW5nZXJwcmludDsKICAgIHRoaXMuX25vdGlmeVNjb3BlTGlzdGVuZXJzKCk7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICovCiAgIHNldExldmVsKAogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICBsZXZlbCwKICApIHsKICAgIHRoaXMuX2xldmVsID0gbGV2ZWw7CiAgICB0aGlzLl9ub3RpZnlTY29wZUxpc3RlbmVycygpOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBTZXRzIHRoZSB0cmFuc2FjdGlvbiBuYW1lIG9uIHRoZSBzY29wZSBmb3IgZnV0dXJlIGV2ZW50cy4KICAgKi8KICAgc2V0VHJhbnNhY3Rpb25OYW1lKG5hbWUpIHsKICAgIHRoaXMuX3RyYW5zYWN0aW9uTmFtZSA9IG5hbWU7CiAgICB0aGlzLl9ub3RpZnlTY29wZUxpc3RlbmVycygpOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqLwogICBzZXRDb250ZXh0KGtleSwgY29udGV4dCkgewogICAgaWYgKGNvbnRleHQgPT09IG51bGwpIHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1keW5hbWljLWRlbGV0ZQogICAgICBkZWxldGUgdGhpcy5fY29udGV4dHNba2V5XTsKICAgIH0gZWxzZSB7CiAgICAgIHRoaXMuX2NvbnRleHRzW2tleV0gPSBjb250ZXh0OwogICAgfQoKICAgIHRoaXMuX25vdGlmeVNjb3BlTGlzdGVuZXJzKCk7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFNldHMgdGhlIFNwYW4gb24gdGhlIHNjb3BlLgogICAqIEBwYXJhbSBzcGFuIFNwYW4KICAgKiBAZGVwcmVjYXRlZCBJbnN0ZWFkIG9mIHNldHRpbmcgYSBzcGFuIG9uIGEgc2NvcGUsIHVzZSBgc3RhcnRTcGFuKClgL2BzdGFydFNwYW5NYW51YWwoKWAgaW5zdGVhZC4KICAgKi8KICAgc2V0U3BhbihzcGFuKSB7CiAgICB0aGlzLl9zcGFuID0gc3BhbjsKICAgIHRoaXMuX25vdGlmeVNjb3BlTGlzdGVuZXJzKCk7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFJldHVybnMgdGhlIGBTcGFuYCBpZiB0aGVyZSBpcyBvbmUuCiAgICogQGRlcHJlY2F0ZWQgVXNlIGBnZXRBY3RpdmVTcGFuKClgIGluc3RlYWQuCiAgICovCiAgIGdldFNwYW4oKSB7CiAgICByZXR1cm4gdGhpcy5fc3BhbjsKICB9CgogIC8qKgogICAqIFJldHVybnMgdGhlIGBUcmFuc2FjdGlvbmAgYXR0YWNoZWQgdG8gdGhlIHNjb3BlIChpZiB0aGVyZSBpcyBvbmUpLgogICAqIEBkZXByZWNhdGVkIFlvdSBzaG91bGQgbm90IHJlbHkgb24gdGhlIHRyYW5zYWN0aW9uLCBidXQganVzdCB1c2UgYHN0YXJ0U3BhbigpYCBBUElzIGluc3RlYWQuCiAgICovCiAgIGdldFRyYW5zYWN0aW9uKCkgewogICAgLy8gT2Z0ZW4sIHRoaXMgc3BhbiAoaWYgaXQgZXhpc3RzIGF0IGFsbCkgd2lsbCBiZSBhIHRyYW5zYWN0aW9uLCBidXQgaXQncyBub3QgZ3VhcmFudGVlZCB0byBiZS4gUmVnYXJkbGVzcywgaXQgd2lsbAogICAgLy8gaGF2ZSBhIHBvaW50ZXIgdG8gdGhlIGN1cnJlbnRseS1hY3RpdmUgdHJhbnNhY3Rpb24uCiAgICBjb25zdCBzcGFuID0gdGhpcy5fc3BhbjsKICAgIC8vIENhbm5vdCByZXBsYWNlIHdpdGggZ2V0Um9vdFNwYW4gYmVjYXVzZSBnZXRSb290U3BhbiByZXR1cm5zIGEgc3Bhbiwgbm90IGEgdHJhbnNhY3Rpb24KICAgIC8vIEFsc28sIHRoaXMgbWV0aG9kIHdpbGwgYmUgcmVtb3ZlZCBhbnl3YXkuCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgIHJldHVybiBzcGFuICYmIHNwYW4udHJhbnNhY3Rpb247CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqLwogICBzZXRTZXNzaW9uKHNlc3Npb24pIHsKICAgIGlmICghc2Vzc2lvbikgewogICAgICBkZWxldGUgdGhpcy5fc2Vzc2lvbjsKICAgIH0gZWxzZSB7CiAgICAgIHRoaXMuX3Nlc3Npb24gPSBzZXNzaW9uOwogICAgfQogICAgdGhpcy5fbm90aWZ5U2NvcGVMaXN0ZW5lcnMoKTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKi8KICAgZ2V0U2Vzc2lvbigpIHsKICAgIHJldHVybiB0aGlzLl9zZXNzaW9uOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKi8KICAgdXBkYXRlKGNhcHR1cmVDb250ZXh0KSB7CiAgICBpZiAoIWNhcHR1cmVDb250ZXh0KSB7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIGNvbnN0IHNjb3BlVG9NZXJnZSA9IHR5cGVvZiBjYXB0dXJlQ29udGV4dCA9PT0gJ2Z1bmN0aW9uJyA/IGNhcHR1cmVDb250ZXh0KHRoaXMpIDogY2FwdHVyZUNvbnRleHQ7CgogICAgaWYgKHNjb3BlVG9NZXJnZSBpbnN0YW5jZW9mIFNjb3BlKSB7CiAgICAgIGNvbnN0IHNjb3BlRGF0YSA9IHNjb3BlVG9NZXJnZS5nZXRTY29wZURhdGEoKTsKCiAgICAgIHRoaXMuX3RhZ3MgPSB7IC4uLnRoaXMuX3RhZ3MsIC4uLnNjb3BlRGF0YS50YWdzIH07CiAgICAgIHRoaXMuX2V4dHJhID0geyAuLi50aGlzLl9leHRyYSwgLi4uc2NvcGVEYXRhLmV4dHJhIH07CiAgICAgIHRoaXMuX2NvbnRleHRzID0geyAuLi50aGlzLl9jb250ZXh0cywgLi4uc2NvcGVEYXRhLmNvbnRleHRzIH07CiAgICAgIGlmIChzY29wZURhdGEudXNlciAmJiBPYmplY3Qua2V5cyhzY29wZURhdGEudXNlcikubGVuZ3RoKSB7CiAgICAgICAgdGhpcy5fdXNlciA9IHNjb3BlRGF0YS51c2VyOwogICAgICB9CiAgICAgIGlmIChzY29wZURhdGEubGV2ZWwpIHsKICAgICAgICB0aGlzLl9sZXZlbCA9IHNjb3BlRGF0YS5sZXZlbDsKICAgICAgfQogICAgICBpZiAoc2NvcGVEYXRhLmZpbmdlcnByaW50Lmxlbmd0aCkgewogICAgICAgIHRoaXMuX2ZpbmdlcnByaW50ID0gc2NvcGVEYXRhLmZpbmdlcnByaW50OwogICAgICB9CiAgICAgIGlmIChzY29wZVRvTWVyZ2UuZ2V0UmVxdWVzdFNlc3Npb24oKSkgewogICAgICAgIHRoaXMuX3JlcXVlc3RTZXNzaW9uID0gc2NvcGVUb01lcmdlLmdldFJlcXVlc3RTZXNzaW9uKCk7CiAgICAgIH0KICAgICAgaWYgKHNjb3BlRGF0YS5wcm9wYWdhdGlvbkNvbnRleHQpIHsKICAgICAgICB0aGlzLl9wcm9wYWdhdGlvbkNvbnRleHQgPSBzY29wZURhdGEucHJvcGFnYXRpb25Db250ZXh0OwogICAgICB9CiAgICB9IGVsc2UgaWYgKGlzUGxhaW5PYmplY3Qoc2NvcGVUb01lcmdlKSkgewogICAgICBjb25zdCBzY29wZUNvbnRleHQgPSBjYXB0dXJlQ29udGV4dCA7CiAgICAgIHRoaXMuX3RhZ3MgPSB7IC4uLnRoaXMuX3RhZ3MsIC4uLnNjb3BlQ29udGV4dC50YWdzIH07CiAgICAgIHRoaXMuX2V4dHJhID0geyAuLi50aGlzLl9leHRyYSwgLi4uc2NvcGVDb250ZXh0LmV4dHJhIH07CiAgICAgIHRoaXMuX2NvbnRleHRzID0geyAuLi50aGlzLl9jb250ZXh0cywgLi4uc2NvcGVDb250ZXh0LmNvbnRleHRzIH07CiAgICAgIGlmIChzY29wZUNvbnRleHQudXNlcikgewogICAgICAgIHRoaXMuX3VzZXIgPSBzY29wZUNvbnRleHQudXNlcjsKICAgICAgfQogICAgICBpZiAoc2NvcGVDb250ZXh0LmxldmVsKSB7CiAgICAgICAgdGhpcy5fbGV2ZWwgPSBzY29wZUNvbnRleHQubGV2ZWw7CiAgICAgIH0KICAgICAgaWYgKHNjb3BlQ29udGV4dC5maW5nZXJwcmludCkgewogICAgICAgIHRoaXMuX2ZpbmdlcnByaW50ID0gc2NvcGVDb250ZXh0LmZpbmdlcnByaW50OwogICAgICB9CiAgICAgIGlmIChzY29wZUNvbnRleHQucmVxdWVzdFNlc3Npb24pIHsKICAgICAgICB0aGlzLl9yZXF1ZXN0U2Vzc2lvbiA9IHNjb3BlQ29udGV4dC5yZXF1ZXN0U2Vzc2lvbjsKICAgICAgfQogICAgICBpZiAoc2NvcGVDb250ZXh0LnByb3BhZ2F0aW9uQ29udGV4dCkgewogICAgICAgIHRoaXMuX3Byb3BhZ2F0aW9uQ29udGV4dCA9IHNjb3BlQ29udGV4dC5wcm9wYWdhdGlvbkNvbnRleHQ7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICovCiAgIGNsZWFyKCkgewogICAgdGhpcy5fYnJlYWRjcnVtYnMgPSBbXTsKICAgIHRoaXMuX3RhZ3MgPSB7fTsKICAgIHRoaXMuX2V4dHJhID0ge307CiAgICB0aGlzLl91c2VyID0ge307CiAgICB0aGlzLl9jb250ZXh0cyA9IHt9OwogICAgdGhpcy5fbGV2ZWwgPSB1bmRlZmluZWQ7CiAgICB0aGlzLl90cmFuc2FjdGlvbk5hbWUgPSB1bmRlZmluZWQ7CiAgICB0aGlzLl9maW5nZXJwcmludCA9IHVuZGVmaW5lZDsKICAgIHRoaXMuX3JlcXVlc3RTZXNzaW9uID0gdW5kZWZpbmVkOwogICAgdGhpcy5fc3BhbiA9IHVuZGVmaW5lZDsKICAgIHRoaXMuX3Nlc3Npb24gPSB1bmRlZmluZWQ7CiAgICB0aGlzLl9ub3RpZnlTY29wZUxpc3RlbmVycygpOwogICAgdGhpcy5fYXR0YWNobWVudHMgPSBbXTsKICAgIHRoaXMuX3Byb3BhZ2F0aW9uQ29udGV4dCA9IGdlbmVyYXRlUHJvcGFnYXRpb25Db250ZXh0KCk7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICovCiAgIGFkZEJyZWFkY3J1bWIoYnJlYWRjcnVtYiwgbWF4QnJlYWRjcnVtYnMpIHsKICAgIGNvbnN0IG1heENydW1icyA9IHR5cGVvZiBtYXhCcmVhZGNydW1icyA9PT0gJ251bWJlcicgPyBtYXhCcmVhZGNydW1icyA6IERFRkFVTFRfTUFYX0JSRUFEQ1JVTUJTOwoKICAgIC8vIE5vIGRhdGEgaGFzIGJlZW4gY2hhbmdlZCwgc28gZG9uJ3Qgbm90aWZ5IHNjb3BlIGxpc3RlbmVycwogICAgaWYgKG1heENydW1icyA8PSAwKSB7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIGNvbnN0IG1lcmdlZEJyZWFkY3J1bWIgPSB7CiAgICAgIHRpbWVzdGFtcDogZGF0ZVRpbWVzdGFtcEluU2Vjb25kcygpLAogICAgICAuLi5icmVhZGNydW1iLAogICAgfTsKCiAgICBjb25zdCBicmVhZGNydW1icyA9IHRoaXMuX2JyZWFkY3J1bWJzOwogICAgYnJlYWRjcnVtYnMucHVzaChtZXJnZWRCcmVhZGNydW1iKTsKICAgIHRoaXMuX2JyZWFkY3J1bWJzID0gYnJlYWRjcnVtYnMubGVuZ3RoID4gbWF4Q3J1bWJzID8gYnJlYWRjcnVtYnMuc2xpY2UoLW1heENydW1icykgOiBicmVhZGNydW1iczsKCiAgICB0aGlzLl9ub3RpZnlTY29wZUxpc3RlbmVycygpOwoKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKi8KICAgZ2V0TGFzdEJyZWFkY3J1bWIoKSB7CiAgICByZXR1cm4gdGhpcy5fYnJlYWRjcnVtYnNbdGhpcy5fYnJlYWRjcnVtYnMubGVuZ3RoIC0gMV07CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqLwogICBjbGVhckJyZWFkY3J1bWJzKCkgewogICAgdGhpcy5fYnJlYWRjcnVtYnMgPSBbXTsKICAgIHRoaXMuX25vdGlmeVNjb3BlTGlzdGVuZXJzKCk7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICovCiAgIGFkZEF0dGFjaG1lbnQoYXR0YWNobWVudCkgewogICAgdGhpcy5fYXR0YWNobWVudHMucHVzaChhdHRhY2htZW50KTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKiBAZGVwcmVjYXRlZCBVc2UgYGdldFNjb3BlRGF0YSgpYCBpbnN0ZWFkLgogICAqLwogICBnZXRBdHRhY2htZW50cygpIHsKICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldFNjb3BlRGF0YSgpOwoKICAgIHJldHVybiBkYXRhLmF0dGFjaG1lbnRzOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKi8KICAgY2xlYXJBdHRhY2htZW50cygpIHsKICAgIHRoaXMuX2F0dGFjaG1lbnRzID0gW107CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKiBAaW5oZXJpdERvYyAqLwogICBnZXRTY29wZURhdGEoKSB7CiAgICBjb25zdCB7CiAgICAgIF9icmVhZGNydW1icywKICAgICAgX2F0dGFjaG1lbnRzLAogICAgICBfY29udGV4dHMsCiAgICAgIF90YWdzLAogICAgICBfZXh0cmEsCiAgICAgIF91c2VyLAogICAgICBfbGV2ZWwsCiAgICAgIF9maW5nZXJwcmludCwKICAgICAgX2V2ZW50UHJvY2Vzc29ycywKICAgICAgX3Byb3BhZ2F0aW9uQ29udGV4dCwKICAgICAgX3Nka1Byb2Nlc3NpbmdNZXRhZGF0YSwKICAgICAgX3RyYW5zYWN0aW9uTmFtZSwKICAgICAgX3NwYW4sCiAgICB9ID0gdGhpczsKCiAgICByZXR1cm4gewogICAgICBicmVhZGNydW1iczogX2JyZWFkY3J1bWJzLAogICAgICBhdHRhY2htZW50czogX2F0dGFjaG1lbnRzLAogICAgICBjb250ZXh0czogX2NvbnRleHRzLAogICAgICB0YWdzOiBfdGFncywKICAgICAgZXh0cmE6IF9leHRyYSwKICAgICAgdXNlcjogX3VzZXIsCiAgICAgIGxldmVsOiBfbGV2ZWwsCiAgICAgIGZpbmdlcnByaW50OiBfZmluZ2VycHJpbnQgfHwgW10sCiAgICAgIGV2ZW50UHJvY2Vzc29yczogX2V2ZW50UHJvY2Vzc29ycywKICAgICAgcHJvcGFnYXRpb25Db250ZXh0OiBfcHJvcGFnYXRpb25Db250ZXh0LAogICAgICBzZGtQcm9jZXNzaW5nTWV0YWRhdGE6IF9zZGtQcm9jZXNzaW5nTWV0YWRhdGEsCiAgICAgIHRyYW5zYWN0aW9uTmFtZTogX3RyYW5zYWN0aW9uTmFtZSwKICAgICAgc3BhbjogX3NwYW4sCiAgICB9OwogIH0KCiAgLyoqCiAgICogQXBwbGllcyBkYXRhIGZyb20gdGhlIHNjb3BlIHRvIHRoZSBldmVudCBhbmQgcnVucyBhbGwgZXZlbnQgcHJvY2Vzc29ycyBvbiBpdC4KICAgKgogICAqIEBwYXJhbSBldmVudCBFdmVudAogICAqIEBwYXJhbSBoaW50IE9iamVjdCBjb250YWluaW5nIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG9yaWdpbmFsIGV4Y2VwdGlvbiwgZm9yIHVzZSBieSB0aGUgZXZlbnQgcHJvY2Vzc29ycy4KICAgKiBAaGlkZGVuCiAgICogQGRlcHJlY2F0ZWQgVXNlIGBhcHBseVNjb3BlRGF0YVRvRXZlbnQoKWAgZGlyZWN0bHkKICAgKi8KICAgYXBwbHlUb0V2ZW50KAogICAgZXZlbnQsCiAgICBoaW50ID0ge30sCiAgICBhZGRpdGlvbmFsRXZlbnRQcm9jZXNzb3JzID0gW10sCiAgKSB7CiAgICBhcHBseVNjb3BlRGF0YVRvRXZlbnQoZXZlbnQsIHRoaXMuZ2V0U2NvcGVEYXRhKCkpOwoKICAgIC8vIFRPRE8gKHY4KTogVXBkYXRlIHRoaXMgb3JkZXIgdG8gYmU6IEdsb2JhbCA+IENsaWVudCA+IFNjb3BlCiAgICBjb25zdCBldmVudFByb2Nlc3NvcnMgPSBbCiAgICAgIC4uLmFkZGl0aW9uYWxFdmVudFByb2Nlc3NvcnMsCiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgICAuLi5nZXRHbG9iYWxFdmVudFByb2Nlc3NvcnMoKSwKICAgICAgLi4udGhpcy5fZXZlbnRQcm9jZXNzb3JzLAogICAgXTsKCiAgICByZXR1cm4gbm90aWZ5RXZlbnRQcm9jZXNzb3JzKGV2ZW50UHJvY2Vzc29ycywgZXZlbnQsIGhpbnQpOwogIH0KCiAgLyoqCiAgICogQWRkIGRhdGEgd2hpY2ggd2lsbCBiZSBhY2Nlc3NpYmxlIGR1cmluZyBldmVudCBwcm9jZXNzaW5nIGJ1dCB3b24ndCBnZXQgc2VudCB0byBTZW50cnkKICAgKi8KICAgc2V0U0RLUHJvY2Vzc2luZ01ldGFkYXRhKG5ld0RhdGEpIHsKICAgIHRoaXMuX3Nka1Byb2Nlc3NpbmdNZXRhZGF0YSA9IHsgLi4udGhpcy5fc2RrUHJvY2Vzc2luZ01ldGFkYXRhLCAuLi5uZXdEYXRhIH07CgogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqLwogICBzZXRQcm9wYWdhdGlvbkNvbnRleHQoY29udGV4dCkgewogICAgdGhpcy5fcHJvcGFnYXRpb25Db250ZXh0ID0gY29udGV4dDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKi8KICAgZ2V0UHJvcGFnYXRpb25Db250ZXh0KCkgewogICAgcmV0dXJuIHRoaXMuX3Byb3BhZ2F0aW9uQ29udGV4dDsKICB9CgogIC8qKgogICAqIENhcHR1cmUgYW4gZXhjZXB0aW9uIGZvciB0aGlzIHNjb3BlLgogICAqCiAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXhjZXB0aW9uIHRvIGNhcHR1cmUuCiAgICogQHBhcmFtIGhpbnQgT3B0aW5hbCBhZGRpdGlvbmFsIGRhdGEgdG8gYXR0YWNoIHRvIHRoZSBTZW50cnkgZXZlbnQuCiAgICogQHJldHVybnMgdGhlIGlkIG9mIHRoZSBjYXB0dXJlZCBTZW50cnkgZXZlbnQuCiAgICovCiAgIGNhcHR1cmVFeGNlcHRpb24oZXhjZXB0aW9uLCBoaW50KSB7CiAgICBjb25zdCBldmVudElkID0gaGludCAmJiBoaW50LmV2ZW50X2lkID8gaGludC5ldmVudF9pZCA6IHV1aWQ0KCk7CgogICAgaWYgKCF0aGlzLl9jbGllbnQpIHsKICAgICAgbG9nZ2VyLndhcm4oJ05vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBleGNlcHRpb24hJyk7CiAgICAgIHJldHVybiBldmVudElkOwogICAgfQoKICAgIGNvbnN0IHN5bnRoZXRpY0V4Y2VwdGlvbiA9IG5ldyBFcnJvcignU2VudHJ5IHN5bnRoZXRpY0V4Y2VwdGlvbicpOwoKICAgIHRoaXMuX2NsaWVudC5jYXB0dXJlRXhjZXB0aW9uKAogICAgICBleGNlcHRpb24sCiAgICAgIHsKICAgICAgICBvcmlnaW5hbEV4Y2VwdGlvbjogZXhjZXB0aW9uLAogICAgICAgIHN5bnRoZXRpY0V4Y2VwdGlvbiwKICAgICAgICAuLi5oaW50LAogICAgICAgIGV2ZW50X2lkOiBldmVudElkLAogICAgICB9LAogICAgICB0aGlzLAogICAgKTsKCiAgICByZXR1cm4gZXZlbnRJZDsKICB9CgogIC8qKgogICAqIENhcHR1cmUgYSBtZXNzYWdlIGZvciB0aGlzIHNjb3BlLgogICAqCiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gY2FwdHVyZS4KICAgKiBAcGFyYW0gbGV2ZWwgQW4gb3B0aW9uYWwgc2V2ZXJpdHkgbGV2ZWwgdG8gcmVwb3J0IHRoZSBtZXNzYWdlIHdpdGguCiAgICogQHBhcmFtIGhpbnQgT3B0aW9uYWwgYWRkaXRpb25hbCBkYXRhIHRvIGF0dGFjaCB0byB0aGUgU2VudHJ5IGV2ZW50LgogICAqIEByZXR1cm5zIHRoZSBpZCBvZiB0aGUgY2FwdHVyZWQgbWVzc2FnZS4KICAgKi8KICAgY2FwdHVyZU1lc3NhZ2UobWVzc2FnZSwgbGV2ZWwsIGhpbnQpIHsKICAgIGNvbnN0IGV2ZW50SWQgPSBoaW50ICYmIGhpbnQuZXZlbnRfaWQgPyBoaW50LmV2ZW50X2lkIDogdXVpZDQoKTsKCiAgICBpZiAoIXRoaXMuX2NsaWVudCkgewogICAgICBsb2dnZXIud2FybignTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIG1lc3NhZ2UhJyk7CiAgICAgIHJldHVybiBldmVudElkOwogICAgfQoKICAgIGNvbnN0IHN5bnRoZXRpY0V4Y2VwdGlvbiA9IG5ldyBFcnJvcihtZXNzYWdlKTsKCiAgICB0aGlzLl9jbGllbnQuY2FwdHVyZU1lc3NhZ2UoCiAgICAgIG1lc3NhZ2UsCiAgICAgIGxldmVsLAogICAgICB7CiAgICAgICAgb3JpZ2luYWxFeGNlcHRpb246IG1lc3NhZ2UsCiAgICAgICAgc3ludGhldGljRXhjZXB0aW9uLAogICAgICAgIC4uLmhpbnQsCiAgICAgICAgZXZlbnRfaWQ6IGV2ZW50SWQsCiAgICAgIH0sCiAgICAgIHRoaXMsCiAgICApOwoKICAgIHJldHVybiBldmVudElkOwogIH0KCiAgLyoqCiAgICogQ2FwdHVyZXMgYSBtYW51YWxseSBjcmVhdGVkIGV2ZW50IGZvciB0aGlzIHNjb3BlIGFuZCBzZW5kcyBpdCB0byBTZW50cnkuCiAgICoKICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBldmVudCB0byBjYXB0dXJlLgogICAqIEBwYXJhbSBoaW50IE9wdGlvbmFsIGFkZGl0aW9uYWwgZGF0YSB0byBhdHRhY2ggdG8gdGhlIFNlbnRyeSBldmVudC4KICAgKiBAcmV0dXJucyB0aGUgaWQgb2YgdGhlIGNhcHR1cmVkIGV2ZW50LgogICAqLwogICBjYXB0dXJlRXZlbnQoZXZlbnQsIGhpbnQpIHsKICAgIGNvbnN0IGV2ZW50SWQgPSBoaW50ICYmIGhpbnQuZXZlbnRfaWQgPyBoaW50LmV2ZW50X2lkIDogdXVpZDQoKTsKCiAgICBpZiAoIXRoaXMuX2NsaWVudCkgewogICAgICBsb2dnZXIud2FybignTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIGV2ZW50IScpOwogICAgICByZXR1cm4gZXZlbnRJZDsKICAgIH0KCiAgICB0aGlzLl9jbGllbnQuY2FwdHVyZUV2ZW50KGV2ZW50LCB7IC4uLmhpbnQsIGV2ZW50X2lkOiBldmVudElkIH0sIHRoaXMpOwoKICAgIHJldHVybiBldmVudElkOwogIH0KCiAgLyoqCiAgICogVGhpcyB3aWxsIGJlIGNhbGxlZCBvbiBldmVyeSBzZXQgY2FsbC4KICAgKi8KICAgX25vdGlmeVNjb3BlTGlzdGVuZXJzKCkgewogICAgLy8gV2UgbmVlZCB0aGlzIGNoZWNrIGZvciB0aGlzLl9ub3RpZnlpbmdMaXN0ZW5lcnMgdG8gYmUgYWJsZSB0byB3b3JrIG9uIHNjb3BlIGR1cmluZyB1cGRhdGVzCiAgICAvLyBJZiB0aGlzIGNoZWNrIGlzIG5vdCBoZXJlIHdlJ2xsIHByb2R1Y2UgZW5kbGVzcyByZWN1cnNpb24gd2hlbiBzb21ldGhpbmcgaXMgZG9uZSB3aXRoIHRoZSBzY29wZQogICAgLy8gZHVyaW5nIHRoZSBjYWxsYmFjay4KICAgIGlmICghdGhpcy5fbm90aWZ5aW5nTGlzdGVuZXJzKSB7CiAgICAgIHRoaXMuX25vdGlmeWluZ0xpc3RlbmVycyA9IHRydWU7CiAgICAgIHRoaXMuX3Njb3BlTGlzdGVuZXJzLmZvckVhY2goY2FsbGJhY2sgPT4gewogICAgICAgIGNhbGxiYWNrKHRoaXMpOwogICAgICB9KTsKICAgICAgdGhpcy5fbm90aWZ5aW5nTGlzdGVuZXJzID0gZmFsc2U7CiAgICB9CiAgfQp9CgpmdW5jdGlvbiBnZW5lcmF0ZVByb3BhZ2F0aW9uQ29udGV4dCgpIHsKICByZXR1cm4gewogICAgdHJhY2VJZDogdXVpZDQoKSwKICAgIHNwYW5JZDogdXVpZDQoKS5zdWJzdHJpbmcoMTYpLAogIH07Cn0KCmNvbnN0IFNES19WRVJTSU9OID0gJzcuMTE5LjInOwoKLyoqCiAqIEFQSSBjb21wYXRpYmlsaXR5IHZlcnNpb24gb2YgdGhpcyBodWIuCiAqCiAqIFdBUk5JTkc6IFRoaXMgbnVtYmVyIHNob3VsZCBvbmx5IGJlIGluY3JlYXNlZCB3aGVuIHRoZSBnbG9iYWwgaW50ZXJmYWNlCiAqIGNoYW5nZXMgYW5kIG5ldyBtZXRob2RzIGFyZSBpbnRyb2R1Y2VkLgogKgogKiBAaGlkZGVuCiAqLwpjb25zdCBBUElfVkVSU0lPTiA9IHBhcnNlRmxvYXQoU0RLX1ZFUlNJT04pOwoKLyoqCiAqIERlZmF1bHQgbWF4aW11bSBudW1iZXIgb2YgYnJlYWRjcnVtYnMgYWRkZWQgdG8gYW4gZXZlbnQuIENhbiBiZSBvdmVyd3JpdHRlbgogKiB3aXRoIHtAbGluayBPcHRpb25zLm1heEJyZWFkY3J1bWJzfS4KICovCmNvbnN0IERFRkFVTFRfQlJFQURDUlVNQlMgPSAxMDA7CgovKioKICogQGRlcHJlY2F0ZWQgVGhlIGBIdWJgIGNsYXNzIHdpbGwgYmUgcmVtb3ZlZCBpbiB2ZXJzaW9uIDggb2YgdGhlIFNESyBpbiBmYXZvdXIgb2YgYFNjb3BlYCBhbmQgYENsaWVudGAgb2JqZWN0cy4KICoKICogSWYgeW91IHByZXZpb3VzbHkgdXNlZCB0aGUgYEh1YmAgY2xhc3MgZGlyZWN0bHksIHJlcGxhY2UgaXQgd2l0aCBgU2NvcGVgIGFuZCBgQ2xpZW50YCBvYmplY3RzLiBNb3JlIGluZm9ybWF0aW9uOgogKiAtIFtNdWx0aXBsZSBTZW50cnkgSW5zdGFuY2VzXShodHRwczovL2RvY3Muc2VudHJ5LmlvL3BsYXRmb3Jtcy9qYXZhc2NyaXB0L2Jlc3QtcHJhY3RpY2VzL211bHRpcGxlLXNlbnRyeS1pbnN0YW5jZXMvKQogKiAtIFtCcm93c2VyIEV4dGVuc2lvbnNdKGh0dHBzOi8vZG9jcy5zZW50cnkuaW8vcGxhdGZvcm1zL2phdmFzY3JpcHQvYmVzdC1wcmFjdGljZXMvYnJvd3Nlci1leHRlbnNpb25zLykKICoKICogU29tZSBvZiBvdXIgQVBJcyBhcmUgdHlwZWQgd2l0aCB0aGUgSHViIGNsYXNzIGluc3RlYWQgb2YgdGhlIGludGVyZmFjZSAoZS5nLiBgZ2V0Q3VycmVudEh1YmApLiBNb3N0IG9mIHRoZW0gYXJlIGRlcHJlY2F0ZWQKICogdGhlbXNlbHZlcyBhbmQgd2lsbCBhbHNvIGJlIHJlbW92ZWQgaW4gdmVyc2lvbiA4LiBNb3JlIGluZm9ybWF0aW9uOgogKiAtIFtNaWdyYXRpb24gR3VpZGVdKGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvYmxvYi9kZXZlbG9wL01JR1JBVElPTi5tZCNkZXByZWNhdGUtaHViKQogKi8KLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCmNsYXNzIEh1YiAgewogIC8qKiBJcyBhIHtAbGluayBMYXllcn1bXSBjb250YWluaW5nIHRoZSBjbGllbnQgYW5kIHNjb3BlICovCgogIC8qKiBDb250YWlucyB0aGUgbGFzdCBldmVudCBpZCBvZiBhIGNhcHR1cmVkIGV2ZW50LiAgKi8KCiAgLyoqCiAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgaHViLCB3aWxsIHB1c2ggb25lIHtAbGluayBMYXllcn0gaW50byB0aGUKICAgKiBpbnRlcm5hbCBzdGFjayBvbiBjcmVhdGlvbi4KICAgKgogICAqIEBwYXJhbSBjbGllbnQgYm91bmQgdG8gdGhlIGh1Yi4KICAgKiBAcGFyYW0gc2NvcGUgYm91bmQgdG8gdGhlIGh1Yi4KICAgKiBAcGFyYW0gdmVyc2lvbiBudW1iZXIsIGhpZ2hlciBudW1iZXIgbWVhbnMgaGlnaGVyIHByaW9yaXR5LgogICAqCiAgICogQGRlcHJlY2F0ZWQgSW5zdGFudGlhdGlvbiBvZiBIdWIgb2JqZWN0cyBpcyBkZXByZWNhdGVkIGFuZCB0aGUgY29uc3RydWN0b3Igd2lsbCBiZSByZW1vdmVkIGluIHZlcnNpb24gOCBvZiB0aGUgU0RLLgogICAqCiAgICogSWYgeW91IGFyZSBjdXJyZW50bHkgdXNpbmcgdGhlIEh1YiBmb3IgbXVsdGktY2xpZW50IHVzZSBsaWtlIHNvOgogICAqCiAgICogYGBgCiAgICogLy8gT0xECiAgICogY29uc3QgaHViID0gbmV3IEh1YigpOwogICAqIGh1Yi5iaW5kQ2xpZW50KGNsaWVudCk7CiAgICogbWFrZU1haW4oaHViKQogICAqIGBgYAogICAqCiAgICogaW5zdGVhZCBpbml0aWFsaXplIHRoZSBjbGllbnQgYXMgZm9sbG93czoKICAgKgogICAqIGBgYAogICAqIC8vIE5FVwogICAqIFNlbnRyeS53aXRoSXNvbGF0aW9uU2NvcGUoKCkgPT4gewogICAqICAgIFNlbnRyeS5zZXRDdXJyZW50Q2xpZW50KGNsaWVudCk7CiAgICogICAgY2xpZW50LmluaXQoKTsKICAgKiB9KTsKICAgKiBgYGAKICAgKgogICAqIElmIHlvdSBhcmUgdXNpbmcgdGhlIEh1YiB0byBjYXB0dXJlIGV2ZW50cyBsaWtlIHNvOgogICAqCiAgICogYGBgCiAgICogLy8gT0xECiAgICogY29uc3QgY2xpZW50ID0gbmV3IENsaWVudCgpOwogICAqIGNvbnN0IGh1YiA9IG5ldyBIdWIoY2xpZW50KTsKICAgKiBodWIuY2FwdHVyZUV4Y2VwdGlvbigpCiAgICogYGBgCiAgICoKICAgKiBpbnN0ZWFkIGNhcHR1cmUgaXNvbGF0ZWQgZXZlbnRzIGFzIGZvbGxvd3M6CiAgICoKICAgKiBgYGAKICAgKiAvLyBORVcKICAgKiBjb25zdCBjbGllbnQgPSBuZXcgQ2xpZW50KCk7CiAgICogY29uc3Qgc2NvcGUgPSBuZXcgU2NvcGUoKTsKICAgKiBzY29wZS5zZXRDbGllbnQoY2xpZW50KTsKICAgKiBzY29wZS5jYXB0dXJlRXhjZXB0aW9uKCk7CiAgICogYGBgCiAgICovCiAgIGNvbnN0cnVjdG9yKAogICAgY2xpZW50LAogICAgc2NvcGUsCiAgICBpc29sYXRpb25TY29wZSwKICAgICAgX3ZlcnNpb24gPSBBUElfVkVSU0lPTiwKICApIHt0aGlzLl92ZXJzaW9uID0gX3ZlcnNpb247CiAgICBsZXQgYXNzaWduZWRTY29wZTsKICAgIGlmICghc2NvcGUpIHsKICAgICAgYXNzaWduZWRTY29wZSA9IG5ldyBTY29wZSgpOwogICAgICBhc3NpZ25lZFNjb3BlLnNldENsaWVudChjbGllbnQpOwogICAgfSBlbHNlIHsKICAgICAgYXNzaWduZWRTY29wZSA9IHNjb3BlOwogICAgfQoKICAgIGxldCBhc3NpZ25lZElzb2xhdGlvblNjb3BlOwogICAgaWYgKCFpc29sYXRpb25TY29wZSkgewogICAgICBhc3NpZ25lZElzb2xhdGlvblNjb3BlID0gbmV3IFNjb3BlKCk7CiAgICAgIGFzc2lnbmVkSXNvbGF0aW9uU2NvcGUuc2V0Q2xpZW50KGNsaWVudCk7CiAgICB9IGVsc2UgewogICAgICBhc3NpZ25lZElzb2xhdGlvblNjb3BlID0gaXNvbGF0aW9uU2NvcGU7CiAgICB9CgogICAgdGhpcy5fc3RhY2sgPSBbeyBzY29wZTogYXNzaWduZWRTY29wZSB9XTsKCiAgICBpZiAoY2xpZW50KSB7CiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgICB0aGlzLmJpbmRDbGllbnQoY2xpZW50KTsKICAgIH0KCiAgICB0aGlzLl9pc29sYXRpb25TY29wZSA9IGFzc2lnbmVkSXNvbGF0aW9uU2NvcGU7CiAgfQoKICAvKioKICAgKiBDaGVja3MgaWYgdGhpcyBodWIncyB2ZXJzaW9uIGlzIG9sZGVyIHRoYW4gdGhlIGdpdmVuIHZlcnNpb24uCiAgICoKICAgKiBAcGFyYW0gdmVyc2lvbiBBIHZlcnNpb24gbnVtYmVyIHRvIGNvbXBhcmUgdG8uCiAgICogQHJldHVybiBUcnVlIGlmIHRoZSBnaXZlbiB2ZXJzaW9uIGlzIG5ld2VyOyBvdGhlcndpc2UgZmFsc2UuCiAgICoKICAgKiBAZGVwcmVjYXRlZCBUaGlzIHdpbGwgYmUgcmVtb3ZlZCBpbiB2OC4KICAgKi8KICAgaXNPbGRlclRoYW4odmVyc2lvbikgewogICAgcmV0dXJuIHRoaXMuX3ZlcnNpb24gPCB2ZXJzaW9uOwogIH0KCiAgLyoqCiAgICogVGhpcyBiaW5kcyB0aGUgZ2l2ZW4gY2xpZW50IHRvIHRoZSBjdXJyZW50IHNjb3BlLgogICAqIEBwYXJhbSBjbGllbnQgQW4gU0RLIGNsaWVudCAoY2xpZW50KSBpbnN0YW5jZS4KICAgKgogICAqIEBkZXByZWNhdGVkIFVzZSBgaW5pdEFuZEJpbmQoKWAgZGlyZWN0bHksIG9yIGBzZXRDdXJyZW50Q2xpZW50KClgIGFuZC9vciBgY2xpZW50LmluaXQoKWAgaW5zdGVhZC4KICAgKi8KICAgYmluZENsaWVudChjbGllbnQpIHsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgY29uc3QgdG9wID0gdGhpcy5nZXRTdGFja1RvcCgpOwogICAgdG9wLmNsaWVudCA9IGNsaWVudDsKICAgIHRvcC5zY29wZS5zZXRDbGllbnQoY2xpZW50KTsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgaWYgKGNsaWVudCAmJiBjbGllbnQuc2V0dXBJbnRlZ3JhdGlvbnMpIHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICAgIGNsaWVudC5zZXR1cEludGVncmF0aW9ucygpOwogICAgfQogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKgogICAqIEBkZXByZWNhdGVkIFVzZSBgd2l0aFNjb3BlYCBpbnN0ZWFkLgogICAqLwogICBwdXNoU2NvcGUoKSB7CiAgICAvLyBXZSB3YW50IHRvIGNsb25lIHRoZSBjb250ZW50IG9mIHByZXYgc2NvcGUKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgY29uc3Qgc2NvcGUgPSB0aGlzLmdldFNjb3BlKCkuY2xvbmUoKTsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgdGhpcy5nZXRTdGFjaygpLnB1c2goewogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgICAgY2xpZW50OiB0aGlzLmdldENsaWVudCgpLAogICAgICBzY29wZSwKICAgIH0pOwogICAgcmV0dXJuIHNjb3BlOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKgogICAqIEBkZXByZWNhdGVkIFVzZSBgd2l0aFNjb3BlYCBpbnN0ZWFkLgogICAqLwogICBwb3BTY29wZSgpIHsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgaWYgKHRoaXMuZ2V0U3RhY2soKS5sZW5ndGggPD0gMSkgcmV0dXJuIGZhbHNlOwogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICByZXR1cm4gISF0aGlzLmdldFN0YWNrKCkucG9wKCk7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqCiAgICogQGRlcHJlY2F0ZWQgVXNlIGBTZW50cnkud2l0aFNjb3BlKClgIGluc3RlYWQuCiAgICovCiAgIHdpdGhTY29wZShjYWxsYmFjaykgewogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICBjb25zdCBzY29wZSA9IHRoaXMucHVzaFNjb3BlKCk7CgogICAgbGV0IG1heWJlUHJvbWlzZVJlc3VsdDsKICAgIHRyeSB7CiAgICAgIG1heWJlUHJvbWlzZVJlc3VsdCA9IGNhbGxiYWNrKHNjb3BlKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICAgIHRoaXMucG9wU2NvcGUoKTsKICAgICAgdGhyb3cgZTsKICAgIH0KCiAgICBpZiAoaXNUaGVuYWJsZShtYXliZVByb21pc2VSZXN1bHQpKSB7CiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBpc1RoZW5hYmxlIHJldHVybnMgdGhlIHdyb25nIHR5cGUKICAgICAgcmV0dXJuIG1heWJlUHJvbWlzZVJlc3VsdC50aGVuKAogICAgICAgIHJlcyA9PiB7CiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgICAgICAgIHRoaXMucG9wU2NvcGUoKTsKICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgfSwKICAgICAgICBlID0+IHsKICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgICAgICAgdGhpcy5wb3BTY29wZSgpOwogICAgICAgICAgdGhyb3cgZTsKICAgICAgICB9LAogICAgICApOwogICAgfQoKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgdGhpcy5wb3BTY29wZSgpOwogICAgcmV0dXJuIG1heWJlUHJvbWlzZVJlc3VsdDsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICoKICAgKiBAZGVwcmVjYXRlZCBVc2UgYFNlbnRyeS5nZXRDbGllbnQoKWAgaW5zdGVhZC4KICAgKi8KICAgZ2V0Q2xpZW50KCkgewogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICByZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLmNsaWVudCA7CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIHRoZSBzY29wZSBvZiB0aGUgdG9wIHN0YWNrLgogICAqCiAgICogQGRlcHJlY2F0ZWQgVXNlIGBTZW50cnkuZ2V0Q3VycmVudFNjb3BlKClgIGluc3RlYWQuCiAgICovCiAgIGdldFNjb3BlKCkgewogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICByZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLnNjb3BlOwogIH0KCiAgLyoqCiAgICogQGRlcHJlY2F0ZWQgVXNlIGBTZW50cnkuZ2V0SXNvbGF0aW9uU2NvcGUoKWAgaW5zdGVhZC4KICAgKi8KICAgZ2V0SXNvbGF0aW9uU2NvcGUoKSB7CiAgICByZXR1cm4gdGhpcy5faXNvbGF0aW9uU2NvcGU7CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIHRoZSBzY29wZSBzdGFjayBmb3IgZG9tYWlucyBvciB0aGUgcHJvY2Vzcy4KICAgKiBAZGVwcmVjYXRlZCBUaGlzIHdpbGwgYmUgcmVtb3ZlZCBpbiB2OC4KICAgKi8KICAgZ2V0U3RhY2soKSB7CiAgICByZXR1cm4gdGhpcy5fc3RhY2s7CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIHRoZSB0b3Btb3N0IHNjb3BlIGxheWVyIGluIHRoZSBvcmRlciBkb21haW4gPiBsb2NhbCA+IHByb2Nlc3MuCiAgICogQGRlcHJlY2F0ZWQgVGhpcyB3aWxsIGJlIHJlbW92ZWQgaW4gdjguCiAgICovCiAgIGdldFN0YWNrVG9wKCkgewogICAgcmV0dXJuIHRoaXMuX3N0YWNrW3RoaXMuX3N0YWNrLmxlbmd0aCAtIDFdOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKgogICAqIEBkZXByZWNhdGVkIFVzZSBgU2VudHJ5LmNhcHR1cmVFeGNlcHRpb24oKWAgaW5zdGVhZC4KICAgKi8KICAgY2FwdHVyZUV4Y2VwdGlvbihleGNlcHRpb24sIGhpbnQpIHsKICAgIGNvbnN0IGV2ZW50SWQgPSAodGhpcy5fbGFzdEV2ZW50SWQgPSBoaW50ICYmIGhpbnQuZXZlbnRfaWQgPyBoaW50LmV2ZW50X2lkIDogdXVpZDQoKSk7CiAgICBjb25zdCBzeW50aGV0aWNFeGNlcHRpb24gPSBuZXcgRXJyb3IoJ1NlbnRyeSBzeW50aGV0aWNFeGNlcHRpb24nKTsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgdGhpcy5nZXRTY29wZSgpLmNhcHR1cmVFeGNlcHRpb24oZXhjZXB0aW9uLCB7CiAgICAgIG9yaWdpbmFsRXhjZXB0aW9uOiBleGNlcHRpb24sCiAgICAgIHN5bnRoZXRpY0V4Y2VwdGlvbiwKICAgICAgLi4uaGludCwKICAgICAgZXZlbnRfaWQ6IGV2ZW50SWQsCiAgICB9KTsKCiAgICByZXR1cm4gZXZlbnRJZDsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICoKICAgKiBAZGVwcmVjYXRlZCBVc2UgIGBTZW50cnkuY2FwdHVyZU1lc3NhZ2UoKWAgaW5zdGVhZC4KICAgKi8KICAgY2FwdHVyZU1lc3NhZ2UoCiAgICBtZXNzYWdlLAogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICBsZXZlbCwKICAgIGhpbnQsCiAgKSB7CiAgICBjb25zdCBldmVudElkID0gKHRoaXMuX2xhc3RFdmVudElkID0gaGludCAmJiBoaW50LmV2ZW50X2lkID8gaGludC5ldmVudF9pZCA6IHV1aWQ0KCkpOwogICAgY29uc3Qgc3ludGhldGljRXhjZXB0aW9uID0gbmV3IEVycm9yKG1lc3NhZ2UpOwogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICB0aGlzLmdldFNjb3BlKCkuY2FwdHVyZU1lc3NhZ2UobWVzc2FnZSwgbGV2ZWwsIHsKICAgICAgb3JpZ2luYWxFeGNlcHRpb246IG1lc3NhZ2UsCiAgICAgIHN5bnRoZXRpY0V4Y2VwdGlvbiwKICAgICAgLi4uaGludCwKICAgICAgZXZlbnRfaWQ6IGV2ZW50SWQsCiAgICB9KTsKCiAgICByZXR1cm4gZXZlbnRJZDsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICoKICAgKiBAZGVwcmVjYXRlZCBVc2UgYFNlbnRyeS5jYXB0dXJlRXZlbnQoKWAgaW5zdGVhZC4KICAgKi8KICAgY2FwdHVyZUV2ZW50KGV2ZW50LCBoaW50KSB7CiAgICBjb25zdCBldmVudElkID0gaGludCAmJiBoaW50LmV2ZW50X2lkID8gaGludC5ldmVudF9pZCA6IHV1aWQ0KCk7CiAgICBpZiAoIWV2ZW50LnR5cGUpIHsKICAgICAgdGhpcy5fbGFzdEV2ZW50SWQgPSBldmVudElkOwogICAgfQogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICB0aGlzLmdldFNjb3BlKCkuY2FwdHVyZUV2ZW50KGV2ZW50LCB7IC4uLmhpbnQsIGV2ZW50X2lkOiBldmVudElkIH0pOwogICAgcmV0dXJuIGV2ZW50SWQ7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqCiAgICogQGRlcHJlY2F0ZWQgVGhpcyB3aWxsIGJlIHJlbW92ZWQgaW4gdjguCiAgICovCiAgIGxhc3RFdmVudElkKCkgewogICAgcmV0dXJuIHRoaXMuX2xhc3RFdmVudElkOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKgogICAqIEBkZXByZWNhdGVkIFVzZSBgU2VudHJ5LmFkZEJyZWFkY3J1bWIoKWAgaW5zdGVhZC4KICAgKi8KICAgYWRkQnJlYWRjcnVtYihicmVhZGNydW1iLCBoaW50KSB7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgIGNvbnN0IHsgc2NvcGUsIGNsaWVudCB9ID0gdGhpcy5nZXRTdGFja1RvcCgpOwoKICAgIGlmICghY2xpZW50KSByZXR1cm47CgogICAgY29uc3QgeyBiZWZvcmVCcmVhZGNydW1iID0gbnVsbCwgbWF4QnJlYWRjcnVtYnMgPSBERUZBVUxUX0JSRUFEQ1JVTUJTIH0gPQogICAgICAoY2xpZW50LmdldE9wdGlvbnMgJiYgY2xpZW50LmdldE9wdGlvbnMoKSkgfHwge307CgogICAgaWYgKG1heEJyZWFkY3J1bWJzIDw9IDApIHJldHVybjsKCiAgICBjb25zdCB0aW1lc3RhbXAgPSBkYXRlVGltZXN0YW1wSW5TZWNvbmRzKCk7CiAgICBjb25zdCBtZXJnZWRCcmVhZGNydW1iID0geyB0aW1lc3RhbXAsIC4uLmJyZWFkY3J1bWIgfTsKICAgIGNvbnN0IGZpbmFsQnJlYWRjcnVtYiA9IGJlZm9yZUJyZWFkY3J1bWIKICAgICAgPyAoY29uc29sZVNhbmRib3goKCkgPT4gYmVmb3JlQnJlYWRjcnVtYihtZXJnZWRCcmVhZGNydW1iLCBoaW50KSkgKQogICAgICA6IG1lcmdlZEJyZWFkY3J1bWI7CgogICAgaWYgKGZpbmFsQnJlYWRjcnVtYiA9PT0gbnVsbCkgcmV0dXJuOwoKICAgIGlmIChjbGllbnQuZW1pdCkgewogICAgICBjbGllbnQuZW1pdCgnYmVmb3JlQWRkQnJlYWRjcnVtYicsIGZpbmFsQnJlYWRjcnVtYiwgaGludCk7CiAgICB9CgogICAgLy8gVE9ETyh2OCk6IEkga25vdyB0aGlzIGNvbW1lbnQgZG9lc24ndCBtYWtlIG11Y2ggc2Vuc2UgYmVjYXVzZSB0aGUgaHViIHdpbGwgYmUgZGVwcmVjYXRlZCBidXQgSSBzdGlsbCB3YW50ZWQgdG8KICAgIC8vIHdyaXRlIGl0IGRvd24uIEluIHRoZW9yeSwgd2Ugd291bGQgaGF2ZSB0byBhZGQgdGhlIGJyZWFkY3J1bWJzIHRvIHRoZSBpc29sYXRpb24gc2NvcGUgaGVyZSwgaG93ZXZlciwgdGhhdCB3b3VsZAogICAgLy8gZHVwbGljYXRlIGFsbCBvZiB0aGUgYnJlYWRjcnVtYnMuIFRoZXJlIHdhcyB0aGUgcG9zc2liaWxpdHkgb2YgYWRkaW5nIGJyZWFkY3J1bWJzIHRvIGJvdGgsIHRoZSBpc29sYXRpb24gc2NvcGUKICAgIC8vIGFuZCB0aGUgbm9ybWFsIHNjb3BlLCBhbmQgZGVkdXBsaWNhdGluZyBpdCBkb3duIHRoZSBsaW5lIGluIHRoZSBldmVudCBwcm9jZXNzaW5nIHBpcGVsaW5lLiBIb3dldmVyLCB0aGF0IHdvdWxkCiAgICAvLyBoYXZlIGJlZW4gdmVyeSBmcmFnaWxlLCBiZWNhdXNlIHRoZSBicmVhZGNydW1iIG9iamVjdHMgd291bGQgaGF2ZSBuZWVkZWQgdG8ga2VlcCB0aGVpciBpZGVudGl0eSBhbGwgdGhyb3VnaG91dAogICAgLy8gdGhlIGV2ZW50IHByb2Nlc3NpbmcgcGlwZWxpbmUuCiAgICAvLyBJbiB0aGUgbmV3IGltcGxlbWVudGF0aW9uLCB0aGUgdG9wIGxldmVsIGBTZW50cnkuYWRkQnJlYWRjcnVtYigpYCBzaG91bGQgT05MWSB3cml0ZSB0byB0aGUgaXNvbGF0aW9uIHNjb3BlLgoKICAgIHNjb3BlLmFkZEJyZWFkY3J1bWIoZmluYWxCcmVhZGNydW1iLCBtYXhCcmVhZGNydW1icyk7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqIEBkZXByZWNhdGVkIFVzZSBgU2VudHJ5LnNldFVzZXIoKWAgaW5zdGVhZC4KICAgKi8KICAgc2V0VXNlcih1c2VyKSB7CiAgICAvLyBUT0RPKHY4KTogVGhlIHRvcCBsZXZlbCBgU2VudHJ5LnNldFVzZXIoKWAgZnVuY3Rpb24gc2hvdWxkIHdyaXRlIE9OTFkgdG8gdGhlIGlzb2xhdGlvbiBzY29wZS4KICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgdGhpcy5nZXRTY29wZSgpLnNldFVzZXIodXNlcik7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgIHRoaXMuZ2V0SXNvbGF0aW9uU2NvcGUoKS5zZXRVc2VyKHVzZXIpOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKiBAZGVwcmVjYXRlZCBVc2UgYFNlbnRyeS5zZXRUYWdzKClgIGluc3RlYWQuCiAgICovCiAgIHNldFRhZ3ModGFncykgewogICAgLy8gVE9ETyh2OCk6IFRoZSB0b3AgbGV2ZWwgYFNlbnRyeS5zZXRUYWdzKClgIGZ1bmN0aW9uIHNob3VsZCB3cml0ZSBPTkxZIHRvIHRoZSBpc29sYXRpb24gc2NvcGUuCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgIHRoaXMuZ2V0U2NvcGUoKS5zZXRUYWdzKHRhZ3MpOwogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICB0aGlzLmdldElzb2xhdGlvblNjb3BlKCkuc2V0VGFncyh0YWdzKTsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICogQGRlcHJlY2F0ZWQgVXNlIGBTZW50cnkuc2V0RXh0cmFzKClgIGluc3RlYWQuCiAgICovCiAgIHNldEV4dHJhcyhleHRyYXMpIHsKICAgIC8vIFRPRE8odjgpOiBUaGUgdG9wIGxldmVsIGBTZW50cnkuc2V0RXh0cmFzKClgIGZ1bmN0aW9uIHNob3VsZCB3cml0ZSBPTkxZIHRvIHRoZSBpc29sYXRpb24gc2NvcGUuCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgIHRoaXMuZ2V0U2NvcGUoKS5zZXRFeHRyYXMoZXh0cmFzKTsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgdGhpcy5nZXRJc29sYXRpb25TY29wZSgpLnNldEV4dHJhcyhleHRyYXMpOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKiBAZGVwcmVjYXRlZCBVc2UgYFNlbnRyeS5zZXRUYWcoKWAgaW5zdGVhZC4KICAgKi8KICAgc2V0VGFnKGtleSwgdmFsdWUpIHsKICAgIC8vIFRPRE8odjgpOiBUaGUgdG9wIGxldmVsIGBTZW50cnkuc2V0VGFnKClgIGZ1bmN0aW9uIHNob3VsZCB3cml0ZSBPTkxZIHRvIHRoZSBpc29sYXRpb24gc2NvcGUuCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgIHRoaXMuZ2V0U2NvcGUoKS5zZXRUYWcoa2V5LCB2YWx1ZSk7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgIHRoaXMuZ2V0SXNvbGF0aW9uU2NvcGUoKS5zZXRUYWcoa2V5LCB2YWx1ZSk7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqIEBkZXByZWNhdGVkIFVzZSBgU2VudHJ5LnNldEV4dHJhKClgIGluc3RlYWQuCiAgICovCiAgIHNldEV4dHJhKGtleSwgZXh0cmEpIHsKICAgIC8vIFRPRE8odjgpOiBUaGUgdG9wIGxldmVsIGBTZW50cnkuc2V0RXh0cmEoKWAgZnVuY3Rpb24gc2hvdWxkIHdyaXRlIE9OTFkgdG8gdGhlIGlzb2xhdGlvbiBzY29wZS4KICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgdGhpcy5nZXRTY29wZSgpLnNldEV4dHJhKGtleSwgZXh0cmEpOwogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICB0aGlzLmdldElzb2xhdGlvblNjb3BlKCkuc2V0RXh0cmEoa2V5LCBleHRyYSk7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqIEBkZXByZWNhdGVkIFVzZSBgU2VudHJ5LnNldENvbnRleHQoKWAgaW5zdGVhZC4KICAgKi8KICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQogICBzZXRDb250ZXh0KG5hbWUsIGNvbnRleHQpIHsKICAgIC8vIFRPRE8odjgpOiBUaGUgdG9wIGxldmVsIGBTZW50cnkuc2V0Q29udGV4dCgpYCBmdW5jdGlvbiBzaG91bGQgd3JpdGUgT05MWSB0byB0aGUgaXNvbGF0aW9uIHNjb3BlLgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICB0aGlzLmdldFNjb3BlKCkuc2V0Q29udGV4dChuYW1lLCBjb250ZXh0KTsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgdGhpcy5nZXRJc29sYXRpb25TY29wZSgpLnNldENvbnRleHQobmFtZSwgY29udGV4dCk7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqCiAgICogQGRlcHJlY2F0ZWQgVXNlIGBnZXRTY29wZSgpYCBkaXJlY3RseS4KICAgKi8KICAgY29uZmlndXJlU2NvcGUoY2FsbGJhY2spIHsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgY29uc3QgeyBzY29wZSwgY2xpZW50IH0gPSB0aGlzLmdldFN0YWNrVG9wKCk7CiAgICBpZiAoY2xpZW50KSB7CiAgICAgIGNhbGxiYWNrKHNjb3BlKTsKICAgIH0KICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICovCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgIHJ1bihjYWxsYmFjaykgewogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICBjb25zdCBvbGRIdWIgPSBtYWtlTWFpbih0aGlzKTsKICAgIHRyeSB7CiAgICAgIGNhbGxiYWNrKHRoaXMpOwogICAgfSBmaW5hbGx5IHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICAgIG1ha2VNYWluKG9sZEh1Yik7CiAgICB9CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqIEBkZXByZWNhdGVkIFVzZSBgU2VudHJ5LmdldENsaWVudCgpLmdldEludGVncmF0aW9uQnlOYW1lKClgIGluc3RlYWQuCiAgICovCiAgIGdldEludGVncmF0aW9uKGludGVncmF0aW9uKSB7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuZ2V0Q2xpZW50KCk7CiAgICBpZiAoIWNsaWVudCkgcmV0dXJuIG51bGw7CiAgICB0cnkgewogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgICAgcmV0dXJuIGNsaWVudC5nZXRJbnRlZ3JhdGlvbihpbnRlZ3JhdGlvbik7CiAgICB9IGNhdGNoIChfb08pIHsKICAgICAgREVCVUdfQlVJTEQgJiYgbG9nZ2VyLndhcm4oYENhbm5vdCByZXRyaWV2ZSBpbnRlZ3JhdGlvbiAke2ludGVncmF0aW9uLmlkfSBmcm9tIHRoZSBjdXJyZW50IEh1YmApOwogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICB9CgogIC8qKgogICAqIFN0YXJ0cyBhIG5ldyBgVHJhbnNhY3Rpb25gIGFuZCByZXR1cm5zIGl0LiBUaGlzIGlzIHRoZSBlbnRyeSBwb2ludCB0byBtYW51YWwgdHJhY2luZyBpbnN0cnVtZW50YXRpb24uCiAgICoKICAgKiBBIHRyZWUgc3RydWN0dXJlIGNhbiBiZSBidWlsdCBieSBhZGRpbmcgY2hpbGQgc3BhbnMgdG8gdGhlIHRyYW5zYWN0aW9uLCBhbmQgY2hpbGQgc3BhbnMgdG8gb3RoZXIgc3BhbnMuIFRvIHN0YXJ0IGEKICAgKiBuZXcgY2hpbGQgc3BhbiB3aXRoaW4gdGhlIHRyYW5zYWN0aW9uIG9yIGFueSBzcGFuLCBjYWxsIHRoZSByZXNwZWN0aXZlIGAuc3RhcnRDaGlsZCgpYCBtZXRob2QuCiAgICoKICAgKiBFdmVyeSBjaGlsZCBzcGFuIG11c3QgYmUgZmluaXNoZWQgYmVmb3JlIHRoZSB0cmFuc2FjdGlvbiBpcyBmaW5pc2hlZCwgb3RoZXJ3aXNlIHRoZSB1bmZpbmlzaGVkIHNwYW5zIGFyZSBkaXNjYXJkZWQuCiAgICoKICAgKiBUaGUgdHJhbnNhY3Rpb24gbXVzdCBiZSBmaW5pc2hlZCB3aXRoIGEgY2FsbCB0byBpdHMgYC5lbmQoKWAgbWV0aG9kLCBhdCB3aGljaCBwb2ludCB0aGUgdHJhbnNhY3Rpb24gd2l0aCBhbGwgaXRzCiAgICogZmluaXNoZWQgY2hpbGQgc3BhbnMgd2lsbCBiZSBzZW50IHRvIFNlbnRyeS4KICAgKgogICAqIEBwYXJhbSBjb250ZXh0IFByb3BlcnRpZXMgb2YgdGhlIG5ldyBgVHJhbnNhY3Rpb25gLgogICAqIEBwYXJhbSBjdXN0b21TYW1wbGluZ0NvbnRleHQgSW5mb3JtYXRpb24gZ2l2ZW4gdG8gdGhlIHRyYW5zYWN0aW9uIHNhbXBsaW5nIGZ1bmN0aW9uIChhbG9uZyB3aXRoIGNvbnRleHQtZGVwZW5kZW50CiAgICogZGVmYXVsdCB2YWx1ZXMpLiBTZWUge0BsaW5rIE9wdGlvbnMudHJhY2VzU2FtcGxlcn0uCiAgICoKICAgKiBAcmV0dXJucyBUaGUgdHJhbnNhY3Rpb24gd2hpY2ggd2FzIGp1c3Qgc3RhcnRlZAogICAqCiAgICogQGRlcHJlY2F0ZWQgVXNlIGBzdGFydFNwYW4oKWAsIGBzdGFydFNwYW5NYW51YWwoKWAgb3IgYHN0YXJ0SW5hY3RpdmVTcGFuKClgIGluc3RlYWQuCiAgICovCiAgIHN0YXJ0VHJhbnNhY3Rpb24oY29udGV4dCwgY3VzdG9tU2FtcGxpbmdDb250ZXh0KSB7CiAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9jYWxsRXh0ZW5zaW9uTWV0aG9kKCdzdGFydFRyYW5zYWN0aW9uJywgY29udGV4dCwgY3VzdG9tU2FtcGxpbmdDb250ZXh0KTsKCiAgICBpZiAoREVCVUdfQlVJTEQgJiYgIXJlc3VsdCkgewogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXRDbGllbnQoKTsKICAgICAgaWYgKCFjbGllbnQpIHsKICAgICAgICBsb2dnZXIud2FybigKICAgICAgICAgICJUcmFjaW5nIGV4dGVuc2lvbiAnc3RhcnRUcmFuc2FjdGlvbicgaXMgbWlzc2luZy4gWW91IHNob3VsZCAnaW5pdCcgdGhlIFNESyBiZWZvcmUgY2FsbGluZyAnc3RhcnRUcmFuc2FjdGlvbiciLAogICAgICAgICk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgbG9nZ2VyLndhcm4oYFRyYWNpbmcgZXh0ZW5zaW9uICdzdGFydFRyYW5zYWN0aW9uJyBoYXMgbm90IGJlZW4gYWRkZWQuIENhbGwgJ2FkZFRyYWNpbmdFeHRlbnNpb25zJyBiZWZvcmUgY2FsbGluZyAnaW5pdCc6ClNlbnRyeS5hZGRUcmFjaW5nRXh0ZW5zaW9ucygpOwpTZW50cnkuaW5pdCh7Li4ufSk7CmApOwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKICB9CgogIC8qKgogICAqIEBpbmhlcml0RG9jCiAgICogQGRlcHJlY2F0ZWQgVXNlIGBzcGFuVG9UcmFjZUhlYWRlcigpYCBpbnN0ZWFkLgogICAqLwogICB0cmFjZUhlYWRlcnMoKSB7CiAgICByZXR1cm4gdGhpcy5fY2FsbEV4dGVuc2lvbk1ldGhvZCgndHJhY2VIZWFkZXJzJyk7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqCiAgICogQGRlcHJlY2F0ZWQgVXNlIHRvcCBsZXZlbCBgY2FwdHVyZVNlc3Npb25gIGluc3RlYWQuCiAgICovCiAgIGNhcHR1cmVTZXNzaW9uKGVuZFNlc3Npb24gPSBmYWxzZSkgewogICAgLy8gYm90aCBzZW5kIHRoZSB1cGRhdGUgYW5kIHB1bGwgdGhlIHNlc3Npb24gZnJvbSB0aGUgc2NvcGUKICAgIGlmIChlbmRTZXNzaW9uKSB7CiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgICByZXR1cm4gdGhpcy5lbmRTZXNzaW9uKCk7CiAgICB9CgogICAgLy8gb25seSBzZW5kIHRoZSB1cGRhdGUKICAgIHRoaXMuX3NlbmRTZXNzaW9uVXBkYXRlKCk7CiAgfQoKICAvKioKICAgKiBAaW5oZXJpdERvYwogICAqIEBkZXByZWNhdGVkIFVzZSB0b3AgbGV2ZWwgYGVuZFNlc3Npb25gIGluc3RlYWQuCiAgICovCiAgIGVuZFNlc3Npb24oKSB7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgIGNvbnN0IGxheWVyID0gdGhpcy5nZXRTdGFja1RvcCgpOwogICAgY29uc3Qgc2NvcGUgPSBsYXllci5zY29wZTsKICAgIGNvbnN0IHNlc3Npb24gPSBzY29wZS5nZXRTZXNzaW9uKCk7CiAgICBpZiAoc2Vzc2lvbikgewogICAgICBjbG9zZVNlc3Npb24oc2Vzc2lvbik7CiAgICB9CiAgICB0aGlzLl9zZW5kU2Vzc2lvblVwZGF0ZSgpOwoKICAgIC8vIHRoZSBzZXNzaW9uIGlzIG92ZXI7IHRha2UgaXQgb2ZmIG9mIHRoZSBzY29wZQogICAgc2NvcGUuc2V0U2Vzc2lvbigpOwogIH0KCiAgLyoqCiAgICogQGluaGVyaXREb2MKICAgKiBAZGVwcmVjYXRlZCBVc2UgdG9wIGxldmVsIGBzdGFydFNlc3Npb25gIGluc3RlYWQuCiAgICovCiAgIHN0YXJ0U2Vzc2lvbihjb250ZXh0KSB7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24KICAgIGNvbnN0IHsgc2NvcGUsIGNsaWVudCB9ID0gdGhpcy5nZXRTdGFja1RvcCgpOwogICAgY29uc3QgeyByZWxlYXNlLCBlbnZpcm9ubWVudCA9IERFRkFVTFRfRU5WSVJPTk1FTlQgfSA9IChjbGllbnQgJiYgY2xpZW50LmdldE9wdGlvbnMoKSkgfHwge307CgogICAgLy8gV2lsbCBmZXRjaCB1c2VyQWdlbnQgaWYgY2FsbGVkIGZyb20gYnJvd3NlciBzZGsKICAgIGNvbnN0IHsgdXNlckFnZW50IH0gPSBHTE9CQUxfT0JKLm5hdmlnYXRvciB8fCB7fTsKCiAgICBjb25zdCBzZXNzaW9uID0gbWFrZVNlc3Npb24oewogICAgICByZWxlYXNlLAogICAgICBlbnZpcm9ubWVudCwKICAgICAgdXNlcjogc2NvcGUuZ2V0VXNlcigpLAogICAgICAuLi4odXNlckFnZW50ICYmIHsgdXNlckFnZW50IH0pLAogICAgICAuLi5jb250ZXh0LAogICAgfSk7CgogICAgLy8gRW5kIGV4aXN0aW5nIHNlc3Npb24gaWYgdGhlcmUncyBvbmUKICAgIGNvbnN0IGN1cnJlbnRTZXNzaW9uID0gc2NvcGUuZ2V0U2Vzc2lvbiAmJiBzY29wZS5nZXRTZXNzaW9uKCk7CiAgICBpZiAoY3VycmVudFNlc3Npb24gJiYgY3VycmVudFNlc3Npb24uc3RhdHVzID09PSAnb2snKSB7CiAgICAgIHVwZGF0ZVNlc3Npb24oY3VycmVudFNlc3Npb24sIHsgc3RhdHVzOiAnZXhpdGVkJyB9KTsKICAgIH0KICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgdGhpcy5lbmRTZXNzaW9uKCk7CgogICAgLy8gQWZ0ZXJ3YXJkcyB3ZSBzZXQgdGhlIG5ldyBzZXNzaW9uIG9uIHRoZSBzY29wZQogICAgc2NvcGUuc2V0U2Vzc2lvbihzZXNzaW9uKTsKCiAgICByZXR1cm4gc2Vzc2lvbjsKICB9CgogIC8qKgogICAqIFJldHVybnMgaWYgZGVmYXVsdCBQSUkgc2hvdWxkIGJlIHNlbnQgdG8gU2VudHJ5IGFuZCBwcm9wYWdhdGVkIGluIG91cmdvaW5nIHJlcXVlc3RzCiAgICogd2hlbiBUcmFjaW5nIGlzIHVzZWQuCiAgICoKICAgKiBAZGVwcmVjYXRlZCBVc2UgdG9wLWxldmVsIGBnZXRDbGllbnQoKS5nZXRPcHRpb25zKCkuc2VuZERlZmF1bHRQaWlgIGluc3RlYWQuIFRoaXMgZnVuY3Rpb24KICAgKiBvbmx5IHVubmVjZXNzYXJpbHkgaW5jcmVhc2VkIEFQSSBzdXJmYWNlIGJ1dCBvbmx5IHdyYXBwZWQgYWNjZXNzaW5nIHRoZSBvcHRpb24uCiAgICovCiAgIHNob3VsZFNlbmREZWZhdWx0UGlpKCkgewogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldENsaWVudCgpOwogICAgY29uc3Qgb3B0aW9ucyA9IGNsaWVudCAmJiBjbGllbnQuZ2V0T3B0aW9ucygpOwogICAgcmV0dXJuIEJvb2xlYW4ob3B0aW9ucyAmJiBvcHRpb25zLnNlbmREZWZhdWx0UGlpKTsKICB9CgogIC8qKgogICAqIFNlbmRzIHRoZSBjdXJyZW50IFNlc3Npb24gb24gdGhlIHNjb3BlCiAgICovCiAgIF9zZW5kU2Vzc2lvblVwZGF0ZSgpIHsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgY29uc3QgeyBzY29wZSwgY2xpZW50IH0gPSB0aGlzLmdldFN0YWNrVG9wKCk7CgogICAgY29uc3Qgc2Vzc2lvbiA9IHNjb3BlLmdldFNlc3Npb24oKTsKICAgIGlmIChzZXNzaW9uICYmIGNsaWVudCAmJiBjbGllbnQuY2FwdHVyZVNlc3Npb24pIHsKICAgICAgY2xpZW50LmNhcHR1cmVTZXNzaW9uKHNlc3Npb24pOwogICAgfQogIH0KCiAgLyoqCiAgICogQ2FsbHMgZ2xvYmFsIGV4dGVuc2lvbiBtZXRob2QgYW5kIGJpbmRpbmcgY3VycmVudCBpbnN0YW5jZSB0byB0aGUgZnVuY3Rpb24gY2FsbAogICAqLwogIC8vIEB0cy1leHBlY3QtZXJyb3IgRnVuY3Rpb24gbGFja3MgZW5kaW5nIHJldHVybiBzdGF0ZW1lbnQgYW5kIHJldHVybiB0eXBlIGRvZXMgbm90IGluY2x1ZGUgJ3VuZGVmaW5lZCcuIHRzKDIzNjYpCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkKICAgX2NhbGxFeHRlbnNpb25NZXRob2QobWV0aG9kLCAuLi5hcmdzKSB7CiAgICBjb25zdCBjYXJyaWVyID0gZ2V0TWFpbkNhcnJpZXIoKTsKICAgIGNvbnN0IHNlbnRyeSA9IGNhcnJpZXIuX19TRU5UUllfXzsKICAgIGlmIChzZW50cnkgJiYgc2VudHJ5LmV4dGVuc2lvbnMgJiYgdHlwZW9mIHNlbnRyeS5leHRlbnNpb25zW21ldGhvZF0gPT09ICdmdW5jdGlvbicpIHsKICAgICAgcmV0dXJuIHNlbnRyeS5leHRlbnNpb25zW21ldGhvZF0uYXBwbHkodGhpcywgYXJncyk7CiAgICB9CiAgICBERUJVR19CVUlMRCAmJiBsb2dnZXIud2FybihgRXh0ZW5zaW9uIG1ldGhvZCAke21ldGhvZH0gY291bGRuJ3QgYmUgZm91bmQsIGRvaW5nIG5vdGhpbmcuYCk7CiAgfQp9CgovKioKICogUmV0dXJucyB0aGUgZ2xvYmFsIHNoaW0gcmVnaXN0cnkuCiAqCiAqIEZJWE1FOiBUaGlzIGZ1bmN0aW9uIGlzIHByb2JsZW1hdGljLCBiZWNhdXNlIGRlc3BpdGUgYWx3YXlzIHJldHVybmluZyBhIHZhbGlkIENhcnJpZXIsCiAqIGl0IGhhcyBhbiBvcHRpb25hbCBgX19TRU5UUllfX2AgcHJvcGVydHksIHdoaWNoIHRoZW4gaW4gdHVybiByZXF1aXJlcyB1cyB0byBhbHdheXMgcGVyZm9ybSBhbiB1bm5lY2Vzc2FyeSBjaGVjawogKiBhdCB0aGUgY2FsbC1zaXRlLiBXZSBhbHdheXMgYWNjZXNzIHRoZSBjYXJyaWVyIHRocm91Z2ggdGhpcyBmdW5jdGlvbiwgc28gd2UgY2FuIGd1YXJhbnRlZSB0aGF0IGBfX1NFTlRSWV9fYCBpcyB0aGVyZS4KICoqLwpmdW5jdGlvbiBnZXRNYWluQ2FycmllcigpIHsKICBHTE9CQUxfT0JKLl9fU0VOVFJZX18gPSBHTE9CQUxfT0JKLl9fU0VOVFJZX18gfHwgewogICAgZXh0ZW5zaW9uczoge30sCiAgICBodWI6IHVuZGVmaW5lZCwKICB9OwogIHJldHVybiBHTE9CQUxfT0JKOwp9CgovKioKICogUmVwbGFjZXMgdGhlIGN1cnJlbnQgbWFpbiBodWIgd2l0aCB0aGUgcGFzc2VkIG9uZSBvbiB0aGUgZ2xvYmFsIG9iamVjdAogKgogKiBAcmV0dXJucyBUaGUgb2xkIHJlcGxhY2VkIGh1YgogKgogKiBAZGVwcmVjYXRlZCBVc2UgYHNldEN1cnJlbnRDbGllbnQoKWAgaW5zdGVhZC4KICovCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgpmdW5jdGlvbiBtYWtlTWFpbihodWIpIHsKICBjb25zdCByZWdpc3RyeSA9IGdldE1haW5DYXJyaWVyKCk7CiAgY29uc3Qgb2xkSHViID0gZ2V0SHViRnJvbUNhcnJpZXIocmVnaXN0cnkpOwogIHNldEh1Yk9uQ2FycmllcihyZWdpc3RyeSwgaHViKTsKICByZXR1cm4gb2xkSHViOwp9CgovKioKICogUmV0dXJucyB0aGUgZGVmYXVsdCBodWIgaW5zdGFuY2UuCiAqCiAqIElmIGEgaHViIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCBpbiB0aGUgZ2xvYmFsIGNhcnJpZXIgYnV0IHRoaXMgbW9kdWxlCiAqIGNvbnRhaW5zIGEgbW9yZSByZWNlbnQgdmVyc2lvbiwgaXQgcmVwbGFjZXMgdGhlIHJlZ2lzdGVyZWQgdmVyc2lvbi4KICogT3RoZXJ3aXNlLCB0aGUgY3VycmVudGx5IHJlZ2lzdGVyZWQgaHViIHdpbGwgYmUgcmV0dXJuZWQuCiAqCiAqIEBkZXByZWNhdGVkIFVzZSB0aGUgcmVzcGVjdGl2ZSByZXBsYWNlbWVudCBtZXRob2QgZGlyZWN0bHkgaW5zdGVhZC4KICovCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgpmdW5jdGlvbiBnZXRDdXJyZW50SHViKCkgewogIC8vIEdldCBtYWluIGNhcnJpZXIgKGdsb2JhbCBmb3IgZXZlcnkgZW52aXJvbm1lbnQpCiAgY29uc3QgcmVnaXN0cnkgPSBnZXRNYWluQ2FycmllcigpOwoKICBpZiAocmVnaXN0cnkuX19TRU5UUllfXyAmJiByZWdpc3RyeS5fX1NFTlRSWV9fLmFjcykgewogICAgY29uc3QgaHViID0gcmVnaXN0cnkuX19TRU5UUllfXy5hY3MuZ2V0Q3VycmVudEh1YigpOwoKICAgIGlmIChodWIpIHsKICAgICAgcmV0dXJuIGh1YjsKICAgIH0KICB9CgogIC8vIFJldHVybiBodWIgdGhhdCBsaXZlcyBvbiBhIGdsb2JhbCBvYmplY3QKICByZXR1cm4gZ2V0R2xvYmFsSHViKHJlZ2lzdHJ5KTsKfQoKLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCmZ1bmN0aW9uIGdldEdsb2JhbEh1YihyZWdpc3RyeSA9IGdldE1haW5DYXJyaWVyKCkpIHsKICAvLyBJZiB0aGVyZSdzIG5vIGh1Yiwgb3IgaXRzIGFuIG9sZCBBUEksIGFzc2lnbiBhIG5ldyBvbmUKCiAgaWYgKAogICAgIWhhc0h1Yk9uQ2FycmllcihyZWdpc3RyeSkgfHwKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogICAgZ2V0SHViRnJvbUNhcnJpZXIocmVnaXN0cnkpLmlzT2xkZXJUaGFuKEFQSV9WRVJTSU9OKQogICkgewogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgICBzZXRIdWJPbkNhcnJpZXIocmVnaXN0cnksIG5ldyBIdWIoKSk7CiAgfQoKICAvLyBSZXR1cm4gaHViIHRoYXQgbGl2ZXMgb24gYSBnbG9iYWwgb2JqZWN0CiAgcmV0dXJuIGdldEh1YkZyb21DYXJyaWVyKHJlZ2lzdHJ5KTsKfQoKLyoqCiAqIFRoaXMgd2lsbCB0ZWxsIHdoZXRoZXIgYSBjYXJyaWVyIGhhcyBhIGh1YiBvbiBpdCBvciBub3QKICogQHBhcmFtIGNhcnJpZXIgb2JqZWN0CiAqLwpmdW5jdGlvbiBoYXNIdWJPbkNhcnJpZXIoY2FycmllcikgewogIHJldHVybiAhIShjYXJyaWVyICYmIGNhcnJpZXIuX19TRU5UUllfXyAmJiBjYXJyaWVyLl9fU0VOVFJZX18uaHViKTsKfQoKLyoqCiAqIFRoaXMgd2lsbCBjcmVhdGUgYSBuZXcge0BsaW5rIEh1Yn0gYW5kIGFkZCB0byB0aGUgcGFzc2VkIG9iamVjdCBvbgogKiBfX1NFTlRSWV9fLmh1Yi4KICogQHBhcmFtIGNhcnJpZXIgb2JqZWN0CiAqIEBoaWRkZW4KICovCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgpmdW5jdGlvbiBnZXRIdWJGcm9tQ2FycmllcihjYXJyaWVyKSB7CiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgcmV0dXJuIGdldEdsb2JhbFNpbmdsZXRvbignaHViJywgKCkgPT4gbmV3IEh1YigpLCBjYXJyaWVyKTsKfQoKLyoqCiAqIFRoaXMgd2lsbCBzZXQgcGFzc2VkIHtAbGluayBIdWJ9IG9uIHRoZSBwYXNzZWQgb2JqZWN0J3MgX19TRU5UUllfXy5odWIgYXR0cmlidXRlCiAqIEBwYXJhbSBjYXJyaWVyIG9iamVjdAogKiBAcGFyYW0gaHViIEh1YgogKiBAcmV0dXJucyBBIGJvb2xlYW4gaW5kaWNhdGluZyBzdWNjZXNzIG9yIGZhaWx1cmUKICovCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgpmdW5jdGlvbiBzZXRIdWJPbkNhcnJpZXIoY2FycmllciwgaHViKSB7CiAgaWYgKCFjYXJyaWVyKSByZXR1cm4gZmFsc2U7CiAgY29uc3QgX19TRU5UUllfXyA9IChjYXJyaWVyLl9fU0VOVFJZX18gPSBjYXJyaWVyLl9fU0VOVFJZX18gfHwge30pOwogIF9fU0VOVFJZX18uaHViID0gaHViOwogIHJldHVybiB0cnVlOwp9CgovKioKICogQXBwbHkgU2RrSW5mbyAobmFtZSwgdmVyc2lvbiwgcGFja2FnZXMsIGludGVncmF0aW9ucykgdG8gdGhlIGNvcnJlc3BvbmRpbmcgZXZlbnQga2V5LgogKiBNZXJnZSB3aXRoIGV4aXN0aW5nIGRhdGEgaWYgYW55LgogKiovCmZ1bmN0aW9uIGVuaGFuY2VFdmVudFdpdGhTZGtJbmZvKGV2ZW50LCBzZGtJbmZvKSB7CiAgaWYgKCFzZGtJbmZvKSB7CiAgICByZXR1cm4gZXZlbnQ7CiAgfQogIGV2ZW50LnNkayA9IGV2ZW50LnNkayB8fCB7fTsKICBldmVudC5zZGsubmFtZSA9IGV2ZW50LnNkay5uYW1lIHx8IHNka0luZm8ubmFtZTsKICBldmVudC5zZGsudmVyc2lvbiA9IGV2ZW50LnNkay52ZXJzaW9uIHx8IHNka0luZm8udmVyc2lvbjsKICBldmVudC5zZGsuaW50ZWdyYXRpb25zID0gWy4uLihldmVudC5zZGsuaW50ZWdyYXRpb25zIHx8IFtdKSwgLi4uKHNka0luZm8uaW50ZWdyYXRpb25zIHx8IFtdKV07CiAgZXZlbnQuc2RrLnBhY2thZ2VzID0gWy4uLihldmVudC5zZGsucGFja2FnZXMgfHwgW10pLCAuLi4oc2RrSW5mby5wYWNrYWdlcyB8fCBbXSldOwogIHJldHVybiBldmVudDsKfQoKLyoqIENyZWF0ZXMgYW4gZW52ZWxvcGUgZnJvbSBhIFNlc3Npb24gKi8KZnVuY3Rpb24gY3JlYXRlU2Vzc2lvbkVudmVsb3BlKAogIHNlc3Npb24sCiAgZHNuLAogIG1ldGFkYXRhLAogIHR1bm5lbCwKKSB7CiAgY29uc3Qgc2RrSW5mbyA9IGdldFNka01ldGFkYXRhRm9yRW52ZWxvcGVIZWFkZXIobWV0YWRhdGEpOwogIGNvbnN0IGVudmVsb3BlSGVhZGVycyA9IHsKICAgIHNlbnRfYXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSwKICAgIC4uLihzZGtJbmZvICYmIHsgc2RrOiBzZGtJbmZvIH0pLAogICAgLi4uKCEhdHVubmVsICYmIGRzbiAmJiB7IGRzbjogZHNuVG9TdHJpbmcoZHNuKSB9KSwKICB9OwoKICBjb25zdCBlbnZlbG9wZUl0ZW0gPQogICAgJ2FnZ3JlZ2F0ZXMnIGluIHNlc3Npb24gPyBbeyB0eXBlOiAnc2Vzc2lvbnMnIH0sIHNlc3Npb25dIDogW3sgdHlwZTogJ3Nlc3Npb24nIH0sIHNlc3Npb24udG9KU09OKCldOwoKICByZXR1cm4gY3JlYXRlRW52ZWxvcGUoZW52ZWxvcGVIZWFkZXJzLCBbZW52ZWxvcGVJdGVtXSk7Cn0KCi8qKgogKiBDcmVhdGUgYW4gRW52ZWxvcGUgZnJvbSBhbiBldmVudC4KICovCmZ1bmN0aW9uIGNyZWF0ZUV2ZW50RW52ZWxvcGUoCiAgZXZlbnQsCiAgZHNuLAogIG1ldGFkYXRhLAogIHR1bm5lbCwKKSB7CiAgY29uc3Qgc2RrSW5mbyA9IGdldFNka01ldGFkYXRhRm9yRW52ZWxvcGVIZWFkZXIobWV0YWRhdGEpOwoKICAvKgogICAgTm90ZTogRHVlIHRvIFRTLCBldmVudC50eXBlIG1heSBiZSBgcmVwbGF5X2V2ZW50YCwgdGhlb3JldGljYWxseS4KICAgIEluIHByYWN0aWNlLCB3ZSBuZXZlciBjYWxsIGBjcmVhdGVFdmVudEVudmVsb3BlYCB3aXRoIGByZXBsYXlfZXZlbnRgIHR5cGUsCiAgICBhbmQgd2UnZCBoYXZlIHRvIGFkanV0IGEgbG9vb3Qgb2YgdHlwZXMgdG8gbWFrZSB0aGlzIHdvcmsgcHJvcGVybHkuCiAgICBXZSB3YW50IHRvIGF2b2lkIGNhc3RpbmcgdGhpcyBhcm91bmQsIGFzIHRoYXQgY291bGQgbGVhZCB0byBidWdzIChlLmcuIHdoZW4gd2UgYWRkIGFub3RoZXIgdHlwZSkKICAgIFNvIHRoZSBzYWZlIGNob2ljZSBpcyB0byByZWFsbHkgZ3VhcmQgYWdhaW5zdCB0aGUgcmVwbGF5X2V2ZW50IHR5cGUgaGVyZS4KICAqLwogIGNvbnN0IGV2ZW50VHlwZSA9IGV2ZW50LnR5cGUgJiYgZXZlbnQudHlwZSAhPT0gJ3JlcGxheV9ldmVudCcgPyBldmVudC50eXBlIDogJ2V2ZW50JzsKCiAgZW5oYW5jZUV2ZW50V2l0aFNka0luZm8oZXZlbnQsIG1ldGFkYXRhICYmIG1ldGFkYXRhLnNkayk7CgogIGNvbnN0IGVudmVsb3BlSGVhZGVycyA9IGNyZWF0ZUV2ZW50RW52ZWxvcGVIZWFkZXJzKGV2ZW50LCBzZGtJbmZvLCB0dW5uZWwsIGRzbik7CgogIC8vIFByZXZlbnQgdGhpcyBkYXRhICh3aGljaCwgaWYgaXQgZXhpc3RzLCB3YXMgdXNlZCBpbiBlYXJsaWVyIHN0ZXBzIGluIHRoZSBwcm9jZXNzaW5nIHBpcGVsaW5lKSBmcm9tIGJlaW5nIHNlbnQgdG8KICAvLyBzZW50cnkuIChOb3RlOiBPdXIgdXNlIG9mIHRoaXMgcHJvcGVydHkgY29tZXMgYW5kIGdvZXMgd2l0aCB3aGF0ZXZlciB3ZSBtaWdodCBiZSBkZWJ1Z2dpbmcsIHdoYXRldmVyIGhhY2tzIHdlIG1heQogIC8vIGhhdmUgdGVtcG9yYXJpbHkgYWRkZWQsIGV0Yy4gRXZlbiBpZiB3ZSBkb24ndCBoYXBwZW4gdG8gYmUgdXNpbmcgaXQgYXQgc29tZSBwb2ludCBpbiB0aGUgZnV0dXJlLCBsZXQncyBub3QgZ2V0IHJpZAogIC8vIG9mIHRoaXMgYGRlbGV0ZWAsIGxlc3Qgd2UgbWlzcyBwdXR0aW5nIGl0IGJhY2sgaW4gdGhlIG5leHQgdGltZSB0aGUgcHJvcGVydHkgaXMgaW4gdXNlLikKICBkZWxldGUgZXZlbnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhOwoKICBjb25zdCBldmVudEl0ZW0gPSBbeyB0eXBlOiBldmVudFR5cGUgfSwgZXZlbnRdOwogIHJldHVybiBjcmVhdGVFbnZlbG9wZShlbnZlbG9wZUhlYWRlcnMsIFtldmVudEl0ZW1dKTsKfQoKY29uc3QgU0VOVFJZX0FQSV9WRVJTSU9OID0gJzcnOwoKLyoqIFJldHVybnMgdGhlIHByZWZpeCB0byBjb25zdHJ1Y3QgU2VudHJ5IGluZ2VzdGlvbiBBUEkgZW5kcG9pbnRzLiAqLwpmdW5jdGlvbiBnZXRCYXNlQXBpRW5kcG9pbnQoZHNuKSB7CiAgY29uc3QgcHJvdG9jb2wgPSBkc24ucHJvdG9jb2wgPyBgJHtkc24ucHJvdG9jb2x9OmAgOiAnJzsKICBjb25zdCBwb3J0ID0gZHNuLnBvcnQgPyBgOiR7ZHNuLnBvcnR9YCA6ICcnOwogIHJldHVybiBgJHtwcm90b2NvbH0vLyR7ZHNuLmhvc3R9JHtwb3J0fSR7ZHNuLnBhdGggPyBgLyR7ZHNuLnBhdGh9YCA6ICcnfS9hcGkvYDsKfQoKLyoqIFJldHVybnMgdGhlIGluZ2VzdCBBUEkgZW5kcG9pbnQgZm9yIHRhcmdldC4gKi8KZnVuY3Rpb24gX2dldEluZ2VzdEVuZHBvaW50KGRzbikgewogIHJldHVybiBgJHtnZXRCYXNlQXBpRW5kcG9pbnQoZHNuKX0ke2Rzbi5wcm9qZWN0SWR9L2VudmVsb3BlL2A7Cn0KCi8qKiBSZXR1cm5zIGEgVVJMLWVuY29kZWQgc3RyaW5nIHdpdGggYXV0aCBjb25maWcgc3VpdGFibGUgZm9yIGEgcXVlcnkgc3RyaW5nLiAqLwpmdW5jdGlvbiBfZW5jb2RlZEF1dGgoZHNuLCBzZGtJbmZvKSB7CiAgcmV0dXJuIHVybEVuY29kZSh7CiAgICAvLyBXZSBzZW5kIG9ubHkgdGhlIG1pbmltdW0gc2V0IG9mIHJlcXVpcmVkIGluZm9ybWF0aW9uLiBTZWUKICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvaXNzdWVzLzI1NzIuCiAgICBzZW50cnlfa2V5OiBkc24ucHVibGljS2V5LAogICAgc2VudHJ5X3ZlcnNpb246IFNFTlRSWV9BUElfVkVSU0lPTiwKICAgIC4uLihzZGtJbmZvICYmIHsgc2VudHJ5X2NsaWVudDogYCR7c2RrSW5mby5uYW1lfS8ke3Nka0luZm8udmVyc2lvbn1gIH0pLAogIH0pOwp9CgovKioKICogUmV0dXJucyB0aGUgZW52ZWxvcGUgZW5kcG9pbnQgVVJMIHdpdGggYXV0aCBpbiB0aGUgcXVlcnkgc3RyaW5nLgogKgogKiBTZW5kaW5nIGF1dGggYXMgcGFydCBvZiB0aGUgcXVlcnkgc3RyaW5nIGFuZCBub3QgYXMgY3VzdG9tIEhUVFAgaGVhZGVycyBhdm9pZHMgQ09SUyBwcmVmbGlnaHQgcmVxdWVzdHMuCiAqLwpmdW5jdGlvbiBnZXRFbnZlbG9wZUVuZHBvaW50V2l0aFVybEVuY29kZWRBdXRoKAogIGRzbiwKICAvLyBUT0RPICh2OCk6IFJlbW92ZSBgdHVubmVsT3JPcHRpb25zYCBpbiBmYXZvciBvZiBgb3B0aW9uc2AsIGFuZCB1c2UgdGhlIHN1YnN0aXR1dGUgY29kZSBiZWxvdwogIC8vIG9wdGlvbnM6IENsaWVudE9wdGlvbnMgPSB7fSBhcyBDbGllbnRPcHRpb25zLAogIHR1bm5lbE9yT3B0aW9ucyA9IHt9ICwKKSB7CiAgLy8gVE9ETyAodjgpOiBVc2UgdGhpcyBjb2RlIGluc3RlYWQKICAvLyBjb25zdCB7IHR1bm5lbCwgX21ldGFkYXRhID0ge30gfSA9IG9wdGlvbnM7CiAgLy8gcmV0dXJuIHR1bm5lbCA/IHR1bm5lbCA6IGAke19nZXRJbmdlc3RFbmRwb2ludChkc24pfT8ke19lbmNvZGVkQXV0aChkc24sIF9tZXRhZGF0YS5zZGspfWA7CgogIGNvbnN0IHR1bm5lbCA9IHR5cGVvZiB0dW5uZWxPck9wdGlvbnMgPT09ICdzdHJpbmcnID8gdHVubmVsT3JPcHRpb25zIDogdHVubmVsT3JPcHRpb25zLnR1bm5lbDsKICBjb25zdCBzZGtJbmZvID0KICAgIHR5cGVvZiB0dW5uZWxPck9wdGlvbnMgPT09ICdzdHJpbmcnIHx8ICF0dW5uZWxPck9wdGlvbnMuX21ldGFkYXRhID8gdW5kZWZpbmVkIDogdHVubmVsT3JPcHRpb25zLl9tZXRhZGF0YS5zZGs7CgogIHJldHVybiB0dW5uZWwgPyB0dW5uZWwgOiBgJHtfZ2V0SW5nZXN0RW5kcG9pbnQoZHNuKX0/JHtfZW5jb2RlZEF1dGgoZHNuLCBzZGtJbmZvKX1gOwp9Cgpjb25zdCBERUZBVUxUX1RSQU5TUE9SVF9CVUZGRVJfU0laRSA9IDMwOwoKLyoqCiAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYSBTZW50cnkgYFRyYW5zcG9ydGAKICoKICogQHBhcmFtIG9wdGlvbnMKICogQHBhcmFtIG1ha2VSZXF1ZXN0CiAqLwpmdW5jdGlvbiBjcmVhdGVUcmFuc3BvcnQoCiAgb3B0aW9ucywKICBtYWtlUmVxdWVzdCwKICBidWZmZXIgPSBtYWtlUHJvbWlzZUJ1ZmZlcigKICAgIG9wdGlvbnMuYnVmZmVyU2l6ZSB8fCBERUZBVUxUX1RSQU5TUE9SVF9CVUZGRVJfU0laRSwKICApLAopIHsKICBsZXQgcmF0ZUxpbWl0cyA9IHt9OwogIGNvbnN0IGZsdXNoID0gKHRpbWVvdXQpID0+IGJ1ZmZlci5kcmFpbih0aW1lb3V0KTsKCiAgZnVuY3Rpb24gc2VuZChlbnZlbG9wZSkgewogICAgY29uc3QgZmlsdGVyZWRFbnZlbG9wZUl0ZW1zID0gW107CgogICAgLy8gRHJvcCByYXRlIGxpbWl0ZWQgaXRlbXMgZnJvbSBlbnZlbG9wZQogICAgZm9yRWFjaEVudmVsb3BlSXRlbShlbnZlbG9wZSwgKGl0ZW0sIHR5cGUpID0+IHsKICAgICAgY29uc3QgZGF0YUNhdGVnb3J5ID0gZW52ZWxvcGVJdGVtVHlwZVRvRGF0YUNhdGVnb3J5KHR5cGUpOwogICAgICBpZiAoaXNSYXRlTGltaXRlZChyYXRlTGltaXRzLCBkYXRhQ2F0ZWdvcnkpKSB7CiAgICAgICAgY29uc3QgZXZlbnQgPSBnZXRFdmVudEZvckVudmVsb3BlSXRlbShpdGVtLCB0eXBlKTsKICAgICAgICBvcHRpb25zLnJlY29yZERyb3BwZWRFdmVudCgncmF0ZWxpbWl0X2JhY2tvZmYnLCBkYXRhQ2F0ZWdvcnksIGV2ZW50KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmaWx0ZXJlZEVudmVsb3BlSXRlbXMucHVzaChpdGVtKTsKICAgICAgfQogICAgfSk7CgogICAgLy8gU2tpcCBzZW5kaW5nIGlmIGVudmVsb3BlIGlzIGVtcHR5IGFmdGVyIGZpbHRlcmluZyBvdXQgcmF0ZSBsaW1pdGVkIGV2ZW50cwogICAgaWYgKGZpbHRlcmVkRW52ZWxvcGVJdGVtcy5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuIHJlc29sdmVkU3luY1Byb21pc2UoKTsKICAgIH0KCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQogICAgY29uc3QgZmlsdGVyZWRFbnZlbG9wZSA9IGNyZWF0ZUVudmVsb3BlKGVudmVsb3BlWzBdLCBmaWx0ZXJlZEVudmVsb3BlSXRlbXMgKTsKCiAgICAvLyBDcmVhdGVzIGNsaWVudCByZXBvcnQgZm9yIGVhY2ggaXRlbSBpbiBhbiBlbnZlbG9wZQogICAgY29uc3QgcmVjb3JkRW52ZWxvcGVMb3NzID0gKHJlYXNvbikgPT4gewogICAgICBmb3JFYWNoRW52ZWxvcGVJdGVtKGZpbHRlcmVkRW52ZWxvcGUsIChpdGVtLCB0eXBlKSA9PiB7CiAgICAgICAgY29uc3QgZXZlbnQgPSBnZXRFdmVudEZvckVudmVsb3BlSXRlbShpdGVtLCB0eXBlKTsKICAgICAgICBvcHRpb25zLnJlY29yZERyb3BwZWRFdmVudChyZWFzb24sIGVudmVsb3BlSXRlbVR5cGVUb0RhdGFDYXRlZ29yeSh0eXBlKSwgZXZlbnQpOwogICAgICB9KTsKICAgIH07CgogICAgY29uc3QgcmVxdWVzdFRhc2sgPSAoKSA9PgogICAgICBtYWtlUmVxdWVzdCh7IGJvZHk6IHNlcmlhbGl6ZUVudmVsb3BlKGZpbHRlcmVkRW52ZWxvcGUsIG9wdGlvbnMudGV4dEVuY29kZXIpIH0pLnRoZW4oCiAgICAgICAgcmVzcG9uc2UgPT4gewogICAgICAgICAgLy8gV2UgZG9uJ3Qgd2FudCB0byB0aHJvdyBvbiBOT0sgcmVzcG9uc2VzLCBidXQgd2Ugd2FudCB0byBhdCBsZWFzdCBsb2cgdGhlbQogICAgICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IHVuZGVmaW5lZCAmJiAocmVzcG9uc2Uuc3RhdHVzQ29kZSA8IDIwMCB8fCByZXNwb25zZS5zdGF0dXNDb2RlID49IDMwMCkpIHsKICAgICAgICAgICAgREVCVUdfQlVJTEQgJiYgbG9nZ2VyLndhcm4oYFNlbnRyeSByZXNwb25kZWQgd2l0aCBzdGF0dXMgY29kZSAke3Jlc3BvbnNlLnN0YXR1c0NvZGV9IHRvIHNlbnQgZXZlbnQuYCk7CiAgICAgICAgICB9CgogICAgICAgICAgcmF0ZUxpbWl0cyA9IHVwZGF0ZVJhdGVMaW1pdHMocmF0ZUxpbWl0cywgcmVzcG9uc2UpOwogICAgICAgICAgcmV0dXJuIHJlc3BvbnNlOwogICAgICAgIH0sCiAgICAgICAgZXJyb3IgPT4gewogICAgICAgICAgcmVjb3JkRW52ZWxvcGVMb3NzKCduZXR3b3JrX2Vycm9yJyk7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9LAogICAgICApOwoKICAgIHJldHVybiBidWZmZXIuYWRkKHJlcXVlc3RUYXNrKS50aGVuKAogICAgICByZXN1bHQgPT4gcmVzdWx0LAogICAgICBlcnJvciA9PiB7CiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgU2VudHJ5RXJyb3IpIHsKICAgICAgICAgIERFQlVHX0JVSUxEICYmIGxvZ2dlci5lcnJvcignU2tpcHBlZCBzZW5kaW5nIGV2ZW50IGJlY2F1c2UgYnVmZmVyIGlzIGZ1bGwuJyk7CiAgICAgICAgICByZWNvcmRFbnZlbG9wZUxvc3MoJ3F1ZXVlX292ZXJmbG93Jyk7CiAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRTeW5jUHJvbWlzZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICAgIH0sCiAgICApOwogIH0KCiAgLy8gV2UgdXNlIHRoaXMgdG8gaWRlbnRpZmlmeSBpZiB0aGUgdHJhbnNwb3J0IGlzIHRoZSBiYXNlIHRyYW5zcG9ydAogIC8vIFRPRE8gKHY4KTogUmVtb3ZlIHRoaXMgYWdhaW4gYXMgd2UnbGwgbm8gbG9uZ2VyIG5lZWQgaXQKICBzZW5kLl9fc2VudHJ5X19iYXNlVHJhbnNwb3J0X18gPSB0cnVlOwoKICByZXR1cm4gewogICAgc2VuZCwKICAgIGZsdXNoLAogIH07Cn0KCmZ1bmN0aW9uIGdldEV2ZW50Rm9yRW52ZWxvcGVJdGVtKGl0ZW0sIHR5cGUpIHsKICBpZiAodHlwZSAhPT0gJ2V2ZW50JyAmJiB0eXBlICE9PSAndHJhbnNhY3Rpb24nKSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoaXRlbSkgPyAoaXRlbSApWzFdIDogdW5kZWZpbmVkOwp9CgovKiogbm9ybWFsaXplcyBXaW5kb3dzIHBhdGhzICovCmZ1bmN0aW9uIG5vcm1hbGl6ZVdpbmRvd3NQYXRoKHBhdGgpIHsKICByZXR1cm4gcGF0aAogICAgLnJlcGxhY2UoL15bQS1aXTovLCAnJykgLy8gcmVtb3ZlIFdpbmRvd3Mtc3R5bGUgcHJlZml4CiAgICAucmVwbGFjZSgvXFwvZywgJy8nKTsgLy8gcmVwbGFjZSBhbGwgYFxgIGluc3RhbmNlcyB3aXRoIGAvYAp9CgovKiogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgZ2V0cyB0aGUgbW9kdWxlIG5hbWUgZnJvbSBhIGZpbGVuYW1lICovCmZ1bmN0aW9uIGNyZWF0ZUdldE1vZHVsZUZyb21GaWxlbmFtZSgKICBiYXNlUGF0aCA9IHByb2Nlc3MuYXJndlsxXSA/IGRpcm5hbWUocHJvY2Vzcy5hcmd2WzFdKSA6IHByb2Nlc3MuY3dkKCksCiAgaXNXaW5kb3dzID0gc2VwID09PSAnXFwnLAopIHsKICBjb25zdCBub3JtYWxpemVkQmFzZSA9IGlzV2luZG93cyA/IG5vcm1hbGl6ZVdpbmRvd3NQYXRoKGJhc2VQYXRoKSA6IGJhc2VQYXRoOwoKICByZXR1cm4gKGZpbGVuYW1lKSA9PiB7CiAgICBpZiAoIWZpbGVuYW1lKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICBjb25zdCBub3JtYWxpemVkRmlsZW5hbWUgPSBpc1dpbmRvd3MgPyBub3JtYWxpemVXaW5kb3dzUGF0aChmaWxlbmFtZSkgOiBmaWxlbmFtZTsKCiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0CiAgICBsZXQgeyBkaXIsIGJhc2U6IGZpbGUsIGV4dCB9ID0gcG9zaXgucGFyc2Uobm9ybWFsaXplZEZpbGVuYW1lKTsKCiAgICBpZiAoZXh0ID09PSAnLmpzJyB8fCBleHQgPT09ICcubWpzJyB8fCBleHQgPT09ICcuY2pzJykgewogICAgICBmaWxlID0gZmlsZS5zbGljZSgwLCBleHQubGVuZ3RoICogLTEpOwogICAgfQoKICAgIGlmICghZGlyKSB7CiAgICAgIC8vIE5vIGRpcm5hbWUgd2hhdHNvZXZlcgogICAgICBkaXIgPSAnLic7CiAgICB9CgogICAgY29uc3QgbiA9IGRpci5sYXN0SW5kZXhPZignL25vZGVfbW9kdWxlcycpOwogICAgaWYgKG4gPiAtMSkgewogICAgICByZXR1cm4gYCR7ZGlyLnNsaWNlKG4gKyAxNCkucmVwbGFjZSgvXC8vZywgJy4nKX06JHtmaWxlfWA7CiAgICB9CgogICAgLy8gTGV0J3Mgc2VlIGlmIGl0J3MgYSBwYXJ0IG9mIHRoZSBtYWluIG1vZHVsZQogICAgLy8gVG8gYmUgYSBwYXJ0IG9mIG1haW4gbW9kdWxlLCBpdCBoYXMgdG8gc2hhcmUgdGhlIHNhbWUgYmFzZQogICAgaWYgKGRpci5zdGFydHNXaXRoKG5vcm1hbGl6ZWRCYXNlKSkgewogICAgICBsZXQgbW9kdWxlTmFtZSA9IGRpci5zbGljZShub3JtYWxpemVkQmFzZS5sZW5ndGggKyAxKS5yZXBsYWNlKC9cLy9nLCAnLicpOwoKICAgICAgaWYgKG1vZHVsZU5hbWUpIHsKICAgICAgICBtb2R1bGVOYW1lICs9ICc6JzsKICAgICAgfQogICAgICBtb2R1bGVOYW1lICs9IGZpbGU7CgogICAgICByZXR1cm4gbW9kdWxlTmFtZTsKICAgIH0KCiAgICByZXR1cm4gZmlsZTsKICB9Owp9CgpmdW5jdGlvbiBfbnVsbGlzaENvYWxlc2NlJDIobGhzLCByaHNGbikgeyBpZiAobGhzICE9IG51bGwpIHsgcmV0dXJuIGxoczsgfSBlbHNlIHsgcmV0dXJuIHJoc0ZuKCk7IH0gfS8qKgogKiBUaGlzIGNvZGUgd2FzIG9yaWdpbmFsbHkgZm9ya2VkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL1Rvb1RhbGxOYXRlL3Byb3h5LWFnZW50cy90cmVlL2IxMzMyOTVmZDE2ZjY0NzU1NzhiNmIxNWJkOWI0ZTMzZWNiMGQwYjcKICogV2l0aCB0aGUgZm9sbG93aW5nIGxpY2VuY2U6CiAqCiAqIChUaGUgTUlUIExpY2Vuc2UpCiAqCiAqIENvcHlyaWdodCAoYykgMjAxMyBOYXRoYW4gUmFqbGljaCA8bmF0aGFuQHRvb3RhbGxuYXRlLm5ldD4qCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwogKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKICogJ1NvZnR3YXJlJyksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZwogKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bwogKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOioKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUKICogaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuKgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgJ0FTIElTJywgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKICogRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GCiAqIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4KICogSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkKICogQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwKICogVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUKICogU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCiAqLwoKY29uc3QgSU5URVJOQUwgPSBTeW1ib2woJ0FnZW50QmFzZUludGVybmFsU3RhdGUnKTsKCmNsYXNzIEFnZW50IGV4dGVuZHMgaHR0cC5BZ2VudCB7CgogIC8vIFNldCBieSBgaHR0cC5BZ2VudGAgLSBtaXNzaW5nIGZyb20gYEB0eXBlcy9ub2RlYAoKICBjb25zdHJ1Y3RvcihvcHRzKSB7CiAgICBzdXBlcihvcHRzKTsKICAgIHRoaXNbSU5URVJOQUxdID0ge307CiAgfQoKICAvKioKICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGlzIGlzIGFuIGBodHRwYCBvciBgaHR0cHNgIHJlcXVlc3QuCiAgICovCiAgaXNTZWN1cmVFbmRwb2ludChvcHRpb25zKSB7CiAgICBpZiAob3B0aW9ucykgewogICAgICAvLyBGaXJzdCBjaGVjayB0aGUgYHNlY3VyZUVuZHBvaW50YCBwcm9wZXJ0eSBleHBsaWNpdGx5LCBzaW5jZSB0aGlzCiAgICAgIC8vIG1lYW5zIHRoYXQgYSBwYXJlbnQgYEFnZW50YCBpcyAicGFzc2luZyB0aHJvdWdoIiB0byB0aGlzIGluc3RhbmNlLgogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzCiAgICAgIGlmICh0eXBlb2YgKG9wdGlvbnMgKS5zZWN1cmVFbmRwb2ludCA9PT0gJ2Jvb2xlYW4nKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbnMuc2VjdXJlRW5kcG9pbnQ7CiAgICAgIH0KCiAgICAgIC8vIElmIG5vIGV4cGxpY2l0IGBzZWN1cmVgIGVuZHBvaW50LCBjaGVjayBpZiBgcHJvdG9jb2xgIHByb3BlcnR5IGlzCiAgICAgIC8vIHNldC4gVGhpcyB3aWxsIHVzdWFsbHkgYmUgdGhlIGNhc2Ugc2luY2UgdXNpbmcgYSBmdWxsIHN0cmluZyBVUkwKICAgICAgLy8gb3IgYFVSTGAgaW5zdGFuY2Ugc2hvdWxkIGJlIHRoZSBtb3N0IGNvbW1vbiB1c2FnZS4KICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnByb3RvY29sID09PSAnc3RyaW5nJykgewogICAgICAgIHJldHVybiBvcHRpb25zLnByb3RvY29sID09PSAnaHR0cHM6JzsKICAgICAgfQogICAgfQoKICAgIC8vIEZpbmFsbHksIGlmIG5vIGBwcm90b2NvbGAgcHJvcGVydHkgd2FzIHNldCwgdGhlbiBmYWxsIGJhY2sgdG8KICAgIC8vIGNoZWNraW5nIHRoZSBzdGFjayB0cmFjZSBvZiB0aGUgY3VycmVudCBjYWxsIHN0YWNrLCBhbmQgdHJ5IHRvCiAgICAvLyBkZXRlY3QgdGhlICJodHRwcyIgbW9kdWxlLgogICAgY29uc3QgeyBzdGFjayB9ID0gbmV3IEVycm9yKCk7CiAgICBpZiAodHlwZW9mIHN0YWNrICE9PSAnc3RyaW5nJykgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHN0YWNrLnNwbGl0KCdcbicpLnNvbWUobCA9PiBsLmluZGV4T2YoJyhodHRwcy5qczonKSAhPT0gLTEgfHwgbC5pbmRleE9mKCdub2RlOmh0dHBzOicpICE9PSAtMSk7CiAgfQoKICBjcmVhdGVTb2NrZXQocmVxLCBvcHRpb25zLCBjYikgewogICAgY29uc3QgY29ubmVjdE9wdHMgPSB7CiAgICAgIC4uLm9wdGlvbnMsCiAgICAgIHNlY3VyZUVuZHBvaW50OiB0aGlzLmlzU2VjdXJlRW5kcG9pbnQob3B0aW9ucyksCiAgICB9OwogICAgUHJvbWlzZS5yZXNvbHZlKCkKICAgICAgLnRoZW4oKCkgPT4gdGhpcy5jb25uZWN0KHJlcSwgY29ubmVjdE9wdHMpKQogICAgICAudGhlbihzb2NrZXQgPT4gewogICAgICAgIGlmIChzb2NrZXQgaW5zdGFuY2VvZiBodHRwLkFnZW50KSB7CiAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGBhZGRSZXF1ZXN0KClgIGlzbid0IGRlZmluZWQgaW4gYEB0eXBlcy9ub2RlYAogICAgICAgICAgcmV0dXJuIHNvY2tldC5hZGRSZXF1ZXN0KHJlcSwgY29ubmVjdE9wdHMpOwogICAgICAgIH0KICAgICAgICB0aGlzW0lOVEVSTkFMXS5jdXJyZW50U29ja2V0ID0gc29ja2V0OwogICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgYGNyZWF0ZVNvY2tldCgpYCBpc24ndCBkZWZpbmVkIGluIGBAdHlwZXMvbm9kZWAKICAgICAgICBzdXBlci5jcmVhdGVTb2NrZXQocmVxLCBvcHRpb25zLCBjYik7CiAgICAgIH0sIGNiKTsKICB9CgogIGNyZWF0ZUNvbm5lY3Rpb24oKSB7CiAgICBjb25zdCBzb2NrZXQgPSB0aGlzW0lOVEVSTkFMXS5jdXJyZW50U29ja2V0OwogICAgdGhpc1tJTlRFUk5BTF0uY3VycmVudFNvY2tldCA9IHVuZGVmaW5lZDsKICAgIGlmICghc29ja2V0KSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gc29ja2V0IHdhcyByZXR1cm5lZCBpbiB0aGUgYGNvbm5lY3QoKWAgZnVuY3Rpb24nKTsKICAgIH0KICAgIHJldHVybiBzb2NrZXQ7CiAgfQoKICBnZXQgZGVmYXVsdFBvcnQoKSB7CiAgICByZXR1cm4gX251bGxpc2hDb2FsZXNjZSQyKHRoaXNbSU5URVJOQUxdLmRlZmF1bHRQb3J0LCAoKSA9PiAoICh0aGlzLnByb3RvY29sID09PSAnaHR0cHM6JyA/IDQ0MyA6IDgwKSkpOwogIH0KCiAgc2V0IGRlZmF1bHRQb3J0KHYpIHsKICAgIGlmICh0aGlzW0lOVEVSTkFMXSkgewogICAgICB0aGlzW0lOVEVSTkFMXS5kZWZhdWx0UG9ydCA9IHY7CiAgICB9CiAgfQoKICBnZXQgcHJvdG9jb2woKSB7CiAgICByZXR1cm4gX251bGxpc2hDb2FsZXNjZSQyKHRoaXNbSU5URVJOQUxdLnByb3RvY29sLCAoKSA9PiAoICh0aGlzLmlzU2VjdXJlRW5kcG9pbnQoKSA/ICdodHRwczonIDogJ2h0dHA6JykpKTsKICB9CgogIHNldCBwcm90b2NvbCh2KSB7CiAgICBpZiAodGhpc1tJTlRFUk5BTF0pIHsKICAgICAgdGhpc1tJTlRFUk5BTF0ucHJvdG9jb2wgPSB2OwogICAgfQogIH0KfQoKZnVuY3Rpb24gZGVidWckMSguLi5hcmdzKSB7CiAgbG9nZ2VyLmxvZygnW2h0dHBzLXByb3h5LWFnZW50OnBhcnNlLXByb3h5LXJlc3BvbnNlXScsIC4uLmFyZ3MpOwp9CgpmdW5jdGlvbiBwYXJzZVByb3h5UmVzcG9uc2Uoc29ja2V0KSB7CiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgIC8vIHdlIG5lZWQgdG8gYnVmZmVyIGFueSBIVFRQIHRyYWZmaWMgdGhhdCBoYXBwZW5zIHdpdGggdGhlIHByb3h5IGJlZm9yZSB3ZSBnZXQKICAgIC8vIHRoZSBDT05ORUNUIHJlc3BvbnNlLCBzbyB0aGF0IGlmIHRoZSByZXNwb25zZSBpcyBhbnl0aGluZyBvdGhlciB0aGFuIGFuICIyMDAiCiAgICAvLyByZXNwb25zZSBjb2RlLCB0aGVuIHdlIGNhbiByZS1wbGF5IHRoZSAiZGF0YSIgZXZlbnRzIG9uIHRoZSBzb2NrZXQgb25jZSB0aGUKICAgIC8vIEhUVFAgcGFyc2VyIGlzIGhvb2tlZCB1cC4uLgogICAgbGV0IGJ1ZmZlcnNMZW5ndGggPSAwOwogICAgY29uc3QgYnVmZmVycyA9IFtdOwoKICAgIGZ1bmN0aW9uIHJlYWQoKSB7CiAgICAgIGNvbnN0IGIgPSBzb2NrZXQucmVhZCgpOwogICAgICBpZiAoYikgb25kYXRhKGIpOwogICAgICBlbHNlIHNvY2tldC5vbmNlKCdyZWFkYWJsZScsIHJlYWQpOwogICAgfQoKICAgIGZ1bmN0aW9uIGNsZWFudXAoKSB7CiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpOwogICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7CiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcigncmVhZGFibGUnLCByZWFkKTsKICAgIH0KCiAgICBmdW5jdGlvbiBvbmVuZCgpIHsKICAgICAgY2xlYW51cCgpOwogICAgICBkZWJ1ZyQxKCdvbmVuZCcpOwogICAgICByZWplY3QobmV3IEVycm9yKCdQcm94eSBjb25uZWN0aW9uIGVuZGVkIGJlZm9yZSByZWNlaXZpbmcgQ09OTkVDVCByZXNwb25zZScpKTsKICAgIH0KCiAgICBmdW5jdGlvbiBvbmVycm9yKGVycikgewogICAgICBjbGVhbnVwKCk7CiAgICAgIGRlYnVnJDEoJ29uZXJyb3IgJW8nLCBlcnIpOwogICAgICByZWplY3QoZXJyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBvbmRhdGEoYikgewogICAgICBidWZmZXJzLnB1c2goYik7CiAgICAgIGJ1ZmZlcnNMZW5ndGggKz0gYi5sZW5ndGg7CgogICAgICBjb25zdCBidWZmZXJlZCA9IEJ1ZmZlci5jb25jYXQoYnVmZmVycywgYnVmZmVyc0xlbmd0aCk7CiAgICAgIGNvbnN0IGVuZE9mSGVhZGVycyA9IGJ1ZmZlcmVkLmluZGV4T2YoJ1xyXG5cclxuJyk7CgogICAgICBpZiAoZW5kT2ZIZWFkZXJzID09PSAtMSkgewogICAgICAgIC8vIGtlZXAgYnVmZmVyaW5nCiAgICAgICAgZGVidWckMSgnaGF2ZSBub3QgcmVjZWl2ZWQgZW5kIG9mIEhUVFAgaGVhZGVycyB5ZXQuLi4nKTsKICAgICAgICByZWFkKCk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICBjb25zdCBoZWFkZXJQYXJ0cyA9IGJ1ZmZlcmVkLnNsaWNlKDAsIGVuZE9mSGVhZGVycykudG9TdHJpbmcoJ2FzY2lpJykuc3BsaXQoJ1xyXG4nKTsKICAgICAgY29uc3QgZmlyc3RMaW5lID0gaGVhZGVyUGFydHMuc2hpZnQoKTsKICAgICAgaWYgKCFmaXJzdExpbmUpIHsKICAgICAgICBzb2NrZXQuZGVzdHJveSgpOwogICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlJykpOwogICAgICB9CiAgICAgIGNvbnN0IGZpcnN0TGluZVBhcnRzID0gZmlyc3RMaW5lLnNwbGl0KCcgJyk7CiAgICAgIGNvbnN0IHN0YXR1c0NvZGUgPSArZmlyc3RMaW5lUGFydHNbMV07CiAgICAgIGNvbnN0IHN0YXR1c1RleHQgPSBmaXJzdExpbmVQYXJ0cy5zbGljZSgyKS5qb2luKCcgJyk7CiAgICAgIGNvbnN0IGhlYWRlcnMgPSB7fTsKICAgICAgZm9yIChjb25zdCBoZWFkZXIgb2YgaGVhZGVyUGFydHMpIHsKICAgICAgICBpZiAoIWhlYWRlcikgY29udGludWU7CiAgICAgICAgY29uc3QgZmlyc3RDb2xvbiA9IGhlYWRlci5pbmRleE9mKCc6Jyk7CiAgICAgICAgaWYgKGZpcnN0Q29sb24gPT09IC0xKSB7CiAgICAgICAgICBzb2NrZXQuZGVzdHJveSgpOwogICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoYEludmFsaWQgaGVhZGVyIGZyb20gcHJveHkgQ09OTkVDVCByZXNwb25zZTogIiR7aGVhZGVyfSJgKSk7CiAgICAgICAgfQogICAgICAgIGNvbnN0IGtleSA9IGhlYWRlci5zbGljZSgwLCBmaXJzdENvbG9uKS50b0xvd2VyQ2FzZSgpOwogICAgICAgIGNvbnN0IHZhbHVlID0gaGVhZGVyLnNsaWNlKGZpcnN0Q29sb24gKyAxKS50cmltU3RhcnQoKTsKICAgICAgICBjb25zdCBjdXJyZW50ID0gaGVhZGVyc1trZXldOwogICAgICAgIGlmICh0eXBlb2YgY3VycmVudCA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgIGhlYWRlcnNba2V5XSA9IFtjdXJyZW50LCB2YWx1ZV07CiAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGN1cnJlbnQpKSB7CiAgICAgICAgICBjdXJyZW50LnB1c2godmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBoZWFkZXJzW2tleV0gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZGVidWckMSgnZ290IHByb3h5IHNlcnZlciByZXNwb25zZTogJW8gJW8nLCBmaXJzdExpbmUsIGhlYWRlcnMpOwogICAgICBjbGVhbnVwKCk7CiAgICAgIHJlc29sdmUoewogICAgICAgIGNvbm5lY3Q6IHsKICAgICAgICAgIHN0YXR1c0NvZGUsCiAgICAgICAgICBzdGF0dXNUZXh0LAogICAgICAgICAgaGVhZGVycywKICAgICAgICB9LAogICAgICAgIGJ1ZmZlcmVkLAogICAgICB9KTsKICAgIH0KCiAgICBzb2NrZXQub24oJ2Vycm9yJywgb25lcnJvcik7CiAgICBzb2NrZXQub24oJ2VuZCcsIG9uZW5kKTsKCiAgICByZWFkKCk7CiAgfSk7Cn0KCmZ1bmN0aW9uIF9udWxsaXNoQ29hbGVzY2UkMShsaHMsIHJoc0ZuKSB7IGlmIChsaHMgIT0gbnVsbCkgeyByZXR1cm4gbGhzOyB9IGVsc2UgeyByZXR1cm4gcmhzRm4oKTsgfSB9IGZ1bmN0aW9uIF9vcHRpb25hbENoYWluJDEob3BzKSB7IGxldCBsYXN0QWNjZXNzTEhTID0gdW5kZWZpbmVkOyBsZXQgdmFsdWUgPSBvcHNbMF07IGxldCBpID0gMTsgd2hpbGUgKGkgPCBvcHMubGVuZ3RoKSB7IGNvbnN0IG9wID0gb3BzW2ldOyBjb25zdCBmbiA9IG9wc1tpICsgMV07IGkgKz0gMjsgaWYgKChvcCA9PT0gJ29wdGlvbmFsQWNjZXNzJyB8fCBvcCA9PT0gJ29wdGlvbmFsQ2FsbCcpICYmIHZhbHVlID09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBpZiAob3AgPT09ICdhY2Nlc3MnIHx8IG9wID09PSAnb3B0aW9uYWxBY2Nlc3MnKSB7IGxhc3RBY2Nlc3NMSFMgPSB2YWx1ZTsgdmFsdWUgPSBmbih2YWx1ZSk7IH0gZWxzZSBpZiAob3AgPT09ICdjYWxsJyB8fCBvcCA9PT0gJ29wdGlvbmFsQ2FsbCcpIHsgdmFsdWUgPSBmbigoLi4uYXJncykgPT4gdmFsdWUuY2FsbChsYXN0QWNjZXNzTEhTLCAuLi5hcmdzKSk7IGxhc3RBY2Nlc3NMSFMgPSB1bmRlZmluZWQ7IH0gfSByZXR1cm4gdmFsdWU7IH0KCmZ1bmN0aW9uIGRlYnVnKC4uLmFyZ3MpIHsKICBsb2dnZXIubG9nKCdbaHR0cHMtcHJveHktYWdlbnRdJywgLi4uYXJncyk7Cn0KCi8qKgogKiBUaGUgYEh0dHBzUHJveHlBZ2VudGAgaW1wbGVtZW50cyBhbiBIVFRQIEFnZW50IHN1YmNsYXNzIHRoYXQgY29ubmVjdHMgdG8KICogdGhlIHNwZWNpZmllZCAiSFRUUChzKSBwcm94eSBzZXJ2ZXIiIGluIG9yZGVyIHRvIHByb3h5IEhUVFBTIHJlcXVlc3RzLgogKgogKiBPdXRnb2luZyBIVFRQIHJlcXVlc3RzIGFyZSBmaXJzdCB0dW5uZWxlZCB0aHJvdWdoIHRoZSBwcm94eSBzZXJ2ZXIgdXNpbmcgdGhlCiAqIGBDT05ORUNUYCBIVFRQIHJlcXVlc3QgbWV0aG9kIHRvIGVzdGFibGlzaCBhIGNvbm5lY3Rpb24gdG8gdGhlIHByb3h5IHNlcnZlciwKICogYW5kIHRoZW4gdGhlIHByb3h5IHNlcnZlciBjb25uZWN0cyB0byB0aGUgZGVzdGluYXRpb24gdGFyZ2V0IGFuZCBpc3N1ZXMgdGhlCiAqIEhUVFAgcmVxdWVzdCBmcm9tIHRoZSBwcm94eSBzZXJ2ZXIuCiAqCiAqIGBodHRwczpgIHJlcXVlc3RzIGhhdmUgdGhlaXIgc29ja2V0IGNvbm5lY3Rpb24gdXBncmFkZWQgdG8gVExTIG9uY2UKICogdGhlIGNvbm5lY3Rpb24gdG8gdGhlIHByb3h5IHNlcnZlciBoYXMgYmVlbiBlc3RhYmxpc2hlZC4KICovCmNsYXNzIEh0dHBzUHJveHlBZ2VudCBleHRlbmRzIEFnZW50IHsKICBzdGF0aWMgX19pbml0U3RhdGljKCkge3RoaXMucHJvdG9jb2xzID0gWydodHRwJywgJ2h0dHBzJ107IH0KCiAgY29uc3RydWN0b3IocHJveHksIG9wdHMpIHsKICAgIHN1cGVyKG9wdHMpOwogICAgdGhpcy5vcHRpb25zID0ge307CiAgICB0aGlzLnByb3h5ID0gdHlwZW9mIHByb3h5ID09PSAnc3RyaW5nJyA/IG5ldyBVUkwocHJveHkpIDogcHJveHk7CiAgICB0aGlzLnByb3h5SGVhZGVycyA9IF9udWxsaXNoQ29hbGVzY2UkMShfb3B0aW9uYWxDaGFpbiQxKFtvcHRzLCAnb3B0aW9uYWxBY2Nlc3MnLCBfMiA9PiBfMi5oZWFkZXJzXSksICgpID0+ICgge30pKTsKICAgIGRlYnVnKCdDcmVhdGluZyBuZXcgSHR0cHNQcm94eUFnZW50IGluc3RhbmNlOiAlbycsIHRoaXMucHJveHkuaHJlZik7CgogICAgLy8gVHJpbSBvZmYgdGhlIGJyYWNrZXRzIGZyb20gSVB2NiBhZGRyZXNzZXMKICAgIGNvbnN0IGhvc3QgPSAodGhpcy5wcm94eS5ob3N0bmFtZSB8fCB0aGlzLnByb3h5Lmhvc3QpLnJlcGxhY2UoL15cW3xcXSQvZywgJycpOwogICAgY29uc3QgcG9ydCA9IHRoaXMucHJveHkucG9ydCA/IHBhcnNlSW50KHRoaXMucHJveHkucG9ydCwgMTApIDogdGhpcy5wcm94eS5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyA0NDMgOiA4MDsKICAgIHRoaXMuY29ubmVjdE9wdHMgPSB7CiAgICAgIC8vIEF0dGVtcHQgdG8gbmVnb3RpYXRlIGh0dHAvMS4xIGZvciBwcm94eSBzZXJ2ZXJzIHRoYXQgc3VwcG9ydCBodHRwLzIKICAgICAgQUxQTlByb3RvY29sczogWydodHRwLzEuMSddLAogICAgICAuLi4ob3B0cyA/IG9taXQob3B0cywgJ2hlYWRlcnMnKSA6IG51bGwpLAogICAgICBob3N0LAogICAgICBwb3J0LAogICAgfTsKICB9CgogIC8qKgogICAqIENhbGxlZCB3aGVuIHRoZSBub2RlLWNvcmUgSFRUUCBjbGllbnQgbGlicmFyeSBpcyBjcmVhdGluZyBhCiAgICogbmV3IEhUVFAgcmVxdWVzdC4KICAgKi8KICBhc3luYyBjb25uZWN0KHJlcSwgb3B0cykgewogICAgY29uc3QgeyBwcm94eSB9ID0gdGhpczsKCiAgICBpZiAoIW9wdHMuaG9zdCkgewogICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdObyAiaG9zdCIgcHJvdmlkZWQnKTsKICAgIH0KCiAgICAvLyBDcmVhdGUgYSBzb2NrZXQgY29ubmVjdGlvbiB0byB0aGUgcHJveHkgc2VydmVyLgogICAgbGV0IHNvY2tldDsKICAgIGlmIChwcm94eS5wcm90b2NvbCA9PT0gJ2h0dHBzOicpIHsKICAgICAgZGVidWcoJ0NyZWF0aW5nIGB0bHMuU29ja2V0YDogJW8nLCB0aGlzLmNvbm5lY3RPcHRzKTsKICAgICAgY29uc3Qgc2VydmVybmFtZSA9IHRoaXMuY29ubmVjdE9wdHMuc2VydmVybmFtZSB8fCB0aGlzLmNvbm5lY3RPcHRzLmhvc3Q7CiAgICAgIHNvY2tldCA9IHRscy5jb25uZWN0KHsKICAgICAgICAuLi50aGlzLmNvbm5lY3RPcHRzLAogICAgICAgIHNlcnZlcm5hbWU6IHNlcnZlcm5hbWUgJiYgbmV0LmlzSVAoc2VydmVybmFtZSkgPyB1bmRlZmluZWQgOiBzZXJ2ZXJuYW1lLAogICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgIGRlYnVnKCdDcmVhdGluZyBgbmV0LlNvY2tldGA6ICVvJywgdGhpcy5jb25uZWN0T3B0cyk7CiAgICAgIHNvY2tldCA9IG5ldC5jb25uZWN0KHRoaXMuY29ubmVjdE9wdHMpOwogICAgfQoKICAgIGNvbnN0IGhlYWRlcnMgPQogICAgICB0eXBlb2YgdGhpcy5wcm94eUhlYWRlcnMgPT09ICdmdW5jdGlvbicgPyB0aGlzLnByb3h5SGVhZGVycygpIDogeyAuLi50aGlzLnByb3h5SGVhZGVycyB9OwogICAgY29uc3QgaG9zdCA9IG5ldC5pc0lQdjYob3B0cy5ob3N0KSA/IGBbJHtvcHRzLmhvc3R9XWAgOiBvcHRzLmhvc3Q7CiAgICBsZXQgcGF5bG9hZCA9IGBDT05ORUNUICR7aG9zdH06JHtvcHRzLnBvcnR9IEhUVFAvMS4xXHJcbmA7CgogICAgLy8gSW5qZWN0IHRoZSBgUHJveHktQXV0aG9yaXphdGlvbmAgaGVhZGVyIGlmIG5lY2Vzc2FyeS4KICAgIGlmIChwcm94eS51c2VybmFtZSB8fCBwcm94eS5wYXNzd29yZCkgewogICAgICBjb25zdCBhdXRoID0gYCR7ZGVjb2RlVVJJQ29tcG9uZW50KHByb3h5LnVzZXJuYW1lKX06JHtkZWNvZGVVUklDb21wb25lbnQocHJveHkucGFzc3dvcmQpfWA7CiAgICAgIGhlYWRlcnNbJ1Byb3h5LUF1dGhvcml6YXRpb24nXSA9IGBCYXNpYyAke0J1ZmZlci5mcm9tKGF1dGgpLnRvU3RyaW5nKCdiYXNlNjQnKX1gOwogICAgfQoKICAgIGhlYWRlcnMuSG9zdCA9IGAke2hvc3R9OiR7b3B0cy5wb3J0fWA7CgogICAgaWYgKCFoZWFkZXJzWydQcm94eS1Db25uZWN0aW9uJ10pIHsKICAgICAgaGVhZGVyc1snUHJveHktQ29ubmVjdGlvbiddID0gdGhpcy5rZWVwQWxpdmUgPyAnS2VlcC1BbGl2ZScgOiAnY2xvc2UnOwogICAgfQogICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGhlYWRlcnMpKSB7CiAgICAgIHBheWxvYWQgKz0gYCR7bmFtZX06ICR7aGVhZGVyc1tuYW1lXX1cclxuYDsKICAgIH0KCiAgICBjb25zdCBwcm94eVJlc3BvbnNlUHJvbWlzZSA9IHBhcnNlUHJveHlSZXNwb25zZShzb2NrZXQpOwoKICAgIHNvY2tldC53cml0ZShgJHtwYXlsb2FkfVxyXG5gKTsKCiAgICBjb25zdCB7IGNvbm5lY3QsIGJ1ZmZlcmVkIH0gPSBhd2FpdCBwcm94eVJlc3BvbnNlUHJvbWlzZTsKICAgIHJlcS5lbWl0KCdwcm94eUNvbm5lY3QnLCBjb25uZWN0KTsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnQKICAgIC8vIEB0cy1pZ25vcmUgTm90IEV2ZW50RW1pdHRlciBpbiBOb2RlIHR5cGVzCiAgICB0aGlzLmVtaXQoJ3Byb3h5Q29ubmVjdCcsIGNvbm5lY3QsIHJlcSk7CgogICAgaWYgKGNvbm5lY3Quc3RhdHVzQ29kZSA9PT0gMjAwKSB7CiAgICAgIHJlcS5vbmNlKCdzb2NrZXQnLCByZXN1bWUpOwoKICAgICAgaWYgKG9wdHMuc2VjdXJlRW5kcG9pbnQpIHsKICAgICAgICAvLyBUaGUgcHJveHkgaXMgY29ubmVjdGluZyB0byBhIFRMUyBzZXJ2ZXIsIHNvIHVwZ3JhZGUKICAgICAgICAvLyB0aGlzIHNvY2tldCBjb25uZWN0aW9uIHRvIGEgVExTIGNvbm5lY3Rpb24uCiAgICAgICAgZGVidWcoJ1VwZ3JhZGluZyBzb2NrZXQgY29ubmVjdGlvbiB0byBUTFMnKTsKICAgICAgICBjb25zdCBzZXJ2ZXJuYW1lID0gb3B0cy5zZXJ2ZXJuYW1lIHx8IG9wdHMuaG9zdDsKICAgICAgICByZXR1cm4gdGxzLmNvbm5lY3QoewogICAgICAgICAgLi4ub21pdChvcHRzLCAnaG9zdCcsICdwYXRoJywgJ3BvcnQnKSwKICAgICAgICAgIHNvY2tldCwKICAgICAgICAgIHNlcnZlcm5hbWU6IG5ldC5pc0lQKHNlcnZlcm5hbWUpID8gdW5kZWZpbmVkIDogc2VydmVybmFtZSwKICAgICAgICB9KTsKICAgICAgfQoKICAgICAgcmV0dXJuIHNvY2tldDsKICAgIH0KCiAgICAvLyBTb21lIG90aGVyIHN0YXR1cyBjb2RlIHRoYXQncyBub3QgMjAwLi4uIG5lZWQgdG8gcmUtcGxheSB0aGUgSFRUUAogICAgLy8gaGVhZGVyICJkYXRhIiBldmVudHMgb250byB0aGUgc29ja2V0IG9uY2UgdGhlIEhUVFAgbWFjaGluZXJ5IGlzCiAgICAvLyBhdHRhY2hlZCBzbyB0aGF0IHRoZSBub2RlIGNvcmUgYGh0dHBgIGNhbiBwYXJzZSBhbmQgaGFuZGxlIHRoZQogICAgLy8gZXJyb3Igc3RhdHVzIGNvZGUuCgogICAgLy8gQ2xvc2UgdGhlIG9yaWdpbmFsIHNvY2tldCwgYW5kIGEgbmV3ICJmYWtlIiBzb2NrZXQgaXMgcmV0dXJuZWQKICAgIC8vIGluc3RlYWQsIHNvIHRoYXQgdGhlIHByb3h5IGRvZXNuJ3QgZ2V0IHRoZSBIVFRQIHJlcXVlc3QKICAgIC8vIHdyaXR0ZW4gdG8gaXQgKHdoaWNoIG1heSBjb250YWluIGBBdXRob3JpemF0aW9uYCBoZWFkZXJzIG9yIG90aGVyCiAgICAvLyBzZW5zaXRpdmUgZGF0YSkuCiAgICAvLwogICAgLy8gU2VlOiBodHRwczovL2hhY2tlcm9uZS5jb20vcmVwb3J0cy81NDE1MDIKICAgIHNvY2tldC5kZXN0cm95KCk7CgogICAgY29uc3QgZmFrZVNvY2tldCA9IG5ldyBuZXQuU29ja2V0KHsgd3JpdGFibGU6IGZhbHNlIH0pOwogICAgZmFrZVNvY2tldC5yZWFkYWJsZSA9IHRydWU7CgogICAgLy8gTmVlZCB0byB3YWl0IGZvciB0aGUgInNvY2tldCIgZXZlbnQgdG8gcmUtcGxheSB0aGUgImRhdGEiIGV2ZW50cy4KICAgIHJlcS5vbmNlKCdzb2NrZXQnLCAocykgPT4gewogICAgICBkZWJ1ZygnUmVwbGF5aW5nIHByb3h5IGJ1ZmZlciBmb3IgZmFpbGVkIHJlcXVlc3QnKTsKICAgICAgLy8gUmVwbGF5IHRoZSAiYnVmZmVyZWQiIEJ1ZmZlciBvbnRvIHRoZSBmYWtlIGBzb2NrZXRgLCBzaW5jZSBhdAogICAgICAvLyB0aGlzIHBvaW50IHRoZSBIVFRQIG1vZHVsZSBtYWNoaW5lcnkgaGFzIGJlZW4gaG9va2VkIHVwIGZvcgogICAgICAvLyB0aGUgdXNlci4KICAgICAgcy5wdXNoKGJ1ZmZlcmVkKTsKICAgICAgcy5wdXNoKG51bGwpOwogICAgfSk7CgogICAgcmV0dXJuIGZha2VTb2NrZXQ7CiAgfQp9IEh0dHBzUHJveHlBZ2VudC5fX2luaXRTdGF0aWMoKTsKCmZ1bmN0aW9uIHJlc3VtZShzb2NrZXQpIHsKICBzb2NrZXQucmVzdW1lKCk7Cn0KCmZ1bmN0aW9uIG9taXQoCiAgb2JqLAogIC4uLmtleXMKKQoKIHsKICBjb25zdCByZXQgPSB7fQoKOwogIGxldCBrZXk7CiAgZm9yIChrZXkgaW4gb2JqKSB7CiAgICBpZiAoIWtleXMuaW5jbHVkZXMoa2V5KSkgewogICAgICByZXRba2V5XSA9IG9ialtrZXldOwogICAgfQogIH0KICByZXR1cm4gcmV0Owp9CgpmdW5jdGlvbiBfbnVsbGlzaENvYWxlc2NlKGxocywgcmhzRm4pIHsgaWYgKGxocyAhPSBudWxsKSB7IHJldHVybiBsaHM7IH0gZWxzZSB7IHJldHVybiByaHNGbigpOyB9IH0KLy8gRXN0aW1hdGVkIG1heGltdW0gc2l6ZSBmb3IgcmVhc29uYWJsZSBzdGFuZGFsb25lIGV2ZW50CmNvbnN0IEdaSVBfVEhSRVNIT0xEID0gMTAyNCAqIDMyOwoKLyoqCiAqIEdldHMgYSBzdHJlYW0gZnJvbSBhIFVpbnQ4QXJyYXkgb3Igc3RyaW5nCiAqIFJlYWRhYmxlLmZyb20gaXMgaWRlYWwgYnV0IHdhcyBhZGRlZCBpbiBub2RlLmpzIHYxMi4zLjAgYW5kIHYxMC4xNy4wCiAqLwpmdW5jdGlvbiBzdHJlYW1Gcm9tQm9keShib2R5KSB7CiAgcmV0dXJuIG5ldyBSZWFkYWJsZSh7CiAgICByZWFkKCkgewogICAgICB0aGlzLnB1c2goYm9keSk7CiAgICAgIHRoaXMucHVzaChudWxsKTsKICAgIH0sCiAgfSk7Cn0KCi8qKgogKiBDcmVhdGVzIGEgVHJhbnNwb3J0IHRoYXQgdXNlcyBuYXRpdmUgdGhlIG5hdGl2ZSAnaHR0cCcgYW5kICdodHRwcycgbW9kdWxlcyB0byBzZW5kIGV2ZW50cyB0byBTZW50cnkuCiAqLwpmdW5jdGlvbiBtYWtlTm9kZVRyYW5zcG9ydChvcHRpb25zKSB7CiAgbGV0IHVybFNlZ21lbnRzOwoKICB0cnkgewogICAgdXJsU2VnbWVudHMgPSBuZXcgVVJMKG9wdGlvbnMudXJsKTsKICB9IGNhdGNoIChlKSB7CiAgICBjb25zb2xlU2FuZGJveCgoKSA9PiB7CiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlCiAgICAgIGNvbnNvbGUud2FybigKICAgICAgICAnW0BzZW50cnkvbm9kZV06IEludmFsaWQgZHNuIG9yIHR1bm5lbCBvcHRpb24sIHdpbGwgbm90IHNlbmQgYW55IGV2ZW50cy4gVGhlIHR1bm5lbCBvcHRpb24gbXVzdCBiZSBhIGZ1bGwgVVJMIHdoZW4gdXNlZC4nLAogICAgICApOwogICAgfSk7CiAgICByZXR1cm4gY3JlYXRlVHJhbnNwb3J0KG9wdGlvbnMsICgpID0+IFByb21pc2UucmVzb2x2ZSh7fSkpOwogIH0KCiAgY29uc3QgaXNIdHRwcyA9IHVybFNlZ21lbnRzLnByb3RvY29sID09PSAnaHR0cHM6JzsKCiAgLy8gUHJveHkgcHJpb3JpdGl6YXRpb246IGh0dHAgPT4gYG9wdGlvbnMucHJveHlgIHwgYHByb2Nlc3MuZW52Lmh0dHBfcHJveHlgCiAgLy8gUHJveHkgcHJpb3JpdGl6YXRpb246IGh0dHBzID0+IGBvcHRpb25zLnByb3h5YCB8IGBwcm9jZXNzLmVudi5odHRwc19wcm94eWAgfCBgcHJvY2Vzcy5lbnYuaHR0cF9wcm94eWAKICBjb25zdCBwcm94eSA9IGFwcGx5Tm9Qcm94eU9wdGlvbigKICAgIHVybFNlZ21lbnRzLAogICAgb3B0aW9ucy5wcm94eSB8fCAoaXNIdHRwcyA/IHByb2Nlc3MuZW52Lmh0dHBzX3Byb3h5IDogdW5kZWZpbmVkKSB8fCBwcm9jZXNzLmVudi5odHRwX3Byb3h5LAogICk7CgogIGNvbnN0IG5hdGl2ZUh0dHBNb2R1bGUgPSBpc0h0dHBzID8gaHR0cHMgOiBodHRwOwogIGNvbnN0IGtlZXBBbGl2ZSA9IG9wdGlvbnMua2VlcEFsaXZlID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IG9wdGlvbnMua2VlcEFsaXZlOwoKICAvLyBUT0RPKHY3KTogRXZhbHVhdGUgaWYgd2UgY2FuIHNldCBrZWVwQWxpdmUgdG8gdHJ1ZS4gVGhpcyB3b3VsZCBpbnZvbHZlIHRlc3RpbmcgZm9yIG1lbW9yeSBsZWFrcyBpbiBvbGRlciBub2RlCiAgLy8gdmVyc2lvbnMoPj0gOCkgYXMgdGhleSBoYWQgbWVtb3J5IGxlYWtzIHdoZW4gdXNpbmcgaXQ6ICMyNTU1CiAgY29uc3QgYWdlbnQgPSBwcm94eQogICAgPyAobmV3IEh0dHBzUHJveHlBZ2VudChwcm94eSkgKQogICAgOiBuZXcgbmF0aXZlSHR0cE1vZHVsZS5BZ2VudCh7IGtlZXBBbGl2ZSwgbWF4U29ja2V0czogMzAsIHRpbWVvdXQ6IDIwMDAgfSk7CgogIGNvbnN0IHJlcXVlc3RFeGVjdXRvciA9IGNyZWF0ZVJlcXVlc3RFeGVjdXRvcihvcHRpb25zLCBfbnVsbGlzaENvYWxlc2NlKG9wdGlvbnMuaHR0cE1vZHVsZSwgKCkgPT4gKCBuYXRpdmVIdHRwTW9kdWxlKSksIGFnZW50KTsKICByZXR1cm4gY3JlYXRlVHJhbnNwb3J0KG9wdGlvbnMsIHJlcXVlc3RFeGVjdXRvcik7Cn0KCi8qKgogKiBIb25vcnMgdGhlIGBub19wcm94eWAgZW52IHZhcmlhYmxlIHdpdGggdGhlIGhpZ2hlc3QgcHJpb3JpdHkgdG8gYWxsb3cgZm9yIGhvc3RzIGV4Y2x1c2lvbi4KICoKICogQHBhcmFtIHRyYW5zcG9ydFVybCBUaGUgVVJMIHRoZSB0cmFuc3BvcnQgaW50ZW5kcyB0byBzZW5kIGV2ZW50cyB0by4KICogQHBhcmFtIHByb3h5IFRoZSBjbGllbnQgY29uZmlndXJlZCBwcm94eS4KICogQHJldHVybnMgQSBwcm94eSB0aGUgdHJhbnNwb3J0IHNob3VsZCB1c2UuCiAqLwpmdW5jdGlvbiBhcHBseU5vUHJveHlPcHRpb24odHJhbnNwb3J0VXJsU2VnbWVudHMsIHByb3h5KSB7CiAgY29uc3QgeyBub19wcm94eSB9ID0gcHJvY2Vzcy5lbnY7CgogIGNvbnN0IHVybElzRXhlbXB0RnJvbVByb3h5ID0KICAgIG5vX3Byb3h5ICYmCiAgICBub19wcm94eQogICAgICAuc3BsaXQoJywnKQogICAgICAuc29tZSgKICAgICAgICBleGVtcHRpb24gPT4gdHJhbnNwb3J0VXJsU2VnbWVudHMuaG9zdC5lbmRzV2l0aChleGVtcHRpb24pIHx8IHRyYW5zcG9ydFVybFNlZ21lbnRzLmhvc3RuYW1lLmVuZHNXaXRoKGV4ZW1wdGlvbiksCiAgICAgICk7CgogIGlmICh1cmxJc0V4ZW1wdEZyb21Qcm94eSkgewogICAgcmV0dXJuIHVuZGVmaW5lZDsKICB9IGVsc2UgewogICAgcmV0dXJuIHByb3h5OwogIH0KfQoKLyoqCiAqIENyZWF0ZXMgYSBSZXF1ZXN0RXhlY3V0b3IgdG8gYmUgdXNlZCB3aXRoIGBjcmVhdGVUcmFuc3BvcnRgLgogKi8KZnVuY3Rpb24gY3JlYXRlUmVxdWVzdEV4ZWN1dG9yKAogIG9wdGlvbnMsCiAgaHR0cE1vZHVsZSwKICBhZ2VudCwKKSB7CiAgY29uc3QgeyBob3N0bmFtZSwgcGF0aG5hbWUsIHBvcnQsIHByb3RvY29sLCBzZWFyY2ggfSA9IG5ldyBVUkwob3B0aW9ucy51cmwpOwogIHJldHVybiBmdW5jdGlvbiBtYWtlUmVxdWVzdChyZXF1ZXN0KSB7CiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgICBsZXQgYm9keSA9IHN0cmVhbUZyb21Cb2R5KHJlcXVlc3QuYm9keSk7CgogICAgICBjb25zdCBoZWFkZXJzID0geyAuLi5vcHRpb25zLmhlYWRlcnMgfTsKCiAgICAgIGlmIChyZXF1ZXN0LmJvZHkubGVuZ3RoID4gR1pJUF9USFJFU0hPTEQpIHsKICAgICAgICBoZWFkZXJzWydjb250ZW50LWVuY29kaW5nJ10gPSAnZ3ppcCc7CiAgICAgICAgYm9keSA9IGJvZHkucGlwZShjcmVhdGVHemlwKCkpOwogICAgICB9CgogICAgICBjb25zdCByZXEgPSBodHRwTW9kdWxlLnJlcXVlc3QoCiAgICAgICAgewogICAgICAgICAgbWV0aG9kOiAnUE9TVCcsCiAgICAgICAgICBhZ2VudCwKICAgICAgICAgIGhlYWRlcnMsCiAgICAgICAgICBob3N0bmFtZSwKICAgICAgICAgIHBhdGg6IGAke3BhdGhuYW1lfSR7c2VhcmNofWAsCiAgICAgICAgICBwb3J0LAogICAgICAgICAgcHJvdG9jb2wsCiAgICAgICAgICBjYTogb3B0aW9ucy5jYUNlcnRzLAogICAgICAgIH0sCiAgICAgICAgcmVzID0+IHsKICAgICAgICAgIHJlcy5vbignZGF0YScsICgpID0+IHsKICAgICAgICAgICAgLy8gRHJhaW4gc29ja2V0CiAgICAgICAgICB9KTsKCiAgICAgICAgICByZXMub24oJ2VuZCcsICgpID0+IHsKICAgICAgICAgICAgLy8gRHJhaW4gc29ja2V0CiAgICAgICAgICB9KTsKCiAgICAgICAgICByZXMuc2V0RW5jb2RpbmcoJ3V0ZjgnKTsKCiAgICAgICAgICAvLyAiS2V5LXZhbHVlIHBhaXJzIG9mIGhlYWRlciBuYW1lcyBhbmQgdmFsdWVzLiBIZWFkZXIgbmFtZXMgYXJlIGxvd2VyLWNhc2VkLiIKICAgICAgICAgIC8vIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvaHR0cC5odG1sI2h0dHBfbWVzc2FnZV9oZWFkZXJzCiAgICAgICAgICBjb25zdCByZXRyeUFmdGVySGVhZGVyID0gX251bGxpc2hDb2FsZXNjZShyZXMuaGVhZGVyc1sncmV0cnktYWZ0ZXInXSwgKCkgPT4gKCBudWxsKSk7CiAgICAgICAgICBjb25zdCByYXRlTGltaXRzSGVhZGVyID0gX251bGxpc2hDb2FsZXNjZShyZXMuaGVhZGVyc1sneC1zZW50cnktcmF0ZS1saW1pdHMnXSwgKCkgPT4gKCBudWxsKSk7CgogICAgICAgICAgcmVzb2x2ZSh7CiAgICAgICAgICAgIHN0YXR1c0NvZGU6IHJlcy5zdGF0dXNDb2RlLAogICAgICAgICAgICBoZWFkZXJzOiB7CiAgICAgICAgICAgICAgJ3JldHJ5LWFmdGVyJzogcmV0cnlBZnRlckhlYWRlciwKICAgICAgICAgICAgICAneC1zZW50cnktcmF0ZS1saW1pdHMnOiBBcnJheS5pc0FycmF5KHJhdGVMaW1pdHNIZWFkZXIpID8gcmF0ZUxpbWl0c0hlYWRlclswXSA6IHJhdGVMaW1pdHNIZWFkZXIsCiAgICAgICAgICAgIH0sCiAgICAgICAgICB9KTsKICAgICAgICB9LAogICAgICApOwoKICAgICAgcmVxLm9uKCdlcnJvcicsIHJlamVjdCk7CiAgICAgIGJvZHkucGlwZShyZXEpOwogICAgfSk7CiAgfTsKfQoKZnVuY3Rpb24gX29wdGlvbmFsQ2hhaW4ob3BzKSB7IGxldCBsYXN0QWNjZXNzTEhTID0gdW5kZWZpbmVkOyBsZXQgdmFsdWUgPSBvcHNbMF07IGxldCBpID0gMTsgd2hpbGUgKGkgPCBvcHMubGVuZ3RoKSB7IGNvbnN0IG9wID0gb3BzW2ldOyBjb25zdCBmbiA9IG9wc1tpICsgMV07IGkgKz0gMjsgaWYgKChvcCA9PT0gJ29wdGlvbmFsQWNjZXNzJyB8fCBvcCA9PT0gJ29wdGlvbmFsQ2FsbCcpICYmIHZhbHVlID09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBpZiAob3AgPT09ICdhY2Nlc3MnIHx8IG9wID09PSAnb3B0aW9uYWxBY2Nlc3MnKSB7IGxhc3RBY2Nlc3NMSFMgPSB2YWx1ZTsgdmFsdWUgPSBmbih2YWx1ZSk7IH0gZWxzZSBpZiAob3AgPT09ICdjYWxsJyB8fCBvcCA9PT0gJ29wdGlvbmFsQ2FsbCcpIHsgdmFsdWUgPSBmbigoLi4uYXJncykgPT4gdmFsdWUuY2FsbChsYXN0QWNjZXNzTEhTLCAuLi5hcmdzKSk7IGxhc3RBY2Nlc3NMSFMgPSB1bmRlZmluZWQ7IH0gfSByZXR1cm4gdmFsdWU7IH0KY29uc3Qgb3B0aW9ucyA9IHdvcmtlckRhdGE7CmxldCBzZXNzaW9uOwpsZXQgaGFzU2VudEFuckV2ZW50ID0gZmFsc2U7CgpmdW5jdGlvbiBsb2cobXNnKSB7CiAgaWYgKG9wdGlvbnMuZGVidWcpIHsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlCiAgICBjb25zb2xlLmxvZyhgW0FOUiBXb3JrZXJdICR7bXNnfWApOwogIH0KfQoKY29uc3QgdXJsID0gZ2V0RW52ZWxvcGVFbmRwb2ludFdpdGhVcmxFbmNvZGVkQXV0aChvcHRpb25zLmRzbik7CmNvbnN0IHRyYW5zcG9ydCA9IG1ha2VOb2RlVHJhbnNwb3J0KHsKICB1cmwsCiAgcmVjb3JkRHJvcHBlZEV2ZW50OiAoKSA9PiB7CiAgICAvLwogIH0sCn0pOwoKYXN5bmMgZnVuY3Rpb24gc2VuZEFibm9ybWFsU2Vzc2lvbigpIHsKICAvLyBvZiB3ZSBoYXZlIGFuIGV4aXN0aW5nIHNlc3Npb24gcGFzc2VkIGZyb20gdGhlIG1haW4gdGhyZWFkLCBzZW5kIGl0IGFzIGFibm9ybWFsCiAgaWYgKHNlc3Npb24pIHsKICAgIGxvZygnU2VuZGluZyBhYm5vcm1hbCBzZXNzaW9uJyk7CiAgICB1cGRhdGVTZXNzaW9uKHNlc3Npb24sIHsgc3RhdHVzOiAnYWJub3JtYWwnLCBhYm5vcm1hbF9tZWNoYW5pc206ICdhbnJfZm9yZWdyb3VuZCcgfSk7CgogICAgY29uc3QgZW52ZWxvcGUgPSBjcmVhdGVTZXNzaW9uRW52ZWxvcGUoc2Vzc2lvbiwgb3B0aW9ucy5kc24sIG9wdGlvbnMuc2RrTWV0YWRhdGEpOwogICAgLy8gTG9nIHRoZSBlbnZlbG9wZSBzbyB0byBhaWQgaW4gdGVzdGluZwogICAgbG9nKEpTT04uc3RyaW5naWZ5KGVudmVsb3BlKSk7CgogICAgYXdhaXQgdHJhbnNwb3J0LnNlbmQoZW52ZWxvcGUpOwoKICAgIHRyeSB7CiAgICAgIC8vIE5vdGlmeSB0aGUgbWFpbiBwcm9jZXNzIHRoYXQgdGhlIHNlc3Npb24gaGFzIGVuZGVkIHNvIHRoZSBzZXNzaW9uIGNhbiBiZSBjbGVhcmVkIGZyb20gdGhlIHNjb3BlCiAgICAgIF9vcHRpb25hbENoYWluKFtwYXJlbnRQb3J0LCAnb3B0aW9uYWxBY2Nlc3MnLCBfMiA9PiBfMi5wb3N0TWVzc2FnZSwgJ2NhbGwnLCBfMyA9PiBfMygnc2Vzc2lvbi1lbmRlZCcpXSk7CiAgICB9IGNhdGNoIChfKSB7CiAgICAgIC8vIGlnbm9yZQogICAgfQogIH0KfQoKbG9nKCdTdGFydGVkJyk7CgpmdW5jdGlvbiBwcmVwYXJlU3RhY2tGcmFtZXMoc3RhY2tGcmFtZXMpIHsKICBpZiAoIXN0YWNrRnJhbWVzKSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgLy8gU3RyaXAgU2VudHJ5IGZyYW1lcyBhbmQgcmV2ZXJzZSB0aGUgc3RhY2sgZnJhbWVzIHNvIHRoZXkgYXJlIGluIHRoZSBjb3JyZWN0IG9yZGVyCiAgY29uc3Qgc3RyaXBwZWRGcmFtZXMgPSBzdHJpcFNlbnRyeUZyYW1lc0FuZFJldmVyc2Uoc3RhY2tGcmFtZXMpOwoKICAvLyBJZiB3ZSBoYXZlIGFuIGFwcCByb290IHBhdGgsIHJld3JpdGUgdGhlIGZpbGVuYW1lcyB0byBiZSByZWxhdGl2ZSB0byB0aGUgYXBwIHJvb3QKICBpZiAob3B0aW9ucy5hcHBSb290UGF0aCkgewogICAgZm9yIChjb25zdCBmcmFtZSBvZiBzdHJpcHBlZEZyYW1lcykgewogICAgICBpZiAoIWZyYW1lLmZpbGVuYW1lKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KCiAgICAgIGZyYW1lLmZpbGVuYW1lID0gbm9ybWFsaXplVXJsVG9CYXNlKGZyYW1lLmZpbGVuYW1lLCBvcHRpb25zLmFwcFJvb3RQYXRoKTsKICAgIH0KICB9CgogIHJldHVybiBzdHJpcHBlZEZyYW1lczsKfQoKZnVuY3Rpb24gYXBwbHlTY29wZVRvRXZlbnQoZXZlbnQsIHNjb3BlKSB7CiAgYXBwbHlTY29wZURhdGFUb0V2ZW50KGV2ZW50LCBzY29wZSk7CgogIGlmICghX29wdGlvbmFsQ2hhaW4oW2V2ZW50LCAnYWNjZXNzJywgXzQgPT4gXzQuY29udGV4dHMsICdvcHRpb25hbEFjY2VzcycsIF81ID0+IF81LnRyYWNlXSkpIHsKICAgIGNvbnN0IHsgdHJhY2VJZCwgc3BhbklkLCBwYXJlbnRTcGFuSWQgfSA9IHNjb3BlLnByb3BhZ2F0aW9uQ29udGV4dDsKICAgIGV2ZW50LmNvbnRleHRzID0gewogICAgICB0cmFjZTogewogICAgICAgIHRyYWNlX2lkOiB0cmFjZUlkLAogICAgICAgIHNwYW5faWQ6IHNwYW5JZCwKICAgICAgICBwYXJlbnRfc3Bhbl9pZDogcGFyZW50U3BhbklkLAogICAgICB9LAogICAgICAuLi5ldmVudC5jb250ZXh0cywKICAgIH07CiAgfQp9Cgphc3luYyBmdW5jdGlvbiBzZW5kQW5yRXZlbnQoZnJhbWVzLCBzY29wZSkgewogIGlmIChoYXNTZW50QW5yRXZlbnQpIHsKICAgIHJldHVybjsKICB9CgogIGhhc1NlbnRBbnJFdmVudCA9IHRydWU7CgogIGF3YWl0IHNlbmRBYm5vcm1hbFNlc3Npb24oKTsKCiAgbG9nKCdTZW5kaW5nIGV2ZW50Jyk7CgogIGNvbnN0IGV2ZW50ID0gewogICAgZXZlbnRfaWQ6IHV1aWQ0KCksCiAgICBjb250ZXh0czogb3B0aW9ucy5jb250ZXh0cywKICAgIHJlbGVhc2U6IG9wdGlvbnMucmVsZWFzZSwKICAgIGVudmlyb25tZW50OiBvcHRpb25zLmVudmlyb25tZW50LAogICAgZGlzdDogb3B0aW9ucy5kaXN0LAogICAgcGxhdGZvcm06ICdub2RlJywKICAgIGxldmVsOiAnZXJyb3InLAogICAgZXhjZXB0aW9uOiB7CiAgICAgIHZhbHVlczogWwogICAgICAgIHsKICAgICAgICAgIHR5cGU6ICdBcHBsaWNhdGlvbk5vdFJlc3BvbmRpbmcnLAogICAgICAgICAgdmFsdWU6IGBBcHBsaWNhdGlvbiBOb3QgUmVzcG9uZGluZyBmb3IgYXQgbGVhc3QgJHtvcHRpb25zLmFuclRocmVzaG9sZH0gbXNgLAogICAgICAgICAgc3RhY2t0cmFjZTogeyBmcmFtZXM6IHByZXBhcmVTdGFja0ZyYW1lcyhmcmFtZXMpIH0sCiAgICAgICAgICAvLyBUaGlzIGVuc3VyZXMgdGhlIFVJIGRvZXNuJ3Qgc2F5ICdDcmFzaGVkIGluJyBmb3IgdGhlIHN0YWNrIHRyYWNlCiAgICAgICAgICBtZWNoYW5pc206IHsgdHlwZTogJ0FOUicgfSwKICAgICAgICB9LAogICAgICBdLAogICAgfSwKICAgIHRhZ3M6IG9wdGlvbnMuc3RhdGljVGFncywKICB9OwoKICBpZiAoc2NvcGUpIHsKICAgIGFwcGx5U2NvcGVUb0V2ZW50KGV2ZW50LCBzY29wZSk7CiAgfQoKICBjb25zdCBlbnZlbG9wZSA9IGNyZWF0ZUV2ZW50RW52ZWxvcGUoZXZlbnQsIG9wdGlvbnMuZHNuLCBvcHRpb25zLnNka01ldGFkYXRhKTsKICAvLyBMb2cgdGhlIGVudmVsb3BlIHRvIGFpZCBpbiB0ZXN0aW5nCiAgbG9nKEpTT04uc3RyaW5naWZ5KGVudmVsb3BlKSk7CgogIGF3YWl0IHRyYW5zcG9ydC5zZW5kKGVudmVsb3BlKTsKICBhd2FpdCB0cmFuc3BvcnQuZmx1c2goMjAwMCk7CgogIC8vIERlbGF5IGZvciA1IHNlY29uZHMgc28gdGhhdCBzdGRpbyBjYW4gZmx1c2ggaW4gdGhlIG1haW4gZXZlbnQgbG9vcCBldmVyIHJlc3RhcnRzLgogIC8vIFRoaXMgaXMgbWFpbmx5IGZvciB0aGUgYmVuZWZpdCBvZiBsb2dnaW5nL2RlYnVnZ2luZyBpc3N1ZXMuCiAgc2V0VGltZW91dCgoKSA9PiB7CiAgICBwcm9jZXNzLmV4aXQoMCk7CiAgfSwgNTAwMCk7Cn0KCmxldCBkZWJ1Z2dlclBhdXNlOwoKaWYgKG9wdGlvbnMuY2FwdHVyZVN0YWNrVHJhY2UpIHsKICBsb2coJ0Nvbm5lY3RpbmcgdG8gZGVidWdnZXInKTsKCiAgY29uc3Qgc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKCkgOwogIHNlc3Npb24uY29ubmVjdFRvTWFpblRocmVhZCgpOwoKICBsb2coJ0Nvbm5lY3RlZCB0byBkZWJ1Z2dlcicpOwoKICAvLyBDb2xsZWN0IHNjcmlwdElkIC0+IHVybCBtYXAgc28gd2UgY2FuIGxvb2sgdXAgdGhlIGZpbGVuYW1lcyBsYXRlcgogIGNvbnN0IHNjcmlwdHMgPSBuZXcgTWFwKCk7CgogIHNlc3Npb24ub24oJ0RlYnVnZ2VyLnNjcmlwdFBhcnNlZCcsIGV2ZW50ID0+IHsKICAgIHNjcmlwdHMuc2V0KGV2ZW50LnBhcmFtcy5zY3JpcHRJZCwgZXZlbnQucGFyYW1zLnVybCk7CiAgfSk7CgogIHNlc3Npb24ub24oJ0RlYnVnZ2VyLnBhdXNlZCcsIGV2ZW50ID0+IHsKICAgIGlmIChldmVudC5wYXJhbXMucmVhc29uICE9PSAnb3RoZXInKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICB0cnkgewogICAgICBsb2coJ0RlYnVnZ2VyIHBhdXNlZCcpOwoKICAgICAgLy8gY29weSB0aGUgZnJhbWVzCiAgICAgIGNvbnN0IGNhbGxGcmFtZXMgPSBbLi4uZXZlbnQucGFyYW1zLmNhbGxGcmFtZXNdOwoKICAgICAgY29uc3QgZ2V0TW9kdWxlTmFtZSA9IG9wdGlvbnMuYXBwUm9vdFBhdGggPyBjcmVhdGVHZXRNb2R1bGVGcm9tRmlsZW5hbWUob3B0aW9ucy5hcHBSb290UGF0aCkgOiAoKSA9PiB1bmRlZmluZWQ7CiAgICAgIGNvbnN0IHN0YWNrRnJhbWVzID0gY2FsbEZyYW1lcy5tYXAoZnJhbWUgPT4KICAgICAgICBjYWxsRnJhbWVUb1N0YWNrRnJhbWUoZnJhbWUsIHNjcmlwdHMuZ2V0KGZyYW1lLmxvY2F0aW9uLnNjcmlwdElkKSwgZ2V0TW9kdWxlTmFtZSksCiAgICAgICk7CgogICAgICAvLyBFdmFsdWF0ZSBhIHNjcmlwdCBpbiB0aGUgY3VycmVudGx5IHBhdXNlZCBjb250ZXh0CiAgICAgIHNlc3Npb24ucG9zdCgKICAgICAgICAnUnVudGltZS5ldmFsdWF0ZScsCiAgICAgICAgewogICAgICAgICAgLy8gR3JhYiB0aGUgdHJhY2UgY29udGV4dCBmcm9tIHRoZSBjdXJyZW50IHNjb3BlCiAgICAgICAgICBleHByZXNzaW9uOiAnZ2xvYmFsLl9fU0VOVFJZX0dFVF9TQ09QRVNfXygpOycsCiAgICAgICAgICAvLyBEb24ndCByZS10cmlnZ2VyIHRoZSBkZWJ1Z2dlciBpZiB0aGlzIGNhdXNlcyBhbiBlcnJvcgogICAgICAgICAgc2lsZW50OiB0cnVlLAogICAgICAgICAgLy8gU2VyaWFsaXplIHRoZSByZXN1bHQgdG8ganNvbiBvdGhlcndpc2Ugb25seSBwcmltaXRpdmVzIGFyZSBzdXBwb3J0ZWQKICAgICAgICAgIHJldHVybkJ5VmFsdWU6IHRydWUsCiAgICAgICAgfSwKICAgICAgICAoZXJyLCBwYXJhbSkgPT4gewogICAgICAgICAgaWYgKGVycikgewogICAgICAgICAgICBsb2coYEVycm9yIGV4ZWN1dGluZyBzY3JpcHQ6ICcke2Vyci5tZXNzYWdlfSdgKTsKICAgICAgICAgIH0KCiAgICAgICAgICBjb25zdCBzY29wZXMgPSBwYXJhbSAmJiBwYXJhbS5yZXN1bHQgPyAocGFyYW0ucmVzdWx0LnZhbHVlICkgOiB1bmRlZmluZWQ7CgogICAgICAgICAgc2Vzc2lvbi5wb3N0KCdEZWJ1Z2dlci5yZXN1bWUnKTsKICAgICAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIuZGlzYWJsZScpOwoKICAgICAgICAgIHNlbmRBbnJFdmVudChzdGFja0ZyYW1lcywgc2NvcGVzKS50aGVuKG51bGwsICgpID0+IHsKICAgICAgICAgICAgbG9nKCdTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQuJyk7CiAgICAgICAgICB9KTsKICAgICAgICB9LAogICAgICApOwogICAgfSBjYXRjaCAoZSkgewogICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLnJlc3VtZScpOwogICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLmRpc2FibGUnKTsKICAgICAgdGhyb3cgZTsKICAgIH0KICB9KTsKCiAgZGVidWdnZXJQYXVzZSA9ICgpID0+IHsKICAgIHRyeSB7CiAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIuZW5hYmxlJywgKCkgPT4gewogICAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIucGF1c2UnKTsKICAgICAgfSk7CiAgICB9IGNhdGNoIChfKSB7CiAgICAgIC8vCiAgICB9CiAgfTsKfQoKZnVuY3Rpb24gY3JlYXRlSHJUaW1lcigpIHsKICAvLyBUT0RPICh2OCk6IFdlIGNhbiB1c2UgcHJvY2Vzcy5ocnRpbWUuYmlnaW50KCkgYWZ0ZXIgd2UgZHJvcCBub2RlIHY4CiAgbGV0IGxhc3RQb2xsID0gcHJvY2Vzcy5ocnRpbWUoKTsKCiAgcmV0dXJuIHsKICAgIGdldFRpbWVNczogKCkgPT4gewogICAgICBjb25zdCBbc2Vjb25kcywgbmFub1NlY29uZHNdID0gcHJvY2Vzcy5ocnRpbWUobGFzdFBvbGwpOwogICAgICByZXR1cm4gTWF0aC5mbG9vcihzZWNvbmRzICogMWUzICsgbmFub1NlY29uZHMgLyAxZTYpOwogICAgfSwKICAgIHJlc2V0OiAoKSA9PiB7CiAgICAgIGxhc3RQb2xsID0gcHJvY2Vzcy5ocnRpbWUoKTsKICAgIH0sCiAgfTsKfQoKZnVuY3Rpb24gd2F0Y2hkb2dUaW1lb3V0KCkgewogIGxvZygnV2F0Y2hkb2cgdGltZW91dCcpOwoKICBpZiAoZGVidWdnZXJQYXVzZSkgewogICAgbG9nKCdQYXVzaW5nIGRlYnVnZ2VyIHRvIGNhcHR1cmUgc3RhY2sgdHJhY2UnKTsKICAgIGRlYnVnZ2VyUGF1c2UoKTsKICB9IGVsc2UgewogICAgbG9nKCdDYXB0dXJpbmcgZXZlbnQgd2l0aG91dCBhIHN0YWNrIHRyYWNlJyk7CiAgICBzZW5kQW5yRXZlbnQoKS50aGVuKG51bGwsICgpID0+IHsKICAgICAgbG9nKCdTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQgb24gd2F0Y2hkb2cgdGltZW91dC4nKTsKICAgIH0pOwogIH0KfQoKY29uc3QgeyBwb2xsIH0gPSB3YXRjaGRvZ1RpbWVyKGNyZWF0ZUhyVGltZXIsIG9wdGlvbnMucG9sbEludGVydmFsLCBvcHRpb25zLmFuclRocmVzaG9sZCwgd2F0Y2hkb2dUaW1lb3V0KTsKCl9vcHRpb25hbENoYWluKFtwYXJlbnRQb3J0LCAnb3B0aW9uYWxBY2Nlc3MnLCBfNiA9PiBfNi5vbiwgJ2NhbGwnLCBfNyA9PiBfNygnbWVzc2FnZScsIChtc2cpID0+IHsKICBpZiAobXNnLnNlc3Npb24pIHsKICAgIHNlc3Npb24gPSBtYWtlU2Vzc2lvbihtc2cuc2Vzc2lvbik7CiAgfQoKICBwb2xsKCk7Cn0pXSk7"; -var BottleneckError, States; -BottleneckError = __nccwpck_require__(88185); -States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function () { - return 0; - }); - } +/***/ }), - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; +/***/ 34441: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (current != null && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } +const util = __nccwpck_require__(39023); +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); - remove(id) { - var current; - current = this._jobs[id]; +const INTEGRATION_NAME = 'Console'; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } +const _consoleIntegration = (() => { + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + setup(client) { + utils.addConsoleInstrumentationHandler(({ args, level }) => { + if (core.getClient() !== client) { + return; + } - return current != null; - } + core.addBreadcrumb( + { + category: 'console', + level: utils.severityLevelFromString(level), + message: util.format.apply(undefined, args), + }, + { + input: [...args], + level, + }, + ); + }); + }, + }; +}) ; - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } +const consoleIntegration = core.defineIntegration(_consoleIntegration); - statusJobs(status) { - var k, pos, ref, results, v; +/** + * Console module integration. + * @deprecated Use `consoleIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const Console = core.convertIntegrationFnToClass(INTEGRATION_NAME, consoleIntegration) - if (status != null) { - pos = this.status.indexOf(status); +; - if (pos < 0) { - throw new BottleneckError(`status must be one of ${this.status.join(', ')}`); - } +// eslint-disable-next-line deprecation/deprecation - ref = this._jobs; - results = []; +exports.Console = Console; +exports.consoleIntegration = consoleIntegration; +//# sourceMappingURL=console.js.map - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } +/***/ }), - return results; - } else { - return Object.keys(this._jobs); - } - } +/***/ 90079: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - statusCounts() { - return this.counts.reduce((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }, {}); - } +var { + _optionalChain +} = __nccwpck_require__(57540); -}; -module.exports = States; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +const child_process = __nccwpck_require__(35317); +const fs = __nccwpck_require__(79896); +const os = __nccwpck_require__(70857); +const path = __nccwpck_require__(16928); +const util = __nccwpck_require__(39023); +const core = __nccwpck_require__(75442); -/***/ 33923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/* eslint-disable max-lines */ -"use strict"; +// TODO: Required until we drop support for Node v8 +const readFileAsync = util.promisify(fs.readFile); +const readDirAsync = util.promisify(fs.readdir); +const INTEGRATION_NAME = 'Context'; -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +const _nodeContextIntegration = ((options = {}) => { + let cachedContext; -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + const _options = { + app: true, + os: true, + device: true, + culture: true, + cloudResource: true, + ...options, + }; -var DLList, Sync; -DLList = __nccwpck_require__(64792); -Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList(); - } + /** Add contexts to the event. Caches the context so we only look it up once. */ + async function addContext(event) { + if (cachedContext === undefined) { + cachedContext = _getContexts(); + } - isEmpty() { - return this._queue.length === 0; - } + const updatedContext = _updateContext(await cachedContext); - _tryToRun() { - var _this = this; + event.contexts = { + ...event.contexts, + app: { ...updatedContext.app, ..._optionalChain([event, 'access', _ => _.contexts, 'optionalAccess', _2 => _2.app]) }, + os: { ...updatedContext.os, ..._optionalChain([event, 'access', _3 => _3.contexts, 'optionalAccess', _4 => _4.os]) }, + device: { ...updatedContext.device, ..._optionalChain([event, 'access', _5 => _5.contexts, 'optionalAccess', _6 => _6.device]) }, + culture: { ...updatedContext.culture, ..._optionalChain([event, 'access', _7 => _7.contexts, 'optionalAccess', _8 => _8.culture]) }, + cloud_resource: { ...updatedContext.cloud_resource, ..._optionalChain([event, 'access', _9 => _9.contexts, 'optionalAccess', _10 => _10.cloud_resource]) }, + }; - return _asyncToGenerator(function* () { - var args, cb, error, reject, resolve, returned, task; + return event; + } - if (_this._running < 1 && _this._queue.length > 0) { - _this._running++; + /** Get the contexts from node. */ + async function _getContexts() { + const contexts = {}; - var _this$_queue$shift = _this._queue.shift(); + if (_options.os) { + contexts.os = await getOsContext(); + } - task = _this$_queue$shift.task; - args = _this$_queue$shift.args; - resolve = _this$_queue$shift.resolve; - reject = _this$_queue$shift.reject; - cb = yield _asyncToGenerator(function* () { - try { - returned = yield task(...args); - return function () { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function () { - return reject(error); - }; - } - })(); - _this._running--; + if (_options.app) { + contexts.app = getAppContext(); + } - _this._tryToRun(); + if (_options.device) { + contexts.device = getDeviceContext(_options.device); + } - return cb(); + if (_options.culture) { + const culture = getCultureContext(); + + if (culture) { + contexts.culture = culture; } - })(); + } + + if (_options.cloudResource) { + contexts.cloud_resource = getCloudResourceContext(); + } + + return contexts; } - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function (_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(event) { + return addContext(event); + }, + }; +}) ; - this._queue.push({ - task, - args, - resolve, - reject - }); +const nodeContextIntegration = core.defineIntegration(_nodeContextIntegration); - this._tryToRun(); +/** + * Add node modules / packages to the event. + * @deprecated Use `nodeContextIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const Context = core.convertIntegrationFnToClass(INTEGRATION_NAME, nodeContextIntegration) - return promise; +; + +// eslint-disable-next-line deprecation/deprecation + +/** + * Updates the context with dynamic values that can change + */ +function _updateContext(contexts) { + // Only update properties if they exist + if (_optionalChain([contexts, 'optionalAccess', _11 => _11.app, 'optionalAccess', _12 => _12.app_memory])) { + contexts.app.app_memory = process.memoryUsage().rss; } -}; -module.exports = Sync; + if (_optionalChain([contexts, 'optionalAccess', _13 => _13.device, 'optionalAccess', _14 => _14.free_memory])) { + contexts.device.free_memory = os.freemem(); + } -/***/ }), + return contexts; +} -/***/ 1666: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/** + * Returns the operating system context. + * + * Based on the current platform, this uses a different strategy to provide the + * most accurate OS information. Since this might involve spawning subprocesses + * or accessing the file system, this should only be executed lazily and cached. + * + * - On macOS (Darwin), this will execute the `sw_vers` utility. The context + * has a `name`, `version`, `build` and `kernel_version` set. + * - On Linux, this will try to load a distribution release from `/etc` and set + * the `name`, `version` and `kernel_version` fields. + * - On all other platforms, only a `name` and `version` will be returned. Note + * that `version` might actually be the kernel version. + */ +async function getOsContext() { + const platformId = os.platform(); + switch (platformId) { + case 'darwin': + return getDarwinInfo(); + case 'linux': + return getLinuxInfo(); + default: + return { + name: PLATFORM_NAMES[platformId] || platformId, + version: os.release(), + }; + } +} -"use strict"; +function getCultureContext() { + try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any + if (typeof (process.versions ).icu !== 'string') { + // Node was built without ICU support + return; + } + // Check that node was built with full Intl support. Its possible it was built without support for non-English + // locales which will make resolvedOptions inaccurate + // + // https://nodejs.org/api/intl.html#detecting-internationalization-support + const january = new Date(9e8); + const spanish = new Intl.DateTimeFormat('es', { month: 'long' }); + if (spanish.format(january) === 'enero') { + const options = Intl.DateTimeFormat().resolvedOptions(); -module.exports = __nccwpck_require__(29263); + return { + locale: options.locale, + timezone: options.timeZone, + }; + } + } catch (err) { + // + } -/***/ }), + return; +} -/***/ 90651: -/***/ ((__unused_webpack_module, exports) => { +function getAppContext() { + const app_memory = process.memoryUsage().rss; + const app_start_time = new Date(Date.now() - process.uptime() * 1000).toISOString(); -"use strict"; + return { app_start_time, app_memory }; +} +/** + * Gets device information from os + */ +function getDeviceContext(deviceOpt) { + const device = {}; -exports.load = function (received, defaults, onto = {}) { - var k, ref, v; + // Sometimes os.uptime() throws due to lacking permissions: https://github.com/getsentry/sentry-javascript/issues/8202 + let uptime; + try { + uptime = os.uptime && os.uptime(); + } catch (e) { + // noop + } - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; + // os.uptime or its return value seem to be undefined in certain environments (e.g. Azure functions). + // Hence, we only set boot time, if we get a valid uptime value. + // @see https://github.com/getsentry/sentry-javascript/issues/5856 + if (typeof uptime === 'number') { + device.boot_time = new Date(Date.now() - uptime * 1000).toISOString(); } - return onto; -}; + device.arch = os.arch(); -exports.overwrite = function (received, defaults, onto = {}) { - var k, v; + if (deviceOpt === true || deviceOpt.memory) { + device.memory_size = os.totalmem(); + device.free_memory = os.freemem(); + } - for (k in received) { - v = received[k]; + if (deviceOpt === true || deviceOpt.cpu) { + const cpuInfo = os.cpus(); + if (cpuInfo && cpuInfo.length) { + const firstCpu = cpuInfo[0]; - if (defaults[k] !== void 0) { - onto[k] = v; + device.processor_count = cpuInfo.length; + device.cpu_description = firstCpu.model; + device.processor_frequency = firstCpu.speed; } } - return onto; + return device; +} + +/** Mapping of Node's platform names to actual OS names. */ +const PLATFORM_NAMES = { + aix: 'IBM AIX', + freebsd: 'FreeBSD', + openbsd: 'OpenBSD', + sunos: 'SunOS', + win32: 'Windows', }; -/***/ }), +/** Linux version file to check for a distribution. */ + +/** Mapping of linux release files located in /etc to distributions. */ +const LINUX_DISTROS = [ + { name: 'fedora-release', distros: ['Fedora'] }, + { name: 'redhat-release', distros: ['Red Hat Linux', 'Centos'] }, + { name: 'redhat_version', distros: ['Red Hat Linux'] }, + { name: 'SuSE-release', distros: ['SUSE Linux'] }, + { name: 'lsb-release', distros: ['Ubuntu Linux', 'Arch Linux'] }, + { name: 'debian_version', distros: ['Debian'] }, + { name: 'debian_release', distros: ['Debian'] }, + { name: 'arch-release', distros: ['Arch Linux'] }, + { name: 'gentoo-release', distros: ['Gentoo Linux'] }, + { name: 'novell-release', distros: ['SUSE Linux'] }, + { name: 'alpine-release', distros: ['Alpine Linux'] }, +]; -/***/ 80890: -/***/ (function(module) { +/** Functions to extract the OS version from Linux release files. */ +const LINUX_VERSIONS + + = { + alpine: content => content, + arch: content => matchFirst(/distrib_release=(.*)/, content), + centos: content => matchFirst(/release ([^ ]+)/, content), + debian: content => content, + fedora: content => matchFirst(/release (..)/, content), + mint: content => matchFirst(/distrib_release=(.*)/, content), + red: content => matchFirst(/release ([^ ]+)/, content), + suse: content => matchFirst(/VERSION = (.*)\n/, content), + ubuntu: content => matchFirst(/distrib_release=(.*)/, content), +}; /** - * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. - * https://github.com/SGrondin/bottleneck - */ -(function (global, factory) { - true ? module.exports = factory() : - 0; -}(this, (function () { 'use strict'; + * Executes a regular expression with one capture group. + * + * @param regex A regular expression to execute. + * @param text Content to execute the RegEx on. + * @returns The captured string if matched; otherwise undefined. + */ +function matchFirst(regex, text) { + const match = regex.exec(text); + return match ? match[1] : undefined; +} - var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; +/** Loads the macOS operating system context. */ +async function getDarwinInfo() { + // Default values that will be used in case no operating system information + // can be loaded. The default version is computed via heuristics from the + // kernel version, but the build ID is missing. + const darwinInfo = { + kernel_version: os.release(), + name: 'Mac OS X', + version: `10.${Number(os.release().split('.')[0]) - 4}`, + }; - function getCjsExportFromNamespace (n) { - return n && n['default'] || n; - } + try { + // We try to load the actual macOS version by executing the `sw_vers` tool. + // This tool should be available on every standard macOS installation. In + // case this fails, we stick with the values computed above. + + const output = await new Promise((resolve, reject) => { + child_process.execFile('/usr/bin/sw_vers', (error, stdout) => { + if (error) { + reject(error); + return; + } + resolve(stdout); + }); + }); - var load = function(received, defaults, onto = {}) { - var k, ref, v; - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; - } - return onto; - }; + darwinInfo.name = matchFirst(/^ProductName:\s+(.*)$/m, output); + darwinInfo.version = matchFirst(/^ProductVersion:\s+(.*)$/m, output); + darwinInfo.build = matchFirst(/^BuildVersion:\s+(.*)$/m, output); + } catch (e) { + // ignore + } - var overwrite = function(received, defaults, onto = {}) { - var k, v; - for (k in received) { - v = received[k]; - if (defaults[k] !== void 0) { - onto[k] = v; - } - } - return onto; - }; + return darwinInfo; +} - var parser = { - load: load, - overwrite: overwrite - }; +/** Returns a distribution identifier to look up version callbacks. */ +function getLinuxDistroId(name) { + return name.split(' ')[0].toLowerCase(); +} - var DLList; +/** Loads the Linux operating system context. */ +async function getLinuxInfo() { + // By default, we cannot assume anything about the distribution or Linux + // version. `os.release()` returns the kernel version and we assume a generic + // "Linux" name, which will be replaced down below. + const linuxInfo = { + kernel_version: os.release(), + name: 'Linux', + }; - DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; - } + try { + // We start guessing the distribution by listing files in the /etc + // directory. This is were most Linux distributions (except Knoppix) store + // release files with certain distribution-dependent meta data. We search + // for exactly one known file defined in `LINUX_DISTROS` and exit if none + // are found. In case there are more than one file, we just stick with the + // first one. + const etcFiles = await readDirAsync('/etc'); + const distroFile = LINUX_DISTROS.find(file => etcFiles.includes(file.name)); + if (!distroFile) { + return linuxInfo; + } + + // Once that file is known, load its contents. To make searching in those + // files easier, we lowercase the file contents. Since these files are + // usually quite small, this should not allocate too much memory and we only + // hold on to it for a very short amount of time. + const distroPath = path.join('/etc', distroFile.name); + const contents = ((await readFileAsync(distroPath, { encoding: 'utf-8' })) ).toLowerCase(); + + // Some Linux distributions store their release information in the same file + // (e.g. RHEL and Centos). In those cases, we scan the file for an + // identifier, that basically consists of the first word of the linux + // distribution name (e.g. "red" for Red Hat). In case there is no match, we + // just assume the first distribution in our list. + const { distros } = distroFile; + linuxInfo.name = distros.find(d => contents.indexOf(getLinuxDistroId(d)) >= 0) || distros[0]; + + // Based on the found distribution, we can now compute the actual version + // number. This is different for every distribution, so several strategies + // are computed in `LINUX_VERSIONS`. + const id = getLinuxDistroId(linuxInfo.name); + linuxInfo.version = LINUX_VERSIONS[id](contents); + } catch (e) { + // ignore + } - push(value) { - var node; - this.length++; - if (typeof this.incr === "function") { - this.incr(); - } - node = { - value, - prev: this._last, - next: null - }; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; - } - return void 0; - } + return linuxInfo; +} - shift() { - var value; - if (this._first == null) { - return; - } else { - this.length--; - if (typeof this.decr === "function") { - this.decr(); - } - } - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } - return value; - } +/** + * Grabs some information about hosting provider based on best effort. + */ +function getCloudResourceContext() { + if (process.env.VERCEL) { + // https://vercel.com/docs/concepts/projects/environment-variables/system-environment-variables#system-environment-variables + return { + 'cloud.provider': 'vercel', + 'cloud.region': process.env.VERCEL_REGION, + }; + } else if (process.env.AWS_REGION) { + // https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html + return { + 'cloud.provider': 'aws', + 'cloud.region': process.env.AWS_REGION, + 'cloud.platform': process.env.AWS_EXECUTION_ENV, + }; + } else if (process.env.GCP_PROJECT) { + // https://cloud.google.com/composer/docs/how-to/managing/environment-variables#reserved_variables + return { + 'cloud.provider': 'gcp', + }; + } else if (process.env.ALIYUN_REGION_ID) { + // TODO: find where I found these environment variables - at least gc.github.com returns something + return { + 'cloud.provider': 'alibaba_cloud', + 'cloud.region': process.env.ALIYUN_REGION_ID, + }; + } else if (process.env.WEBSITE_SITE_NAME && process.env.REGION_NAME) { + // https://learn.microsoft.com/en-us/azure/app-service/reference-app-settings?tabs=kudu%2Cdotnet#app-environment + return { + 'cloud.provider': 'azure', + 'cloud.region': process.env.REGION_NAME, + }; + } else if (process.env.IBM_CLOUD_REGION) { + // TODO: find where I found these environment variables - at least gc.github.com returns something + return { + 'cloud.provider': 'ibm_cloud', + 'cloud.region': process.env.IBM_CLOUD_REGION, + }; + } else if (process.env.TENCENTCLOUD_REGION) { + // https://www.tencentcloud.com/document/product/583/32748 + return { + 'cloud.provider': 'tencent_cloud', + 'cloud.region': process.env.TENCENTCLOUD_REGION, + 'cloud.account.id': process.env.TENCENTCLOUD_APPID, + 'cloud.availability_zone': process.env.TENCENTCLOUD_ZONE, + }; + } else if (process.env.NETLIFY) { + // https://docs.netlify.com/configure-builds/environment-variables/#read-only-variables + return { + 'cloud.provider': 'netlify', + }; + } else if (process.env.FLY_REGION) { + // https://fly.io/docs/reference/runtime-environment/ + return { + 'cloud.provider': 'fly.io', + 'cloud.region': process.env.FLY_REGION, + }; + } else if (process.env.DYNO) { + // https://devcenter.heroku.com/articles/dynos#local-environment-variables + return { + 'cloud.provider': 'heroku', + }; + } else { + return undefined; + } +} - first() { - if (this._first != null) { - return this._first.value; - } - } +exports.Context = Context; +exports.getDeviceContext = getDeviceContext; +exports.nodeContextIntegration = nodeContextIntegration; +exports.readDirAsync = readDirAsync; +exports.readFileAsync = readFileAsync; +//# sourceMappingURL=context.js.map - getArray() { - var node, ref, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } - return results; - } - forEachShift(cb) { - var node; - node = this.shift(); - while (node != null) { - (cb(node), node = this.shift()); - } - return void 0; - } +/***/ }), - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } - return results; - } +/***/ 73456: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - }; +var { + _optionalChain +} = __nccwpck_require__(57540); - var DLList_1 = DLList; +Object.defineProperty(exports, "__esModule", ({ value: true })); - var Events; +const fs = __nccwpck_require__(79896); +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); - Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { - throw new Error("An Emitter already exists for this object"); - } - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; - } - }; - } +const FILE_CONTENT_CACHE = new utils.LRUMap(100); +const DEFAULT_LINES_OF_CONTEXT = 7; +const INTEGRATION_NAME = 'ContextLines'; - _addListener(name, status, cb) { - var base; - if ((base = this._events)[name] == null) { - base[name] = []; - } - this._events[name].push({cb, status}); - return this.instance; - } +// TODO: Replace with promisify when minimum supported node >= v8 +function readTextFileAsync(path) { + return new Promise((resolve, reject) => { + fs.readFile(path, 'utf8', (err, data) => { + if (err) reject(err); + else resolve(data); + }); + }); +} - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } - } +const _contextLinesIntegration = ((options = {}) => { + const contextLines = options.frameContextLines !== undefined ? options.frameContextLines : DEFAULT_LINES_OF_CONTEXT; - async trigger(name, ...args) { - var e, promises; - try { - if (name !== "debug") { - this.trigger("debug", `Event triggered: ${name}`, args); - } - if (this._events[name] == null) { - return; - } - this._events[name] = this._events[name].filter(function(listener) { - return listener.status !== "none"; - }); - promises = this._events[name].map(async(listener) => { - var e, returned; - if (listener.status === "none") { - return; - } - if (listener.status === "once") { - listener.status = "none"; - } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; - if (typeof (returned != null ? returned.then : void 0) === "function") { - return (await returned); - } else { - return returned; - } - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - }); - return ((await Promise.all(promises))).find(function(x) { - return x != null; - }); - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - } + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(event) { + return addSourceContext(event, contextLines); + }, + }; +}) ; - }; +const contextLinesIntegration = core.defineIntegration(_contextLinesIntegration); - var Events_1 = Events; +/** + * Add node modules / packages to the event. + * @deprecated Use `contextLinesIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const ContextLines = core.convertIntegrationFnToClass(INTEGRATION_NAME, contextLinesIntegration) - var DLList$1, Events$1, Queues; +; - DLList$1 = DLList_1; +async function addSourceContext(event, contextLines) { + // keep a lookup map of which files we've already enqueued to read, + // so we don't enqueue the same file multiple times which would cause multiple i/o reads + const enqueuedReadSourceFileTasks = {}; + const readSourceFileTasks = []; - Events$1 = Events_1; + if (contextLines > 0 && _optionalChain([event, 'access', _2 => _2.exception, 'optionalAccess', _3 => _3.values])) { + for (const exception of event.exception.values) { + if (!_optionalChain([exception, 'access', _4 => _4.stacktrace, 'optionalAccess', _5 => _5.frames])) { + continue; + } - Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events$1(this); - this._length = 0; - this._lists = (function() { - var j, ref, results; - results = []; - for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { - results.push(new DLList$1((() => { - return this.incr(); - }), (() => { - return this.decr(); - }))); - } - return results; - }).call(this); - } + // We want to iterate in reverse order as calling cache.get will bump the file in our LRU cache. + // This ends up prioritizes source context for frames at the top of the stack instead of the bottom. + for (let i = exception.stacktrace.frames.length - 1; i >= 0; i--) { + const frame = exception.stacktrace.frames[i]; + // Call cache.get to bump the file to the top of the cache and ensure we have not already + // enqueued a read operation for this filename + if (frame.filename && !enqueuedReadSourceFileTasks[frame.filename] && !FILE_CONTENT_CACHE.get(frame.filename)) { + readSourceFileTasks.push(_readSourceFile(frame.filename)); + enqueuedReadSourceFileTasks[frame.filename] = 1; + } + } + } + } - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } + // check if files to read > 0, if so, await all of them to be read before adding source contexts. + // Normally, Promise.all here could be short circuited if one of the promises rejects, but we + // are guarding from that by wrapping the i/o read operation in a try/catch. + if (readSourceFileTasks.length > 0) { + await Promise.all(readSourceFileTasks); + } - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } + // Perform the same loop as above, but this time we can assume all files are in the cache + // and attempt to add source context to frames. + if (contextLines > 0 && _optionalChain([event, 'access', _6 => _6.exception, 'optionalAccess', _7 => _7.values])) { + for (const exception of event.exception.values) { + if (exception.stacktrace && exception.stacktrace.frames) { + await addSourceContextToFrames(exception.stacktrace.frames, contextLines); + } + } + } - push(job) { - return this._lists[job.options.priority].push(job); - } + return event; +} - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } - } +/** Adds context lines to frames */ +function addSourceContextToFrames(frames, contextLines) { + for (const frame of frames) { + // Only add context if we have a filename and it hasn't already been added + if (frame.filename && frame.context_line === undefined) { + const sourceFileLines = FILE_CONTENT_CACHE.get(frame.filename); - shiftAll(fn) { - return this._lists.forEach(function(list) { - return list.forEachShift(fn); - }); - } + if (sourceFileLines) { + try { + utils.addContextToFrame(sourceFileLines, frame, contextLines); + } catch (e) { + // anomaly, being defensive in case + // unlikely to ever happen in practice but can definitely happen in theory + } + } + } + } +} - getFirst(arr = this._lists) { - var j, len, list; - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; - if (list.length > 0) { - return list; - } - } - return []; - } +// eslint-disable-next-line deprecation/deprecation - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); - } +/** + * Reads file contents and caches them in a global LRU cache. + * If reading fails, mark the file as null in the cache so we don't try again. + * + * @param filename filepath to read content from. + */ +async function _readSourceFile(filename) { + const cachedFile = FILE_CONTENT_CACHE.get(filename); - }; + // We have already attempted to read this file and failed, do not try again + if (cachedFile === null) { + return null; + } - var Queues_1 = Queues; + // We have a cache hit, return it + if (cachedFile !== undefined) { + return cachedFile; + } - var BottleneckError; + // Guard from throwing if readFile fails, this enables us to use Promise.all and + // not have it short circuiting if one of the promises rejects + since context lines are added + // on a best effort basis, we want to throw here anyways. - BottleneckError = class BottleneckError extends Error {}; + // If we made it to here, it means that our file is not cache nor marked as failed, so attempt to read it + let content = null; + try { + const rawFileContents = await readTextFileAsync(filename); + content = rawFileContents.split('\n'); + } catch (_) { + // if we fail, we will mark the file as null in the cache and short circuit next time we try to read it + } - var BottleneckError_1 = BottleneckError; + FILE_CONTENT_CACHE.set(filename, content); + return content; +} - var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; +exports.ContextLines = ContextLines; +exports.contextLinesIntegration = contextLinesIntegration; +//# sourceMappingURL=contextlines.js.map - NUM_PRIORITIES = 10; - DEFAULT_PRIORITY = 5; +/***/ }), - parser$1 = parser; +/***/ 70345: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - BottleneckError$1 = BottleneckError_1; +Object.defineProperty(exports, "__esModule", ({ value: true })); - Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser$1.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; - } - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } +function isResponseObject(response) { + return response && (response ).statusCode !== undefined; +} - _randomIndex() { - return Math.random().toString(36).slice(2); - } +function isErrorEvent(event) { + return event && (event ).error !== undefined; +} - doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError$1(message)); - } - this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); - return true; - } else { - return false; - } - } +function sendErrorToSentry(errorData) { + core.captureException(errorData, { + mechanism: { + type: 'hapi', + handled: false, + data: { + function: 'hapiErrorPlugin', + }, + }, + }); +} - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); - if (!(status === expected || (expected === "DONE" && status === null))) { - throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } - } +const hapiErrorPlugin = { + name: 'SentryHapiErrorPlugin', + version: core.SDK_VERSION, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + register: async function (serverArg) { + const server = serverArg ; - doReceive() { - this._states.start(this.options.id); - return this.Events.trigger("received", {args: this.args, options: this.options}); - } + server.events.on('request', (request, event) => { + // eslint-disable-next-line deprecation/deprecation + const transaction = core.getActiveTransaction(); - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); - this._states.next(this.options.id); - return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); - } + if (isErrorEvent(event)) { + sendErrorToSentry(event.error); + } - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - return this.Events.trigger("scheduled", {args: this.args, options: this.options}); - } + if (transaction) { + transaction.setStatus('internal_error'); + transaction.end(); + } + }); + }, +}; - async doExecute(chained, clearGlobalState, run, free) { - var error, eventInfo, passed; - if (this.retryCount === 0) { - this._assertStatus("RUNNING"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - this.Events.trigger("executing", eventInfo); - try { - passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); - if (clearGlobalState()) { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._resolve(passed); - } - } catch (error1) { - error = error1; - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - } +const hapiTracingPlugin = { + name: 'SentryHapiTracingPlugin', + version: core.SDK_VERSION, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + register: async function (serverArg) { + const server = serverArg ; - doExpire(clearGlobalState, run, free) { - var error, eventInfo; - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); - } - this._assertStatus("EXECUTING"); - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } + server.ext('onPreHandler', (request, h) => { + const transaction = core.continueTrace( + { + sentryTrace: request.headers['sentry-trace'] || undefined, + baggage: request.headers['baggage'] || undefined, + }, + transactionContext => { + // eslint-disable-next-line deprecation/deprecation + return core.startTransaction({ + ...transactionContext, + op: 'hapi.request', + name: request.route.path, + description: `${request.route.method} ${request.path}`, + }); + }, + ); - async _onFailure(error, eventInfo, clearGlobalState, run, free) { - var retry, retryAfter; - if (clearGlobalState()) { - retry = (await this.Events.trigger("failed", error, eventInfo)); - if (retry != null) { - retryAfter = ~~retry; - this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); - this.retryCount++; - return run(retryAfter); - } else { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._reject(error); - } - } - } + // eslint-disable-next-line deprecation/deprecation + core.getCurrentScope().setSpan(transaction); - doDone(eventInfo) { - this._assertStatus("EXECUTING"); - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } + return h.continue; + }); - }; + server.ext('onPreResponse', (request, h) => { + // eslint-disable-next-line deprecation/deprecation + const transaction = core.getActiveTransaction(); - var Job_1 = Job; + if (request.response && isResponseObject(request.response) && transaction) { + const response = request.response ; + response.header('sentry-trace', core.spanToTraceHeader(transaction)); - var BottleneckError$2, LocalDatastore, parser$2; + const dynamicSamplingContext = utils.dynamicSamplingContextToSentryBaggageHeader( + core.getDynamicSamplingContextFromSpan(transaction), + ); - parser$2 = parser; + if (dynamicSamplingContext) { + response.header('baggage', dynamicSamplingContext); + } + } - BottleneckError$2 = BottleneckError_1; + return h.continue; + }); - LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser$2.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; - this._startHeartbeat(); - } + server.ext('onPostHandler', (request, h) => { + // eslint-disable-next-line deprecation/deprecation + const transaction = core.getActiveTransaction(); - _startHeartbeat() { - var base; - if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { - return typeof (base = (this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); - if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; - this.instance._drainAll(this.computeCapacity()); - } - if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - ({ - reservoirIncreaseAmount: amount, - reservoirIncreaseMaximum: maximum, - reservoir - } = this.storeOptions); - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); - } - } - }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); - } - } + if (transaction) { + if (request.response && isResponseObject(request.response)) { + core.setHttpStatus(transaction, request.response.statusCode); + } - async __publish__(message) { - await this.yieldLoop(); - return this.instance.Events.trigger("message", message.toString()); - } + transaction.end(); + } - async __disconnect__(flush) { - await this.yieldLoop(); - clearInterval(this.heartbeat); - return this.Promise.resolve(); - } + return h.continue; + }); + }, +}; - yieldLoop(t = 0) { - return new this.Promise(function(resolve, reject) { - return setTimeout(resolve, t); - }); - } +const INTEGRATION_NAME = 'Hapi'; - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; - } +const _hapiIntegration = ((options = {}) => { + const server = options.server ; - async __updateSettings__(options) { - await this.yieldLoop(); - parser$2.overwrite(options, options, this.storeOptions); - this._startHeartbeat(); - this.instance._drainAll(this.computeCapacity()); - return true; - } + return { + name: INTEGRATION_NAME, + setupOnce() { + if (!server) { + return; + } - async __running__() { - await this.yieldLoop(); - return this._running; - } + utils.fill(server, 'start', (originalStart) => { + return async function () { + await this.register(hapiTracingPlugin); + await this.register(hapiErrorPlugin); + const result = originalStart.apply(this); + return result; + }; + }); + }, + }; +}) ; - async __queued__() { - await this.yieldLoop(); - return this.instance.queued(); - } +const hapiIntegration = core.defineIntegration(_hapiIntegration); - async __done__() { - await this.yieldLoop(); - return this._done; - } +/** + * Hapi Framework Integration. + * @deprecated Use `hapiIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const Hapi = core.convertIntegrationFnToClass(INTEGRATION_NAME, hapiIntegration); - async __groupCheck__(time) { - await this.yieldLoop(); - return (this._nextRequest + this.timeout) < time; - } +// eslint-disable-next-line deprecation/deprecation - computeCapacity() { - var maxConcurrent, reservoir; - ({maxConcurrent, reservoir} = this.storeOptions); - if ((maxConcurrent != null) && (reservoir != null)) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } +exports.Hapi = Hapi; +exports.hapiErrorPlugin = hapiErrorPlugin; +exports.hapiIntegration = hapiIntegration; +exports.hapiTracingPlugin = hapiTracingPlugin; +//# sourceMappingURL=index.js.map - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return (capacity == null) || weight <= capacity; - } - async __incrementReservoir__(incr) { - var reservoir; - await this.yieldLoop(); - reservoir = this.storeOptions.reservoir += incr; - this.instance._drainAll(this.computeCapacity()); - return reservoir; - } +/***/ }), - async __currentReservoir__() { - await this.yieldLoop(); - return this.storeOptions.reservoir; - } +/***/ 15842: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - isBlocked(now) { - return this._unblockTime >= now; - } +var { + _optionalChain +} = __nccwpck_require__(57540); - check(weight, now) { - return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - async __check__(weight) { - var now; - await this.yieldLoop(); - now = Date.now(); - return this.check(weight, now); - } +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(96652); +const nodeVersion = __nccwpck_require__(85858); +const http = __nccwpck_require__(21524); + +const _httpIntegration = ((options = {}) => { + const { breadcrumbs, tracing, shouldCreateSpanForRequest } = options; + + const convertedOptions = { + breadcrumbs, + tracing: + tracing === false + ? false + : utils.dropUndefinedKeys({ + // If tracing is forced to `true`, we don't want to set `enableIfHasTracingEnabled` + enableIfHasTracingEnabled: tracing === true ? undefined : true, + shouldCreateSpanForRequest, + }), + }; - async __register__(index, weight, expiration) { - var now, wait; - await this.yieldLoop(); - now = Date.now(); - if (this.conditionsCheck(weight)) { - this._running += weight; - if (this.storeOptions.reservoir != null) { - this.storeOptions.reservoir -= weight; - } - wait = Math.max(this._nextRequest - now, 0); - this._nextRequest = now + wait + this.storeOptions.minTime; - return { - success: true, - wait, - reservoir: this.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - } + // eslint-disable-next-line deprecation/deprecation + return new Http(convertedOptions) ; +}) ; - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } +/** + * The http module integration instruments Node's internal http module. It creates breadcrumbs, spans for outgoing + * http requests, and attaches trace data when tracing is enabled via its `tracing` option. + * + * By default, this will always create breadcrumbs, and will create spans if tracing is enabled. + */ +const httpIntegration = core.defineIntegration(_httpIntegration); - async __submit__(queueLength, weight) { - var blocked, now, reachedHWM; - await this.yieldLoop(); - if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { - throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); - } - now = Date.now(); - reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); - blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); - if (blocked) { - this._unblockTime = now + this.computePenalty(); - this._nextRequest = this._unblockTime + this.storeOptions.minTime; - this.instance._dropAllQueued(); - } - return { - reachedHWM, - blocked, - strategy: this.storeOptions.strategy - }; - } +/** + * The http module integration instruments Node's internal http module. It creates breadcrumbs, transactions for outgoing + * http requests and attaches trace data when tracing is enabled via its `tracing` option. + * + * @deprecated Use `httpIntegration()` instead. + */ +class Http { + /** + * @inheritDoc + */ + static __initStatic() {this.id = 'Http';} - async __free__(index, weight) { - await this.yieldLoop(); - this._running -= weight; - this._done += weight; - this.instance._drainAll(this.computeCapacity()); - return { - running: this._running - }; - } + /** + * @inheritDoc + */ + // eslint-disable-next-line deprecation/deprecation + __init() {this.name = Http.id;} - }; + /** + * @inheritDoc + */ + constructor(options = {}) {Http.prototype.__init.call(this); + this._breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs; + this._tracing = !options.tracing ? undefined : options.tracing === true ? {} : options.tracing; + } - var LocalDatastore_1 = LocalDatastore; + /** + * @inheritDoc + */ + setupOnce( + _addGlobalEventProcessor, + // eslint-disable-next-line deprecation/deprecation + setupOnceGetCurrentHub, + ) { + // eslint-disable-next-line deprecation/deprecation + const clientOptions = _optionalChain([setupOnceGetCurrentHub, 'call', _ => _(), 'access', _2 => _2.getClient, 'call', _3 => _3(), 'optionalAccess', _4 => _4.getOptions, 'call', _5 => _5()]); - var BottleneckError$3, States; + // If `tracing` is not explicitly set, we default this based on whether or not tracing is enabled. + // But for compatibility, we only do that if `enableIfHasTracingEnabled` is set. + const shouldCreateSpans = _shouldCreateSpans(this._tracing, clientOptions); - BottleneckError$3 = BottleneckError_1; + // No need to instrument if we don't want to track anything + if (!this._breadcrumbs && !shouldCreateSpans) { + return; + } - States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function() { - return 0; - }); - } + // Do not auto-instrument for other instrumenter + if (clientOptions && clientOptions.instrumenter !== 'sentry') { + debugBuild.DEBUG_BUILD && utils.logger.log('HTTP Integration is skipped because of instrumenter configuration.'); + return; + } - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; - if ((current != null) && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } + const shouldCreateSpanForRequest = _getShouldCreateSpanForRequest(shouldCreateSpans, this._tracing, clientOptions); - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } + // eslint-disable-next-line deprecation/deprecation + const tracePropagationTargets = _optionalChain([clientOptions, 'optionalAccess', _6 => _6.tracePropagationTargets]) || _optionalChain([this, 'access', _7 => _7._tracing, 'optionalAccess', _8 => _8.tracePropagationTargets]); + + // eslint-disable-next-line @typescript-eslint/no-var-requires + const httpModule = __nccwpck_require__(58611); + const wrappedHttpHandlerMaker = _createWrappedRequestMethodFactory( + httpModule, + this._breadcrumbs, + shouldCreateSpanForRequest, + tracePropagationTargets, + ); + utils.fill(httpModule, 'get', wrappedHttpHandlerMaker); + utils.fill(httpModule, 'request', wrappedHttpHandlerMaker); + + // NOTE: Prior to Node 9, `https` used internals of `http` module, thus we don't patch it. + // If we do, we'd get double breadcrumbs and double spans for `https` calls. + // It has been changed in Node 9, so for all versions equal and above, we patch `https` separately. + if (nodeVersion.NODE_VERSION.major > 8) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const httpsModule = __nccwpck_require__(65692); + const wrappedHttpsHandlerMaker = _createWrappedRequestMethodFactory( + httpsModule, + this._breadcrumbs, + shouldCreateSpanForRequest, + tracePropagationTargets, + ); + utils.fill(httpsModule, 'get', wrappedHttpsHandlerMaker); + utils.fill(httpsModule, 'request', wrappedHttpsHandlerMaker); + } + } +}Http.__initStatic(); - remove(id) { - var current; - current = this._jobs[id]; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } - return current != null; - } +// for ease of reading below - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } +/** + * Function which creates a function which creates wrapped versions of internal `request` and `get` calls within `http` + * and `https` modules. (NB: Not a typo - this is a creator^2!) + * + * @param breadcrumbsEnabled Whether or not to record outgoing requests as breadcrumbs + * @param tracingEnabled Whether or not to record outgoing requests as tracing spans + * + * @returns A function which accepts the exiting handler and returns a wrapped handler + */ +function _createWrappedRequestMethodFactory( + httpModule, + breadcrumbsEnabled, + shouldCreateSpanForRequest, + tracePropagationTargets, +) { + // We're caching results so we don't have to recompute regexp every time we create a request. + const createSpanUrlMap = new utils.LRUMap(100); + const headersUrlMap = new utils.LRUMap(100); - statusJobs(status) { - var k, pos, ref, results, v; - if (status != null) { - pos = this.status.indexOf(status); - if (pos < 0) { - throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); - } - ref = this._jobs; - results = []; - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } - return results; - } else { - return Object.keys(this._jobs); - } - } + const shouldCreateSpan = (url) => { + if (shouldCreateSpanForRequest === undefined) { + return true; + } - statusCounts() { - return this.counts.reduce(((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }), {}); - } + const cachedDecision = createSpanUrlMap.get(url); + if (cachedDecision !== undefined) { + return cachedDecision; + } - }; + const decision = shouldCreateSpanForRequest(url); + createSpanUrlMap.set(url, decision); + return decision; + }; - var States_1 = States; + const shouldAttachTraceData = (url) => { + if (tracePropagationTargets === undefined) { + return true; + } - var DLList$2, Sync; + const cachedDecision = headersUrlMap.get(url); + if (cachedDecision !== undefined) { + return cachedDecision; + } - DLList$2 = DLList_1; + const decision = utils.stringMatchesSomePattern(url, tracePropagationTargets); + headersUrlMap.set(url, decision); + return decision; + }; - Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList$2(); - } + /** + * Captures Breadcrumb based on provided request/response pair + */ + function addRequestBreadcrumb( + event, + requestSpanData, + req, + res, + ) { + // eslint-disable-next-line deprecation/deprecation + if (!core.getCurrentHub().getIntegration(Http)) { + return; + } - isEmpty() { - return this._queue.length === 0; - } + core.addBreadcrumb( + { + category: 'http', + data: { + status_code: res && res.statusCode, + ...requestSpanData, + }, + type: 'http', + }, + { + event, + request: req, + response: res, + }, + ); + } - async _tryToRun() { - var args, cb, error, reject, resolve, returned, task; - if ((this._running < 1) && this._queue.length > 0) { - this._running++; - ({task, args, resolve, reject} = this._queue.shift()); - cb = (await (async function() { - try { - returned = (await task(...args)); - return function() { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function() { - return reject(error); - }; - } - })()); - this._running--; - this._tryToRun(); - return cb(); - } - } + return function wrappedRequestMethodFactory(originalRequestMethod) { + return function wrappedMethod( ...args) { + const requestArgs = http.normalizeRequestArgs(httpModule, args); + const requestOptions = requestArgs[0]; + // eslint-disable-next-line deprecation/deprecation + const rawRequestUrl = http.extractRawUrl(requestOptions); + const requestUrl = http.extractUrl(requestOptions); + const client = core.getClient(); + + // we don't want to record requests to Sentry as either breadcrumbs or spans, so just use the original method + if (core.isSentryRequestUrl(requestUrl, client)) { + return originalRequestMethod.apply(httpModule, requestArgs); + } + + const scope = core.getCurrentScope(); + const isolationScope = core.getIsolationScope(); + const parentSpan = core.getActiveSpan(); + + const data = getRequestSpanData(requestUrl, requestOptions); + + const requestSpan = shouldCreateSpan(rawRequestUrl) + ? // eslint-disable-next-line deprecation/deprecation + _optionalChain([parentSpan, 'optionalAccess', _9 => _9.startChild, 'call', _10 => _10({ + op: 'http.client', + origin: 'auto.http.node.http', + description: `${data['http.method']} ${data.url}`, + data, + })]) + : undefined; + + if (client && shouldAttachTraceData(rawRequestUrl)) { + const { traceId, spanId, sampled, dsc } = { + ...isolationScope.getPropagationContext(), + ...scope.getPropagationContext(), + }; - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function(_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); - this._queue.push({task, args, resolve, reject}); - this._tryToRun(); - return promise; - } + const sentryTraceHeader = requestSpan + ? core.spanToTraceHeader(requestSpan) + : utils.generateSentryTraceHeader(traceId, spanId, sampled); - }; + const sentryBaggageHeader = utils.dynamicSamplingContextToSentryBaggageHeader( + dsc || + (requestSpan + ? core.getDynamicSamplingContextFromSpan(requestSpan) + : core.getDynamicSamplingContextFromClient(traceId, client, scope)), + ); - var Sync_1 = Sync; + addHeadersToRequestOptions(requestOptions, requestUrl, sentryTraceHeader, sentryBaggageHeader); + } else { + debugBuild.DEBUG_BUILD && + utils.logger.log( + `[Tracing] Not adding sentry-trace header to outgoing request (${requestUrl}) due to mismatching tracePropagationTargets option.`, + ); + } - var version = "2.19.5"; - var version$1 = { - version: version - }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + return originalRequestMethod + .apply(httpModule, requestArgs) + .once('response', function ( res) { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const req = this; + if (breadcrumbsEnabled) { + addRequestBreadcrumb('response', data, req, res); + } + if (requestSpan) { + if (res.statusCode) { + core.setHttpStatus(requestSpan, res.statusCode); + } + requestSpan.updateName( + http.cleanSpanDescription(core.spanToJSON(requestSpan).description || '', requestOptions, req) || '', + ); + requestSpan.end(); + } + }) + .once('error', function () { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const req = this; - var version$2 = /*#__PURE__*/Object.freeze({ - version: version, - default: version$1 - }); + if (breadcrumbsEnabled) { + addRequestBreadcrumb('error', data, req); + } + if (requestSpan) { + core.setHttpStatus(requestSpan, 500); + requestSpan.updateName( + http.cleanSpanDescription(core.spanToJSON(requestSpan).description || '', requestOptions, req) || '', + ); + requestSpan.end(); + } + }); + }; + }; +} - var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); +function addHeadersToRequestOptions( + requestOptions, + requestUrl, + sentryTraceHeader, + sentryBaggageHeader, +) { + // Don't overwrite sentry-trace and baggage header if it's already set. + const headers = requestOptions.headers || {}; + if (headers['sentry-trace']) { + return; + } - var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); + debugBuild.DEBUG_BUILD && + utils.logger.log(`[Tracing] Adding sentry-trace header ${sentryTraceHeader} to outgoing request to "${requestUrl}": `); - var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); + requestOptions.headers = { + ...requestOptions.headers, + 'sentry-trace': sentryTraceHeader, + // Setting a header to `undefined` will crash in node so we only set the baggage header when it's defined + ...(sentryBaggageHeader && + sentryBaggageHeader.length > 0 && { baggage: normalizeBaggageHeader(requestOptions, sentryBaggageHeader) }), + }; +} - var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; +function getRequestSpanData(requestUrl, requestOptions) { + const method = requestOptions.method || 'GET'; + const data = { + url: requestUrl, + 'http.method': method, + }; + if (requestOptions.hash) { + // strip leading "#" + data['http.fragment'] = requestOptions.hash.substring(1); + } + if (requestOptions.search) { + // strip leading "?" + data['http.query'] = requestOptions.search.substring(1); + } + return data; +} - parser$3 = parser; +function normalizeBaggageHeader( + requestOptions, + sentryBaggageHeader, +) { + if (!requestOptions.headers || !requestOptions.headers.baggage) { + return sentryBaggageHeader; + } else if (!sentryBaggageHeader) { + return requestOptions.headers.baggage ; + } else if (Array.isArray(requestOptions.headers.baggage)) { + return [...requestOptions.headers.baggage, sentryBaggageHeader]; + } + // Type-cast explanation: + // Technically this the following could be of type `(number | string)[]` but for the sake of simplicity + // we say this is undefined behaviour, since it would not be baggage spec conform if the user did this. + return [requestOptions.headers.baggage, sentryBaggageHeader] ; +} + +/** Exported for tests only. */ +function _shouldCreateSpans( + tracingOptions, + clientOptions, +) { + return tracingOptions === undefined + ? false + : tracingOptions.enableIfHasTracingEnabled + ? core.hasTracingEnabled(clientOptions) + : true; +} + +/** Exported for tests only. */ +function _getShouldCreateSpanForRequest( + shouldCreateSpans, + tracingOptions, + clientOptions, +) { + const handler = shouldCreateSpans + ? // eslint-disable-next-line deprecation/deprecation + _optionalChain([tracingOptions, 'optionalAccess', _11 => _11.shouldCreateSpanForRequest]) || _optionalChain([clientOptions, 'optionalAccess', _12 => _12.shouldCreateSpanForRequest]) + : () => false; - Events$2 = Events_1; + return handler; +} - RedisConnection$1 = require$$2; +exports.Http = Http; +exports._getShouldCreateSpanForRequest = _getShouldCreateSpanForRequest; +exports._shouldCreateSpans = _shouldCreateSpans; +exports.httpIntegration = httpIntegration; +//# sourceMappingURL=http.js.map - IORedisConnection$1 = require$$3; - Scripts$1 = require$$4; +/***/ }), - Group = (function() { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser$3.load(this.limiterOptions, this.defaults, this); - this.Events = new Events$2(this); - this.instances = {}; - this.Bottleneck = Bottleneck_1; - this._startAutoCleanup(); - this.sharedConnection = this.connection != null; - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } - } - } +/***/ 20028: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - async deleteKey(key = "") { - var deleted, instance; - instance = this.instances[key]; - if (this.connection) { - deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); - } - if (instance != null) { - delete this.instances[key]; - await instance.disconnect(); - } - return (instance != null) || deleted > 0; - } +const console = __nccwpck_require__(34441); +const http = __nccwpck_require__(15842); +const onuncaughtexception = __nccwpck_require__(63295); +const onunhandledrejection = __nccwpck_require__(31061); +const modules = __nccwpck_require__(45705); +const contextlines = __nccwpck_require__(73456); +const context = __nccwpck_require__(90079); +const core = __nccwpck_require__(75442); +const index = __nccwpck_require__(58676); +const index$1 = __nccwpck_require__(12561); +const spotlight = __nccwpck_require__(38880); +const index$2 = __nccwpck_require__(6008); +const index$3 = __nccwpck_require__(70345); + +/* eslint-disable deprecation/deprecation */ + +exports.Console = console.Console; +exports.Http = http.Http; +exports.OnUncaughtException = onuncaughtexception.OnUncaughtException; +exports.OnUnhandledRejection = onunhandledrejection.OnUnhandledRejection; +exports.Modules = modules.Modules; +exports.ContextLines = contextlines.ContextLines; +exports.Context = context.Context; +exports.RequestData = core.RequestData; +exports.LocalVariables = index.LocalVariables; +exports.Undici = index$1.Undici; +exports.Spotlight = spotlight.Spotlight; +exports.Anr = index$2.Anr; +exports.Hapi = index$3.Hapi; +//# sourceMappingURL=index.js.map - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } - return results; - } - keys() { - return Object.keys(this.instances); - } +/***/ }), - async clusterKeys() { - var cursor, end, found, i, k, keys, len, next, start; - if (this.connection == null) { - return this.Promise.resolve(this.keys()); - } - keys = []; - cursor = null; - start = `b_${this.id}-`.length; - end = "_settings".length; - while (cursor !== 0) { - [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); - cursor = ~~next; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } - return keys; - } +/***/ 58527: +/***/ ((__unused_webpack_module, exports) => { - _startAutoCleanup() { - var base; - clearInterval(this.interval); - return typeof (base = (this.interval = setInterval(async() => { - var e, k, ref, results, time, v; - time = Date.now(); - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - try { - if ((await v._store.__groupCheck__(time))) { - results.push(this.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } - return results; - }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - updateSettings(options = {}) { - parser$3.overwrite(options, this.defaults, this); - parser$3.overwrite(options, options, this.limiterOptions); - if (options.timeout != null) { - return this._startAutoCleanup(); - } - } +/** + * Creates a rate limiter that will call the disable callback when the rate limit is reached and the enable callback + * when a timeout has occurred. + * @param maxPerSecond Maximum number of calls per second + * @param enable Callback to enable capture + * @param disable Callback to disable capture + * @returns A function to call to increment the rate limiter count + */ +function createRateLimiter( + maxPerSecond, + enable, + disable, +) { + let count = 0; + let retrySeconds = 5; + let disabledTimeout = 0; - disconnect(flush = true) { - var ref; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; - } - } + setInterval(() => { + if (disabledTimeout === 0) { + if (count > maxPerSecond) { + retrySeconds *= 2; + disable(retrySeconds); - } - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; + // Cap at one day + if (retrySeconds > 86400) { + retrySeconds = 86400; + } + disabledTimeout = retrySeconds; + } + } else { + disabledTimeout -= 1; - return Group; + if (disabledTimeout === 0) { + enable(); + } + } - }).call(commonjsGlobal); + count = 0; + }, 1000).unref(); - var Group_1 = Group; + return () => { + count += 1; + }; +} - var Batcher, Events$3, parser$4; +// Add types for the exception event data - parser$4 = parser; +/** Could this be an anonymous function? */ +function isAnonymous(name) { + return name !== undefined && (name.length === 0 || name === '?' || name === ''); +} - Events$3 = Events_1; +/** Do the function names appear to match? */ +function functionNamesMatch(a, b) { + return a === b || (isAnonymous(a) && isAnonymous(b)); +} - Batcher = (function() { - class Batcher { - constructor(options = {}) { - this.options = options; - parser$4.load(this.options, this.defaults, this); - this.Events = new Events$3(this); - this._arr = []; - this._resetPromise(); - this._lastFlush = Date.now(); - } +/** Creates a unique hash from stack frames */ +function hashFrames(frames) { + if (frames === undefined) { + return; + } - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } + // Only hash the 10 most recent frames (ie. the last 10) + return frames.slice(-10).reduce((acc, frame) => `${acc},${frame.function},${frame.lineno},${frame.colno}`, ''); +} - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); - this._resolve(); - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } +/** + * We use the stack parser to create a unique hash from the exception stack trace + * This is used to lookup vars when the exception passes through the event processor + */ +function hashFromStack(stackParser, stack) { + if (stack === undefined) { + return undefined; + } - add(data) { - var ret; - this._arr.push(data); - ret = this._promise; - if (this._arr.length === this.maxSize) { - this._flush(); - } else if ((this.maxTime != null) && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } - return ret; - } + return hashFrames(stackParser(stack, 1)); +} - } - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise - }; +exports.createRateLimiter = createRateLimiter; +exports.functionNamesMatch = functionNamesMatch; +exports.hashFrames = hashFrames; +exports.hashFromStack = hashFromStack; +exports.isAnonymous = isAnonymous; +//# sourceMappingURL=common.js.map - return Batcher; - }).call(commonjsGlobal); +/***/ }), - var Batcher_1 = Batcher; +/***/ 58676: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); +Object.defineProperty(exports, "__esModule", ({ value: true })); - var require$$8 = getCjsExportFromNamespace(version$2); +const localVariablesSync = __nccwpck_require__(66083); - var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, - splice = [].splice; +/** + * Adds local variables to exception frames. + * + * @deprecated Use `localVariablesIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const LocalVariables = localVariablesSync.LocalVariablesSync; +// eslint-disable-next-line deprecation/deprecation - NUM_PRIORITIES$1 = 10; +const localVariablesIntegration = localVariablesSync.localVariablesSyncIntegration; - DEFAULT_PRIORITY$1 = 5; +exports.LocalVariables = LocalVariables; +exports.localVariablesIntegration = localVariablesIntegration; +//# sourceMappingURL=index.js.map - parser$5 = parser; - Queues$1 = Queues_1; +/***/ }), - Job$1 = Job_1; +/***/ 66083: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - LocalDatastore$1 = LocalDatastore_1; +var { + _optionalChain +} = __nccwpck_require__(57540); - RedisDatastore$1 = require$$4$1; +Object.defineProperty(exports, "__esModule", ({ value: true })); - Events$4 = Events_1; +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const nodeVersion = __nccwpck_require__(85858); +const common = __nccwpck_require__(58527); - States$1 = States_1; +/* eslint-disable max-lines */ - Sync$1 = Sync_1; +/** Creates a container for callbacks to be called sequentially */ +function createCallbackList(complete) { + // A collection of callbacks to be executed last to first + let callbacks = []; - Bottleneck = (function() { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); - this._validateOptions(options, invalid); - parser$5.load(options, this.instanceDefaults, this); - this._queues = new Queues$1(NUM_PRIORITIES$1); - this._scheduled = {}; - this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events$4(this); - this._submitLock = new Sync$1("submit", this.Promise); - this._registerLock = new Sync$1("register", this.Promise); - storeOptions = parser$5.load(options, this.storeDefaults, {}); - this._store = (function() { - if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { - storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); - return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }).call(this); - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } + let completedCalled = false; + function checkedComplete(result) { + callbacks = []; + if (completedCalled) { + return; + } + completedCalled = true; + complete(result); + } - _validateOptions(options, invalid) { - if (!((options != null) && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } + // complete should be called last + callbacks.push(checkedComplete); - ready() { - return this._store.ready; - } + function add(fn) { + callbacks.push(fn); + } - clients() { - return this._store.clients; - } + function next(result) { + const popped = callbacks.pop() || checkedComplete; - channel() { - return `b_${this.id}`; - } + try { + popped(result); + } catch (_) { + // If there is an error, we still want to call the complete callback + checkedComplete(result); + } + } - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } + return { add, next }; +} - publish(message) { - return this._store.__publish__(message); - } +/** + * Promise API is available as `Experimental` and in Node 19 only. + * + * Callback-based API is `Stable` since v14 and `Experimental` since v8. + * Because of that, we are creating our own `AsyncSession` class. + * + * https://nodejs.org/docs/latest-v19.x/api/inspector.html#promises-api + * https://nodejs.org/docs/latest-v14.x/api/inspector.html + */ +class AsyncSession { - disconnect(flush = true) { - return this._store.__disconnect__(flush); - } + /** Throws if inspector API is not available */ + constructor() { + /* + TODO: We really should get rid of this require statement below for a couple of reasons: + 1. It makes the integration unusable in the SvelteKit SDK, as it's not possible to use `require` + in SvelteKit server code (at least not by default). + 2. Throwing in a constructor is bad practice + + More context for a future attempt to fix this: + We already tried replacing it with import but didn't get it to work because of async problems. + We still called import in the constructor but assigned to a promise which we "awaited" in + `configureAndConnect`. However, this broke the Node integration tests as no local variables + were reported any more. We probably missed a place where we need to await the promise, too. + */ - chain(_limiter) { - this._limiter = _limiter; - return this; - } + // Node can be built without inspector support so this can throw + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { Session } = __nccwpck_require__(50264); + this._session = new Session(); + } - queued(priority) { - return this._queues.queued(priority); - } + /** @inheritdoc */ + configureAndConnect(onPause, captureAll) { + this._session.connect(); - clusterQueued() { - return this._store.__queued__(); - } + this._session.on('Debugger.paused', event => { + onPause(event, () => { + // After the pause work is complete, resume execution or the exception context memory is leaked + this._session.post('Debugger.resume'); + }); + }); - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } + this._session.post('Debugger.enable'); + this._session.post('Debugger.setPauseOnExceptions', { state: captureAll ? 'all' : 'uncaught' }); + } - running() { - return this._store.__running__(); - } + setPauseOnExceptions(captureAll) { + this._session.post('Debugger.setPauseOnExceptions', { state: captureAll ? 'all' : 'uncaught' }); + } - done() { - return this._store.__done__(); - } + /** @inheritdoc */ + getLocalVariables(objectId, complete) { + this._getProperties(objectId, props => { + const { add, next } = createCallbackList(complete); - jobStatus(id) { - return this._states.jobStatus(id); - } + for (const prop of props) { + if (_optionalChain([prop, 'optionalAccess', _2 => _2.value, 'optionalAccess', _3 => _3.objectId]) && _optionalChain([prop, 'optionalAccess', _4 => _4.value, 'access', _5 => _5.className]) === 'Array') { + const id = prop.value.objectId; + add(vars => this._unrollArray(id, prop.name, vars, next)); + } else if (_optionalChain([prop, 'optionalAccess', _6 => _6.value, 'optionalAccess', _7 => _7.objectId]) && _optionalChain([prop, 'optionalAccess', _8 => _8.value, 'optionalAccess', _9 => _9.className]) === 'Object') { + const id = prop.value.objectId; + add(vars => this._unrollObject(id, prop.name, vars, next)); + } else if (_optionalChain([prop, 'optionalAccess', _10 => _10.value, 'optionalAccess', _11 => _11.value]) != null || _optionalChain([prop, 'optionalAccess', _12 => _12.value, 'optionalAccess', _13 => _13.description]) != null) { + add(vars => this._unrollOther(prop, vars, next)); + } + } - jobs(status) { - return this._states.statusJobs(status); - } + next({}); + }); + } - counts() { - return this._states.statusCounts(); - } + /** + * Gets all the PropertyDescriptors of an object + */ + _getProperties(objectId, next) { + this._session.post( + 'Runtime.getProperties', + { + objectId, + ownProperties: true, + }, + (err, params) => { + if (err) { + next([]); + } else { + next(params.result); + } + }, + ); + } - _randomIndex() { - return Math.random().toString(36).slice(2); - } + /** + * Unrolls an array property + */ + _unrollArray(objectId, name, vars, next) { + this._getProperties(objectId, props => { + vars[name] = props + .filter(v => v.name !== 'length' && !isNaN(parseInt(v.name, 10))) + .sort((a, b) => parseInt(a.name, 10) - parseInt(b.name, 10)) + .map(v => _optionalChain([v, 'optionalAccess', _14 => _14.value, 'optionalAccess', _15 => _15.value])); + + next(vars); + }); + } - check(weight = 1) { - return this._store.__check__(weight); - } + /** + * Unrolls an object property + */ + _unrollObject(objectId, name, vars, next) { + this._getProperties(objectId, props => { + vars[name] = props + .map(v => [v.name, _optionalChain([v, 'optionalAccess', _16 => _16.value, 'optionalAccess', _17 => _17.value])]) + .reduce((obj, [key, val]) => { + obj[key] = val; + return obj; + }, {} ); + + next(vars); + }); + } - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; - } - } + /** + * Unrolls other properties + */ + _unrollOther(prop, vars, next) { + if (_optionalChain([prop, 'optionalAccess', _18 => _18.value, 'optionalAccess', _19 => _19.value]) != null) { + vars[prop.name] = prop.value.value; + } else if (_optionalChain([prop, 'optionalAccess', _20 => _20.value, 'optionalAccess', _21 => _21.description]) != null && _optionalChain([prop, 'optionalAccess', _22 => _22.value, 'optionalAccess', _23 => _23.type]) !== 'function') { + vars[prop.name] = `<${prop.value.description}>`; + } - async _free(index, job, options, eventInfo) { - var e, running; - try { - ({running} = (await this._store.__free__(index, options.weight))); - this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (running === 0 && this.empty()) { - return this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return this.Events.trigger("error", e); - } - } + next(vars); + } +} - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function() { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } +/** + * When using Vercel pkg, the inspector module is not available. + * https://github.com/getsentry/sentry-javascript/issues/6769 + */ +function tryNewAsyncSession() { + try { + return new AsyncSession(); + } catch (e) { + return undefined; + } +} - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; - if (this.queued() === 0) { - return this.Promise.resolve(null); - } - queue = this._queues.getFirst(); - ({options, args} = next = queue.first()); - if ((capacity != null) && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); - if (success) { - queue.shift(); - empty = this.empty(); - if (empty) { - this.Events.trigger("empty"); - } - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } - this._run(index, next, wait); - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } +const INTEGRATION_NAME = 'LocalVariables'; - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then((drained) => { - var newCapacity; - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch((e) => { - return this.Events.trigger("error", e); - }); - } +/** + * Adds local variables to exception frames + */ +const _localVariablesSyncIntegration = (( + options = {}, + session = tryNewAsyncSession(), +) => { + const cachedFrames = new utils.LRUMap(20); + let rateLimiter; + let shouldProcessEvent = false; - _dropAllQueued(message) { - return this._queues.shiftAll(function(job) { - return job.doDrop({message}); - }); - } + function handlePaused( + stackParser, + { params: { reason, data, callFrames } }, + complete, + ) { + if (reason !== 'exception' && reason !== 'promiseRejection') { + complete(); + return; + } - stop(options = {}) { - var done, waitForExecuting; - options = parser$5.load(options, this.stopDefaults); - waitForExecuting = (at) => { - var finished; - finished = () => { - var counts; - counts = this._states.counts; - return (counts[0] + counts[1] + counts[2] + counts[3]) === at; - }; - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; - done = options.dropWaitingJobs ? (this._run = function(index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; - for (k in ref) { - v = ref[k]; - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } - this._dropAllQueued(options.dropErrorMessage); - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES$1 - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); - this._receive = function(job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; - return done; - } + _optionalChain([rateLimiter, 'optionalCall', _24 => _24()]); - async _addToQueue(job) { - var args, blocked, error, options, reachedHWM, shifted, strategy; - ({args, options} = job); - try { - ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); - } catch (error1) { - error = error1; - this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); - job.doDrop({error}); - return false; - } - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - if (shifted != null) { - shifted.doDrop(); - } - if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } - return reachedHWM; - } - } - job.doQueue(reachedHWM, blocked); - this._queues.push(job); - await this._drainAll(); - return reachedHWM; - } + // data.description contains the original error.stack + const exceptionHash = common.hashFromStack(stackParser, _optionalChain([data, 'optionalAccess', _25 => _25.description])); - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } + if (exceptionHash == undefined) { + complete(); + return; + } - submit(...args) { - var cb, fn, job, options, ref, ref1, task; - if (typeof args[0] === "function") { - ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); - options = parser$5.load({}, this.jobDefaults); - } else { - ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); - options = parser$5.load(options, this.jobDefaults); - } - task = (...args) => { - return new this.Promise(function(resolve, reject) { - return fn(...args, function(...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function(args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function(args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; - } - }); - return this._receive(job); - } + const { add, next } = createCallbackList(frames => { + cachedFrames.set(exceptionHash, frames); + complete(); + }); - schedule(...args) { - var job, options, task; - if (typeof args[0] === "function") { - [task, ...args] = args; - options = {}; - } else { - [options, task, ...args] = args; - } - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - this._receive(job); - return job.promise; - } + // Because we're queuing up and making all these calls synchronously, we can potentially overflow the stack + // For this reason we only attempt to get local variables for the first 5 frames + for (let i = 0; i < Math.min(callFrames.length, 5); i++) { + const { scopeChain, functionName, this: obj } = callFrames[i]; - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - wrapped = function(...args) { - return schedule(fn.bind(this), ...args); - }; - wrapped.withOptions = function(options, ...args) { - return schedule(options, fn, ...args); - }; - return wrapped; - } + const localScope = scopeChain.find(scope => scope.type === 'local'); - async updateSettings(options = {}) { - await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); - parser$5.overwrite(options, this.instanceDefaults, this); - return this; - } + // obj.className is undefined in ESM modules + const fn = obj.className === 'global' || !obj.className ? functionName : `${obj.className}.${functionName}`; - currentReservoir() { - return this._store.__currentReservoir__(); - } + if (_optionalChain([localScope, 'optionalAccess', _26 => _26.object, 'access', _27 => _27.objectId]) === undefined) { + add(frames => { + frames[i] = { function: fn }; + next(frames); + }); + } else { + const id = localScope.object.objectId; + add(frames => + _optionalChain([session, 'optionalAccess', _28 => _28.getLocalVariables, 'call', _29 => _29(id, vars => { + frames[i] = { function: fn, vars }; + next(frames); + })]), + ); + } + } - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } + next([]); + } - } - Bottleneck.default = Bottleneck; + function addLocalVariablesToException(exception) { + const hash = common.hashFrames(_optionalChain([exception, 'optionalAccess', _30 => _30.stacktrace, 'optionalAccess', _31 => _31.frames])); - Bottleneck.Events = Events$4; + if (hash === undefined) { + return; + } - Bottleneck.version = Bottleneck.prototype.version = require$$8.version; + // Check if we have local variables for an exception that matches the hash + // remove is identical to get but also removes the entry from the cache + const cachedFrame = cachedFrames.remove(hash); - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; + if (cachedFrame === undefined) { + return; + } - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; + // Filter out frames where the function name is `new Promise` since these are in the error.stack frames + // but do not appear in the debugger call frames + const frames = (_optionalChain([exception, 'access', _32 => _32.stacktrace, 'optionalAccess', _33 => _33.frames]) || []).filter(frame => frame.function !== 'new Promise'); - Bottleneck.Group = Bottleneck.prototype.Group = Group_1; + for (let i = 0; i < frames.length; i++) { + // Sentry frames are in reverse order + const frameIndex = frames.length - i - 1; - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; + // Drop out if we run out of frames to match up + if (!frames[frameIndex] || !cachedFrame[i]) { + break; + } - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; + if ( + // We need to have vars to add + cachedFrame[i].vars === undefined || + // We're not interested in frames that are not in_app because the vars are not relevant + frames[frameIndex].in_app === false || + // The function names need to match + !common.functionNamesMatch(frames[frameIndex].function, cachedFrame[i].function) + ) { + continue; + } - Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; + frames[frameIndex].vars = cachedFrame[i].vars; + } + } - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY$1, - weight: 1, - expiration: null, - id: "" - }; + function addLocalVariablesToEvent(event) { + for (const exception of _optionalChain([event, 'optionalAccess', _34 => _34.exception, 'optionalAccess', _35 => _35.values]) || []) { + addLocalVariablesToException(exception); + } - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; + return event; + } - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; + return { + name: INTEGRATION_NAME, + setupOnce() { + const client = core.getClient(); + const clientOptions = _optionalChain([client, 'optionalAccess', _36 => _36.getOptions, 'call', _37 => _37()]); + + if (session && _optionalChain([clientOptions, 'optionalAccess', _38 => _38.includeLocalVariables])) { + // Only setup this integration if the Node version is >= v18 + // https://github.com/getsentry/sentry-javascript/issues/7697 + const unsupportedNodeVersion = nodeVersion.NODE_VERSION.major < 18; + + if (unsupportedNodeVersion) { + utils.logger.log('The `LocalVariables` integration is only supported on Node >= v18.'); + return; + } - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; + const captureAll = options.captureAllExceptions !== false; - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; + session.configureAndConnect( + (ev, complete) => + handlePaused(clientOptions.stackParser, ev , complete), + captureAll, + ); - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; + if (captureAll) { + const max = options.maxExceptionsPerSecond || 50; - return Bottleneck; + rateLimiter = common.createRateLimiter( + max, + () => { + utils.logger.log('Local variables rate-limit lifted.'); + _optionalChain([session, 'optionalAccess', _39 => _39.setPauseOnExceptions, 'call', _40 => _40(true)]); + }, + seconds => { + utils.logger.log( + `Local variables rate-limit exceeded. Disabling capturing of caught exceptions for ${seconds} seconds.`, + ); + _optionalChain([session, 'optionalAccess', _41 => _41.setPauseOnExceptions, 'call', _42 => _42(false)]); + }, + ); + } - }).call(commonjsGlobal); + shouldProcessEvent = true; + } + }, + processEvent(event) { + if (shouldProcessEvent) { + return addLocalVariablesToEvent(event); + } - var Bottleneck_1 = Bottleneck; + return event; + }, + // These are entirely for testing + _getCachedFramesCount() { + return cachedFrames.size; + }, + _getFirstCachedFrame() { + return cachedFrames.values()[0]; + }, + }; +}) ; - var lib = Bottleneck_1; +const localVariablesSyncIntegration = core.defineIntegration(_localVariablesSyncIntegration); - return lib; +/** + * Adds local variables to exception frames. + * @deprecated Use `localVariablesSyncIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const LocalVariablesSync = core.convertIntegrationFnToClass( + INTEGRATION_NAME, + localVariablesSyncIntegration, +) -}))); +; + +// eslint-disable-next-line deprecation/deprecation + +exports.LocalVariablesSync = LocalVariablesSync; +exports.createCallbackList = createCallbackList; +exports.localVariablesSyncIntegration = localVariablesSyncIntegration; +//# sourceMappingURL=local-variables-sync.js.map /***/ }), -/***/ 71091: -/***/ ((module) => { +/***/ 45705: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -module.exports = function btoa(str) { - return new Buffer(str).toString('base64') +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const fs = __nccwpck_require__(79896); +const path = __nccwpck_require__(16928); +const core = __nccwpck_require__(75442); + +let moduleCache; + +const INTEGRATION_NAME = 'Modules'; + +/** Extract information about paths */ +function getPaths() { + try { + return require.cache ? Object.keys(require.cache ) : []; + } catch (e) { + return []; + } } +/** Extract information about package.json modules */ +function collectModules() -/***/ }), + { + const mainPaths = (require.main && require.main.paths) || []; + const paths = getPaths(); + const infos -/***/ 99905: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + = {}; + const seen -"use strict"; -/*jshint node:true */ + = {}; -var Buffer = (__nccwpck_require__(20181).Buffer); // browserify -var SlowBuffer = (__nccwpck_require__(20181).SlowBuffer); + paths.forEach(path$1 => { + let dir = path$1; -module.exports = bufferEq; + /** Traverse directories upward in the search of package.json file */ + const updir = () => { + const orig = dir; + dir = path.dirname(orig); -function bufferEq(a, b) { + if (!dir || orig === dir || seen[orig]) { + return undefined; + } + if (mainPaths.indexOf(dir) < 0) { + return updir(); + } - // shortcutting on type is necessary for correctness - if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { - return false; - } + const pkgfile = path.join(orig, 'package.json'); + seen[orig] = true; - // buffer sizes should be well-known information, so despite this - // shortcutting, it doesn't leak any information about the *contents* of the - // buffers. - if (a.length !== b.length) { - return false; - } + if (!fs.existsSync(pkgfile)) { + return updir(); + } - var c = 0; - for (var i = 0; i < a.length; i++) { - /*jshint bitwise:false */ - c |= a[i] ^ b[i]; // XOR + try { + const info = JSON.parse(fs.readFileSync(pkgfile, 'utf8')) + +; + infos[info.name] = info.version; + } catch (_oO) { + // no-empty + } + }; + + updir(); + }); + + return infos; +} + +/** Fetches the list of modules and the versions loaded by the entry file for your node.js app. */ +function _getModules() { + if (!moduleCache) { + moduleCache = collectModules(); } - return c === 0; + return moduleCache; } -bufferEq.install = function() { - Buffer.prototype.equal = SlowBuffer.prototype.equal = function equal(that) { - return bufferEq(this, that); +const _modulesIntegration = (() => { + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + processEvent(event) { + event.modules = { + ...event.modules, + ..._getModules(), + }; + + return event; + }, }; -}; +}) ; -var origBufEqual = Buffer.prototype.equal; -var origSlowBufEqual = SlowBuffer.prototype.equal; -bufferEq.restore = function() { - Buffer.prototype.equal = origBufEqual; - SlowBuffer.prototype.equal = origSlowBufEqual; -}; +const modulesIntegration = core.defineIntegration(_modulesIntegration); + +/** + * Add node modules / packages to the event. + * @deprecated Use `modulesIntegration()` instead. + */ +// eslint-disable-next-line deprecation/deprecation +const Modules = core.convertIntegrationFnToClass(INTEGRATION_NAME, modulesIntegration) + +; + +// eslint-disable-next-line deprecation/deprecation + +exports.Modules = Modules; +exports.modulesIntegration = modulesIntegration; +//# sourceMappingURL=modules.js.map /***/ }), -/***/ 89015: -/***/ ((module) => { +/***/ 63295: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; -/*! - * bytes - * Copyright(c) 2012-2014 TJ Holowaychuk - * Copyright(c) 2015 Jed Watson - * MIT Licensed - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(96652); +const errorhandling = __nccwpck_require__(79981); +const INTEGRATION_NAME = 'OnUncaughtException'; -/** - * Module exports. - * @public - */ +const _onUncaughtExceptionIntegration = ((options = {}) => { + const _options = { + exitEvenIfOtherHandlersAreRegistered: true, + ...options, + }; -module.exports = bytes; -module.exports.format = format; -module.exports.parse = parse; + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + setup(client) { + global.process.on('uncaughtException', makeErrorHandler(client, _options)); + }, + }; +}) ; + +const onUncaughtExceptionIntegration = core.defineIntegration(_onUncaughtExceptionIntegration); /** - * Module variables. - * @private + * Global Exception handler. + * @deprecated Use `onUncaughtExceptionIntegration()` instead. */ +// eslint-disable-next-line deprecation/deprecation +const OnUncaughtException = core.convertIntegrationFnToClass( + INTEGRATION_NAME, + onUncaughtExceptionIntegration, +) -var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g; +; -var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/; +// eslint-disable-next-line deprecation/deprecation -var map = { - b: 1, - kb: 1 << 10, - mb: 1 << 20, - gb: 1 << 30, - tb: Math.pow(1024, 4), - pb: Math.pow(1024, 5), -}; +/** Exported only for tests */ +function makeErrorHandler(client, options) { + const timeout = 2000; + let caughtFirstError = false; + let caughtSecondError = false; + let calledFatalError = false; + let firstError; -var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i; + const clientOptions = client.getOptions(); -/** - * Convert the given value in bytes into a string or parse to string to an integer in bytes. - * - * @param {string|number} value - * @param {{ - * case: [string], - * decimalPlaces: [number] - * fixedDecimals: [boolean] - * thousandsSeparator: [string] - * unitSeparator: [string] - * }} [options] bytes options. - * - * @returns {string|number|null} - */ + return Object.assign( + (error) => { + let onFatalError = errorhandling.logAndExitProcess; + + if (options.onFatalError) { + onFatalError = options.onFatalError; + } else if (clientOptions.onFatalError) { + onFatalError = clientOptions.onFatalError ; + } + + // Attaching a listener to `uncaughtException` will prevent the node process from exiting. We generally do not + // want to alter this behaviour so we check for other listeners that users may have attached themselves and adjust + // exit behaviour of the SDK accordingly: + // - If other listeners are attached, do not exit. + // - If the only listener attached is ours, exit. + const userProvidedListenersCount = ( + global.process.listeners('uncaughtException') + ).reduce((acc, listener) => { + if ( + // There are 3 listeners we ignore: + listener.name === 'domainUncaughtExceptionClear' || // as soon as we're using domains this listener is attached by node itself + (listener.tag && listener.tag === 'sentry_tracingErrorCallback') || // the handler we register for tracing + (listener )._errorHandler // the handler we register in this integration + ) { + return acc; + } else { + return acc + 1; + } + }, 0); -function bytes(value, options) { - if (typeof value === 'string') { - return parse(value); - } + const processWouldExit = userProvidedListenersCount === 0; + const shouldApplyFatalHandlingLogic = options.exitEvenIfOtherHandlersAreRegistered || processWouldExit; - if (typeof value === 'number') { - return format(value, options); - } + if (!caughtFirstError) { + // this is the first uncaught error and the ultimate reason for shutting down + // we want to do absolutely everything possible to ensure it gets captured + // also we want to make sure we don't go recursion crazy if more errors happen after this one + firstError = error; + caughtFirstError = true; - return null; + if (core.getClient() === client) { + core.captureException(error, { + originalException: error, + captureContext: { + level: 'fatal', + }, + mechanism: { + handled: false, + type: 'onuncaughtexception', + }, + }); + } + + if (!calledFatalError && shouldApplyFatalHandlingLogic) { + calledFatalError = true; + onFatalError(error); + } + } else { + if (shouldApplyFatalHandlingLogic) { + if (calledFatalError) { + // we hit an error *after* calling onFatalError - pretty boned at this point, just shut it down + debugBuild.DEBUG_BUILD && + utils.logger.warn( + 'uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown', + ); + errorhandling.logAndExitProcess(error); + } else if (!caughtSecondError) { + // two cases for how we can hit this branch: + // - capturing of first error blew up and we just caught the exception from that + // - quit trying to capture, proceed with shutdown + // - a second independent error happened while waiting for first error to capture + // - want to avoid causing premature shutdown before first error capture finishes + // it's hard to immediately tell case 1 from case 2 without doing some fancy/questionable domain stuff + // so let's instead just delay a bit before we proceed with our action here + // in case 1, we just wait a bit unnecessarily but ultimately do the same thing + // in case 2, the delay hopefully made us wait long enough for the capture to finish + // two potential nonideal outcomes: + // nonideal case 1: capturing fails fast, we sit around for a few seconds unnecessarily before proceeding correctly by calling onFatalError + // nonideal case 2: case 2 happens, 1st error is captured but slowly, timeout completes before capture and we treat second error as the sendErr of (nonexistent) failure from trying to capture first error + // note that after hitting this branch, we might catch more errors where (caughtSecondError && !calledFatalError) + // we ignore them - they don't matter to us, we're just waiting for the second error timeout to finish + caughtSecondError = true; + setTimeout(() => { + if (!calledFatalError) { + // it was probably case 1, let's treat err as the sendErr and call onFatalError + calledFatalError = true; + onFatalError(firstError, error); + } + }, timeout); // capturing could take at least sendTimeout to fail, plus an arbitrary second for how long it takes to collect surrounding source etc + } + } + } + }, + { _errorHandler: true }, + ); } +exports.OnUncaughtException = OnUncaughtException; +exports.makeErrorHandler = makeErrorHandler; +exports.onUncaughtExceptionIntegration = onUncaughtExceptionIntegration; +//# sourceMappingURL=onuncaughtexception.js.map + + +/***/ }), + +/***/ 31061: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const errorhandling = __nccwpck_require__(79981); + +const INTEGRATION_NAME = 'OnUnhandledRejection'; + +const _onUnhandledRejectionIntegration = ((options = {}) => { + const mode = options.mode || 'warn'; + + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + setup(client) { + global.process.on('unhandledRejection', makeUnhandledPromiseHandler(client, { mode })); + }, + }; +}) ; + +const onUnhandledRejectionIntegration = core.defineIntegration(_onUnhandledRejectionIntegration); + /** - * Format the given value in bytes into a string. - * - * If the value is negative, it is kept as such. If it is a float, - * it is rounded. - * - * @param {number} value - * @param {object} [options] - * @param {number} [options.decimalPlaces=2] - * @param {number} [options.fixedDecimals=false] - * @param {string} [options.thousandsSeparator=] - * @param {string} [options.unit=] - * @param {string} [options.unitSeparator=] - * - * @returns {string|null} - * @public + * Global Promise Rejection handler. + * @deprecated Use `onUnhandledRejectionIntegration()` instead. */ +// eslint-disable-next-line deprecation/deprecation +const OnUnhandledRejection = core.convertIntegrationFnToClass( + INTEGRATION_NAME, + onUnhandledRejectionIntegration, +) -function format(value, options) { - if (!Number.isFinite(value)) { - return null; - } +; - var mag = Math.abs(value); - var thousandsSeparator = (options && options.thousandsSeparator) || ''; - var unitSeparator = (options && options.unitSeparator) || ''; - var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2; - var fixedDecimals = Boolean(options && options.fixedDecimals); - var unit = (options && options.unit) || ''; +// eslint-disable-next-line deprecation/deprecation - if (!unit || !map[unit.toLowerCase()]) { - if (mag >= map.pb) { - unit = 'PB'; - } else if (mag >= map.tb) { - unit = 'TB'; - } else if (mag >= map.gb) { - unit = 'GB'; - } else if (mag >= map.mb) { - unit = 'MB'; - } else if (mag >= map.kb) { - unit = 'KB'; - } else { - unit = 'B'; +/** + * Send an exception with reason + * @param reason string + * @param promise promise + * + * Exported only for tests. + */ +function makeUnhandledPromiseHandler( + client, + options, +) { + return function sendUnhandledPromise(reason, promise) { + if (core.getClient() !== client) { + return; } - } - var val = value / map[unit.toLowerCase()]; - var str = val.toFixed(decimalPlaces); + core.captureException(reason, { + originalException: promise, + captureContext: { + extra: { unhandledPromiseRejection: true }, + }, + mechanism: { + handled: false, + type: 'onunhandledrejection', + }, + }); - if (!fixedDecimals) { - str = str.replace(formatDecimalsRegExp, '$1'); - } + handleRejection(reason, options); + }; +} - if (thousandsSeparator) { - str = str.split('.').map(function (s, i) { - return i === 0 - ? s.replace(formatThousandsRegExp, thousandsSeparator) - : s - }).join('.'); - } +/** + * Handler for `mode` option - return str + unitSeparator + unit; + */ +function handleRejection( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + reason, + options, +) { + // https://github.com/nodejs/node/blob/7cf6f9e964aa00772965391c23acda6d71972a9a/lib/internal/process/promises.js#L234-L240 + const rejectionWarning = + 'This error originated either by ' + + 'throwing inside of an async function without a catch block, ' + + 'or by rejecting a promise which was not handled with .catch().' + + ' The promise rejected with the reason:'; + + /* eslint-disable no-console */ + if (options.mode === 'warn') { + utils.consoleSandbox(() => { + console.warn(rejectionWarning); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + console.error(reason && reason.stack ? reason.stack : reason); + }); + } else if (options.mode === 'strict') { + utils.consoleSandbox(() => { + console.warn(rejectionWarning); + }); + errorhandling.logAndExitProcess(reason); + } + /* eslint-enable no-console */ } +exports.OnUnhandledRejection = OnUnhandledRejection; +exports.makeUnhandledPromiseHandler = makeUnhandledPromiseHandler; +exports.onUnhandledRejectionIntegration = onUnhandledRejectionIntegration; +//# sourceMappingURL=onunhandledrejection.js.map + + +/***/ }), + +/***/ 38880: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const http = __nccwpck_require__(58611); +const url = __nccwpck_require__(87016); +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); + +const INTEGRATION_NAME = 'Spotlight'; + +const _spotlightIntegration = ((options = {}) => { + const _options = { + sidecarUrl: options.sidecarUrl || 'http://localhost:8969/stream', + }; + + return { + name: INTEGRATION_NAME, + // TODO v8: Remove this + setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function + setup(client) { + if (typeof process === 'object' && process.env && process.env.NODE_ENV !== 'development') { + utils.logger.warn("[Spotlight] It seems you're not in dev mode. Do you really want to have Spotlight enabled?"); + } + connectToSpotlight(client, _options); + }, + }; +}) ; + +const spotlightIntegration = core.defineIntegration(_spotlightIntegration); + /** - * Parse the string value into an integer in bytes. + * Use this integration to send errors and transactions to Spotlight. * - * If no unit is given, it is assumed the value is in bytes. + * Learn more about spotlight at https://spotlightjs.com * - * @param {number|string} val + * Important: This integration only works with Node 18 or newer. * - * @returns {number|null} - * @public + * @deprecated Use `spotlightIntegration()` instead. */ +// eslint-disable-next-line deprecation/deprecation +const Spotlight = core.convertIntegrationFnToClass(INTEGRATION_NAME, spotlightIntegration) -function parse(val) { - if (typeof val === 'number' && !isNaN(val)) { - return val; - } - - if (typeof val !== 'string') { - return null; - } +; - // Test if the string passed is valid - var results = parseRegExp.exec(val); - var floatValue; - var unit = 'b'; +// eslint-disable-next-line deprecation/deprecation - if (!results) { - // Nothing could be extracted from the given string - floatValue = parseInt(val, 10); - unit = 'b' - } else { - // Retrieve the value and the unit - floatValue = parseFloat(results[1]); - unit = results[4].toLowerCase(); +function connectToSpotlight(client, options) { + const spotlightUrl = parseSidecarUrl(options.sidecarUrl); + if (!spotlightUrl) { + return; } - if (isNaN(floatValue)) { - return null; + let failedRequests = 0; + + if (typeof client.on !== 'function') { + utils.logger.warn('[Spotlight] Cannot connect to spotlight due to missing method on SDK client (`client.on`)'); + return; } - return Math.floor(map[unit] * floatValue); -} + client.on('beforeEnvelope', (envelope) => { + if (failedRequests > 3) { + utils.logger.warn('[Spotlight] Disabled Sentry -> Spotlight integration due to too many failed requests'); + return; + } + const serializedEnvelope = utils.serializeEnvelope(envelope); -/***/ }), + const request = getNativeHttpRequest(); + const req = request( + { + method: 'POST', + path: spotlightUrl.pathname, + hostname: spotlightUrl.hostname, + port: spotlightUrl.port, + headers: { + 'Content-Type': 'application/x-sentry-envelope', + }, + }, + res => { + res.on('data', () => { + // Drain socket + }); -/***/ 76727: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + res.on('end', () => { + // Drain socket + }); + res.setEncoding('utf8'); + }, + ); -"use strict"; + req.on('error', () => { + failedRequests++; + utils.logger.warn('[Spotlight] Failed to send envelope to Spotlight Sidecar'); + }); + req.write(serializedEnvelope); + req.end(); + }); +} +function parseSidecarUrl(url$1) { + try { + return new url.URL(`${url$1}`); + } catch (e) { + utils.logger.warn(`[Spotlight] Invalid sidecar URL: ${url$1}`); + return undefined; + } +} -var GetIntrinsic = __nccwpck_require__(36546); +/** + * We want to get an unpatched http request implementation to avoid capturing our own calls. + */ +function getNativeHttpRequest() { + const { request } = http; + if (isWrapped(request)) { + return request.__sentry_original__; + } -var callBind = __nccwpck_require__(57211); + return request; +} -var $indexOf = callBind(GetIntrinsic('String.prototype.indexOf')); +function isWrapped(impl) { + return '__sentry_original__' in impl; +} -module.exports = function callBoundIntrinsic(name, allowMissing) { - var intrinsic = GetIntrinsic(name, !!allowMissing); - if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) { - return callBind(intrinsic); - } - return intrinsic; -}; +exports.Spotlight = Spotlight; +exports.getNativeHttpRequest = getNativeHttpRequest; +exports.spotlightIntegration = spotlightIntegration; +//# sourceMappingURL=spotlight.js.map /***/ }), -/***/ 57211: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 12561: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; +var { + _optionalChain +} = __nccwpck_require__(57540); +Object.defineProperty(exports, "__esModule", ({ value: true })); -var bind = __nccwpck_require__(58115); -var GetIntrinsic = __nccwpck_require__(36546); -var setFunctionLength = __nccwpck_require__(80296); +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const nodeVersion = __nccwpck_require__(85858); -var $TypeError = __nccwpck_require__(78279); -var $apply = GetIntrinsic('%Function.prototype.apply%'); -var $call = GetIntrinsic('%Function.prototype.call%'); -var $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply); +exports.ChannelName = void 0;(function (ChannelName) { + // https://github.com/nodejs/undici/blob/e6fc80f809d1217814c044f52ed40ef13f21e43c/docs/api/DiagnosticsChannel.md#undicirequestcreate + const RequestCreate = 'undici:request:create'; ChannelName["RequestCreate"] = RequestCreate; + const RequestEnd = 'undici:request:headers'; ChannelName["RequestEnd"] = RequestEnd; + const RequestError = 'undici:request:error'; ChannelName["RequestError"] = RequestError; +})(exports.ChannelName || (exports.ChannelName = {})); -var $defineProperty = __nccwpck_require__(21410); -var $max = GetIntrinsic('%Math.max%'); +// Please note that you cannot use `console.log` to debug the callbacks registered to the `diagnostics_channel` API. +// To debug, you can use `writeFileSync` to write to a file: +// https://nodejs.org/api/async_hooks.html#printing-in-asynchook-callbacks +// +// import { writeFileSync } from 'fs'; +// import { format } from 'util'; +// +// function debug(...args: any): void { +// // Use a function like this one when debugging inside an AsyncHook callback +// // @ts-expect-error any +// writeFileSync('log.out', `${format(...args)}\n`, { flag: 'a' }); +// } -module.exports = function callBind(originalFunction) { - if (typeof originalFunction !== 'function') { - throw new $TypeError('a function is required'); - } - var func = $reflectApply(bind, $call, arguments); - return setFunctionLength( - func, - 1 + $max(0, originalFunction.length - (arguments.length - 1)), - true - ); -}; +const _nativeNodeFetchintegration = ((options) => { + // eslint-disable-next-line deprecation/deprecation + return new Undici(options) ; +}) ; -var applyBind = function applyBind() { - return $reflectApply(bind, $apply, arguments); -}; +const nativeNodeFetchintegration = core.defineIntegration(_nativeNodeFetchintegration); -if ($defineProperty) { - $defineProperty(module.exports, 'apply', { value: applyBind }); -} else { - module.exports.apply = applyBind; -} +/** + * Instruments outgoing HTTP requests made with the `undici` package via + * Node's `diagnostics_channel` API. + * + * Supports Undici 4.7.0 or higher. + * + * Requires Node 16.17.0 or higher. + * + * @deprecated Use `nativeNodeFetchintegration()` instead. + */ +class Undici { + /** + * @inheritDoc + */ + static __initStatic() {this.id = 'Undici';} + /** + * @inheritDoc + */ + // eslint-disable-next-line deprecation/deprecation + __init() {this.name = Undici.id;} -/***/ }), + __init2() {this._createSpanUrlMap = new utils.LRUMap(100);} + __init3() {this._headersUrlMap = new utils.LRUMap(100);} -/***/ 71649: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + constructor(_options = {}) {Undici.prototype.__init.call(this);Undici.prototype.__init2.call(this);Undici.prototype.__init3.call(this);Undici.prototype.__init4.call(this);Undici.prototype.__init5.call(this);Undici.prototype.__init6.call(this); + this._options = { + breadcrumbs: _options.breadcrumbs === undefined ? true : _options.breadcrumbs, + tracing: _options.tracing, + shouldCreateSpanForRequest: _options.shouldCreateSpanForRequest, + }; + } -"use strict"; + /** + * @inheritDoc + */ + setupOnce(_addGlobalEventProcessor) { + // Requires Node 16+ to use the diagnostics_channel API. + if (nodeVersion.NODE_VERSION.major < 16) { + return; + } -const os = __nccwpck_require__(70857); + let ds; + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + ds = __nccwpck_require__(31637) ; + } catch (e) { + // no-op + } -const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; -const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; -const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir(); + if (!ds || !ds.subscribe) { + return; + } -module.exports = (stack, options) => { - options = Object.assign({pretty: false}, options); + // https://github.com/nodejs/undici/blob/e6fc80f809d1217814c044f52ed40ef13f21e43c/docs/api/DiagnosticsChannel.md + ds.subscribe(exports.ChannelName.RequestCreate, this._onRequestCreate); + ds.subscribe(exports.ChannelName.RequestEnd, this._onRequestEnd); + ds.subscribe(exports.ChannelName.RequestError, this._onRequestError); + } - return stack.replace(/\\/g, '/') - .split('\n') - .filter(line => { - const pathMatches = line.match(extractPathRegex); - if (pathMatches === null || !pathMatches[1]) { - return true; - } + /** Helper that wraps shouldCreateSpanForRequest option */ + _shouldCreateSpan(url) { + if (this._options.tracing === false || (this._options.tracing === undefined && !core.hasTracingEnabled())) { + return false; + } - const match = pathMatches[1]; + if (this._options.shouldCreateSpanForRequest === undefined) { + return true; + } - // Electron - if ( - match.includes('.app/Contents/Resources/electron.asar') || - match.includes('.app/Contents/Resources/default_app.asar') - ) { - return false; - } + const cachedDecision = this._createSpanUrlMap.get(url); + if (cachedDecision !== undefined) { + return cachedDecision; + } - return !pathRegex.test(match); - }) - .filter(line => line.trim() !== '') - .map(line => { - if (options.pretty) { - return line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~'))); - } + const decision = this._options.shouldCreateSpanForRequest(url); + this._createSpanUrlMap.set(url, decision); + return decision; + } - return line; - }) - .join('\n'); -}; + __init4() {this._onRequestCreate = (message) => { + // eslint-disable-next-line deprecation/deprecation + if (!_optionalChain([core.getClient, 'call', _10 => _10(), 'optionalAccess', _11 => _11.getIntegration, 'call', _12 => _12(Undici)])) { + return; + } + const { request } = message ; -/***/ }), + const stringUrl = request.origin ? request.origin.toString() + request.path : request.path; -/***/ 10491: -/***/ ((module) => { + const client = core.getClient(); + if (!client) { + return; + } -/* - * Copyright 2001-2010 Georges Menie (www.menie.org) - * Copyright 2010 Salvatore Sanfilippo (adapted to Redis coding style) - * Copyright 2015 Zihua Li (http://zihua.li) (ported to JavaScript) - * Copyright 2016 Mike Diarmid (http://github.com/salakar) (re-write for performance, ~700% perf inc) - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the University of California, Berkeley nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + if (core.isSentryRequestUrl(stringUrl, client) || request.__sentry_span__ !== undefined) { + return; + } -/* CRC16 implementation according to CCITT standards. - * - * Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the - * following parameters: - * - * Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN" - * Width : 16 bit - * Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1) - * Initialization : 0000 - * Reflect Input byte : False - * Reflect Output CRC : False - * Xor constant to output CRC : 0000 - * Output for "123456789" : 31C3 - */ + const clientOptions = client.getOptions(); + const scope = core.getCurrentScope(); + const isolationScope = core.getIsolationScope(); + const parentSpan = core.getActiveSpan(); -var lookup = [ - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 -]; + const span = this._shouldCreateSpan(stringUrl) ? createRequestSpan(parentSpan, request, stringUrl) : undefined; + if (span) { + request.__sentry_span__ = span; + } -/** - * Convert a string to a UTF8 array - faster than via buffer - * @param str - * @returns {Array} - */ -var toUTF8Array = function toUTF8Array(str) { - var char; - var i = 0; - var p = 0; - var utf8 = []; - var len = str.length; + const shouldAttachTraceData = (url) => { + if (clientOptions.tracePropagationTargets === undefined) { + return true; + } - for (; i < len; i++) { - char = str.charCodeAt(i); - if (char < 128) { - utf8[p++] = char; - } else if (char < 2048) { - utf8[p++] = (char >> 6) | 192; - utf8[p++] = (char & 63) | 128; - } else if ( - ((char & 0xFC00) === 0xD800) && (i + 1) < str.length && - ((str.charCodeAt(i + 1) & 0xFC00) === 0xDC00)) { - char = 0x10000 + ((char & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF); - utf8[p++] = (char >> 18) | 240; - utf8[p++] = ((char >> 12) & 63) | 128; - utf8[p++] = ((char >> 6) & 63) | 128; - utf8[p++] = (char & 63) | 128; - } else { - utf8[p++] = (char >> 12) | 224; - utf8[p++] = ((char >> 6) & 63) | 128; - utf8[p++] = (char & 63) | 128; + const cachedDecision = this._headersUrlMap.get(url); + if (cachedDecision !== undefined) { + return cachedDecision; + } + + const decision = utils.stringMatchesSomePattern(url, clientOptions.tracePropagationTargets); + this._headersUrlMap.set(url, decision); + return decision; + }; + + if (shouldAttachTraceData(stringUrl)) { + const { traceId, spanId, sampled, dsc } = { + ...isolationScope.getPropagationContext(), + ...scope.getPropagationContext(), + }; + + const sentryTraceHeader = span ? core.spanToTraceHeader(span) : utils.generateSentryTraceHeader(traceId, spanId, sampled); + + const sentryBaggageHeader = utils.dynamicSamplingContextToSentryBaggageHeader( + dsc || + (span + ? core.getDynamicSamplingContextFromSpan(span) + : core.getDynamicSamplingContextFromClient(traceId, client, scope)), + ); + + setHeadersOnRequest(request, sentryTraceHeader, sentryBaggageHeader); } - } + };} - return utf8; -}; + __init5() {this._onRequestEnd = (message) => { + // eslint-disable-next-line deprecation/deprecation + if (!_optionalChain([core.getClient, 'call', _13 => _13(), 'optionalAccess', _14 => _14.getIntegration, 'call', _15 => _15(Undici)])) { + return; + } -/** - * Convert a string into a redis slot hash. - * @param str - * @returns {number} - */ -var generate = module.exports = function generate(str) { - var char; - var i = 0; - var start = -1; - var result = 0; - var resultHash = 0; - var utf8 = typeof str === 'string' ? toUTF8Array(str) : str; - var len = utf8.length; + const { request, response } = message ; - while (i < len) { - char = utf8[i++]; - if (start === -1) { - if (char === 0x7B) { - start = i; - } - } else if (char !== 0x7D) { - resultHash = lookup[(char ^ (resultHash >> 8)) & 0xFF] ^ (resultHash << 8); - } else if (i - 1 !== start) { - return resultHash & 0x3FFF; + const stringUrl = request.origin ? request.origin.toString() + request.path : request.path; + + if (core.isSentryRequestUrl(stringUrl, core.getClient())) { + return; } - result = lookup[(char ^ (result >> 8)) & 0xFF] ^ (result << 8); - } + const span = request.__sentry_span__; + if (span) { + core.setHttpStatus(span, response.statusCode); + span.end(); + } - return result & 0x3FFF; -}; + if (this._options.breadcrumbs) { + core.addBreadcrumb( + { + category: 'http', + data: { + method: request.method, + status_code: response.statusCode, + url: stringUrl, + }, + type: 'http', + }, + { + event: 'response', + request, + response, + }, + ); + } + };} -/** - * Convert an array of multiple strings into a redis slot hash. - * Returns -1 if one of the keys is not for the same slot as the others - * @param keys - * @returns {number} - */ -module.exports.generateMulti = function generateMulti(keys) { - var i = 1; - var len = keys.length; - var base = generate(keys[0]); + __init6() {this._onRequestError = (message) => { + // eslint-disable-next-line deprecation/deprecation + if (!_optionalChain([core.getClient, 'call', _16 => _16(), 'optionalAccess', _17 => _17.getIntegration, 'call', _18 => _18(Undici)])) { + return; + } - while (i < len) { - if (generate(keys[i++]) !== base) return -1; - } + const { request } = message ; - return base; -}; + const stringUrl = request.origin ? request.origin.toString() + request.path : request.path; + if (core.isSentryRequestUrl(stringUrl, core.getClient())) { + return; + } -/***/ }), + const span = request.__sentry_span__; + if (span) { + span.setStatus('internal_error'); + span.end(); + } -/***/ 45942: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (this._options.breadcrumbs) { + core.addBreadcrumb( + { + category: 'http', + data: { + method: request.method, + url: stringUrl, + }, + level: 'error', + type: 'http', + }, + { + event: 'error', + request, + }, + ); + } + };} +}Undici.__initStatic(); -"use strict"; -/*! - * content-disposition - * Copyright(c) 2014-2017 Douglas Christopher Wilson - * MIT Licensed - */ +function setHeadersOnRequest( + request, + sentryTrace, + sentryBaggageHeader, +) { + let hasSentryHeaders; + if (Array.isArray(request.headers)) { + hasSentryHeaders = request.headers.some(headerLine => headerLine === 'sentry-trace'); + } else { + const headerLines = request.headers.split('\r\n'); + hasSentryHeaders = headerLines.some(headerLine => headerLine.startsWith('sentry-trace:')); + } + if (hasSentryHeaders) { + return; + } + request.addHeader('sentry-trace', sentryTrace); + if (sentryBaggageHeader) { + request.addHeader('baggage', sentryBaggageHeader); + } +} -/** - * Module exports. - * @public - */ +function createRequestSpan( + activeSpan, + request, + stringUrl, +) { + const url = utils.parseUrl(stringUrl); -module.exports = contentDisposition -module.exports.parse = parse + const method = request.method || 'GET'; + const data = { + 'http.method': method, + }; + if (url.search) { + data['http.query'] = url.search; + } + if (url.hash) { + data['http.fragment'] = url.hash; + } + // eslint-disable-next-line deprecation/deprecation + return _optionalChain([activeSpan, 'optionalAccess', _19 => _19.startChild, 'call', _20 => _20({ + op: 'http.client', + origin: 'auto.http.node.undici', + description: `${method} ${utils.getSanitizedUrlString(url)}`, + data, + })]); +} -/** - * Module dependencies. - * @private - */ +exports.Undici = Undici; +exports.nativeNodeFetchintegration = nativeNodeFetchintegration; +//# sourceMappingURL=index.js.map -var basename = (__nccwpck_require__(16928).basename) -var Buffer = (__nccwpck_require__(26843).Buffer) -/** - * RegExp to match non attr-char, *after* encodeURIComponent (i.e. not including "%") - * @private - */ +/***/ }), -var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g // eslint-disable-line no-control-regex +/***/ 79981: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/** - * RegExp to match percent encoding escape. - * @private - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); -var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/ -var HEX_ESCAPE_REPLACE_REGEXP = /%([0-9A-Fa-f]{2})/g +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(96652); + +const DEFAULT_SHUTDOWN_TIMEOUT = 2000; /** - * RegExp to match non-latin1 characters. - * @private + * @hidden */ +function logAndExitProcess(error) { + utils.consoleSandbox(() => { + // eslint-disable-next-line no-console + console.error(error); + }); -var NON_LATIN1_REGEXP = /[^\x20-\x7e\xa0-\xff]/g + const client = core.getClient(); -/** - * RegExp to match quoted-pair in RFC 2616 - * - * quoted-pair = "\" CHAR - * CHAR = - * @private - */ + if (client === undefined) { + debugBuild.DEBUG_BUILD && utils.logger.warn('No NodeClient was defined, we are exiting the process now.'); + global.process.exit(1); + } -var QESC_REGEXP = /\\([\u0000-\u007f])/g // eslint-disable-line no-control-regex + const options = client.getOptions(); + const timeout = + (options && options.shutdownTimeout && options.shutdownTimeout > 0 && options.shutdownTimeout) || + DEFAULT_SHUTDOWN_TIMEOUT; + client.close(timeout).then( + (result) => { + if (!result) { + debugBuild.DEBUG_BUILD && utils.logger.warn('We reached the timeout for emptying the request buffer, still exiting now!'); + } + global.process.exit(1); + }, + error => { + debugBuild.DEBUG_BUILD && utils.logger.error(error); + }, + ); +} -/** - * RegExp to match chars that must be quoted-pair in RFC 2616 - * @private - */ +exports.logAndExitProcess = logAndExitProcess; +//# sourceMappingURL=errorhandling.js.map -var QUOTE_REGEXP = /([\\"])/g -/** - * RegExp for various RFC 2616 grammar - * - * parameter = token "=" ( token | quoted-string ) - * token = 1* - * separators = "(" | ")" | "<" | ">" | "@" - * | "," | ";" | ":" | "\" | <"> - * | "/" | "[" | "]" | "?" | "=" - * | "{" | "}" | SP | HT - * quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) - * qdtext = > - * quoted-pair = "\" CHAR - * CHAR = - * TEXT = - * LWS = [CRLF] 1*( SP | HT ) - * CRLF = CR LF - * CR = - * LF = - * SP = - * HT = - * CTL = - * OCTET = - * @private - */ +/***/ }), -var PARAM_REGEXP = /;[\x09\x20]*([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*=[\x09\x20]*("(?:[\x20!\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*/g // eslint-disable-line no-control-regex -var TEXT_REGEXP = /^[\x20-\x7e\x80-\xff]+$/ -var TOKEN_REGEXP = /^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/ +/***/ 21524: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/** - * RegExp for various RFC 5987 grammar - * - * ext-value = charset "'" [ language ] "'" value-chars - * charset = "UTF-8" / "ISO-8859-1" / mime-charset - * mime-charset = 1*mime-charsetc - * mime-charsetc = ALPHA / DIGIT - * / "!" / "#" / "$" / "%" / "&" - * / "+" / "-" / "^" / "_" / "`" - * / "{" / "}" / "~" - * language = ( 2*3ALPHA [ extlang ] ) - * / 4ALPHA - * / 5*8ALPHA - * extlang = *3( "-" 3ALPHA ) - * value-chars = *( pct-encoded / attr-char ) - * pct-encoded = "%" HEXDIG HEXDIG - * attr-char = ALPHA / DIGIT - * / "!" / "#" / "$" / "&" / "+" / "-" / "." - * / "^" / "_" / "`" / "|" / "~" - * @private - */ +var { + _optionalChain +} = __nccwpck_require__(57540); -var EXT_VALUE_REGEXP = /^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+.^_`|~-])+)$/ +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const url = __nccwpck_require__(87016); +const nodeVersion = __nccwpck_require__(85858); /** - * RegExp for various RFC 6266 grammar + * Assembles a URL that's passed to the users to filter on. + * It can include raw (potentially PII containing) data, which we'll allow users to access to filter + * but won't include in spans or breadcrumbs. * - * disposition-type = "inline" | "attachment" | disp-ext-type - * disp-ext-type = token - * disposition-parm = filename-parm | disp-ext-parm - * filename-parm = "filename" "=" value - * | "filename*" "=" ext-value - * disp-ext-parm = token "=" value - * | ext-token "=" ext-value - * ext-token = - * @private + * @param requestOptions RequestOptions object containing the component parts for a URL + * @returns Fully-formed URL */ - -var DISPOSITION_TYPE_REGEXP = /^([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*(?:$|;)/ // eslint-disable-line no-control-regex +// TODO (v8): This function should include auth, query and fragment (it's breaking, so we need to wait for v8) +function extractRawUrl(requestOptions) { + const { protocol, hostname, port } = parseRequestOptions(requestOptions); + const path = requestOptions.path ? requestOptions.path : '/'; + return `${protocol}//${hostname}${port}${path}`; +} /** - * Create an attachment Content-Disposition header. + * Assemble a URL to be used for breadcrumbs and spans. * - * @param {string} [filename] - * @param {object} [options] - * @param {string} [options.type=attachment] - * @param {string|boolean} [options.fallback=true] - * @return {string} - * @public + * @param requestOptions RequestOptions object containing the component parts for a URL + * @returns Fully-formed URL */ +function extractUrl(requestOptions) { + const { protocol, hostname, port } = parseRequestOptions(requestOptions); -function contentDisposition (filename, options) { - var opts = options || {} + const path = requestOptions.pathname || '/'; - // get type - var type = opts.type || 'attachment' + // always filter authority, see https://develop.sentry.dev/sdk/data-handling/#structuring-data + const authority = requestOptions.auth ? redactAuthority(requestOptions.auth) : ''; - // get parameters - var params = createparams(filename, opts.fallback) + return `${protocol}//${authority}${hostname}${port}${path}`; +} - // format into string - return format(new ContentDisposition(type, params)) +function redactAuthority(auth) { + const [user, password] = auth.split(':'); + return `${user ? '[Filtered]' : ''}:${password ? '[Filtered]' : ''}@`; } /** - * Create parameters object from filename and fallback. + * Handle various edge cases in the span description (for spans representing http(s) requests). * - * @param {string} [filename] - * @param {string|boolean} [fallback=true] - * @return {object} - * @private + * @param description current `description` property of the span representing the request + * @param requestOptions Configuration data for the request + * @param Request Request object + * + * @returns The cleaned description */ - -function createparams (filename, fallback) { - if (filename === undefined) { - return - } - - var params = {} - - if (typeof filename !== 'string') { - throw new TypeError('filename must be a string') +function cleanSpanDescription( + description, + requestOptions, + request, +) { + // nothing to clean + if (!description) { + return description; } - // fallback defaults to true - if (fallback === undefined) { - fallback = true - } + // eslint-disable-next-line prefer-const + let [method, requestUrl] = description.split(' '); - if (typeof fallback !== 'string' && typeof fallback !== 'boolean') { - throw new TypeError('fallback must be a string or boolean') + // superagent sticks the protocol in a weird place (we check for host because if both host *and* protocol are missing, + // we're likely dealing with an internal route and this doesn't apply) + if (requestOptions.host && !requestOptions.protocol) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any + requestOptions.protocol = _optionalChain([(request ), 'optionalAccess', _ => _.agent, 'optionalAccess', _2 => _2.protocol]); // worst comes to worst, this is undefined and nothing changes + // This URL contains the filtered authority ([filtered]:[filtered]@example.com) but no fragment or query params + requestUrl = extractUrl(requestOptions); } - if (typeof fallback === 'string' && NON_LATIN1_REGEXP.test(fallback)) { - throw new TypeError('fallback must be ISO-8859-1 string') + // internal routes can end up starting with a triple slash rather than a single one + if (_optionalChain([requestUrl, 'optionalAccess', _3 => _3.startsWith, 'call', _4 => _4('///')])) { + requestUrl = requestUrl.slice(2); } - // restrict to file base name - var name = basename(filename) - - // determine if name is suitable for quoted string - var isQuotedString = TEXT_REGEXP.test(name) + return `${method} ${requestUrl}`; +} - // generate fallback name - var fallbackName = typeof fallback !== 'string' - ? fallback && getlatin1(name) - : basename(fallback) - var hasFallback = typeof fallbackName === 'string' && fallbackName !== name +// the node types are missing a few properties which node's `urlToOptions` function spits out - // set extended filename parameter - if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) { - params['filename*'] = name +/** + * Convert a URL object into a RequestOptions object. + * + * Copied from Node's internals (where it's used in http(s).request() and http(s).get()), modified only to use the + * RequestOptions type above. + * + * See https://github.com/nodejs/node/blob/master/lib/internal/url.js. + */ +function urlToOptions(url) { + const options = { + protocol: url.protocol, + hostname: + typeof url.hostname === 'string' && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname, + hash: url.hash, + search: url.search, + pathname: url.pathname, + path: `${url.pathname || ''}${url.search || ''}`, + href: url.href, + }; + if (url.port !== '') { + options.port = Number(url.port); } - - // set filename parameter - if (isQuotedString || hasFallback) { - params.filename = hasFallback - ? fallbackName - : name + if (url.username || url.password) { + options.auth = `${url.username}:${url.password}`; } - - return params + return options; } /** - * Format object to Content-Disposition header. + * Normalize inputs to `http(s).request()` and `http(s).get()`. * - * @param {object} obj - * @param {string} obj.type - * @param {object} [obj.parameters] - * @return {string} - * @private + * Legal inputs to `http(s).request()` and `http(s).get()` can take one of ten forms: + * [ RequestOptions | string | URL ], + * [ RequestOptions | string | URL, RequestCallback ], + * [ string | URL, RequestOptions ], and + * [ string | URL, RequestOptions, RequestCallback ]. + * + * This standardizes to one of two forms: [ RequestOptions ] and [ RequestOptions, RequestCallback ]. A similar thing is + * done as the first step of `http(s).request()` and `http(s).get()`; this just does it early so that we can interact + * with the args in a standard way. + * + * @param requestArgs The inputs to `http(s).request()` or `http(s).get()`, as an array. + * + * @returns Equivalent args of the form [ RequestOptions ] or [ RequestOptions, RequestCallback ]. */ +function normalizeRequestArgs( + httpModule, + requestArgs, +) { + let callback, requestOptions; -function format (obj) { - var parameters = obj.parameters - var type = obj.type - - if (!type || typeof type !== 'string' || !TOKEN_REGEXP.test(type)) { - throw new TypeError('invalid type') + // pop off the callback, if there is one + if (typeof requestArgs[requestArgs.length - 1] === 'function') { + callback = requestArgs.pop() ; } - // start with normalized type - var string = String(type).toLowerCase() + // create a RequestOptions object of whatever's at index 0 + if (typeof requestArgs[0] === 'string') { + requestOptions = urlToOptions(new url.URL(requestArgs[0])); + } else if (requestArgs[0] instanceof url.URL) { + requestOptions = urlToOptions(requestArgs[0]); + } else { + requestOptions = requestArgs[0]; - // append parameters - if (parameters && typeof parameters === 'object') { - var param - var params = Object.keys(parameters).sort() + try { + const parsed = new url.URL( + requestOptions.path || '', + `${requestOptions.protocol || 'http:'}//${requestOptions.hostname}`, + ); + requestOptions = { + pathname: parsed.pathname, + search: parsed.search, + hash: parsed.hash, + ...requestOptions, + }; + } catch (e) { + // ignore + } + } - for (var i = 0; i < params.length; i++) { - param = params[i] + // if the options were given separately from the URL, fold them in + if (requestArgs.length === 2) { + requestOptions = { ...requestOptions, ...requestArgs[1] }; + } - var val = param.substr(-1) === '*' - ? ustring(parameters[param]) - : qstring(parameters[param]) + // Figure out the protocol if it's currently missing + if (requestOptions.protocol === undefined) { + // Worst case we end up populating protocol with undefined, which it already is + /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */ - string += '; ' + param + '=' + val + // NOTE: Prior to Node 9, `https` used internals of `http` module, thus we don't patch it. + // Because of that, we cannot rely on `httpModule` to provide us with valid protocol, + // as it will always return `http`, even when using `https` module. + // + // See test/integrations/http.test.ts for more details on Node <=v8 protocol issue. + if (nodeVersion.NODE_VERSION.major > 8) { + requestOptions.protocol = + _optionalChain([(_optionalChain([httpModule, 'optionalAccess', _5 => _5.globalAgent]) ), 'optionalAccess', _6 => _6.protocol]) || + _optionalChain([(requestOptions.agent ), 'optionalAccess', _7 => _7.protocol]) || + _optionalChain([(requestOptions._defaultAgent ), 'optionalAccess', _8 => _8.protocol]); + } else { + requestOptions.protocol = + _optionalChain([(requestOptions.agent ), 'optionalAccess', _9 => _9.protocol]) || + _optionalChain([(requestOptions._defaultAgent ), 'optionalAccess', _10 => _10.protocol]) || + _optionalChain([(_optionalChain([httpModule, 'optionalAccess', _11 => _11.globalAgent]) ), 'optionalAccess', _12 => _12.protocol]); } + /* eslint-enable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */ } - return string + // return args in standardized form + if (callback) { + return [requestOptions, callback]; + } else { + return [requestOptions]; + } } -/** - * Decode a RFC 5987 field value (gracefully). - * - * @param {string} str - * @return {string} - * @private - */ +function parseRequestOptions(requestOptions) -function decodefield (str) { - var match = EXT_VALUE_REGEXP.exec(str) + { + const protocol = requestOptions.protocol || ''; + const hostname = requestOptions.hostname || requestOptions.host || ''; + // Don't log standard :80 (http) and :443 (https) ports to reduce the noise + // Also don't add port if the hostname already includes a port + const port = + !requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 || /^(.*):(\d+)$/.test(hostname) + ? '' + : `:${requestOptions.port}`; - if (!match) { - throw new TypeError('invalid extended field value') - } + return { protocol, hostname, port }; +} - var charset = match[1].toLowerCase() - var encoded = match[2] - var value +exports.cleanSpanDescription = cleanSpanDescription; +exports.extractRawUrl = extractRawUrl; +exports.extractUrl = extractUrl; +exports.normalizeRequestArgs = normalizeRequestArgs; +exports.urlToOptions = urlToOptions; +//# sourceMappingURL=http.js.map - // to binary string - var binary = encoded.replace(HEX_ESCAPE_REPLACE_REGEXP, pdecode) - switch (charset) { - case 'iso-8859-1': - value = getlatin1(binary) - break - case 'utf-8': - value = Buffer.from(binary, 'binary').toString('utf8') - break - default: - throw new TypeError('unsupported charset in extended field') - } +/***/ }), - return value -} +/***/ 29968: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/** - * Get ISO-8859-1 version of string. - * - * @param {string} val - * @return {string} - * @private - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); -function getlatin1 (val) { - // simple Unicode -> ISO-8859-1 transformation - return String(val).replace(NON_LATIN1_REGEXP, '?') -} +const path = __nccwpck_require__(16928); +const utils = __nccwpck_require__(57540); -/** - * Parse Content-Disposition header string. - * - * @param {string} string - * @return {object} - * @public - */ +/** normalizes Windows paths */ +function normalizeWindowsPath(path) { + return path + .replace(/^[A-Z]:/, '') // remove Windows-style prefix + .replace(/\\/g, '/'); // replace all `\` instances with `/` +} -function parse (string) { - if (!string || typeof string !== 'string') { - throw new TypeError('argument string is required') - } +/** Creates a function that gets the module name from a filename */ +function createGetModuleFromFilename( + basePath = process.argv[1] ? utils.dirname(process.argv[1]) : process.cwd(), + isWindows = path.sep === '\\', +) { + const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath; - var match = DISPOSITION_TYPE_REGEXP.exec(string) + return (filename) => { + if (!filename) { + return; + } - if (!match) { - throw new TypeError('invalid type format') - } + const normalizedFilename = isWindows ? normalizeWindowsPath(filename) : filename; - // normalize type - var index = match[0].length - var type = match[1].toLowerCase() + // eslint-disable-next-line prefer-const + let { dir, base: file, ext } = path.posix.parse(normalizedFilename); - var key - var names = [] - var params = {} - var value + if (ext === '.js' || ext === '.mjs' || ext === '.cjs') { + file = file.slice(0, ext.length * -1); + } - // calculate index to start at - index = PARAM_REGEXP.lastIndex = match[0].substr(-1) === ';' - ? index - 1 - : index + if (!dir) { + // No dirname whatsoever + dir = '.'; + } - // match parameters - while ((match = PARAM_REGEXP.exec(string))) { - if (match.index !== index) { - throw new TypeError('invalid parameter format') + const n = dir.lastIndexOf('/node_modules'); + if (n > -1) { + return `${dir.slice(n + 14).replace(/\//g, '.')}:${file}`; } - index += match[0].length - key = match[1].toLowerCase() - value = match[2] + // Let's see if it's a part of the main module + // To be a part of main module, it has to share the same base + if (dir.startsWith(normalizedBase)) { + let moduleName = dir.slice(normalizedBase.length + 1).replace(/\//g, '.'); - if (names.indexOf(key) !== -1) { - throw new TypeError('invalid duplicate parameter') + if (moduleName) { + moduleName += ':'; + } + moduleName += file; + + return moduleName; } - names.push(key) + return file; + }; +} - if (key.indexOf('*') + 1 === key.length) { - // decode extended value - key = key.slice(0, -1) - value = decodefield(value) +exports.createGetModuleFromFilename = createGetModuleFromFilename; +//# sourceMappingURL=module.js.map - // overwrite existing value - params[key] = value - continue - } - if (typeof params[key] === 'string') { - continue - } +/***/ }), - if (value[0] === '"') { - // remove quotes and escapes - value = value - .substr(1, value.length - 2) - .replace(QESC_REGEXP, '$1') - } +/***/ 85858: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - params[key] = value - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - if (index !== -1 && index !== string.length) { - throw new TypeError('invalid parameter format') - } +const utils = __nccwpck_require__(57540); - return new ContentDisposition(type, params) -} +const NODE_VERSION = utils.parseSemver(process.versions.node) ; -/** - * Percent decode a single character. - * - * @param {string} str - * @param {string} hex - * @return {string} - * @private - */ +exports.NODE_VERSION = NODE_VERSION; +//# sourceMappingURL=nodeVersion.js.map -function pdecode (str, hex) { - return String.fromCharCode(parseInt(hex, 16)) -} -/** - * Percent encode a single character. - * - * @param {string} char - * @return {string} - * @private - */ +/***/ }), -function pencode (char) { - return '%' + String(char) - .charCodeAt(0) - .toString(16) - .toUpperCase() -} +/***/ 47204: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/** - * Quote a string for HTTP. - * - * @param {string} val - * @return {string} - * @private - */ +var { + _nullishCoalesce +} = __nccwpck_require__(57540); -function qstring (val) { - var str = String(val) +Object.defineProperty(exports, "__esModule", ({ value: true })); - return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"' -} +const http = __nccwpck_require__(58611); +__nccwpck_require__(65692); /** - * Encode a Unicode string for HTTP (RFC 5987). - * - * @param {string} val - * @return {string} - * @private - */ +* This code was originally forked from https://github.com/TooTallNate/proxy-agents/tree/b133295fd16f6475578b6b15bd9b4e33ecb0d0b7 +* With the following licence: +* +* (The MIT License) +* +* Copyright (c) 2013 Nathan Rajlich * +* +* 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. +*/ -function ustring (val) { - var str = String(val) +const INTERNAL = Symbol('AgentBaseInternalState'); - // percent encode as UTF-8 - var encoded = encodeURIComponent(str) - .replace(ENCODE_URL_ATTR_CHAR_REGEXP, pencode) +class Agent extends http.Agent { - return 'UTF-8\'\'' + encoded -} + // Set by `http.Agent` - missing from `@types/node` -/** - * Class for parsed Content-Disposition header for v8 optimization - * - * @public - * @param {string} type - * @param {object} parameters - * @constructor - */ + constructor(opts) { + super(opts); + this[INTERNAL] = {}; + } -function ContentDisposition (type, parameters) { - this.type = type - this.parameters = parameters + /** + * Determine whether this is an `http` or `https` request. + */ + isSecureEndpoint(options) { + if (options) { + // First check the `secureEndpoint` property explicitly, since this + // means that a parent `Agent` is "passing through" to this instance. + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access + if (typeof (options ).secureEndpoint === 'boolean') { + return options.secureEndpoint; + } + + // If no explicit `secure` endpoint, check if `protocol` property is + // set. This will usually be the case since using a full string URL + // or `URL` instance should be the most common usage. + if (typeof options.protocol === 'string') { + return options.protocol === 'https:'; + } + } + + // Finally, if no `protocol` property was set, then fall back to + // checking the stack trace of the current call stack, and try to + // detect the "https" module. + const { stack } = new Error(); + if (typeof stack !== 'string') return false; + return stack.split('\n').some(l => l.indexOf('(https.js:') !== -1 || l.indexOf('node:https:') !== -1); + } + + createSocket(req, options, cb) { + const connectOpts = { + ...options, + secureEndpoint: this.isSecureEndpoint(options), + }; + Promise.resolve() + .then(() => this.connect(req, connectOpts)) + .then(socket => { + if (socket instanceof http.Agent) { + // @ts-expect-error `addRequest()` isn't defined in `@types/node` + return socket.addRequest(req, connectOpts); + } + this[INTERNAL].currentSocket = socket; + // @ts-expect-error `createSocket()` isn't defined in `@types/node` + super.createSocket(req, options, cb); + }, cb); + } + + createConnection() { + const socket = this[INTERNAL].currentSocket; + this[INTERNAL].currentSocket = undefined; + if (!socket) { + throw new Error('No socket was returned in the `connect()` function'); + } + return socket; + } + + get defaultPort() { + return _nullishCoalesce(this[INTERNAL].defaultPort, () => ( (this.protocol === 'https:' ? 443 : 80))); + } + + set defaultPort(v) { + if (this[INTERNAL]) { + this[INTERNAL].defaultPort = v; + } + } + + get protocol() { + return _nullishCoalesce(this[INTERNAL].protocol, () => ( (this.isSecureEndpoint() ? 'https:' : 'http:'))); + } + + set protocol(v) { + if (this[INTERNAL]) { + this[INTERNAL].protocol = v; + } + } } +exports.Agent = Agent; +//# sourceMappingURL=base.js.map + /***/ }), -/***/ 22541: -/***/ ((__unused_webpack_module, exports) => { +/***/ 75377: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; -/*! - * content-type - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ +var { + _nullishCoalesce, + _optionalChain +} = __nccwpck_require__(57540); +Object.defineProperty(exports, "__esModule", ({ value: true })); +const net = __nccwpck_require__(69278); +const tls = __nccwpck_require__(64756); +const url = __nccwpck_require__(87016); +const utils = __nccwpck_require__(57540); +const base = __nccwpck_require__(47204); +const parseProxyResponse = __nccwpck_require__(1059); -/** - * RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1 - * - * parameter = token "=" ( token / quoted-string ) - * token = 1*tchar - * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" - * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" - * / DIGIT / ALPHA - * ; any VCHAR, except delimiters - * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE - * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text - * obs-text = %x80-FF - * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) - */ -var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g // eslint-disable-line no-control-regex -var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/ // eslint-disable-line no-control-regex -var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/ +function debug(...args) { + utils.logger.log('[https-proxy-agent]', ...args); +} /** - * RegExp to match quoted-pair in RFC 7230 sec 3.2.6 + * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to + * the specified "HTTP(s) proxy server" in order to proxy HTTPS requests. * - * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) - * obs-text = %x80-FF + * Outgoing HTTP requests are first tunneled through the proxy server using the + * `CONNECT` HTTP request method to establish a connection to the proxy server, + * and then the proxy server connects to the destination target and issues the + * HTTP request from the proxy server. + * + * `https:` requests have their socket connection upgraded to TLS once + * the connection to the proxy server has been established. */ -var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g // eslint-disable-line no-control-regex +class HttpsProxyAgent extends base.Agent { + static __initStatic() {this.protocols = ['http', 'https']; } + + constructor(proxy, opts) { + super(opts); + this.options = {}; + this.proxy = typeof proxy === 'string' ? new url.URL(proxy) : proxy; + this.proxyHeaders = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _2 => _2.headers]), () => ( {})); + debug('Creating new HttpsProxyAgent instance: %o', this.proxy.href); + + // Trim off the brackets from IPv6 addresses + const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, ''); + const port = this.proxy.port ? parseInt(this.proxy.port, 10) : this.proxy.protocol === 'https:' ? 443 : 80; + this.connectOpts = { + // Attempt to negotiate http/1.1 for proxy servers that support http/2 + ALPNProtocols: ['http/1.1'], + ...(opts ? omit(opts, 'headers') : null), + host, + port, + }; + } -/** - * RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6 - */ -var QUOTE_REGEXP = /([\\"])/g + /** + * Called when the node-core HTTP client library is creating a + * new HTTP request. + */ + async connect(req, opts) { + const { proxy } = this; -/** - * RegExp to match type in RFC 7231 sec 3.1.1.1 - * - * media-type = type "/" subtype - * type = token - * subtype = token - */ -var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/ + if (!opts.host) { + throw new TypeError('No "host" provided'); + } -/** - * Module exports. - * @public - */ + // Create a socket connection to the proxy server. + let socket; + if (proxy.protocol === 'https:') { + debug('Creating `tls.Socket`: %o', this.connectOpts); + const servername = this.connectOpts.servername || this.connectOpts.host; + socket = tls.connect({ + ...this.connectOpts, + servername: servername && net.isIP(servername) ? undefined : servername, + }); + } else { + debug('Creating `net.Socket`: %o', this.connectOpts); + socket = net.connect(this.connectOpts); + } -exports.format = format -exports.parse = parse + const headers = + typeof this.proxyHeaders === 'function' ? this.proxyHeaders() : { ...this.proxyHeaders }; + const host = net.isIPv6(opts.host) ? `[${opts.host}]` : opts.host; + let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\r\n`; -/** - * Format object to media type. - * - * @param {object} obj - * @return {string} - * @public - */ + // Inject the `Proxy-Authorization` header if necessary. + if (proxy.username || proxy.password) { + const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`; + headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`; + } -function format (obj) { - if (!obj || typeof obj !== 'object') { - throw new TypeError('argument obj is required') - } + headers.Host = `${host}:${opts.port}`; - var parameters = obj.parameters - var type = obj.type + if (!headers['Proxy-Connection']) { + headers['Proxy-Connection'] = this.keepAlive ? 'Keep-Alive' : 'close'; + } + for (const name of Object.keys(headers)) { + payload += `${name}: ${headers[name]}\r\n`; + } - if (!type || !TYPE_REGEXP.test(type)) { - throw new TypeError('invalid type') - } + const proxyResponsePromise = parseProxyResponse.parseProxyResponse(socket); - var string = type + socket.write(`${payload}\r\n`); - // append parameters - if (parameters && typeof parameters === 'object') { - var param - var params = Object.keys(parameters).sort() + const { connect, buffered } = await proxyResponsePromise; + req.emit('proxyConnect', connect); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore Not EventEmitter in Node types + this.emit('proxyConnect', connect, req); - for (var i = 0; i < params.length; i++) { - param = params[i] + if (connect.statusCode === 200) { + req.once('socket', resume); - if (!TOKEN_REGEXP.test(param)) { - throw new TypeError('invalid parameter name') + if (opts.secureEndpoint) { + // The proxy is connecting to a TLS server, so upgrade + // this socket connection to a TLS connection. + debug('Upgrading socket connection to TLS'); + const servername = opts.servername || opts.host; + return tls.connect({ + ...omit(opts, 'host', 'path', 'port'), + socket, + servername: net.isIP(servername) ? undefined : servername, + }); } - string += '; ' + param + '=' + qstring(parameters[param]) + return socket; } - } - return string -} + // Some other status code that's not 200... need to re-play the HTTP + // header "data" events onto the socket once the HTTP machinery is + // attached so that the node core `http` can parse and handle the + // error status code. -/** - * Parse media type to object. - * - * @param {string|object} string - * @return {Object} - * @public - */ + // Close the original socket, and a new "fake" socket is returned + // instead, so that the proxy doesn't get the HTTP request + // written to it (which may contain `Authorization` headers or other + // sensitive data). + // + // See: https://hackerone.com/reports/541502 + socket.destroy(); -function parse (string) { - if (!string) { - throw new TypeError('argument string is required') + const fakeSocket = new net.Socket({ writable: false }); + fakeSocket.readable = true; + + // Need to wait for the "socket" event to re-play the "data" events. + req.once('socket', (s) => { + debug('Replaying proxy buffer for failed request'); + // Replay the "buffered" Buffer onto the fake `socket`, since at + // this point the HTTP module machinery has been hooked up for + // the user. + s.push(buffered); + s.push(null); + }); + + return fakeSocket; } +}HttpsProxyAgent.__initStatic(); - // support req/res-like objects as argument - var header = typeof string === 'object' - ? getcontenttype(string) - : string +function resume(socket) { + socket.resume(); +} - if (typeof header !== 'string') { - throw new TypeError('argument string is required to be a string') - } +function omit( + obj, + ...keys +) - var index = header.indexOf(';') - var type = index !== -1 - ? header.slice(0, index).trim() - : header.trim() + { + const ret = {} - if (!TYPE_REGEXP.test(type)) { - throw new TypeError('invalid media type') +; + let key; + for (key in obj) { + if (!keys.includes(key)) { + ret[key] = obj[key]; + } } + return ret; +} - var obj = new ContentType(type.toLowerCase()) +exports.HttpsProxyAgent = HttpsProxyAgent; +//# sourceMappingURL=index.js.map - // parse parameters - if (index !== -1) { - var key - var match - var value - PARAM_REGEXP.lastIndex = index +/***/ }), - while ((match = PARAM_REGEXP.exec(header))) { - if (match.index !== index) { - throw new TypeError('invalid parameter format') - } +/***/ 1059: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - index += match[0].length - key = match[1].toLowerCase() - value = match[2] +Object.defineProperty(exports, "__esModule", ({ value: true })); - if (value.charCodeAt(0) === 0x22 /* " */) { - // remove quotes - value = value.slice(1, -1) +const utils = __nccwpck_require__(57540); - // remove escapes - if (value.indexOf('\\') !== -1) { - value = value.replace(QESC_REGEXP, '$1') - } - } +function debug(...args) { + utils.logger.log('[https-proxy-agent:parse-proxy-response]', ...args); +} - obj.parameters[key] = value - } +function parseProxyResponse(socket) { + return new Promise((resolve, reject) => { + // we need to buffer any HTTP traffic that happens with the proxy before we get + // the CONNECT response, so that if the response is anything other than an "200" + // response code, then we can re-play the "data" events on the socket once the + // HTTP parser is hooked up... + let buffersLength = 0; + const buffers = []; - if (index !== header.length) { - throw new TypeError('invalid parameter format') + function read() { + const b = socket.read(); + if (b) ondata(b); + else socket.once('readable', read); } - } - - return obj -} -/** - * Get content-type from req/res objects. - * - * @param {object} - * @return {Object} - * @private - */ - -function getcontenttype (obj) { - var header + function cleanup() { + socket.removeListener('end', onend); + socket.removeListener('error', onerror); + socket.removeListener('readable', read); + } - if (typeof obj.getHeader === 'function') { - // res-like - header = obj.getHeader('content-type') - } else if (typeof obj.headers === 'object') { - // req-like - header = obj.headers && obj.headers['content-type'] - } + function onend() { + cleanup(); + debug('onend'); + reject(new Error('Proxy connection ended before receiving CONNECT response')); + } - if (typeof header !== 'string') { - throw new TypeError('content-type header is missing from object') - } + function onerror(err) { + cleanup(); + debug('onerror %o', err); + reject(err); + } - return header -} + function ondata(b) { + buffers.push(b); + buffersLength += b.length; -/** - * Quote a string if necessary. - * - * @param {string} val - * @return {string} - * @private - */ + const buffered = Buffer.concat(buffers, buffersLength); + const endOfHeaders = buffered.indexOf('\r\n\r\n'); -function qstring (val) { - var str = String(val) + if (endOfHeaders === -1) { + // keep buffering + debug('have not received end of HTTP headers yet...'); + read(); + return; + } - // no need to quote tokens - if (TOKEN_REGEXP.test(str)) { - return str - } + const headerParts = buffered.slice(0, endOfHeaders).toString('ascii').split('\r\n'); + const firstLine = headerParts.shift(); + if (!firstLine) { + socket.destroy(); + return reject(new Error('No header received from proxy CONNECT response')); + } + const firstLineParts = firstLine.split(' '); + const statusCode = +firstLineParts[1]; + const statusText = firstLineParts.slice(2).join(' '); + const headers = {}; + for (const header of headerParts) { + if (!header) continue; + const firstColon = header.indexOf(':'); + if (firstColon === -1) { + socket.destroy(); + return reject(new Error(`Invalid header from proxy CONNECT response: "${header}"`)); + } + const key = header.slice(0, firstColon).toLowerCase(); + const value = header.slice(firstColon + 1).trimStart(); + const current = headers[key]; + if (typeof current === 'string') { + headers[key] = [current, value]; + } else if (Array.isArray(current)) { + current.push(value); + } else { + headers[key] = value; + } + } + debug('got proxy server response: %o %o', firstLine, headers); + cleanup(); + resolve({ + connect: { + statusCode, + statusText, + headers, + }, + buffered, + }); + } - if (str.length > 0 && !TEXT_REGEXP.test(str)) { - throw new TypeError('invalid parameter value') - } + socket.on('error', onerror); + socket.on('end', onend); - return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"' + read(); + }); } -/** - * Class to represent a content type. - * @private - */ -function ContentType (type) { - this.parameters = Object.create(null) - this.type = type -} +exports.parseProxyResponse = parseProxyResponse; +//# sourceMappingURL=parse-proxy-response.js.map /***/ }), -/***/ 93628: +/***/ 2850: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); + /** - * Module dependencies. + * @deprecated `Handlers.ExpressRequest` is deprecated and will be removed in v8. Use `PolymorphicRequest` instead. */ -var crypto = __nccwpck_require__(76982); - /** - * Sign the given `val` with `secret`. + * Normalizes data from the request object, accounting for framework differences. * - * @param {String} val - * @param {String} secret - * @return {String} - * @api private + * @deprecated `Handlers.extractRequestData` is deprecated and will be removed in v8. Use `extractRequestData` instead. + * + * @param req The request object from which to extract data + * @param keys An optional array of keys to include in the normalized data. + * @returns An object containing normalized request data */ - -exports.sign = function(val, secret){ - if ('string' != typeof val) throw new TypeError("Cookie value must be provided as a string."); - if ('string' != typeof secret) throw new TypeError("Secret string must be provided."); - return val + '.' + crypto - .createHmac('sha256', secret) - .update(val) - .digest('base64') - .replace(/\=+$/, ''); -}; +function extractRequestData(req, keys) { + return utils.extractRequestData(req, { include: keys }); +} /** - * Unsign and decode the given `val` with `secret`, - * returning `false` if the signature is invalid. + * Options deciding what parts of the request to use when enhancing an event * - * @param {String} val - * @param {String} secret - * @return {String|Boolean} - * @api private + * @deprecated `Handlers.ParseRequestOptions` is deprecated and will be removed in v8. Use + * `AddRequestDataToEventOptions` in `@sentry/utils` instead. */ -exports.unsign = function(val, secret){ - if ('string' != typeof val) throw new TypeError("Signed cookie string must be provided."); - if ('string' != typeof secret) throw new TypeError("Secret string must be provided."); - var str = val.slice(0, val.lastIndexOf('.')) - , mac = exports.sign(str, secret); - - return sha1(mac) == sha1(val) ? str : false; -}; - /** - * Private + * Enriches passed event with request data. + * + * @deprecated `Handlers.parseRequest` is deprecated and will be removed in v8. Use `addRequestDataToEvent` instead. + * + * @param event Will be mutated and enriched with req data + * @param req Request object + * @param options object containing flags to enable functionality + * @hidden */ - -function sha1(str){ - return crypto.createHash('sha1').update(str).digest('hex'); +function parseRequest(event, req, options = {}) { + return utils.addRequestDataToEvent(event, req, { include: options }); } +exports.extractRequestData = extractRequestData; +exports.parseRequest = parseRequest; +//# sourceMappingURL=requestDataDeprecated.js.map + /***/ }), -/***/ 10011: -/***/ ((__unused_webpack_module, exports) => { +/***/ 32554: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; -/*! - * cookie - * Copyright(c) 2012-2014 Roman Shtylman - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ +var { + _optionalChain +} = __nccwpck_require__(57540); +Object.defineProperty(exports, "__esModule", ({ value: true })); +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const index$2 = __nccwpck_require__(15593); +const client = __nccwpck_require__(69279); +const console = __nccwpck_require__(34441); +const context = __nccwpck_require__(90079); +const contextlines = __nccwpck_require__(73456); +const http = __nccwpck_require__(15842); +const index$1 = __nccwpck_require__(58676); +const modules = __nccwpck_require__(45705); +const onuncaughtexception = __nccwpck_require__(63295); +const onunhandledrejection = __nccwpck_require__(31061); +const spotlight = __nccwpck_require__(38880); +const index = __nccwpck_require__(12561); +const module$1 = __nccwpck_require__(29968); +const http$1 = __nccwpck_require__(4121); -/** - * Module exports. - * @public - */ +/* eslint-disable max-lines */ -exports.parse = parse; -exports.serialize = serialize; +/** @deprecated Use `getDefaultIntegrations(options)` instead. */ +const defaultIntegrations = [ + // Common + core.inboundFiltersIntegration(), + core.functionToStringIntegration(), + core.linkedErrorsIntegration(), + core.requestDataIntegration(), + // Native Wrappers + console.consoleIntegration(), + http.httpIntegration(), + index.nativeNodeFetchintegration(), + // Global Handlers + onuncaughtexception.onUncaughtExceptionIntegration(), + onunhandledrejection.onUnhandledRejectionIntegration(), + // Event Info + contextlines.contextLinesIntegration(), + index$1.localVariablesIntegration(), + context.nodeContextIntegration(), + modules.modulesIntegration(), +]; -/** - * Module variables. - * @private - */ +/** Get the default integrations for the Node SDK. */ +function getDefaultIntegrations(_options) { + const carrier = core.getMainCarrier(); -var decode = decodeURIComponent; -var encode = encodeURIComponent; + const autoloadedIntegrations = _optionalChain([carrier, 'access', _ => _.__SENTRY__, 'optionalAccess', _2 => _2.integrations]) || []; -/** - * RegExp to match field-content in RFC 7230 sec 3.2 - * - * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] - * field-vchar = VCHAR / obs-text - * obs-text = %x80-FF - */ - -var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/; + return [ + // eslint-disable-next-line deprecation/deprecation + ...defaultIntegrations, + ...autoloadedIntegrations, + ]; +} /** - * Parse a cookie header. + * The Sentry Node SDK Client. * - * Parse the given cookie header string into an object - * The object has the various cookies as keys(names) => values + * To use this SDK, call the {@link init} function as early as possible in the + * main entry module. To set context information or send manual events, use the + * provided methods. * - * @param {string} str - * @param {object} [options] - * @return {object} - * @public + * @example + * ``` + * + * const { init } = require('@sentry/node'); + * + * init({ + * dsn: '__DSN__', + * // ... + * }); + * ``` + * + * @example + * ``` + * + * const { configureScope } = require('@sentry/node'); + * configureScope((scope: Scope) => { + * scope.setExtra({ battery: 0.7 }); + * scope.setTag({ user_mode: 'admin' }); + * scope.setUser({ id: '4711' }); + * }); + * ``` + * + * @example + * ``` + * + * const { addBreadcrumb } = require('@sentry/node'); + * addBreadcrumb({ + * message: 'My Breadcrumb', + * // ... + * }); + * ``` + * + * @example + * ``` + * + * const Sentry = require('@sentry/node'); + * Sentry.captureMessage('Hello, world!'); + * Sentry.captureException(new Error('Good bye')); + * Sentry.captureEvent({ + * message: 'Manual', + * stacktrace: [ + * // ... + * ], + * }); + * ``` + * + * @see {@link NodeOptions} for documentation on configuration options. */ +// eslint-disable-next-line complexity +function init(options = {}) { + index$2.setNodeAsyncContextStrategy(); -function parse(str, options) { - if (typeof str !== 'string') { - throw new TypeError('argument str must be a string'); + if (options.defaultIntegrations === undefined) { + options.defaultIntegrations = getDefaultIntegrations(); } - var obj = {} - var opt = options || {}; - var pairs = str.split(';') - var dec = opt.decode || decode; - - for (var i = 0; i < pairs.length; i++) { - var pair = pairs[i]; - var index = pair.indexOf('=') + if (options.dsn === undefined && process.env.SENTRY_DSN) { + options.dsn = process.env.SENTRY_DSN; + } - // skip things that don't look like key=value - if (index < 0) { - continue; + const sentryTracesSampleRate = process.env.SENTRY_TRACES_SAMPLE_RATE; + if (options.tracesSampleRate === undefined && sentryTracesSampleRate) { + const tracesSampleRate = parseFloat(sentryTracesSampleRate); + if (isFinite(tracesSampleRate)) { + options.tracesSampleRate = tracesSampleRate; } + } - var key = pair.substring(0, index).trim() - - // only assign once - if (undefined == obj[key]) { - var val = pair.substring(index + 1, pair.length).trim() - - // quoted values - if (val[0] === '"') { - val = val.slice(1, -1) - } - - obj[key] = tryDecode(val, dec); + if (options.release === undefined) { + const detectedRelease = getSentryRelease(); + if (detectedRelease !== undefined) { + options.release = detectedRelease; + } else { + // If release is not provided, then we should disable autoSessionTracking + options.autoSessionTracking = false; } } - return obj; -} - -/** - * Serialize data into a cookie header. - * - * Serialize the a name value pair into a cookie string suitable for - * http headers. An optional options object specified cookie parameters. - * - * serialize('foo', 'bar', { httpOnly: true }) - * => "foo=bar; httpOnly" - * - * @param {string} name - * @param {string} val - * @param {object} [options] - * @return {string} - * @public - */ - -function serialize(name, val, options) { - var opt = options || {}; - var enc = opt.encode || encode; + if (options.environment === undefined && process.env.SENTRY_ENVIRONMENT) { + options.environment = process.env.SENTRY_ENVIRONMENT; + } - if (typeof enc !== 'function') { - throw new TypeError('option encode is invalid'); + if (options.autoSessionTracking === undefined && options.dsn !== undefined) { + options.autoSessionTracking = true; } - if (!fieldContentRegExp.test(name)) { - throw new TypeError('argument name is invalid'); + if (options.instrumenter === undefined) { + options.instrumenter = 'sentry'; } - var value = enc(val); + // TODO(v7): Refactor this to reduce the logic above + const clientOptions = { + ...options, + stackParser: utils.stackParserFromStackParserOptions(options.stackParser || defaultStackParser), + integrations: core.getIntegrationsToSetup(options), + transport: options.transport || http$1.makeNodeTransport, + }; - if (value && !fieldContentRegExp.test(value)) { - throw new TypeError('argument val is invalid'); - } + core.initAndBind(options.clientClass || client.NodeClient, clientOptions); - var str = name + '=' + value; + if (options.autoSessionTracking) { + startSessionTracking(); + } - if (null != opt.maxAge) { - var maxAge = opt.maxAge - 0; + updateScopeFromEnvVariables(); - if (isNaN(maxAge) || !isFinite(maxAge)) { - throw new TypeError('option maxAge is invalid') + if (options.spotlight) { + const client = core.getClient(); + if (client && client.addIntegration) { + // force integrations to be setup even if no DSN was set + // If they have already been added before, they will be ignored anyhow + const integrations = client.getOptions().integrations; + for (const integration of integrations) { + client.addIntegration(integration); + } + client.addIntegration( + spotlight.spotlightIntegration({ sidecarUrl: typeof options.spotlight === 'string' ? options.spotlight : undefined }), + ); } + } +} - str += '; Max-Age=' + Math.floor(maxAge); +/** + * Function that takes an instance of NodeClient and checks if autoSessionTracking option is enabled for that client + */ +function isAutoSessionTrackingEnabled(client) { + if (client === undefined) { + return false; } + const clientOptions = client && client.getOptions(); + if (clientOptions && clientOptions.autoSessionTracking !== undefined) { + return clientOptions.autoSessionTracking; + } + return false; +} - if (opt.domain) { - if (!fieldContentRegExp.test(opt.domain)) { - throw new TypeError('option domain is invalid'); - } +/** + * Returns a release dynamically from environment variables. + */ +function getSentryRelease(fallback) { + // Always read first as Sentry takes this as precedence + if (process.env.SENTRY_RELEASE) { + return process.env.SENTRY_RELEASE; + } - str += '; Domain=' + opt.domain; + // This supports the variable that sentry-webpack-plugin injects + if (utils.GLOBAL_OBJ.SENTRY_RELEASE && utils.GLOBAL_OBJ.SENTRY_RELEASE.id) { + return utils.GLOBAL_OBJ.SENTRY_RELEASE.id; } - if (opt.path) { - if (!fieldContentRegExp.test(opt.path)) { - throw new TypeError('option path is invalid'); - } + return ( + // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables + process.env.GITHUB_SHA || + // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata + process.env.COMMIT_REF || + // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables + process.env.VERCEL_GIT_COMMIT_SHA || + process.env.VERCEL_GITHUB_COMMIT_SHA || + process.env.VERCEL_GITLAB_COMMIT_SHA || + process.env.VERCEL_BITBUCKET_COMMIT_SHA || + // Zeit (now known as Vercel) + process.env.ZEIT_GITHUB_COMMIT_SHA || + process.env.ZEIT_GITLAB_COMMIT_SHA || + process.env.ZEIT_BITBUCKET_COMMIT_SHA || + // Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables + process.env.CF_PAGES_COMMIT_SHA || + fallback + ); +} - str += '; Path=' + opt.path; - } +/** Node.js stack parser */ +const defaultStackParser = utils.createStackParser(utils.nodeStackLineParser(module$1.createGetModuleFromFilename())); - if (opt.expires) { - if (typeof opt.expires.toUTCString !== 'function') { - throw new TypeError('option expires is invalid'); +/** + * Enable automatic Session Tracking for the node process. + */ +function startSessionTracking() { + core.startSession(); + // Emitted in the case of healthy sessions, error of `mechanism.handled: true` and unhandledrejections because + // The 'beforeExit' event is not emitted for conditions causing explicit termination, + // such as calling process.exit() or uncaught exceptions. + // Ref: https://nodejs.org/api/process.html#process_event_beforeexit + process.on('beforeExit', () => { + const session = core.getIsolationScope().getSession(); + const terminalStates = ['exited', 'crashed']; + // Only call endSession, if the Session exists on Scope and SessionStatus is not a + // Terminal Status i.e. Exited or Crashed because + // "When a session is moved away from ok it must not be updated anymore." + // Ref: https://develop.sentry.dev/sdk/sessions/ + if (session && !terminalStates.includes(session.status)) { + core.endSession(); } + }); +} - str += '; Expires=' + opt.expires.toUTCString(); +/** + * Update scope and propagation context based on environmental variables. + * + * See https://github.com/getsentry/rfcs/blob/main/text/0071-continue-trace-over-process-boundaries.md + * for more details. + */ +function updateScopeFromEnvVariables() { + const sentryUseEnvironment = (process.env.SENTRY_USE_ENVIRONMENT || '').toLowerCase(); + if (!['false', 'n', 'no', 'off', '0'].includes(sentryUseEnvironment)) { + const sentryTraceEnv = process.env.SENTRY_TRACE; + const baggageEnv = process.env.SENTRY_BAGGAGE; + const propagationContext = utils.propagationContextFromHeaders(sentryTraceEnv, baggageEnv); + core.getCurrentScope().setPropagationContext(propagationContext); } +} - if (opt.httpOnly) { - str += '; HttpOnly'; - } +exports.defaultIntegrations = defaultIntegrations; +exports.defaultStackParser = defaultStackParser; +exports.getDefaultIntegrations = getDefaultIntegrations; +exports.getSentryRelease = getSentryRelease; +exports.init = init; +exports.isAutoSessionTrackingEnabled = isAutoSessionTrackingEnabled; +//# sourceMappingURL=sdk.js.map - if (opt.secure) { - str += '; Secure'; - } - if (opt.sameSite) { - var sameSite = typeof opt.sameSite === 'string' - ? opt.sameSite.toLowerCase() : opt.sameSite; +/***/ }), - switch (sameSite) { - case true: - str += '; SameSite=Strict'; - break; - case 'lax': - str += '; SameSite=Lax'; - break; - case 'strict': - str += '; SameSite=Strict'; - break; - case 'none': - str += '; SameSite=None'; - break; - default: - throw new TypeError('option sameSite is invalid'); - } - } +/***/ 6963: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - return str; -} +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const tracing = __nccwpck_require__(69846); +const utils = __nccwpck_require__(57540); /** - * Try decoding a string using a decoding function. - * - * @param {string} str - * @param {function} decode - * @private + * Automatically detects and returns integrations that will work with your dependencies. */ +function autoDiscoverNodePerformanceMonitoringIntegrations() { + const loadedIntegrations = tracing.lazyLoadedNodePerformanceMonitoringIntegrations + .map(tryLoad => { + try { + return tryLoad(); + } catch (_) { + return undefined; + } + }) + .filter(integration => !!integration) ; -function tryDecode(str, decode) { - try { - return decode(str); - } catch (e) { - return str; + if (loadedIntegrations.length === 0) { + utils.logger.warn('Performance monitoring integrations could not be automatically loaded.'); } + + // Only return integrations where their dependencies loaded successfully. + return loadedIntegrations.filter(integration => !!integration.loadDependency()); } +exports.autoDiscoverNodePerformanceMonitoringIntegrations = autoDiscoverNodePerformanceMonitoringIntegrations; +//# sourceMappingURL=index.js.map + /***/ }), -/***/ 22975: -/***/ ((__unused_webpack_module, exports) => { +/***/ 42560: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; -/*! - * cookie - * Copyright(c) 2012-2014 Roman Shtylman - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +const tracing = __nccwpck_require__(69846); -/** - * Module exports. - * @public - */ -exports.parse = parse; -exports.serialize = serialize; +exports.Apollo = tracing.Apollo; +exports.Express = tracing.Express; +exports.GraphQL = tracing.GraphQL; +exports.Mongo = tracing.Mongo; +exports.Mysql = tracing.Mysql; +exports.Postgres = tracing.Postgres; +exports.Prisma = tracing.Prisma; +//# sourceMappingURL=integrations.js.map -/** - * Module variables. - * @private - */ -var __toString = Object.prototype.toString +/***/ }), -/** - * RegExp to match cookie-name in RFC 6265 sec 4.1.1 - * This refers out to the obsoleted definition of token in RFC 2616 sec 2.2 - * which has been replaced by the token definition in RFC 7230 appendix B. - * - * cookie-name = token - * token = 1*tchar - * tchar = "!" / "#" / "$" / "%" / "&" / "'" / - * "*" / "+" / "-" / "." / "^" / "_" / - * "`" / "|" / "~" / DIGIT / ALPHA - */ +/***/ 4121: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var cookieNameRegExp = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/; +var { + _nullishCoalesce +} = __nccwpck_require__(57540); + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const http = __nccwpck_require__(58611); +const https = __nccwpck_require__(65692); +const stream = __nccwpck_require__(2203); +const url = __nccwpck_require__(87016); +const zlib = __nccwpck_require__(43106); +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const index = __nccwpck_require__(75377); + +// Estimated maximum size for reasonable standalone event +const GZIP_THRESHOLD = 1024 * 32; /** - * RegExp to match cookie-value in RFC 6265 sec 4.1.1 - * - * cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) - * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E - * ; US-ASCII characters excluding CTLs, - * ; whitespace DQUOTE, comma, semicolon, - * ; and backslash + * Gets a stream from a Uint8Array or string + * Readable.from is ideal but was added in node.js v12.3.0 and v10.17.0 */ - -var cookieValueRegExp = /^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/; +function streamFromBody(body) { + return new stream.Readable({ + read() { + this.push(body); + this.push(null); + }, + }); +} /** - * RegExp to match domain-value in RFC 6265 sec 4.1.1 - * - * domain-value = - * ; defined in [RFC1034], Section 3.5, as - * ; enhanced by [RFC1123], Section 2.1 - * =
,
,.. + * where each
is of the form + * : : : : + * where + * is a delay in seconds + * is the event type(s) (error, transaction, etc) being rate limited and is of the form + * ;;... + * is what's being limited (org, project, or key) - ignored by SDK + * is an arbitrary string like "org_quota" - ignored by SDK + * Semicolon-separated list of metric namespace identifiers. Defines which namespace(s) will be affected. + * Only present if rate limit applies to the metric_bucket data category. + */ + for (const limit of rateLimitHeader.trim().split(',')) { + const [retryAfter, categories, , , namespaces] = limit.split(':', 5); + const headerDelay = parseInt(retryAfter, 10); + const delay = (!isNaN(headerDelay) ? headerDelay : 60) * 1000; // 60sec default + if (!categories) { + updatedRateLimits.all = now + delay; + } else { + for (const category of categories.split(';')) { + if (category === 'metric_bucket') { + // namespaces will be present when category === 'metric_bucket' + if (!namespaces || namespaces.split(';').includes('custom')) { + updatedRateLimits[category] = now + delay; + } + } else { + updatedRateLimits[category] = now + delay; + } + } + } + } + } else if (retryAfterHeader) { + updatedRateLimits.all = now + parseRetryAfterHeader(retryAfterHeader, now); + } else if (statusCode === 429) { + updatedRateLimits.all = now + 60 * 1000; + } - if (inputLength - offset < seqLength) { - throw new Error('"seq" specified length of "' + seqLength + '", only "' + (inputLength - offset) + '" remaining'); - } + return updatedRateLimits; +} - if (signature[offset++] !== ENCODED_TAG_INT) { - throw new Error('Could not find expected "int" for "r"'); - } +exports.DEFAULT_RETRY_AFTER = DEFAULT_RETRY_AFTER; +exports.disabledUntil = disabledUntil; +exports.isRateLimited = isRateLimited; +exports.parseRetryAfterHeader = parseRetryAfterHeader; +exports.updateRateLimits = updateRateLimits; +//# sourceMappingURL=ratelimit.js.map - var rLength = signature[offset++]; - if (inputLength - offset - 2 < rLength) { - throw new Error('"r" specified length of "' + rLength + '", only "' + (inputLength - offset - 2) + '" available'); - } +/***/ }), - if (maxEncodedParamLength < rLength) { - throw new Error('"r" specified length of "' + rLength + '", max of "' + maxEncodedParamLength + '" is acceptable'); - } +/***/ 31289: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var rOffset = offset; - offset += rLength; +Object.defineProperty(exports, "__esModule", ({ value: true })); - if (signature[offset++] !== ENCODED_TAG_INT) { - throw new Error('Could not find expected "int" for "s"'); - } +const cookie = __nccwpck_require__(93344); +const debugBuild = __nccwpck_require__(4426); +const is = __nccwpck_require__(19082); +const logger = __nccwpck_require__(95226); +const normalize = __nccwpck_require__(27815); +const url = __nccwpck_require__(21933); + +const DEFAULT_INCLUDES = { + ip: false, + request: true, + transaction: true, + user: true, +}; +const DEFAULT_REQUEST_INCLUDES = ['cookies', 'data', 'headers', 'method', 'query_string', 'url']; +const DEFAULT_USER_INCLUDES = ['id', 'username', 'email']; - var sLength = signature[offset++]; +/** + * Sets parameterized route as transaction name e.g.: `GET /users/:id` + * Also adds more context data on the transaction from the request. + * + * @deprecated This utility will be removed in v8. + */ +function addRequestDataToTransaction( + transaction, + req, + deps, +) { + if (!transaction) return; + // eslint-disable-next-line deprecation/deprecation + if (!transaction.metadata.source || transaction.metadata.source === 'url') { + // Attempt to grab a parameterized route off of the request + const [name, source] = extractPathForTransaction(req, { path: true, method: true }); + transaction.updateName(name); + // TODO: SEMANTIC_ATTRIBUTE_SENTRY_SOURCE is in core, align this once we merge utils & core + // eslint-disable-next-line deprecation/deprecation + transaction.setMetadata({ source }); + } + transaction.setAttribute('url', req.originalUrl || req.url); + if (req.baseUrl) { + transaction.setAttribute('baseUrl', req.baseUrl); + } + // TODO: We need to rewrite this to a flat format? + // eslint-disable-next-line deprecation/deprecation + transaction.setData('query', extractQueryParams(req, deps)); +} - if (inputLength - offset !== sLength) { - throw new Error('"s" specified length of "' + sLength + '", expected "' + (inputLength - offset) + '"'); - } +/** + * Extracts a complete and parameterized path from the request object and uses it to construct transaction name. + * If the parameterized transaction name cannot be extracted, we fall back to the raw URL. + * + * Additionally, this function determines and returns the transaction name source + * + * eg. GET /mountpoint/user/:id + * + * @param req A request object + * @param options What to include in the transaction name (method, path, or a custom route name to be + * used instead of the request's route) + * + * @returns A tuple of the fully constructed transaction name [0] and its source [1] (can be either 'route' or 'url') + */ +function extractPathForTransaction( + req, + options = {}, +) { + const method = req.method && req.method.toUpperCase(); - if (maxEncodedParamLength < sLength) { - throw new Error('"s" specified length of "' + sLength + '", max of "' + maxEncodedParamLength + '" is acceptable'); - } + let path = ''; + let source = 'url'; - var sOffset = offset; - offset += sLength; + // Check to see if there's a parameterized route we can use (as there is in Express) + if (options.customRoute || req.route) { + path = options.customRoute || `${req.baseUrl || ''}${req.route && req.route.path}`; + source = 'route'; + } - if (offset !== inputLength) { - throw new Error('Expected to consume entire buffer, but "' + (inputLength - offset) + '" bytes remain'); - } + // Otherwise, just take the original URL + else if (req.originalUrl || req.url) { + path = url.stripUrlQueryAndFragment(req.originalUrl || req.url || ''); + } - var rPadding = paramBytes - rLength, - sPadding = paramBytes - sLength; + let name = ''; + if (options.method && method) { + name += method; + } + if (options.method && options.path) { + name += ' '; + } + if (options.path && path) { + name += path; + } - var dst = Buffer.allocUnsafe(rPadding + rLength + sPadding + sLength); + return [name, source]; +} - for (offset = 0; offset < rPadding; ++offset) { - dst[offset] = 0; - } - signature.copy(dst, offset, rOffset + Math.max(-rPadding, 0), rOffset + rLength); +/** JSDoc */ +function extractTransaction(req, type) { + switch (type) { + case 'path': { + return extractPathForTransaction(req, { path: true })[0]; + } + case 'handler': { + return (req.route && req.route.stack && req.route.stack[0] && req.route.stack[0].name) || ''; + } + case 'methodPath': + default: { + // if exist _reconstructedRoute return that path instead of route.path + const customRoute = req._reconstructedRoute ? req._reconstructedRoute : undefined; + return extractPathForTransaction(req, { path: true, method: true, customRoute })[0]; + } + } +} - offset = paramBytes; +/** JSDoc */ +function extractUserData( + user - for (var o = offset; offset < o + sPadding; ++offset) { - dst[offset] = 0; - } - signature.copy(dst, offset, sOffset + Math.max(-sPadding, 0), sOffset + sLength); +, + keys, +) { + const extractedUser = {}; + const attributes = Array.isArray(keys) ? keys : DEFAULT_USER_INCLUDES; - dst = dst.toString('base64'); - dst = base64Url(dst); + attributes.forEach(key => { + if (user && key in user) { + extractedUser[key] = user[key]; + } + }); - return dst; + return extractedUser; } -function countPadding(buf, start, stop) { - var padding = 0; - while (start + padding < stop && buf[start + padding] === 0) { - ++padding; - } +/** + * Normalize data from the request object, accounting for framework differences. + * + * @param req The request object from which to extract data + * @param options.include An optional array of keys to include in the normalized data. Defaults to + * DEFAULT_REQUEST_INCLUDES if not provided. + * @param options.deps Injected, platform-specific dependencies + * @returns An object containing normalized request data + */ +function extractRequestData( + req, + options - var needsSign = buf[start + padding] >= MAX_OCTET; - if (needsSign) { - --padding; - } +, +) { + const { include = DEFAULT_REQUEST_INCLUDES, deps } = options || {}; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const requestData = {}; + + // headers: + // node, express, koa, nextjs: req.headers + const headers = (req.headers || {}) + +; + // method: + // node, express, koa, nextjs: req.method + const method = req.method; + // host: + // express: req.hostname in > 4 and req.host in < 4 + // koa: req.host + // node, nextjs: req.headers.host + // Express 4 mistakenly strips off port number from req.host / req.hostname so we can't rely on them + // See: https://github.com/expressjs/express/issues/3047#issuecomment-236653223 + // Also: https://github.com/getsentry/sentry-javascript/issues/1917 + const host = headers.host || req.hostname || req.host || ''; + // protocol: + // node, nextjs: + // express, koa: req.protocol + const protocol = req.protocol === 'https' || (req.socket && req.socket.encrypted) ? 'https' : 'http'; + // url (including path and query string): + // node, express: req.originalUrl + // koa, nextjs: req.url + const originalUrl = req.originalUrl || req.url || ''; + // absolute url + const absoluteUrl = originalUrl.startsWith(protocol) ? originalUrl : `${protocol}://${host}${originalUrl}`; + include.forEach(key => { + switch (key) { + case 'headers': { + requestData.headers = headers; + + // Remove the Cookie header in case cookie data should not be included in the event + if (!include.includes('cookies')) { + delete (requestData.headers ).cookie; + } - return padding; + break; + } + case 'method': { + requestData.method = method; + break; + } + case 'url': { + requestData.url = absoluteUrl; + break; + } + case 'cookies': { + // cookies: + // node, express, koa: req.headers.cookie + // vercel, sails.js, express (w/ cookie middleware), nextjs: req.cookies + requestData.cookies = + // TODO (v8 / #5257): We're only sending the empty object for backwards compatibility, so the last bit can + // come off in v8 + req.cookies || (headers.cookie && cookie.parseCookie(headers.cookie)) || {}; + break; + } + case 'query_string': { + // query string: + // node: req.url (raw) + // express, koa, nextjs: req.query + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + requestData.query_string = extractQueryParams(req, deps); + break; + } + case 'data': { + if (method === 'GET' || method === 'HEAD') { + break; + } + // body data: + // express, koa, nextjs: req.body + // + // when using node by itself, you have to read the incoming stream(see + // https://nodejs.dev/learn/get-http-request-body-data-using-nodejs); if a user is doing that, we can't know + // where they're going to store the final result, so they'll have to capture this data themselves + if (req.body !== undefined) { + requestData.data = is.isString(req.body) ? req.body : JSON.stringify(normalize.normalize(req.body)); + } + break; + } + default: { + if ({}.hasOwnProperty.call(req, key)) { + requestData[key] = (req )[key]; + } + } + } + }); + + return requestData; } -function joseToDer(signature, alg) { - signature = signatureAsBuffer(signature); - var paramBytes = getParamBytesForAlg(alg); +/** + * Add data from the given request to the given event + * + * @param event The event to which the request data will be added + * @param req Request object + * @param options.include Flags to control what data is included + * @param options.deps Injected platform-specific dependencies + * @returns The mutated `Event` object + */ +function addRequestDataToEvent( + event, + req, + options, +) { + const include = { + ...DEFAULT_INCLUDES, + ...(options && options.include), + }; - var signatureBytes = signature.length; - if (signatureBytes !== paramBytes * 2) { - throw new TypeError('"' + alg + '" signatures must be "' + paramBytes * 2 + '" bytes, saw "' + signatureBytes + '"'); - } + if (include.request) { + const extractedRequestData = Array.isArray(include.request) + ? extractRequestData(req, { include: include.request, deps: options && options.deps }) + : extractRequestData(req, { deps: options && options.deps }); - var rPadding = countPadding(signature, 0, paramBytes); - var sPadding = countPadding(signature, paramBytes, signature.length); - var rLength = paramBytes - rPadding; - var sLength = paramBytes - sPadding; + event.request = { + ...event.request, + ...extractedRequestData, + }; + } - var rsBytes = 1 + 1 + rLength + 1 + 1 + sLength; + if (include.user) { + const extractedUser = req.user && is.isPlainObject(req.user) ? extractUserData(req.user, include.user) : {}; - var shortLength = rsBytes < MAX_OCTET; + if (Object.keys(extractedUser).length) { + event.user = { + ...event.user, + ...extractedUser, + }; + } + } - var dst = Buffer.allocUnsafe((shortLength ? 2 : 3) + rsBytes); + // client ip: + // node, nextjs: req.socket.remoteAddress + // express, koa: req.ip + if (include.ip) { + const ip = req.ip || (req.socket && req.socket.remoteAddress); + if (ip) { + event.user = { + ...event.user, + ip_address: ip, + }; + } + } - var offset = 0; - dst[offset++] = ENCODED_TAG_SEQ; - if (shortLength) { - // Bit 8 has value "0" - // bits 7-1 give the length. - dst[offset++] = rsBytes; - } else { - // Bit 8 of first octet has value "1" - // bits 7-1 give the number of additional length octets. - dst[offset++] = MAX_OCTET | 1; - // length, base 256 - dst[offset++] = rsBytes & 0xff; - } - dst[offset++] = ENCODED_TAG_INT; - dst[offset++] = rLength; - if (rPadding < 0) { - dst[offset++] = 0; - offset += signature.copy(dst, offset, 0, paramBytes); - } else { - offset += signature.copy(dst, offset, rPadding, paramBytes); - } - dst[offset++] = ENCODED_TAG_INT; - dst[offset++] = sLength; - if (sPadding < 0) { - dst[offset++] = 0; - signature.copy(dst, offset, paramBytes); - } else { - signature.copy(dst, offset, paramBytes + sPadding); - } + if (include.transaction && !event.transaction) { + // TODO do we even need this anymore? + // TODO make this work for nextjs + event.transaction = extractTransaction(req, include.transaction); + } - return dst; + return event; } -module.exports = { - derToJose: derToJose, - joseToDer: joseToDer -}; - - -/***/ }), - -/***/ 49333: -/***/ ((module) => { +function extractQueryParams( + req, + deps, +) { + // url (including path and query string): + // node, express: req.originalUrl + // koa, nextjs: req.url + let originalUrl = req.originalUrl || req.url || ''; -"use strict"; + if (!originalUrl) { + return; + } + // The `URL` constructor can't handle internal URLs of the form `/some/path/here`, so stick a dummy protocol and + // hostname on the beginning. Since the point here is just to grab the query string, it doesn't matter what we use. + if (originalUrl.startsWith('/')) { + originalUrl = `http://dogs.are.great${originalUrl}`; + } -function getParamSize(keySize) { - var result = ((keySize / 8) | 0) + (keySize % 8 === 0 ? 0 : 1); - return result; + try { + return ( + req.query || + (typeof URL !== 'undefined' && new URL(originalUrl).search.slice(1)) || + // In Node 8, `URL` isn't in the global scope, so we have to use the built-in module from Node + (deps && deps.url && deps.url.parse(originalUrl).query) || + undefined + ); + } catch (e2) { + return undefined; + } } -var paramBytesForAlg = { - ES256: getParamSize(256), - ES384: getParamSize(384), - ES512: getParamSize(521) -}; +/** + * Transforms a `Headers` object that implements the `Web Fetch API` (https://developer.mozilla.org/en-US/docs/Web/API/Headers) into a simple key-value dict. + * The header keys will be lower case: e.g. A "Content-Type" header will be stored as "content-type". + */ +// TODO(v8): Make this function return undefined when the extraction fails. +function winterCGHeadersToDict(winterCGHeaders) { + const headers = {}; + try { + winterCGHeaders.forEach((value, key) => { + if (typeof value === 'string') { + // We check that value is a string even though it might be redundant to make sure prototype pollution is not possible. + headers[key] = value; + } + }); + } catch (e) { + debugBuild.DEBUG_BUILD && + logger.logger.warn('Sentry failed extracting headers from a request object. If you see this, please file an issue.'); + } -function getParamBytesForAlg(alg) { - var paramBytes = paramBytesForAlg[alg]; - if (paramBytes) { - return paramBytes; - } + return headers; +} - throw new Error('Unknown algorithm "' + alg + '"'); +/** + * Converts a `Request` object that implements the `Web Fetch API` (https://developer.mozilla.org/en-US/docs/Web/API/Headers) into the format that the `RequestData` integration understands. + */ +function winterCGRequestToRequestData(req) { + const headers = winterCGHeadersToDict(req.headers); + return { + method: req.method, + url: req.url, + headers, + }; } -module.exports = getParamBytesForAlg; +exports.DEFAULT_USER_INCLUDES = DEFAULT_USER_INCLUDES; +exports.addRequestDataToEvent = addRequestDataToEvent; +exports.addRequestDataToTransaction = addRequestDataToTransaction; +exports.extractPathForTransaction = extractPathForTransaction; +exports.extractRequestData = extractRequestData; +exports.winterCGHeadersToDict = winterCGHeadersToDict; +exports.winterCGRequestToRequestData = winterCGRequestToRequestData; +//# sourceMappingURL=requestdata.js.map /***/ }), -/***/ 81906: -/***/ ((module) => { +/***/ 22553: +/***/ ((__unused_webpack_module, exports) => { -"use strict"; -/*! - * ee-first - * Copyright(c) 2014 Jonathan Ong - * MIT Licensed - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +// Note: Ideally the `SeverityLevel` type would be derived from `validSeverityLevels`, but that would mean either +// +// a) moving `validSeverityLevels` to `@sentry/types`, +// b) moving the`SeverityLevel` type here, or +// c) importing `validSeverityLevels` from here into `@sentry/types`. +// +// Option A would make `@sentry/types` a runtime dependency of `@sentry/utils` (not good), and options B and C would +// create a circular dependency between `@sentry/types` and `@sentry/utils` (also not good). So a TODO accompanying the +// type, reminding anyone who changes it to change this list also, will have to do. +const validSeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug']; /** - * Module exports. - * @public + * Converts a string-based level into a member of the deprecated {@link Severity} enum. + * + * @deprecated `severityFromString` is deprecated. Please use `severityLevelFromString` instead. + * + * @param level String representation of Severity + * @returns Severity */ - -module.exports = first +function severityFromString(level) { + return severityLevelFromString(level) ; +} /** - * Get the first event in a set of event emitters and event pairs. + * Converts a string-based level into a `SeverityLevel`, normalizing it along the way. * - * @param {array} stuff - * @param {function} done - * @public + * @param level String representation of desired `SeverityLevel`. + * @returns The `SeverityLevel` corresponding to the given string, or 'log' if the string isn't a valid level. */ +function severityLevelFromString(level) { + return (level === 'warn' ? 'warning' : validSeverityLevels.includes(level) ? level : 'log') ; +} -function first(stuff, done) { - if (!Array.isArray(stuff)) - throw new TypeError('arg must be an array of [ee, events...] arrays') +exports.severityFromString = severityFromString; +exports.severityLevelFromString = severityLevelFromString; +exports.validSeverityLevels = validSeverityLevels; +//# sourceMappingURL=severity.js.map - var cleanups = [] - for (var i = 0; i < stuff.length; i++) { - var arr = stuff[i] +/***/ }), - if (!Array.isArray(arr) || arr.length < 2) - throw new TypeError('each array member must be [ee, events...]') +/***/ 62935: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var ee = arr[0] +Object.defineProperty(exports, "__esModule", ({ value: true })); - for (var j = 1; j < arr.length; j++) { - var event = arr[j] - var fn = listener(event, callback) +const nodeStackTrace = __nccwpck_require__(49607); - // listen to the event - ee.on(event, fn) - // push this listener to the list of cleanups - cleanups.push({ - ee: ee, - event: event, - fn: fn, - }) - } - } +const STACKTRACE_FRAME_LIMIT = 50; +// Used to sanitize webpack (error: *) wrapped stack errors +const WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/; +const STRIP_FRAME_REGEXP = /captureMessage|captureException/; - function callback() { - cleanup() - done.apply(null, arguments) - } +/** + * Creates a stack parser with the supplied line parsers + * + * StackFrames are returned in the correct order for Sentry Exception + * frames and with Sentry SDK internal frames removed from the top and bottom + * + */ +function createStackParser(...parsers) { + const sortedParsers = parsers.sort((a, b) => a[0] - b[0]).map(p => p[1]); - function cleanup() { - var x - for (var i = 0; i < cleanups.length; i++) { - x = cleanups[i] - x.ee.removeListener(x.event, x.fn) - } - } + return (stack, skipFirst = 0) => { + const frames = []; + const lines = stack.split('\n'); - function thunk(fn) { - done = fn - } + for (let i = skipFirst; i < lines.length; i++) { + const line = lines[i]; + // Ignore lines over 1kb as they are unlikely to be stack frames. + // Many of the regular expressions use backtracking which results in run time that increases exponentially with + // input size. Huge strings can result in hangs/Denial of Service: + // https://github.com/getsentry/sentry-javascript/issues/2286 + if (line.length > 1024) { + continue; + } - thunk.cancel = cleanup + // https://github.com/getsentry/sentry-javascript/issues/5459 + // Remove webpack (error: *) wrappers + const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line; - return thunk -} + // https://github.com/getsentry/sentry-javascript/issues/7813 + // Skip Error: lines + if (cleanedLine.match(/\S*Error: /)) { + continue; + } -/** - * Create the event listener. - * @private - */ + for (const parser of sortedParsers) { + const frame = parser(cleanedLine); -function listener(event, done) { - return function onevent(arg1) { - var args = new Array(arguments.length) - var ee = this - var err = event === 'error' - ? arg1 - : null + if (frame) { + frames.push(frame); + break; + } + } - // copy args to prevent arguments escaping scope - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] + if (frames.length >= STACKTRACE_FRAME_LIMIT) { + break; + } } - done(err, ee, event, args) + return stripSentryFramesAndReverse(frames); + }; +} + +/** + * Gets a stack parser implementation from Options.stackParser + * @see Options + * + * If options contains an array of line parsers, it is converted into a parser + */ +function stackParserFromStackParserOptions(stackParser) { + if (Array.isArray(stackParser)) { + return createStackParser(...stackParser); } + return stackParser; } +/** + * Removes Sentry frames from the top and bottom of the stack if present and enforces a limit of max number of frames. + * Assumes stack input is ordered from top to bottom and returns the reverse representation so call site of the + * function that caused the crash is the last frame in the array. + * @hidden + */ +function stripSentryFramesAndReverse(stack) { + if (!stack.length) { + return []; + } -/***/ }), + const localStack = Array.from(stack); -/***/ 43344: -/***/ ((module) => { + // If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call) + if (/sentryWrapped/.test(localStack[localStack.length - 1].function || '')) { + localStack.pop(); + } -"use strict"; -/*! - * encodeurl - * Copyright(c) 2016 Douglas Christopher Wilson - * MIT Licensed - */ + // Reversing in the middle of the procedure allows us to just pop the values off the stack + localStack.reverse(); + // If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call) + if (STRIP_FRAME_REGEXP.test(localStack[localStack.length - 1].function || '')) { + localStack.pop(); + // When using synthetic events, we will have a 2 levels deep stack, as `new Error('Sentry syntheticException')` + // is produced within the hub itself, making it: + // + // Sentry.captureException() + // getCurrentHub().captureException() + // + // instead of just the top `Sentry` call itself. + // This forces us to possibly strip an additional frame in the exact same was as above. + if (STRIP_FRAME_REGEXP.test(localStack[localStack.length - 1].function || '')) { + localStack.pop(); + } + } -/** - * Module exports. - * @public - */ + return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map(frame => ({ + ...frame, + filename: frame.filename || localStack[localStack.length - 1].filename, + function: frame.function || '?', + })); +} -module.exports = encodeUrl +const defaultFunctionName = ''; /** - * RegExp to match non-URL code points, *after* encoding (i.e. not including "%") - * and including invalid escape sequences. - * @private + * Safely extract function name from itself */ - -var ENCODE_CHARS_REGEXP = /(?:[^\x21\x25\x26-\x3B\x3D\x3F-\x5B\x5D\x5F\x61-\x7A\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]|$))+/g +function getFunctionName(fn) { + try { + if (!fn || typeof fn !== 'function') { + return defaultFunctionName; + } + return fn.name || defaultFunctionName; + } catch (e) { + // Just accessing custom props in some Selenium environments + // can cause a "Permission denied" exception (see raven-js#495). + return defaultFunctionName; + } +} /** - * RegExp to match unmatched surrogate pair. - * @private + * Node.js stack line parser + * + * This is in @sentry/utils so it can be used from the Electron SDK in the browser for when `nodeIntegration == true`. + * This allows it to be used without referencing or importing any node specific code which causes bundlers to complain */ +function nodeStackLineParser(getModule) { + return [90, nodeStackTrace.node(getModule)]; +} -var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g +exports.filenameIsInApp = nodeStackTrace.filenameIsInApp; +exports.createStackParser = createStackParser; +exports.getFunctionName = getFunctionName; +exports.nodeStackLineParser = nodeStackLineParser; +exports.stackParserFromStackParserOptions = stackParserFromStackParserOptions; +exports.stripSentryFramesAndReverse = stripSentryFramesAndReverse; +//# sourceMappingURL=stacktrace.js.map -/** - * String to replace unmatched surrogate pair with. - * @private - */ -var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2' +/***/ }), + +/***/ 18251: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const is = __nccwpck_require__(19082); /** - * Encode a URL to a percent-encoded form, excluding already-encoded sequences. - * - * This function will take an already-encoded URL and encode all the non-URL - * code points. This function will not encode the "%" character unless it is - * not part of a valid sequence (`%20` will be left as-is, but `%foo` will - * be encoded as `%25foo`). + * Truncates given string to the maximum characters count * - * This encode is meant to be "safe" and does not throw errors. It will try as - * hard as it can to properly encode the given URL, including replacing any raw, - * unpaired surrogate pairs with the Unicode replacement character prior to - * encoding. + * @param str An object that contains serializable values + * @param max Maximum number of characters in truncated string (0 = unlimited) + * @returns string Encoded + */ +function truncate(str, max = 0) { + if (typeof str !== 'string' || max === 0) { + return str; + } + return str.length <= max ? str : `${str.slice(0, max)}...`; +} + +/** + * This is basically just `trim_line` from + * https://github.com/getsentry/sentry/blob/master/src/sentry/lang/javascript/processor.py#L67 * - * @param {string} url - * @return {string} - * @public + * @param str An object that contains serializable values + * @param max Maximum number of characters in truncated string + * @returns string Encoded */ +function snipLine(line, colno) { + let newLine = line; + const lineLength = newLine.length; + if (lineLength <= 150) { + return newLine; + } + if (colno > lineLength) { + // eslint-disable-next-line no-param-reassign + colno = lineLength; + } -function encodeUrl (url) { - return String(url) - .replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE) - .replace(ENCODE_CHARS_REGEXP, encodeURI) -} + let start = Math.max(colno - 60, 0); + if (start < 5) { + start = 0; + } + let end = Math.min(start + 140, lineLength); + if (end > lineLength - 5) { + end = lineLength; + } + if (end === lineLength) { + start = Math.max(end - 140, 0); + } -/***/ }), + newLine = newLine.slice(start, end); + if (start > 0) { + newLine = `'{snip} ${newLine}`; + } + if (end < lineLength) { + newLine += ' {snip}'; + } -/***/ 31449: -/***/ ((module) => { + return newLine; +} -"use strict"; -/*! - * encodeurl - * Copyright(c) 2016 Douglas Christopher Wilson - * MIT Licensed +/** + * Join values in array + * @param input array of values to be joined together + * @param delimiter string to be placed in-between values + * @returns Joined values */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function safeJoin(input, delimiter) { + if (!Array.isArray(input)) { + return ''; + } + const output = []; + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < input.length; i++) { + const value = input[i]; + try { + // This is a hack to fix a Vue3-specific bug that causes an infinite loop of + // console warnings. This happens when a Vue template is rendered with + // an undeclared variable, which we try to stringify, ultimately causing + // Vue to issue another warning which repeats indefinitely. + // see: https://github.com/getsentry/sentry-javascript/pull/8981 + if (is.isVueViewModel(value)) { + output.push('[VueViewModel]'); + } else { + output.push(String(value)); + } + } catch (e) { + output.push('[value cannot be serialized]'); + } + } + return output.join(delimiter); +} /** - * Module exports. - * @public + * Checks if the given value matches a regex or string + * + * @param value The string to test + * @param pattern Either a regex or a string against which `value` will be matched + * @param requireExactStringMatch If true, `value` must match `pattern` exactly. If false, `value` will match + * `pattern` if it contains `pattern`. Only applies to string-type patterns. */ +function isMatchingPattern( + value, + pattern, + requireExactStringMatch = false, +) { + if (!is.isString(value)) { + return false; + } -module.exports = encodeUrl + if (is.isRegExp(pattern)) { + return pattern.test(value); + } + if (is.isString(pattern)) { + return requireExactStringMatch ? value === pattern : value.includes(pattern); + } + + return false; +} /** - * RegExp to match non-URL code points, *after* encoding (i.e. not including "%") - * and including invalid escape sequences. - * @private + * Test the given string against an array of strings and regexes. By default, string matching is done on a + * substring-inclusion basis rather than a strict equality basis + * + * @param testString The string to test + * @param patterns The patterns against which to test the string + * @param requireExactStringMatch If true, `testString` must match one of the given string patterns exactly in order to + * count. If false, `testString` will match a string pattern if it contains that pattern. + * @returns */ +function stringMatchesSomePattern( + testString, + patterns = [], + requireExactStringMatch = false, +) { + return patterns.some(pattern => isMatchingPattern(testString, pattern, requireExactStringMatch)); +} -var ENCODE_CHARS_REGEXP = /(?:[^\x21\x23-\x3B\x3D\x3F-\x5F\x61-\x7A\x7C\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]|$))+/g +exports.isMatchingPattern = isMatchingPattern; +exports.safeJoin = safeJoin; +exports.snipLine = snipLine; +exports.stringMatchesSomePattern = stringMatchesSomePattern; +exports.truncate = truncate; +//# sourceMappingURL=string.js.map -/** - * RegExp to match unmatched surrogate pair. - * @private - */ -var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g +/***/ }), -/** - * String to replace unmatched surrogate pair with. - * @private - */ +/***/ 98958: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2' +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const debugBuild = __nccwpck_require__(4426); +const logger = __nccwpck_require__(95226); +const worldwide = __nccwpck_require__(48567); + +// eslint-disable-next-line deprecation/deprecation +const WINDOW = worldwide.getGlobalObject(); /** - * Encode a URL to a percent-encoded form, excluding already-encoded sequences. - * - * This function will take an already-encoded URL and encode all the non-URL - * code points. This function will not encode the "%" character unless it is - * not part of a valid sequence (`%20` will be left as-is, but `%foo` will - * be encoded as `%25foo`). - * - * This encode is meant to be "safe" and does not throw errors. It will try as - * hard as it can to properly encode the given URL, including replacing any raw, - * unpaired surrogate pairs with the Unicode replacement character prior to - * encoding. + * Tells whether current environment supports ErrorEvent objects + * {@link supportsErrorEvent}. * - * @param {string} url - * @return {string} - * @public + * @returns Answer to the given question. */ +function supportsErrorEvent() { + try { + new ErrorEvent(''); + return true; + } catch (e) { + return false; + } +} -function encodeUrl (url) { - return String(url) - .replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE) - .replace(ENCODE_CHARS_REGEXP, encodeURI) +/** + * Tells whether current environment supports DOMError objects + * {@link supportsDOMError}. + * + * @returns Answer to the given question. + */ +function supportsDOMError() { + try { + // Chrome: VM89:1 Uncaught TypeError: Failed to construct 'DOMError': + // 1 argument required, but only 0 present. + // @ts-expect-error It really needs 1 argument, not 0. + new DOMError(''); + return true; + } catch (e) { + return false; + } } +/** + * Tells whether current environment supports DOMException objects + * {@link supportsDOMException}. + * + * @returns Answer to the given question. + */ +function supportsDOMException() { + try { + new DOMException(''); + return true; + } catch (e) { + return false; + } +} -/***/ }), +/** + * Tells whether current environment supports Fetch API + * {@link supportsFetch}. + * + * @returns Answer to the given question. + */ +function supportsFetch() { + if (!('fetch' in WINDOW)) { + return false; + } -/***/ 61061: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + try { + new Headers(); + new Request('http://www.example.com'); + new Response(); + return true; + } catch (e) { + return false; + } +} +/** + * isNativeFetch checks if the given function is a native implementation of fetch() + */ +// eslint-disable-next-line @typescript-eslint/ban-types +function isNativeFetch(func) { + return func && /^function fetch\(\)\s+\{\s+\[native code\]\s+\}$/.test(func.toString()); +} -"use strict"; +/** + * Tells whether current environment supports Fetch API natively + * {@link supportsNativeFetch}. + * + * @returns true if `window.fetch` is natively implemented, false otherwise + */ +function supportsNativeFetch() { + if (typeof EdgeRuntime === 'string') { + return true; + } + if (!supportsFetch()) { + return false; + } -var util = __nccwpck_require__(39023); -var isArrayish = __nccwpck_require__(9602); + // Fast path to avoid DOM I/O + // eslint-disable-next-line @typescript-eslint/unbound-method + if (isNativeFetch(WINDOW.fetch)) { + return true; + } -var errorEx = function errorEx(name, properties) { - if (!name || name.constructor !== String) { - properties = name || {}; - name = Error.name; - } + // window.fetch is implemented, but is polyfilled or already wrapped (e.g: by a chrome extension) + // so create a "pure" iframe to see if that has native fetch + let result = false; + const doc = WINDOW.document; + // eslint-disable-next-line deprecation/deprecation + if (doc && typeof (doc.createElement ) === 'function') { + try { + const sandbox = doc.createElement('iframe'); + sandbox.hidden = true; + doc.head.appendChild(sandbox); + if (sandbox.contentWindow && sandbox.contentWindow.fetch) { + // eslint-disable-next-line @typescript-eslint/unbound-method + result = isNativeFetch(sandbox.contentWindow.fetch); + } + doc.head.removeChild(sandbox); + } catch (err) { + debugBuild.DEBUG_BUILD && + logger.logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err); + } + } - var errorExError = function ErrorEXError(message) { - if (!this) { - return new ErrorEXError(message); - } + return result; +} - message = message instanceof Error - ? message.message - : (message || this.message); +/** + * Tells whether current environment supports ReportingObserver API + * {@link supportsReportingObserver}. + * + * @returns Answer to the given question. + */ +function supportsReportingObserver() { + return 'ReportingObserver' in WINDOW; +} - Error.call(this, message); - Error.captureStackTrace(this, errorExError); +/** + * Tells whether current environment supports Referrer Policy API + * {@link supportsReferrerPolicy}. + * + * @returns Answer to the given question. + */ +function supportsReferrerPolicy() { + // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default' + // (see https://caniuse.com/#feat=referrer-policy), + // it doesn't. And it throws an exception instead of ignoring this parameter... + // REF: https://github.com/getsentry/raven-js/issues/1233 - this.name = name; + if (!supportsFetch()) { + return false; + } - Object.defineProperty(this, 'message', { - configurable: true, - enumerable: false, - get: function () { - var newMessage = message.split(/\r?\n/g); + try { + new Request('_', { + referrerPolicy: 'origin' , + }); + return true; + } catch (e) { + return false; + } +} - for (var key in properties) { - if (!properties.hasOwnProperty(key)) { - continue; - } +exports.isNativeFetch = isNativeFetch; +exports.supportsDOMError = supportsDOMError; +exports.supportsDOMException = supportsDOMException; +exports.supportsErrorEvent = supportsErrorEvent; +exports.supportsFetch = supportsFetch; +exports.supportsNativeFetch = supportsNativeFetch; +exports.supportsReferrerPolicy = supportsReferrerPolicy; +exports.supportsReportingObserver = supportsReportingObserver; +//# sourceMappingURL=supports.js.map - var modifier = properties[key]; - if ('message' in modifier) { - newMessage = modifier.message(this[key], newMessage) || newMessage; - if (!isArrayish(newMessage)) { - newMessage = [newMessage]; - } - } - } +/***/ }), - return newMessage.join('\n'); - }, - set: function (v) { - message = v; - } - }); +/***/ 51124: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var overwrittenStack = null; +Object.defineProperty(exports, "__esModule", ({ value: true })); - var stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack'); - var stackGetter = stackDescriptor.get; - var stackValue = stackDescriptor.value; - delete stackDescriptor.value; - delete stackDescriptor.writable; +const is = __nccwpck_require__(19082); - stackDescriptor.set = function (newstack) { - overwrittenStack = newstack; - }; +/* eslint-disable @typescript-eslint/explicit-function-return-type */ - stackDescriptor.get = function () { - var stack = (overwrittenStack || ((stackGetter) - ? stackGetter.call(this) - : stackValue)).split(/\r?\n+/g); +/** SyncPromise internal states */ +var States; (function (States) { + /** Pending */ + const PENDING = 0; States[States["PENDING"] = PENDING] = "PENDING"; + /** Resolved / OK */ + const RESOLVED = 1; States[States["RESOLVED"] = RESOLVED] = "RESOLVED"; + /** Rejected / Error */ + const REJECTED = 2; States[States["REJECTED"] = REJECTED] = "REJECTED"; +})(States || (States = {})); - // starting in Node 7, the stack builder caches the message. - // just replace it. - if (!overwrittenStack) { - stack[0] = this.name + ': ' + this.message; - } +// Overloads so we can call resolvedSyncPromise without arguments and generic argument - var lineCount = 1; - for (var key in properties) { - if (!properties.hasOwnProperty(key)) { - continue; - } +/** + * Creates a resolved sync promise. + * + * @param value the value to resolve the promise with + * @returns the resolved sync promise + */ +function resolvedSyncPromise(value) { + return new SyncPromise(resolve => { + resolve(value); + }); +} - var modifier = properties[key]; +/** + * Creates a rejected sync promise. + * + * @param value the value to reject the promise with + * @returns the rejected sync promise + */ +function rejectedSyncPromise(reason) { + return new SyncPromise((_, reject) => { + reject(reason); + }); +} - if ('line' in modifier) { - var line = modifier.line(this[key]); - if (line) { - stack.splice(lineCount++, 0, ' ' + line); - } - } +/** + * Thenable class that behaves like a Promise and follows it's interface + * but is not async internally + */ +class SyncPromise { - if ('stack' in modifier) { - modifier.stack(this[key], stack); - } - } + constructor( + executor, + ) {SyncPromise.prototype.__init.call(this);SyncPromise.prototype.__init2.call(this);SyncPromise.prototype.__init3.call(this);SyncPromise.prototype.__init4.call(this); + this._state = States.PENDING; + this._handlers = []; - return stack.join('\n'); - }; + try { + executor(this._resolve, this._reject); + } catch (e) { + this._reject(e); + } + } - Object.defineProperty(this, 'stack', stackDescriptor); - }; + /** JSDoc */ + then( + onfulfilled, + onrejected, + ) { + return new SyncPromise((resolve, reject) => { + this._handlers.push([ + false, + result => { + if (!onfulfilled) { + // TODO: ¯\_(ツ)_/¯ + // TODO: FIXME + resolve(result ); + } else { + try { + resolve(onfulfilled(result)); + } catch (e) { + reject(e); + } + } + }, + reason => { + if (!onrejected) { + reject(reason); + } else { + try { + resolve(onrejected(reason)); + } catch (e) { + reject(e); + } + } + }, + ]); + this._executeHandlers(); + }); + } - if (Object.setPrototypeOf) { - Object.setPrototypeOf(errorExError.prototype, Error.prototype); - Object.setPrototypeOf(errorExError, Error); - } else { - util.inherits(errorExError, Error); - } + /** JSDoc */ + catch( + onrejected, + ) { + return this.then(val => val, onrejected); + } - return errorExError; -}; + /** JSDoc */ + finally(onfinally) { + return new SyncPromise((resolve, reject) => { + let val; + let isRejected; -errorEx.append = function (str, def) { - return { - message: function (v, message) { - v = v || def; + return this.then( + value => { + isRejected = false; + val = value; + if (onfinally) { + onfinally(); + } + }, + reason => { + isRejected = true; + val = reason; + if (onfinally) { + onfinally(); + } + }, + ).then(() => { + if (isRejected) { + reject(val); + return; + } - if (v) { - message[0] += ' ' + str.replace('%s', v.toString()); - } + resolve(val ); + }); + }); + } - return message; - } - }; -}; + /** JSDoc */ + __init() {this._resolve = (value) => { + this._setResult(States.RESOLVED, value); + };} -errorEx.line = function (str, def) { - return { - line: function (v) { - v = v || def; + /** JSDoc */ + __init2() {this._reject = (reason) => { + this._setResult(States.REJECTED, reason); + };} - if (v) { - return str.replace('%s', v.toString()); - } + /** JSDoc */ + __init3() {this._setResult = (state, value) => { + if (this._state !== States.PENDING) { + return; + } - return null; - } - }; -}; + if (is.isThenable(value)) { + void (value ).then(this._resolve, this._reject); + return; + } -module.exports = errorEx; + this._state = state; + this._value = value; + this._executeHandlers(); + };} -/***/ }), + /** JSDoc */ + __init4() {this._executeHandlers = () => { + if (this._state === States.PENDING) { + return; + } -/***/ 21410: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const cachedHandlers = this._handlers.slice(); + this._handlers = []; -"use strict"; + cachedHandlers.forEach(handler => { + if (handler[0]) { + return; + } + if (this._state === States.RESOLVED) { + // eslint-disable-next-line @typescript-eslint/no-floating-promises + handler[1](this._value ); + } -var GetIntrinsic = __nccwpck_require__(36546); + if (this._state === States.REJECTED) { + handler[2](this._value); + } -/** @type {import('.')} */ -var $defineProperty = GetIntrinsic('%Object.defineProperty%', true) || false; -if ($defineProperty) { - try { - $defineProperty({}, 'a', { value: 1 }); - } catch (e) { - // IE 8 has a broken defineProperty - $defineProperty = false; - } + handler[0] = true; + }); + };} } -module.exports = $defineProperty; +exports.SyncPromise = SyncPromise; +exports.rejectedSyncPromise = rejectedSyncPromise; +exports.resolvedSyncPromise = resolvedSyncPromise; +//# sourceMappingURL=syncpromise.js.map /***/ }), -/***/ 93241: -/***/ ((module) => { - -"use strict"; - - -/** @type {import('./eval')} */ -module.exports = EvalError; +/***/ 50863: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +const worldwide = __nccwpck_require__(48567); -/***/ 90867: -/***/ ((module) => { +const ONE_SECOND_IN_MS = 1000; -"use strict"; +/** + * A partial definition of the [Performance Web API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Performance} + * for accessing a high-resolution monotonic clock. + */ +/** + * Returns a timestamp in seconds since the UNIX epoch using the Date API. + * + * TODO(v8): Return type should be rounded. + */ +function dateTimestampInSeconds() { + return Date.now() / ONE_SECOND_IN_MS; +} -/** @type {import('.')} */ -module.exports = Error; +/** + * Returns a wrapper around the native Performance API browser implementation, or undefined for browsers that do not + * support the API. + * + * Wrapping the native API works around differences in behavior from different browsers. + */ +function createUnixTimestampInSecondsFunc() { + const { performance } = worldwide.GLOBAL_OBJ ; + if (!performance || !performance.now) { + return dateTimestampInSeconds; + } + // Some browser and environments don't have a timeOrigin, so we fallback to + // using Date.now() to compute the starting time. + const approxStartingTimeOrigin = Date.now() - performance.now(); + const timeOrigin = performance.timeOrigin == undefined ? approxStartingTimeOrigin : performance.timeOrigin; -/***/ }), - -/***/ 79078: -/***/ ((module) => { - -"use strict"; + // performance.now() is a monotonic clock, which means it starts at 0 when the process begins. To get the current + // wall clock time (actual UNIX timestamp), we need to add the starting time origin and the current time elapsed. + // + // TODO: This does not account for the case where the monotonic clock that powers performance.now() drifts from the + // wall clock time, which causes the returned timestamp to be inaccurate. We should investigate how to detect and + // correct for this. + // See: https://github.com/getsentry/sentry-javascript/issues/2590 + // See: https://github.com/mdn/content/issues/4713 + // See: https://dev.to/noamr/when-a-millisecond-is-not-a-millisecond-3h6 + return () => { + return (timeOrigin + performance.now()) / ONE_SECOND_IN_MS; + }; +} +/** + * Returns a timestamp in seconds since the UNIX epoch using either the Performance or Date APIs, depending on the + * availability of the Performance API. + * + * BUG: Note that because of how browsers implement the Performance API, the clock might stop when the computer is + * asleep. This creates a skew between `dateTimestampInSeconds` and `timestampInSeconds`. The + * skew can grow to arbitrary amounts like days, weeks or months. + * See https://github.com/getsentry/sentry-javascript/issues/2590. + */ +const timestampInSeconds = createUnixTimestampInSecondsFunc(); -/** @type {import('./range')} */ -module.exports = RangeError; +/** + * Re-exported with an old name for backwards-compatibility. + * TODO (v8): Remove this + * + * @deprecated Use `timestampInSeconds` instead. + */ +const timestampWithMs = timestampInSeconds; +/** + * Internal helper to store what is the source of browserPerformanceTimeOrigin below. For debugging only. + */ +exports._browserPerformanceTimeOriginMode = void 0; -/***/ }), +/** + * The number of milliseconds since the UNIX epoch. This value is only usable in a browser, and only when the + * performance API is available. + */ +const browserPerformanceTimeOrigin = (() => { + // Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or + // performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin + // data as reliable if they are within a reasonable threshold of the current time. -/***/ 74310: -/***/ ((module) => { + const { performance } = worldwide.GLOBAL_OBJ ; + if (!performance || !performance.now) { + exports._browserPerformanceTimeOriginMode = 'none'; + return undefined; + } -"use strict"; + const threshold = 3600 * 1000; + const performanceNow = performance.now(); + const dateNow = Date.now(); + + // if timeOrigin isn't available set delta to threshold so it isn't used + const timeOriginDelta = performance.timeOrigin + ? Math.abs(performance.timeOrigin + performanceNow - dateNow) + : threshold; + const timeOriginIsReliable = timeOriginDelta < threshold; + + // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin + // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing. + // Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always + // a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the + // Date API. + // eslint-disable-next-line deprecation/deprecation + const navigationStart = performance.timing && performance.timing.navigationStart; + const hasNavigationStart = typeof navigationStart === 'number'; + // if navigationStart isn't available set delta to threshold so it isn't used + const navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold; + const navigationStartIsReliable = navigationStartDelta < threshold; + + if (timeOriginIsReliable || navigationStartIsReliable) { + // Use the more reliable time origin + if (timeOriginDelta <= navigationStartDelta) { + exports._browserPerformanceTimeOriginMode = 'timeOrigin'; + return performance.timeOrigin; + } else { + exports._browserPerformanceTimeOriginMode = 'navigationStart'; + return navigationStart; + } + } + // Either both timeOrigin and navigationStart are skewed or neither is available, fallback to Date. + exports._browserPerformanceTimeOriginMode = 'dateNow'; + return dateNow; +})(); -/** @type {import('./ref')} */ -module.exports = ReferenceError; +exports.browserPerformanceTimeOrigin = browserPerformanceTimeOrigin; +exports.dateTimestampInSeconds = dateTimestampInSeconds; +exports.timestampInSeconds = timestampInSeconds; +exports.timestampWithMs = timestampWithMs; +//# sourceMappingURL=time.js.map /***/ }), -/***/ 48640: -/***/ ((module) => { +/***/ 83622: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +const baggage = __nccwpck_require__(93826); +const misc = __nccwpck_require__(57542); -/** @type {import('./syntax')} */ -module.exports = SyntaxError; +// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- RegExp is used for readability here +const TRACEPARENT_REGEXP = new RegExp( + '^[ \\t]*' + // whitespace + '([0-9a-f]{32})?' + // trace_id + '-?([0-9a-f]{16})?' + // span_id + '-?([01])?' + // sampled + '[ \\t]*$', // whitespace +); +/** + * Extract transaction context data from a `sentry-trace` header. + * + * @param traceparent Traceparent string + * + * @returns Object containing data from the header, or undefined if traceparent string is malformed + */ +function extractTraceparentData(traceparent) { + if (!traceparent) { + return undefined; + } -/***/ }), + const matches = traceparent.match(TRACEPARENT_REGEXP); + if (!matches) { + return undefined; + } -/***/ 78279: -/***/ ((module) => { + let parentSampled; + if (matches[3] === '1') { + parentSampled = true; + } else if (matches[3] === '0') { + parentSampled = false; + } -"use strict"; + return { + traceId: matches[1], + parentSampled, + parentSpanId: matches[2], + }; +} +/** + * Create tracing context from incoming headers. + * + * @deprecated Use `propagationContextFromHeaders` instead. + */ +// TODO(v8): Remove this function +function tracingContextFromHeaders( + sentryTrace, + baggage$1, +) -/** @type {import('./type')} */ -module.exports = TypeError; + { + const traceparentData = extractTraceparentData(sentryTrace); + const dynamicSamplingContext = baggage.baggageHeaderToDynamicSamplingContext(baggage$1); + const { traceId, parentSpanId, parentSampled } = traceparentData || {}; -/***/ }), + if (!traceparentData) { + return { + traceparentData, + dynamicSamplingContext: undefined, + propagationContext: { + traceId: traceId || misc.uuid4(), + spanId: misc.uuid4().substring(16), + }, + }; + } else { + return { + traceparentData, + dynamicSamplingContext: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it + propagationContext: { + traceId: traceId || misc.uuid4(), + parentSpanId: parentSpanId || misc.uuid4().substring(16), + spanId: misc.uuid4().substring(16), + sampled: parentSampled, + dsc: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it + }, + }; + } +} -/***/ 54573: -/***/ ((module) => { +/** + * Create a propagation context from incoming headers. + */ +function propagationContextFromHeaders( + sentryTrace, + baggage$1, +) { + const traceparentData = extractTraceparentData(sentryTrace); + const dynamicSamplingContext = baggage.baggageHeaderToDynamicSamplingContext(baggage$1); -"use strict"; + const { traceId, parentSpanId, parentSampled } = traceparentData || {}; + + if (!traceparentData) { + return { + traceId: traceId || misc.uuid4(), + spanId: misc.uuid4().substring(16), + }; + } else { + return { + traceId: traceId || misc.uuid4(), + parentSpanId: parentSpanId || misc.uuid4().substring(16), + spanId: misc.uuid4().substring(16), + sampled: parentSampled, + dsc: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it + }; + } +} +/** + * Create sentry-trace header from span context values. + */ +function generateSentryTraceHeader( + traceId = misc.uuid4(), + spanId = misc.uuid4().substring(16), + sampled, +) { + let sampledString = ''; + if (sampled !== undefined) { + sampledString = sampled ? '-1' : '-0'; + } + return `${traceId}-${spanId}${sampledString}`; +} -/** @type {import('./uri')} */ -module.exports = URIError; +exports.TRACEPARENT_REGEXP = TRACEPARENT_REGEXP; +exports.extractTraceparentData = extractTraceparentData; +exports.generateSentryTraceHeader = generateSentryTraceHeader; +exports.propagationContextFromHeaders = propagationContextFromHeaders; +exports.tracingContextFromHeaders = tracingContextFromHeaders; +//# sourceMappingURL=tracing.js.map /***/ }), -/***/ 3385: -/***/ ((module) => { +/***/ 21933: +/***/ ((__unused_webpack_module, exports) => { -"use strict"; -/*! - * escape-html - * Copyright(c) 2012-2013 TJ Holowaychuk - * Copyright(c) 2015 Andreas Lubbe - * Copyright(c) 2015 Tiancheng "Timothy" Gu - * MIT Licensed +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/** + * Parses string form of URL into an object + * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B + * // intentionally using regex and not href parsing trick because React Native and other + * // environments where DOM might not be available + * @returns parsed URL object */ +function parseUrl(url) { + if (!url) { + return {}; + } + const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/); + if (!match) { + return {}; + } + + // coerce to undefined values to empty string so we don't get 'undefined' + const query = match[6] || ''; + const fragment = match[8] || ''; + return { + host: match[4], + path: match[5], + protocol: match[2], + search: query, + hash: fragment, + relative: match[5] + query + fragment, // everything minus origin + }; +} /** - * Module variables. - * @private + * Strip the query string and fragment off of a given URL or path (if present) + * + * @param urlPath Full URL or path, including possible query string and/or fragment + * @returns URL or path without query string or fragment */ +function stripUrlQueryAndFragment(urlPath) { + // eslint-disable-next-line no-useless-escape + return urlPath.split(/[\?#]/, 1)[0]; +} -var matchHtmlRegExp = /["'&<>]/; +/** + * Returns number of URL segments of a passed string URL. + */ +function getNumberOfUrlSegments(url) { + // split at '/' or at '\/' to split regex urls correctly + return url.split(/\\?\//).filter(s => s.length > 0 && s !== ',').length; +} /** - * Module exports. - * @public + * Takes a URL object and returns a sanitized string which is safe to use as span description + * see: https://develop.sentry.dev/sdk/data-handling/#structuring-data */ +function getSanitizedUrlString(url) { + const { protocol, host, path } = url; -module.exports = escapeHtml; + const filteredHost = + (host && + host + // Always filter out authority + .replace(/^.*@/, '[filtered]:[filtered]@') + // Don't show standard :80 (http) and :443 (https) ports to reduce the noise + // TODO: Use new URL global if it exists + .replace(/(:80)$/, '') + .replace(/(:443)$/, '')) || + ''; + + return `${protocol ? `${protocol}://` : ''}${filteredHost}${path}`; +} + +exports.getNumberOfUrlSegments = getNumberOfUrlSegments; +exports.getSanitizedUrlString = getSanitizedUrlString; +exports.parseUrl = parseUrl; +exports.stripUrlQueryAndFragment = stripUrlQueryAndFragment; +//# sourceMappingURL=url.js.map + + +/***/ }), + +/***/ 458: +/***/ ((__unused_webpack_module, exports) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); /** - * Escape special characters in the given string of html. + * Recursively traverses an object to update an existing nested key. + * Note: The provided key path must include existing properties, + * the function will not create objects while traversing. * - * @param {string} string The string to escape for inserting into HTML - * @return {string} - * @public + * @param obj An object to update + * @param value The value to update the nested key with + * @param keyPath The path to the key to update ex. fizz.buzz.foo */ - -function escapeHtml(string) { - var str = '' + string; - var match = matchHtmlRegExp.exec(str); - - if (!match) { - return str; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function setNestedKey(obj, keyPath, value) { + // Ex. foo.bar.zoop will extract foo and bar.zoop + const match = keyPath.match(/([a-z_]+)\.(.*)/i); + // The match will be null when there's no more recursing to do, i.e., when we've reached the right level of the object + if (match === null) { + obj[keyPath] = value; + } else { + // `match[1]` is the initial segment of the path, and `match[2]` is the remainder of the path + const innerObj = obj[match[1]]; + setNestedKey(innerObj, match[2], value); } +} - var escape; - var html = ''; - var index = 0; - var lastIndex = 0; +/** + * Enforces inclusion of a given integration with specified options in an integration array originally determined by the + * user, by either including the given default instance or by patching an existing user instance with the given options. + * + * Ideally this would happen when integrations are set up, but there isn't currently a mechanism there for merging + * options from a default integration instance with those from a user-provided instance of the same integration, only + * for allowing the user to override a default instance entirely. (TODO: Fix that.) + * + * @param defaultIntegrationInstance An instance of the integration with the correct options already set + * @param userIntegrations Integrations defined by the user. + * @param forcedOptions Options with which to patch an existing user-derived instance on the integration. + * @returns A final integrations array. + * + * @deprecated This will be removed in v8. + */ +function addOrUpdateIntegration( + defaultIntegrationInstance, + userIntegrations, + forcedOptions = {}, +) { + return ( + Array.isArray(userIntegrations) + ? addOrUpdateIntegrationInArray(defaultIntegrationInstance, userIntegrations, forcedOptions) + : addOrUpdateIntegrationInFunction( + defaultIntegrationInstance, + // Somehow TS can't figure out that not being an array makes this necessarily a function + userIntegrations , + forcedOptions, + ) + ) ; +} - for (index = match.index; index < str.length; index++) { - switch (str.charCodeAt(index)) { - case 34: // " - escape = '"'; - break; - case 38: // & - escape = '&'; - break; - case 39: // ' - escape = '''; - break; - case 60: // < - escape = '<'; - break; - case 62: // > - escape = '>'; - break; - default: - continue; - } +function addOrUpdateIntegrationInArray( + defaultIntegrationInstance, + userIntegrations, + forcedOptions, +) { + const userInstance = userIntegrations.find(integration => integration.name === defaultIntegrationInstance.name); - if (lastIndex !== index) { - html += str.substring(lastIndex, index); + if (userInstance) { + for (const [keyPath, value] of Object.entries(forcedOptions)) { + setNestedKey(userInstance, keyPath, value); } - lastIndex = index + 1; - html += escape; + return userIntegrations; } - return lastIndex !== index - ? html + str.substring(lastIndex, index) - : html; + return [...userIntegrations, defaultIntegrationInstance]; } +function addOrUpdateIntegrationInFunction( + defaultIntegrationInstance, + userIntegrationsFunc, + forcedOptions, +) { + const wrapper = defaultIntegrations => { + const userFinalIntegrations = userIntegrationsFunc(defaultIntegrations); + + // There are instances where we want the user to be able to prevent an integration from appearing at all, which they + // would do by providing a function which filters out the integration in question. If that's happened in one of + // those cases, don't add our default back in. + if (defaultIntegrationInstance.allowExclusionByUser) { + const userFinalInstance = userFinalIntegrations.find( + integration => integration.name === defaultIntegrationInstance.name, + ); + if (!userFinalInstance) { + return userFinalIntegrations; + } + } -/***/ }), + return addOrUpdateIntegrationInArray(defaultIntegrationInstance, userFinalIntegrations, forcedOptions); + }; -/***/ 71389: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return wrapper; +} -"use strict"; -/*! - * etag - * Copyright(c) 2014-2016 Douglas Christopher Wilson - * MIT Licensed - */ +exports.addOrUpdateIntegration = addOrUpdateIntegration; +//# sourceMappingURL=userIntegrations.js.map +/***/ }), -/** - * Module exports. - * @public - */ +/***/ 81935: +/***/ ((__unused_webpack_module, exports) => { -module.exports = etag +Object.defineProperty(exports, "__esModule", ({ value: true })); + +// Based on https://github.com/sindresorhus/escape-string-regexp but with modifications to: +// a) reduce the size by skipping the runtime type - checking +// b) ensure it gets down - compiled for old versions of Node(the published package only supports Node 12+). +// +// MIT License +// +// Copyright (c) Sindre Sorhus (https://sindresorhus.com) +// +// 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. /** - * Module dependencies. - * @private + * Given a string, escape characters which have meaning in the regex grammar, such that the result is safe to feed to + * `new RegExp()`. + * + * @param regexString The string to escape + * @returns An version of the string with all special regex characters escaped */ +function escapeStringForRegex(regexString) { + // escape the hyphen separately so we can also replace it with a unicode literal hyphen, to avoid the problems + // discussed in https://github.com/sindresorhus/escape-string-regexp/issues/20. + return regexString.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d'); +} -var crypto = __nccwpck_require__(76982) -var Stats = (__nccwpck_require__(79896).Stats) +exports.escapeStringForRegex = escapeStringForRegex; +//# sourceMappingURL=escapeStringForRegex.js.map -/** - * Module variables. - * @private - */ -var toString = Object.prototype.toString +/***/ }), -/** - * Generate an entity tag. - * - * @param {Buffer|string} entity - * @return {string} - * @private - */ +/***/ 87347: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -function entitytag (entity) { - if (entity.length === 0) { - // fast-path empty - return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"' - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - // compute hash of entity - var hash = crypto - .createHash('sha1') - .update(entity, 'utf8') - .digest('base64') - .substring(0, 27) +const worldwide = __nccwpck_require__(48567); - // compute length of entity - var len = typeof entity === 'string' - ? Buffer.byteLength(entity, 'utf8') - : entity.length +// Based on https://github.com/angular/angular.js/pull/13945/files - return '"' + len.toString(16) + '-' + hash + '"' -} +// eslint-disable-next-line deprecation/deprecation +const WINDOW = worldwide.getGlobalObject(); /** - * Create a simple ETag. + * Tells whether current environment supports History API + * {@link supportsHistory}. * - * @param {string|Buffer|Stats} entity - * @param {object} [options] - * @param {boolean} [options.weak] - * @return {String} - * @public + * @returns Answer to the given question. */ +function supportsHistory() { + // NOTE: in Chrome App environment, touching history.pushState, *even inside + // a try/catch block*, will cause Chrome to output an error to console.error + // borrowed from: https://github.com/angular/angular.js/pull/13945/files + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const chromeVar = (WINDOW ).chrome; + const isChromePackagedApp = chromeVar && chromeVar.app && chromeVar.app.runtime; + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ + const hasHistoryApi = 'history' in WINDOW && !!WINDOW.history.pushState && !!WINDOW.history.replaceState; -function etag (entity, options) { - if (entity == null) { - throw new TypeError('argument entity is required') - } + return !isChromePackagedApp && hasHistoryApi; +} - // support fs.Stats object - var isStats = isstats(entity) - var weak = options && typeof options.weak === 'boolean' - ? options.weak - : isStats +exports.supportsHistory = supportsHistory; +//# sourceMappingURL=supportsHistory.js.map - // validate argument - if (!isStats && typeof entity !== 'string' && !Buffer.isBuffer(entity)) { - throw new TypeError('argument entity must be string, Buffer, or fs.Stats') - } - // generate entity tag - var tag = isStats - ? stattag(entity) - : entitytag(entity) +/***/ }), - return weak - ? 'W/' + tag - : tag -} +/***/ 48567: +/***/ ((__unused_webpack_module, exports) => { -/** - * Determine if object is a Stats object. - * - * @param {object} obj - * @return {boolean} - * @api private - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); -function isstats (obj) { - // genuine fs.Stats - if (typeof Stats === 'function' && obj instanceof Stats) { - return true - } +/** Internal global with common properties and Sentry extensions */ - // quack quack - return obj && typeof obj === 'object' && - 'ctime' in obj && toString.call(obj.ctime) === '[object Date]' && - 'mtime' in obj && toString.call(obj.mtime) === '[object Date]' && - 'ino' in obj && typeof obj.ino === 'number' && - 'size' in obj && typeof obj.size === 'number' +// The code below for 'isGlobalObj' and 'GLOBAL_OBJ' was copied from core-js before modification +// https://github.com/zloirock/core-js/blob/1b944df55282cdc99c90db5f49eb0b6eda2cc0a3/packages/core-js/internals/global.js +// core-js has the following licence: +// +// Copyright (c) 2014-2022 Denis Pushkarev +// +// 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. + +/** Returns 'obj' if it's the global object, otherwise returns undefined */ +function isGlobalObj(obj) { + return obj && obj.Math == Math ? obj : undefined; +} + +/** Get's the global object for the current JavaScript runtime */ +const GLOBAL_OBJ = + (typeof globalThis == 'object' && isGlobalObj(globalThis)) || + // eslint-disable-next-line no-restricted-globals + (typeof window == 'object' && isGlobalObj(window)) || + (typeof self == 'object' && isGlobalObj(self)) || + (typeof global == 'object' && isGlobalObj(global)) || + (function () { + return this; + })() || + {}; + +/** + * @deprecated Use GLOBAL_OBJ instead or WINDOW from @sentry/browser. This will be removed in v8 + */ +function getGlobalObject() { + return GLOBAL_OBJ ; } /** - * Generate a tag for a stat. + * Returns a global singleton contained in the global `__SENTRY__` object. * - * @param {object} stat - * @return {string} - * @private + * If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory + * function and added to the `__SENTRY__` object. + * + * @param name name of the global singleton on __SENTRY__ + * @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__` + * @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `GLOBAL_OBJ`'s return value + * @returns the singleton */ - -function stattag (stat) { - var mtime = stat.mtime.getTime().toString(16) - var size = stat.size.toString(16) - - return '"' + size + '-' + mtime + '"' +function getGlobalSingleton(name, creator, obj) { + const gbl = (obj || GLOBAL_OBJ) ; + const __SENTRY__ = (gbl.__SENTRY__ = gbl.__SENTRY__ || {}); + const singleton = __SENTRY__[name] || (__SENTRY__[name] = creator()); + return singleton; } +exports.GLOBAL_OBJ = GLOBAL_OBJ; +exports.getGlobalObject = getGlobalObject; +exports.getGlobalSingleton = getGlobalSingleton; +//# sourceMappingURL=worldwide.js.map + /***/ }), -/***/ 10121: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 55966: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2013 Roman Shtylman - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const types = __nccwpck_require__(49884); + +/** + * Add a listener that cancels and finishes a transaction when the global + * document is hidden. */ +function registerBackgroundTabDetection() { + if (types.WINDOW.document) { + types.WINDOW.document.addEventListener('visibilitychange', () => { + // eslint-disable-next-line deprecation/deprecation + const activeTransaction = core.getActiveTransaction() ; + if (types.WINDOW.document.hidden && activeTransaction) { + const statusType = 'cancelled'; + const { op, status } = core.spanToJSON(activeTransaction); + debugBuild.DEBUG_BUILD && + utils.logger.log(`[Tracing] Transaction: ${statusType} -> since tab moved to the background, op: ${op}`); + // We should not set status if it is already set, this prevent important statuses like + // error or data loss from being overwritten on transaction. + if (!status) { + activeTransaction.setStatus(statusType); + } + // TODO: Can we rewrite this to an attribute? + // eslint-disable-next-line deprecation/deprecation + activeTransaction.setTag('visibilitychange', 'document.hidden'); + activeTransaction.end(); + } + }); + } else { + debugBuild.DEBUG_BUILD && utils.logger.warn('[Tracing] Could not set up background tab detection due to lack of global document'); + } +} -module.exports = __nccwpck_require__(76657); +exports.registerBackgroundTabDetection = registerBackgroundTabDetection; +//# sourceMappingURL=backgroundtab.js.map /***/ }), -/***/ 65095: -/***/ ((module, exports, __nccwpck_require__) => { - -"use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2013 Roman Shtylman - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ +/***/ 49293: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +Object.defineProperty(exports, "__esModule", ({ value: true })); +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const backgroundtab = __nccwpck_require__(55966); +const instrument = __nccwpck_require__(7380); +const index = __nccwpck_require__(5479); +const request = __nccwpck_require__(26896); +const types = __nccwpck_require__(49884); + +const BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing'; + +/** Options for Browser Tracing integration */ + +const DEFAULT_BROWSER_TRACING_OPTIONS = { + ...core.TRACING_DEFAULTS, + instrumentNavigation: true, + instrumentPageLoad: true, + markBackgroundSpan: true, + enableLongTask: true, + enableInp: false, + interactionsSampleRate: 1, + _experiments: {}, + ...request.defaultRequestInstrumentationOptions, +}; /** - * Module dependencies. - * @private + * The Browser Tracing integration automatically instruments browser pageload/navigation + * actions as transactions, and captures requests, metrics and errors as spans. + * + * The integration can be configured with a variety of options, and can be extended to use + * any routing library. This integration uses {@see IdleTransaction} to create transactions. + * + * We explicitly export the proper type here, as this has to be extended in some cases. */ +const browserTracingIntegration = ((_options = {}) => { + const _hasSetTracePropagationTargets = debugBuild.DEBUG_BUILD + ? !!( + // eslint-disable-next-line deprecation/deprecation + (_options.tracePropagationTargets || _options.tracingOrigins) + ) + : false; -var finalhandler = __nccwpck_require__(1136); -var Router = __nccwpck_require__(85055); -var methods = __nccwpck_require__(84283); -var middleware = __nccwpck_require__(95986); -var query = __nccwpck_require__(90030); -var debug = __nccwpck_require__(66515)('express:application'); -var View = __nccwpck_require__(53800); -var http = __nccwpck_require__(58611); -var compileETag = (__nccwpck_require__(21596).compileETag); -var compileQueryParser = (__nccwpck_require__(21596).compileQueryParser); -var compileTrust = (__nccwpck_require__(21596).compileTrust); -var deprecate = __nccwpck_require__(77267)('express'); -var flatten = __nccwpck_require__(35698); -var merge = __nccwpck_require__(31657); -var resolve = (__nccwpck_require__(16928).resolve); -var setPrototypeOf = __nccwpck_require__(12516) + core.addTracingExtensions(); -/** - * Module variables. - * @private - */ + // TODO (v8): remove this block after tracingOrigins is removed + // Set tracePropagationTargets to tracingOrigins if specified by the user + // In case both are specified, tracePropagationTargets takes precedence + // eslint-disable-next-line deprecation/deprecation + if (!_options.tracePropagationTargets && _options.tracingOrigins) { + // eslint-disable-next-line deprecation/deprecation + _options.tracePropagationTargets = _options.tracingOrigins; + } -var hasOwnProperty = Object.prototype.hasOwnProperty -var slice = Array.prototype.slice; + const options = { + ...DEFAULT_BROWSER_TRACING_OPTIONS, + ..._options, + }; -/** - * Application prototype. - */ + const _collectWebVitals = index.startTrackingWebVitals(); -var app = exports = module.exports = {}; + /** Stores a mapping of interactionIds from PerformanceEventTimings to the origin interaction path */ + const interactionIdToRouteNameMapping = {}; + if (options.enableInp) { + index.startTrackingINP(interactionIdToRouteNameMapping, options.interactionsSampleRate); + } -/** - * Variable for trust proxy inheritance back-compat - * @private - */ + if (options.enableLongTask) { + index.startTrackingLongTasks(); + } + if (options._experiments.enableInteractions) { + index.startTrackingInteractions(); + } -var trustProxyDefaultSymbol = '@@symbol:trust_proxy_default'; + const latestRoute -/** - * Initialize the server. - * - * - setup default configuration - * - setup default middleware - * - setup route reflection methods - * - * @private - */ + = { + name: undefined, + context: undefined, + }; -app.init = function init() { - this.cache = {}; - this.engines = {}; - this.settings = {}; + /** Create routing idle transaction. */ + function _createRouteTransaction(context) { + // eslint-disable-next-line deprecation/deprecation + const hub = core.getCurrentHub(); + + const { beforeStartSpan, idleTimeout, finalTimeout, heartbeatInterval } = options; + + const isPageloadTransaction = context.op === 'pageload'; + + let expandedContext; + if (isPageloadTransaction) { + const sentryTrace = isPageloadTransaction ? getMetaContent('sentry-trace') : ''; + const baggage = isPageloadTransaction ? getMetaContent('baggage') : undefined; + const { traceId, dsc, parentSpanId, sampled } = utils.propagationContextFromHeaders(sentryTrace, baggage); + expandedContext = { + traceId, + parentSpanId, + parentSampled: sampled, + ...context, + metadata: { + // eslint-disable-next-line deprecation/deprecation + ...context.metadata, + dynamicSamplingContext: dsc, + }, + trimEnd: true, + }; + } else { + expandedContext = { + trimEnd: true, + ...context, + }; + } - this.defaultConfiguration(); -}; + const finalContext = beforeStartSpan ? beforeStartSpan(expandedContext) : expandedContext; -/** - * Initialize application configuration. - * @private - */ + // If `beforeStartSpan` set a custom name, record that fact + // eslint-disable-next-line deprecation/deprecation + finalContext.metadata = + finalContext.name !== expandedContext.name + ? // eslint-disable-next-line deprecation/deprecation + { ...finalContext.metadata, source: 'custom' } + : // eslint-disable-next-line deprecation/deprecation + finalContext.metadata; -app.defaultConfiguration = function defaultConfiguration() { - var env = process.env.NODE_ENV || 'development'; + latestRoute.name = finalContext.name; + latestRoute.context = finalContext; - // default settings - this.enable('x-powered-by'); - this.set('etag', 'weak'); - this.set('env', env); - this.set('query parser', 'extended'); - this.set('subdomain offset', 2); - this.set('trust proxy', false); + if (finalContext.sampled === false) { + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Will not send ${finalContext.op} transaction because of beforeNavigate.`); + } - // trust proxy inherit back-compat - Object.defineProperty(this.settings, trustProxyDefaultSymbol, { - configurable: true, - value: true - }); + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Starting ${finalContext.op} transaction on scope`); - debug('booting in %s mode', env); + const { location } = types.WINDOW; - this.on('mount', function onmount(parent) { - // inherit trust proxy - if (this.settings[trustProxyDefaultSymbol] === true - && typeof parent.settings['trust proxy fn'] === 'function') { - delete this.settings['trust proxy']; - delete this.settings['trust proxy fn']; + const idleTransaction = core.startIdleTransaction( + hub, + finalContext, + idleTimeout, + finalTimeout, + true, + { location }, // for use in the tracesSampler + heartbeatInterval, + isPageloadTransaction, // should wait for finish signal if it's a pageload transaction + ); + + if (isPageloadTransaction && types.WINDOW.document) { + types.WINDOW.document.addEventListener('readystatechange', () => { + if (['interactive', 'complete'].includes(types.WINDOW.document.readyState)) { + idleTransaction.sendAutoFinishSignal(); + } + }); + + if (['interactive', 'complete'].includes(types.WINDOW.document.readyState)) { + idleTransaction.sendAutoFinishSignal(); + } } - // inherit protos - setPrototypeOf(this.request, parent.request) - setPrototypeOf(this.response, parent.response) - setPrototypeOf(this.engines, parent.engines) - setPrototypeOf(this.settings, parent.settings) - }); + idleTransaction.registerBeforeFinishCallback(transaction => { + _collectWebVitals(); + index.addPerformanceEntries(transaction); + }); - // setup locals - this.locals = Object.create(null); + return idleTransaction ; + } - // top-most app is mounted at / - this.mountpath = '/'; + return { + name: BROWSER_TRACING_INTEGRATION_ID, + // eslint-disable-next-line @typescript-eslint/no-empty-function + setupOnce: () => {}, + afterAllSetup(client) { + const clientOptions = client.getOptions(); + + const { markBackgroundSpan, traceFetch, traceXHR, shouldCreateSpanForRequest, enableHTTPTimings, _experiments } = + options; + + const clientOptionsTracePropagationTargets = clientOptions && clientOptions.tracePropagationTargets; + // There are three ways to configure tracePropagationTargets: + // 1. via top level client option `tracePropagationTargets` + // 2. via BrowserTracing option `tracePropagationTargets` + // 3. via BrowserTracing option `tracingOrigins` (deprecated) + // + // To avoid confusion, favour top level client option `tracePropagationTargets`, and fallback to + // BrowserTracing option `tracePropagationTargets` and then `tracingOrigins` (deprecated). + // This is done as it minimizes bundle size (we don't have to have undefined checks). + // + // If both 1 and either one of 2 or 3 are set (from above), we log out a warning. + // eslint-disable-next-line deprecation/deprecation + const tracePropagationTargets = clientOptionsTracePropagationTargets || options.tracePropagationTargets; + if (debugBuild.DEBUG_BUILD && _hasSetTracePropagationTargets && clientOptionsTracePropagationTargets) { + utils.logger.warn( + '[Tracing] The `tracePropagationTargets` option was set in the BrowserTracing integration and top level `Sentry.init`. The top level `Sentry.init` value is being used.', + ); + } - // default locals - this.locals.settings = this.settings; + let activeSpan; + let startingUrl = types.WINDOW.location && types.WINDOW.location.href; - // default configuration - this.set('view', View); - this.set('views', resolve('views')); - this.set('jsonp callback name', 'callback'); + if (client.on) { + client.on('startNavigationSpan', (context) => { + if (activeSpan) { + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Finishing current transaction with op: ${core.spanToJSON(activeSpan).op}`); + // If there's an open transaction on the scope, we need to finish it before creating an new one. + activeSpan.end(); + } + activeSpan = _createRouteTransaction({ + op: 'navigation', + ...context, + }); + }); - if (env === 'production') { - this.enable('view cache'); - } + client.on('startPageLoadSpan', (context) => { + if (activeSpan) { + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Finishing current transaction with op: ${core.spanToJSON(activeSpan).op}`); + // If there's an open transaction on the scope, we need to finish it before creating an new one. + activeSpan.end(); + } + activeSpan = _createRouteTransaction({ + op: 'pageload', + ...context, + }); + }); + } - Object.defineProperty(this, 'router', { - get: function() { - throw new Error('\'app.router\' is deprecated!\nPlease see the 3.x to 4.x migration guide for details on how to update your app.'); - } - }); -}; + if (options.instrumentPageLoad && client.emit && types.WINDOW.location) { + const context = { + name: types.WINDOW.location.pathname, + // pageload should always start at timeOrigin (and needs to be in s, not ms) + startTimestamp: utils.browserPerformanceTimeOrigin ? utils.browserPerformanceTimeOrigin / 1000 : undefined, + origin: 'auto.pageload.browser', + attributes: { + [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', + }, + }; + startBrowserTracingPageLoadSpan(client, context); + } + + if (options.instrumentNavigation && client.emit && types.WINDOW.location) { + utils.addHistoryInstrumentationHandler(({ to, from }) => { + /** + * This early return is there to account for some cases where a navigation transaction starts right after + * long-running pageload. We make sure that if `from` is undefined and a valid `startingURL` exists, we don't + * create an uneccessary navigation transaction. + * + * This was hard to duplicate, but this behavior stopped as soon as this fix was applied. This issue might also + * only be caused in certain development environments where the usage of a hot module reloader is causing + * errors. + */ + if (from === undefined && startingUrl && startingUrl.indexOf(to) !== -1) { + startingUrl = undefined; + return; + } -/** - * lazily adds the base router if it has not yet been added. - * - * We cannot add the base router in the defaultConfiguration because - * it reads app settings which might be set after that has run. - * - * @private - */ -app.lazyrouter = function lazyrouter() { - if (!this._router) { - this._router = new Router({ - caseSensitive: this.enabled('case sensitive routing'), - strict: this.enabled('strict routing') - }); + if (from !== to) { + startingUrl = undefined; + const context = { + name: types.WINDOW.location.pathname, + origin: 'auto.navigation.browser', + attributes: { + [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', + }, + }; - this._router.use(query(this.get('query parser fn'))); - this._router.use(middleware.init(this)); - } -}; + startBrowserTracingNavigationSpan(client, context); + } + }); + } -/** - * Dispatch a req, res pair into the application. Starts pipeline processing. - * - * If no callback is provided, then default error handlers will respond - * in the event of an error bubbling through the stack. - * - * @private - */ + if (markBackgroundSpan) { + backgroundtab.registerBackgroundTabDetection(); + } -app.handle = function handle(req, res, callback) { - var router = this._router; + if (_experiments.enableInteractions) { + registerInteractionListener(options, latestRoute); + } - // final handler - var done = callback || finalhandler(req, res, { - env: this.get('env'), - onerror: logerror.bind(this) - }); + if (options.enableInp) { + registerInpInteractionListener(interactionIdToRouteNameMapping, latestRoute); + } - // no routes - if (!router) { - debug('no routes defined on app'); - done(); + request.instrumentOutgoingRequests({ + traceFetch, + traceXHR, + tracePropagationTargets, + shouldCreateSpanForRequest, + enableHTTPTimings, + }); + }, + // TODO v8: Remove this again + // This is private API that we use to fix converted BrowserTracing integrations in Next.js & SvelteKit + options, + }; +}) ; + +/** + * Manually start a page load span. + * This will only do something if the BrowserTracing integration has been setup. + */ +function startBrowserTracingPageLoadSpan(client, spanOptions) { + if (!client.emit) { return; } - router.handle(req, res, done); -}; + client.emit('startPageLoadSpan', spanOptions); + + const span = core.getActiveSpan(); + const op = span && core.spanToJSON(span).op; + return op === 'pageload' ? span : undefined; +} /** - * Proxy `Router#use()` to add middleware to the app router. - * See Router#use() documentation for details. - * - * If the _fn_ parameter is an express app, then it will be - * mounted at the _route_ specified. - * - * @public + * Manually start a navigation span. + * This will only do something if the BrowserTracing integration has been setup. */ +function startBrowserTracingNavigationSpan(client, spanOptions) { + if (!client.emit) { + return; + } -app.use = function use(fn) { - var offset = 0; - var path = '/'; + client.emit('startNavigationSpan', spanOptions); - // default path to '/' - // disambiguate app.use([fn]) - if (typeof fn !== 'function') { - var arg = fn; + const span = core.getActiveSpan(); + const op = span && core.spanToJSON(span).op; + return op === 'navigation' ? span : undefined; +} - while (Array.isArray(arg) && arg.length !== 0) { - arg = arg[0]; +/** Returns the value of a meta tag */ +function getMetaContent(metaName) { + // Can't specify generic to `getDomElement` because tracing can be used + // in a variety of environments, have to disable `no-unsafe-member-access` + // as a result. + const metaTag = utils.getDomElement(`meta[name=${metaName}]`); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + return metaTag ? metaTag.getAttribute('content') : undefined; +} + +/** Start listener for interaction transactions */ +function registerInteractionListener( + options, + latestRoute + +, +) { + let inflightInteractionTransaction; + const registerInteractionTransaction = () => { + const { idleTimeout, finalTimeout, heartbeatInterval } = options; + const op = 'ui.action.click'; + + // eslint-disable-next-line deprecation/deprecation + const currentTransaction = core.getActiveTransaction(); + if (currentTransaction && currentTransaction.op && ['navigation', 'pageload'].includes(currentTransaction.op)) { + debugBuild.DEBUG_BUILD && + utils.logger.warn( + `[Tracing] Did not create ${op} transaction because a pageload or navigation transaction is in progress.`, + ); + return undefined; } - // first arg is the path - if (typeof arg !== 'function') { - offset = 1; - path = fn; + if (inflightInteractionTransaction) { + inflightInteractionTransaction.setFinishReason('interactionInterrupted'); + inflightInteractionTransaction.end(); + inflightInteractionTransaction = undefined; } - } - var fns = flatten(slice.call(arguments, offset)); + if (!latestRoute.name) { + debugBuild.DEBUG_BUILD && utils.logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`); + return undefined; + } - if (fns.length === 0) { - throw new TypeError('app.use() requires a middleware function') - } + const { location } = types.WINDOW; - // setup router - this.lazyrouter(); - var router = this._router; + const context = { + name: latestRoute.name, + op, + trimEnd: true, + data: { + [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: latestRoute.context ? getSource(latestRoute.context) : 'url', + }, + }; - fns.forEach(function (fn) { - // non-express app - if (!fn || !fn.handle || !fn.set) { - return router.use(path, fn); + inflightInteractionTransaction = core.startIdleTransaction( + // eslint-disable-next-line deprecation/deprecation + core.getCurrentHub(), + context, + idleTimeout, + finalTimeout, + true, + { location }, // for use in the tracesSampler + heartbeatInterval, + ); + }; + + ['click'].forEach(type => { + if (types.WINDOW.document) { + addEventListener(type, registerInteractionTransaction, { once: false, capture: true }); } + }); +} - debug('.use app under %s', path); - fn.mountpath = path; - fn.parent = this; +function isPerformanceEventTiming(entry) { + return 'duration' in entry; +} - // restore .app property on req and res - router.use(path, function mounted_app(req, res, next) { - var orig = req.app; - fn.handle(req, res, function (err) { - setPrototypeOf(req, orig.request) - setPrototypeOf(res, orig.response) - next(err); - }); - }); +/** We store up to 10 interaction candidates max to cap memory usage. This is the same cap as getINP from web-vitals */ +const MAX_INTERACTIONS = 10; - // mounted an app - fn.emit('mount', this); - }, this); +/** Creates a listener on interaction entries, and maps interactionIds to the origin path of the interaction */ +function registerInpInteractionListener( + interactionIdToRouteNameMapping, + latestRoute - return this; -}; +, +) { + const handleEntries = ({ entries }) => { + const client = core.getClient(); + // We need to get the replay, user, and activeTransaction from the current scope + // so that we can associate replay id, profile id, and a user display to the span + const replay = + client !== undefined && client.getIntegrationByName !== undefined + ? (client.getIntegrationByName('Replay') ) + : undefined; + const replayId = replay !== undefined ? replay.getReplayId() : undefined; + // eslint-disable-next-line deprecation/deprecation + const activeTransaction = core.getActiveTransaction(); + const currentScope = core.getCurrentScope(); + const user = currentScope !== undefined ? currentScope.getUser() : undefined; + entries.forEach(entry => { + if (isPerformanceEventTiming(entry)) { + const interactionId = entry.interactionId; + if (interactionId === undefined) { + return; + } + const existingInteraction = interactionIdToRouteNameMapping[interactionId]; + const duration = entry.duration; + const startTime = entry.startTime; + const keys = Object.keys(interactionIdToRouteNameMapping); + const minInteractionId = + keys.length > 0 + ? keys.reduce((a, b) => { + return interactionIdToRouteNameMapping[a].duration < interactionIdToRouteNameMapping[b].duration + ? a + : b; + }) + : undefined; + // For a first input event to be considered, we must check that an interaction event does not already exist with the same duration and start time. + // This is also checked in the web-vitals library. + if (entry.entryType === 'first-input') { + const matchingEntry = keys + .map(key => interactionIdToRouteNameMapping[key]) + .some(interaction => { + return interaction.duration === duration && interaction.startTime === startTime; + }); + if (matchingEntry) { + return; + } + } + // Interactions with an id of 0 and are not first-input are not valid. + if (!interactionId) { + return; + } + // If the interaction already exists, we want to use the duration of the longest entry, since that is what the INP metric uses. + if (existingInteraction) { + existingInteraction.duration = Math.max(existingInteraction.duration, duration); + } else if ( + keys.length < MAX_INTERACTIONS || + minInteractionId === undefined || + duration > interactionIdToRouteNameMapping[minInteractionId].duration + ) { + // If the interaction does not exist, we want to add it to the mapping if there is space, or if the duration is longer than the shortest entry. + const routeName = latestRoute.name; + const parentContext = latestRoute.context; + if (routeName && parentContext) { + if (minInteractionId && Object.keys(interactionIdToRouteNameMapping).length >= MAX_INTERACTIONS) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete interactionIdToRouteNameMapping[minInteractionId]; + } + interactionIdToRouteNameMapping[interactionId] = { + routeName, + duration, + parentContext, + user, + activeTransaction, + replayId, + startTime, + }; + } + } + } + }); + }; + instrument.addPerformanceInstrumentationHandler('event', handleEntries); + instrument.addPerformanceInstrumentationHandler('first-input', handleEntries); +} -/** - * Proxy to the app `Router#route()` - * Returns a new `Route` instance for the _path_. - * - * Routes are isolated middleware stacks for specific paths. - * See the Route api docs for details. - * - * @public - */ +function getSource(context) { + const sourceFromAttributes = context.attributes && context.attributes[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]; + // eslint-disable-next-line deprecation/deprecation + const sourceFromData = context.data && context.data[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]; + // eslint-disable-next-line deprecation/deprecation + const sourceFromMetadata = context.metadata && context.metadata.source; -app.route = function route(path) { - this.lazyrouter(); - return this._router.route(path); -}; + return sourceFromAttributes || sourceFromData || sourceFromMetadata; +} -/** - * Register the given template engine callback `fn` - * as `ext`. - * - * By default will `require()` the engine based on the - * file extension. For example if you try to render - * a "foo.ejs" file Express will invoke the following internally: - * - * app.engine('ejs', require('ejs').__express); - * - * For engines that do not provide `.__express` out of the box, - * or if you wish to "map" a different extension to the template engine - * you may use this method. For example mapping the EJS template engine to - * ".html" files: - * - * app.engine('html', require('ejs').renderFile); - * - * In this case EJS provides a `.renderFile()` method with - * the same signature that Express expects: `(path, options, callback)`, - * though note that it aliases this method as `ejs.__express` internally - * so if you're using ".ejs" extensions you don't need to do anything. - * - * Some template engines do not follow this convention, the - * [Consolidate.js](https://github.com/tj/consolidate.js) - * library was created to map all of node's popular template - * engines to follow this convention, thus allowing them to - * work seamlessly within Express. - * - * @param {String} ext - * @param {Function} fn - * @return {app} for chaining - * @public - */ +exports.BROWSER_TRACING_INTEGRATION_ID = BROWSER_TRACING_INTEGRATION_ID; +exports.browserTracingIntegration = browserTracingIntegration; +exports.getMetaContent = getMetaContent; +exports.startBrowserTracingNavigationSpan = startBrowserTracingNavigationSpan; +exports.startBrowserTracingPageLoadSpan = startBrowserTracingPageLoadSpan; +//# sourceMappingURL=browserTracingIntegration.js.map -app.engine = function engine(ext, fn) { - if (typeof fn !== 'function') { - throw new Error('callback function required'); - } - // get file extension - var extension = ext[0] !== '.' - ? '.' + ext - : ext; +/***/ }), - // store engine - this.engines[extension] = fn; +/***/ 6087: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - return this; +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const backgroundtab = __nccwpck_require__(55966); +const instrument = __nccwpck_require__(7380); +const index = __nccwpck_require__(5479); +const request = __nccwpck_require__(26896); +const router = __nccwpck_require__(52828); +const types = __nccwpck_require__(49884); + +const BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing'; + +/** Options for Browser Tracing integration */ + +const DEFAULT_BROWSER_TRACING_OPTIONS = { + ...core.TRACING_DEFAULTS, + markBackgroundTransactions: true, + routingInstrumentation: router.instrumentRoutingWithDefaults, + startTransactionOnLocationChange: true, + startTransactionOnPageLoad: true, + enableLongTask: true, + enableInp: false, + interactionsSampleRate: 1, + _experiments: {}, + ...request.defaultRequestInstrumentationOptions, }; +/** We store up to 10 interaction candidates max to cap memory usage. This is the same cap as getINP from web-vitals */ +const MAX_INTERACTIONS = 10; + /** - * Proxy to `Router#param()` with one added api feature. The _name_ parameter - * can be an array of names. + * The Browser Tracing integration automatically instruments browser pageload/navigation + * actions as transactions, and captures requests, metrics and errors as spans. * - * See the Router#param() docs for more details. + * The integration can be configured with a variety of options, and can be extended to use + * any routing library. This integration uses {@see IdleTransaction} to create transactions. * - * @param {String|Array} name - * @param {Function} fn - * @return {app} for chaining - * @public + * @deprecated Use `browserTracingIntegration()` instead. */ +class BrowserTracing { + // This class currently doesn't have a static `id` field like the other integration classes, because it prevented + // @sentry/tracing from being treeshaken. Tree shakers do not like static fields, because they behave like side effects. + // TODO: Come up with a better plan, than using static fields on integration classes, and use that plan on all + // integrations. -app.param = function param(name, fn) { - this.lazyrouter(); + /** Browser Tracing integration options */ - if (Array.isArray(name)) { - for (var i = 0; i < name.length; i++) { - this.param(name[i], fn); - } + /** + * @inheritDoc + */ - return this; - } + // eslint-disable-next-line deprecation/deprecation - this._router.param(name, fn); + constructor(_options) { + this.name = BROWSER_TRACING_INTEGRATION_ID; + this._hasSetTracePropagationTargets = false; - return this; -}; + core.addTracingExtensions(); -/** - * Assign `setting` to `val`, or return `setting`'s value. - * - * app.set('foo', 'bar'); - * app.set('foo'); - * // => "bar" - * - * Mounted servers inherit their parent server's settings. - * - * @param {String} setting - * @param {*} [val] - * @return {Server} for chaining - * @public - */ + if (debugBuild.DEBUG_BUILD) { + this._hasSetTracePropagationTargets = !!( + _options && + // eslint-disable-next-line deprecation/deprecation + (_options.tracePropagationTargets || _options.tracingOrigins) + ); + } -app.set = function set(setting, val) { - if (arguments.length === 1) { - // app.get(setting) - var settings = this.settings + this.options = { + ...DEFAULT_BROWSER_TRACING_OPTIONS, + ..._options, + }; - while (settings && settings !== Object.prototype) { - if (hasOwnProperty.call(settings, setting)) { - return settings[setting] - } + // Special case: enableLongTask can be set in _experiments + // TODO (v8): Remove this in v8 + if (this.options._experiments.enableLongTask !== undefined) { + this.options.enableLongTask = this.options._experiments.enableLongTask; + } - settings = Object.getPrototypeOf(settings) + // TODO (v8): remove this block after tracingOrigins is removed + // Set tracePropagationTargets to tracingOrigins if specified by the user + // In case both are specified, tracePropagationTargets takes precedence + // eslint-disable-next-line deprecation/deprecation + if (_options && !_options.tracePropagationTargets && _options.tracingOrigins) { + // eslint-disable-next-line deprecation/deprecation + this.options.tracePropagationTargets = _options.tracingOrigins; } - return undefined + this._collectWebVitals = index.startTrackingWebVitals(); + /** Stores a mapping of interactionIds from PerformanceEventTimings to the origin interaction path */ + this._interactionIdToRouteNameMapping = {}; + + if (this.options.enableInp) { + index.startTrackingINP(this._interactionIdToRouteNameMapping, this.options.interactionsSampleRate); + } + if (this.options.enableLongTask) { + index.startTrackingLongTasks(); + } + if (this.options._experiments.enableInteractions) { + index.startTrackingInteractions(); + } + + this._latestRoute = { + name: undefined, + context: undefined, + }; } - debug('set "%s" to %o', setting, val); + /** + * @inheritDoc + */ + // eslint-disable-next-line deprecation/deprecation + setupOnce(_, getCurrentHub) { + this._getCurrentHub = getCurrentHub; + const hub = getCurrentHub(); + // eslint-disable-next-line deprecation/deprecation + const client = hub.getClient(); + const clientOptions = client && client.getOptions(); - // set value - this.settings[setting] = val; + const { + routingInstrumentation: instrumentRouting, + startTransactionOnLocationChange, + startTransactionOnPageLoad, + markBackgroundTransactions, + traceFetch, + traceXHR, + shouldCreateSpanForRequest, + enableHTTPTimings, + _experiments, + } = this.options; + + const clientOptionsTracePropagationTargets = clientOptions && clientOptions.tracePropagationTargets; + // There are three ways to configure tracePropagationTargets: + // 1. via top level client option `tracePropagationTargets` + // 2. via BrowserTracing option `tracePropagationTargets` + // 3. via BrowserTracing option `tracingOrigins` (deprecated) + // + // To avoid confusion, favour top level client option `tracePropagationTargets`, and fallback to + // BrowserTracing option `tracePropagationTargets` and then `tracingOrigins` (deprecated). + // This is done as it minimizes bundle size (we don't have to have undefined checks). + // + // If both 1 and either one of 2 or 3 are set (from above), we log out a warning. + // eslint-disable-next-line deprecation/deprecation + const tracePropagationTargets = clientOptionsTracePropagationTargets || this.options.tracePropagationTargets; + if (debugBuild.DEBUG_BUILD && this._hasSetTracePropagationTargets && clientOptionsTracePropagationTargets) { + utils.logger.warn( + '[Tracing] The `tracePropagationTargets` option was set in the BrowserTracing integration and top level `Sentry.init`. The top level `Sentry.init` value is being used.', + ); + } - // trigger matched settings - switch (setting) { - case 'etag': - this.set('etag fn', compileETag(val)); - break; - case 'query parser': - this.set('query parser fn', compileQueryParser(val)); - break; - case 'trust proxy': - this.set('trust proxy fn', compileTrust(val)); + instrumentRouting( + (context) => { + const transaction = this._createRouteTransaction(context); - // trust proxy inherit back-compat - Object.defineProperty(this.settings, trustProxyDefaultSymbol, { - configurable: true, - value: false - }); + this.options._experiments.onStartRouteTransaction && + this.options._experiments.onStartRouteTransaction(transaction, context, getCurrentHub); - break; - } + return transaction; + }, + startTransactionOnPageLoad, + startTransactionOnLocationChange, + ); - return this; -}; + if (markBackgroundTransactions) { + backgroundtab.registerBackgroundTabDetection(); + } -/** - * Return the app's absolute pathname - * based on the parent(s) that have - * mounted it. - * - * For example if the application was - * mounted as "/admin", which itself - * was mounted as "/blog" then the - * return value would be "/blog/admin". - * - * @return {String} - * @private - */ + if (_experiments.enableInteractions) { + this._registerInteractionListener(); + } -app.path = function path() { - return this.parent - ? this.parent.path() + this.mountpath - : ''; -}; + if (this.options.enableInp) { + this._registerInpInteractionListener(); + } -/** - * Check if `setting` is enabled (truthy). - * - * app.enabled('foo') - * // => false - * - * app.enable('foo') - * app.enabled('foo') - * // => true - * - * @param {String} setting - * @return {Boolean} - * @public - */ + request.instrumentOutgoingRequests({ + traceFetch, + traceXHR, + tracePropagationTargets, + shouldCreateSpanForRequest, + enableHTTPTimings, + }); + } -app.enabled = function enabled(setting) { - return Boolean(this.set(setting)); -}; + /** Create routing idle transaction. */ + _createRouteTransaction(context) { + if (!this._getCurrentHub) { + debugBuild.DEBUG_BUILD && + utils.logger.warn(`[Tracing] Did not create ${context.op} transaction because _getCurrentHub is invalid.`); + return undefined; + } -/** - * Check if `setting` is disabled. - * - * app.disabled('foo') - * // => true - * - * app.enable('foo') - * app.disabled('foo') - * // => false - * - * @param {String} setting - * @return {Boolean} - * @public - */ + const hub = this._getCurrentHub(); -app.disabled = function disabled(setting) { - return !this.set(setting); -}; + const { beforeNavigate, idleTimeout, finalTimeout, heartbeatInterval } = this.options; -/** - * Enable `setting`. - * - * @param {String} setting - * @return {app} for chaining - * @public - */ + const isPageloadTransaction = context.op === 'pageload'; -app.enable = function enable(setting) { - return this.set(setting, true); -}; + let expandedContext; + if (isPageloadTransaction) { + const sentryTrace = isPageloadTransaction ? getMetaContent('sentry-trace') : ''; + const baggage = isPageloadTransaction ? getMetaContent('baggage') : undefined; + const { traceId, dsc, parentSpanId, sampled } = utils.propagationContextFromHeaders(sentryTrace, baggage); + expandedContext = { + traceId, + parentSpanId, + parentSampled: sampled, + ...context, + metadata: { + // eslint-disable-next-line deprecation/deprecation + ...context.metadata, + dynamicSamplingContext: dsc, + }, + trimEnd: true, + }; + } else { + expandedContext = { + trimEnd: true, + ...context, + }; + } -/** - * Disable `setting`. - * - * @param {String} setting - * @return {app} for chaining - * @public - */ + const modifiedContext = typeof beforeNavigate === 'function' ? beforeNavigate(expandedContext) : expandedContext; -app.disable = function disable(setting) { - return this.set(setting, false); -}; + // For backwards compatibility reasons, beforeNavigate can return undefined to "drop" the transaction (prevent it + // from being sent to Sentry). + const finalContext = modifiedContext === undefined ? { ...expandedContext, sampled: false } : modifiedContext; -/** - * Delegate `.VERB(...)` calls to `router.VERB(...)`. - */ + // If `beforeNavigate` set a custom name, record that fact + // eslint-disable-next-line deprecation/deprecation + finalContext.metadata = + finalContext.name !== expandedContext.name + ? // eslint-disable-next-line deprecation/deprecation + { ...finalContext.metadata, source: 'custom' } + : // eslint-disable-next-line deprecation/deprecation + finalContext.metadata; -methods.forEach(function(method){ - app[method] = function(path){ - if (method === 'get' && arguments.length === 1) { - // app.get(setting) - return this.set(path); + this._latestRoute.name = finalContext.name; + this._latestRoute.context = finalContext; + + // eslint-disable-next-line deprecation/deprecation + if (finalContext.sampled === false) { + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Will not send ${finalContext.op} transaction because of beforeNavigate.`); } - this.lazyrouter(); + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Starting ${finalContext.op} transaction on scope`); - var route = this._router.route(path); - route[method].apply(route, slice.call(arguments, 1)); - return this; - }; -}); + const { location } = types.WINDOW; -/** - * Special-cased "all" method, applying the given route `path`, - * middleware, and callback to _every_ HTTP method. - * - * @param {String} path - * @param {Function} ... - * @return {app} for chaining - * @public - */ + const idleTransaction = core.startIdleTransaction( + hub, + finalContext, + idleTimeout, + finalTimeout, + true, + { location }, // for use in the tracesSampler + heartbeatInterval, + isPageloadTransaction, // should wait for finish signal if it's a pageload transaction + ); -app.all = function all(path) { - this.lazyrouter(); + if (isPageloadTransaction) { + if (types.WINDOW.document) { + types.WINDOW.document.addEventListener('readystatechange', () => { + if (['interactive', 'complete'].includes(types.WINDOW.document.readyState)) { + idleTransaction.sendAutoFinishSignal(); + } + }); - var route = this._router.route(path); - var args = slice.call(arguments, 1); + if (['interactive', 'complete'].includes(types.WINDOW.document.readyState)) { + idleTransaction.sendAutoFinishSignal(); + } + } + } - for (var i = 0; i < methods.length; i++) { - route[methods[i]].apply(route, args); + idleTransaction.registerBeforeFinishCallback(transaction => { + this._collectWebVitals(); + index.addPerformanceEntries(transaction); + }); + + return idleTransaction ; } - return this; -}; + /** Start listener for interaction transactions */ + _registerInteractionListener() { + let inflightInteractionTransaction; + const registerInteractionTransaction = () => { + const { idleTimeout, finalTimeout, heartbeatInterval } = this.options; + const op = 'ui.action.click'; -// del -> delete alias + // eslint-disable-next-line deprecation/deprecation + const currentTransaction = core.getActiveTransaction(); + if (currentTransaction && currentTransaction.op && ['navigation', 'pageload'].includes(currentTransaction.op)) { + debugBuild.DEBUG_BUILD && + utils.logger.warn( + `[Tracing] Did not create ${op} transaction because a pageload or navigation transaction is in progress.`, + ); + return undefined; + } -app.del = deprecate.function(app.delete, 'app.del: Use app.delete instead'); + if (inflightInteractionTransaction) { + inflightInteractionTransaction.setFinishReason('interactionInterrupted'); + inflightInteractionTransaction.end(); + inflightInteractionTransaction = undefined; + } -/** - * Render the given view `name` name with `options` - * and a callback accepting an error and the - * rendered template string. - * - * Example: - * - * app.render('email', { name: 'Tobi' }, function(err, html){ - * // ... - * }) - * - * @param {String} name - * @param {Object|Function} options or fn - * @param {Function} callback - * @public - */ + if (!this._getCurrentHub) { + debugBuild.DEBUG_BUILD && utils.logger.warn(`[Tracing] Did not create ${op} transaction because _getCurrentHub is invalid.`); + return undefined; + } -app.render = function render(name, options, callback) { - var cache = this.cache; - var done = callback; - var engines = this.engines; - var opts = options; - var renderOptions = {}; - var view; + if (!this._latestRoute.name) { + debugBuild.DEBUG_BUILD && utils.logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`); + return undefined; + } - // support callback function as second arg - if (typeof options === 'function') { - done = options; - opts = {}; - } + const hub = this._getCurrentHub(); + const { location } = types.WINDOW; - // merge app.locals - merge(renderOptions, this.locals); + const context = { + name: this._latestRoute.name, + op, + trimEnd: true, + data: { + [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: this._latestRoute.context + ? getSource(this._latestRoute.context) + : 'url', + }, + }; - // merge options._locals - if (opts._locals) { - merge(renderOptions, opts._locals); - } - - // merge options - merge(renderOptions, opts); + inflightInteractionTransaction = core.startIdleTransaction( + hub, + context, + idleTimeout, + finalTimeout, + true, + { location }, // for use in the tracesSampler + heartbeatInterval, + ); + }; - // set .cache unless explicitly provided - if (renderOptions.cache == null) { - renderOptions.cache = this.enabled('view cache'); + ['click'].forEach(type => { + if (types.WINDOW.document) { + addEventListener(type, registerInteractionTransaction, { once: false, capture: true }); + } + }); } - // primed cache - if (renderOptions.cache) { - view = cache[name]; + /** Creates a listener on interaction entries, and maps interactionIds to the origin path of the interaction */ + _registerInpInteractionListener() { + const handleEntries = ({ entries }) => { + const client = core.getClient(); + // We need to get the replay, user, and activeTransaction from the current scope + // so that we can associate replay id, profile id, and a user display to the span + const replay = + client !== undefined && client.getIntegrationByName !== undefined + ? (client.getIntegrationByName('Replay') ) + : undefined; + const replayId = replay !== undefined ? replay.getReplayId() : undefined; + // eslint-disable-next-line deprecation/deprecation + const activeTransaction = core.getActiveTransaction(); + const currentScope = core.getCurrentScope(); + const user = currentScope !== undefined ? currentScope.getUser() : undefined; + entries.forEach(entry => { + if (isPerformanceEventTiming(entry)) { + const interactionId = entry.interactionId; + if (interactionId === undefined) { + return; + } + const existingInteraction = this._interactionIdToRouteNameMapping[interactionId]; + const duration = entry.duration; + const startTime = entry.startTime; + const keys = Object.keys(this._interactionIdToRouteNameMapping); + const minInteractionId = + keys.length > 0 + ? keys.reduce((a, b) => { + return this._interactionIdToRouteNameMapping[a].duration < + this._interactionIdToRouteNameMapping[b].duration + ? a + : b; + }) + : undefined; + // For a first input event to be considered, we must check that an interaction event does not already exist with the same duration and start time. + // This is also checked in the web-vitals library. + if (entry.entryType === 'first-input') { + const matchingEntry = keys + .map(key => this._interactionIdToRouteNameMapping[key]) + .some(interaction => { + return interaction.duration === duration && interaction.startTime === startTime; + }); + if (matchingEntry) { + return; + } + } + // Interactions with an id of 0 and are not first-input are not valid. + if (!interactionId) { + return; + } + // If the interaction already exists, we want to use the duration of the longest entry, since that is what the INP metric uses. + if (existingInteraction) { + existingInteraction.duration = Math.max(existingInteraction.duration, duration); + } else if ( + keys.length < MAX_INTERACTIONS || + minInteractionId === undefined || + duration > this._interactionIdToRouteNameMapping[minInteractionId].duration + ) { + // If the interaction does not exist, we want to add it to the mapping if there is space, or if the duration is longer than the shortest entry. + const routeName = this._latestRoute.name; + const parentContext = this._latestRoute.context; + if (routeName && parentContext) { + if (minInteractionId && Object.keys(this._interactionIdToRouteNameMapping).length >= MAX_INTERACTIONS) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete this._interactionIdToRouteNameMapping[minInteractionId]; + } + this._interactionIdToRouteNameMapping[interactionId] = { + routeName, + duration, + parentContext, + user, + activeTransaction, + replayId, + startTime, + }; + } + } + } + }); + }; + instrument.addPerformanceInstrumentationHandler('event', handleEntries); + instrument.addPerformanceInstrumentationHandler('first-input', handleEntries); } +} - // view - if (!view) { - var View = this.get('view'); +/** Returns the value of a meta tag */ +function getMetaContent(metaName) { + // Can't specify generic to `getDomElement` because tracing can be used + // in a variety of environments, have to disable `no-unsafe-member-access` + // as a result. + const metaTag = utils.getDomElement(`meta[name=${metaName}]`); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + return metaTag ? metaTag.getAttribute('content') : undefined; +} - view = new View(name, { - defaultEngine: this.get('view engine'), - root: this.get('views'), - engines: engines - }); +function getSource(context) { + const sourceFromAttributes = context.attributes && context.attributes[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]; + // eslint-disable-next-line deprecation/deprecation + const sourceFromData = context.data && context.data[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]; + // eslint-disable-next-line deprecation/deprecation + const sourceFromMetadata = context.metadata && context.metadata.source; - if (!view.path) { - var dirs = Array.isArray(view.root) && view.root.length > 1 - ? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"' - : 'directory "' + view.root + '"' - var err = new Error('Failed to lookup view "' + name + '" in views ' + dirs); - err.view = view; - return done(err); - } + return sourceFromAttributes || sourceFromData || sourceFromMetadata; +} - // prime the cache - if (renderOptions.cache) { - cache[name] = view; - } - } +function isPerformanceEventTiming(entry) { + return 'duration' in entry; +} - // render - tryRender(view, renderOptions, done); -}; +exports.BROWSER_TRACING_INTEGRATION_ID = BROWSER_TRACING_INTEGRATION_ID; +exports.BrowserTracing = BrowserTracing; +exports.getMetaContent = getMetaContent; +//# sourceMappingURL=browsertracing.js.map + + +/***/ }), + +/***/ 7380: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const getCLS = __nccwpck_require__(61330); +const getFID = __nccwpck_require__(22641); +const getINP = __nccwpck_require__(843); +const getLCP = __nccwpck_require__(67077); +const observe = __nccwpck_require__(70248); +const onTTFB = __nccwpck_require__(54255); + +const handlers = {}; +const instrumented = {}; + +let _previousCls; +let _previousFid; +let _previousLcp; +let _previousTtfb; +let _previousInp; /** - * Listen for connections. - * - * A node `http.Server` is returned, with this - * application (which is a `Function`) as its - * callback. If you wish to create both an HTTP - * and HTTPS server you may do so with the "http" - * and "https" modules as shown here: - * - * var http = require('http') - * , https = require('https') - * , express = require('express') - * , app = express(); - * - * http.createServer(app).listen(80); - * https.createServer({ ... }, app).listen(443); + * Add a callback that will be triggered when a CLS metric is available. + * Returns a cleanup callback which can be called to remove the instrumentation handler. * - * @return {http.Server} - * @public + * Pass `stopOnCallback = true` to stop listening for CLS when the cleanup callback is called. + * This will lead to the CLS being finalized and frozen. */ - -app.listen = function listen() { - var server = http.createServer(this); - return server.listen.apply(server, arguments); -}; +function addClsInstrumentationHandler( + callback, + stopOnCallback = false, +) { + return addMetricObserver('cls', callback, instrumentCls, _previousCls, stopOnCallback); +} /** - * Log error using console.error. + * Add a callback that will be triggered when a LCP metric is available. + * Returns a cleanup callback which can be called to remove the instrumentation handler. * - * @param {Error} err - * @private + * Pass `stopOnCallback = true` to stop listening for LCP when the cleanup callback is called. + * This will lead to the LCP being finalized and frozen. */ +function addLcpInstrumentationHandler( + callback, + stopOnCallback = false, +) { + return addMetricObserver('lcp', callback, instrumentLcp, _previousLcp, stopOnCallback); +} -function logerror(err) { - /* istanbul ignore next */ - if (this.get('env') !== 'test') console.error(err.stack || err.toString()); +/** + * Add a callback that will be triggered when a FID metric is available. + */ +function addTtfbInstrumentationHandler(callback) { + return addMetricObserver('ttfb', callback, instrumentTtfb, _previousTtfb); } /** - * Try rendering a view. - * @private + * Add a callback that will be triggered when a FID metric is available. + * Returns a cleanup callback which can be called to remove the instrumentation handler. */ +function addFidInstrumentationHandler(callback) { + return addMetricObserver('fid', callback, instrumentFid, _previousFid); +} -function tryRender(view, options, callback) { - try { - view.render(options, callback); - } catch (err) { - callback(err); - } +/** + * Add a callback that will be triggered when a INP metric is available. + * Returns a cleanup callback which can be called to remove the instrumentation handler. + */ +function addInpInstrumentationHandler( + callback, +) { + return addMetricObserver('inp', callback, instrumentInp, _previousInp); } +/** + * Add a callback that will be triggered when a performance observer is triggered, + * and receives the entries of the observer. + * Returns a cleanup callback which can be called to remove the instrumentation handler. + */ +function addPerformanceInstrumentationHandler( + type, + callback, +) { + addHandler(type, callback); -/***/ }), + if (!instrumented[type]) { + instrumentPerformanceObserver(type); + instrumented[type] = true; + } -/***/ 76657: -/***/ ((module, exports, __nccwpck_require__) => { + return getCleanupCallback(type, callback); +} -"use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2013 Roman Shtylman - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ +/** Trigger all handlers of a given type. */ +function triggerHandlers(type, data) { + const typeHandlers = handlers[type]; + if (!typeHandlers || !typeHandlers.length) { + return; + } + for (const handler of typeHandlers) { + try { + handler(data); + } catch (e) { + debugBuild.DEBUG_BUILD && + utils.logger.error( + `Error while triggering instrumentation handler.\nType: ${type}\nName: ${utils.getFunctionName(handler)}\nError:`, + e, + ); + } + } +} -/** - * Module dependencies. - */ +function instrumentCls() { + return getCLS.onCLS( + metric => { + triggerHandlers('cls', { + metric, + }); + _previousCls = metric; + }, + { reportAllChanges: true }, + ); +} -var bodyParser = __nccwpck_require__(40129) -var EventEmitter = (__nccwpck_require__(24434).EventEmitter); -var mixin = __nccwpck_require__(60489); -var proto = __nccwpck_require__(65095); -var Route = __nccwpck_require__(67178); -var Router = __nccwpck_require__(85055); -var req = __nccwpck_require__(83412); -var res = __nccwpck_require__(73606); +function instrumentFid() { + return getFID.onFID(metric => { + triggerHandlers('fid', { + metric, + }); + _previousFid = metric; + }); +} -/** - * Expose `createApplication()`. - */ +function instrumentLcp() { + return getLCP.onLCP(metric => { + triggerHandlers('lcp', { + metric, + }); + _previousLcp = metric; + }); +} -exports = module.exports = createApplication; +function instrumentTtfb() { + return onTTFB.onTTFB(metric => { + triggerHandlers('ttfb', { + metric, + }); + _previousTtfb = metric; + }); +} -/** - * Create an express application. - * - * @return {Function} - * @api public - */ +function instrumentInp() { + return getINP.onINP(metric => { + triggerHandlers('inp', { + metric, + }); + _previousInp = metric; + }); +} -function createApplication() { - var app = function(req, res, next) { - app.handle(req, res, next); - }; +function addMetricObserver( + type, + callback, + instrumentFn, + previousValue, + stopOnCallback = false, +) { + addHandler(type, callback); - mixin(app, EventEmitter.prototype, false); - mixin(app, proto, false); + let stopListening; - // expose the prototype that will get set on requests - app.request = Object.create(req, { - app: { configurable: true, enumerable: true, writable: true, value: app } - }) + if (!instrumented[type]) { + stopListening = instrumentFn(); + instrumented[type] = true; + } - // expose the prototype that will get set on responses - app.response = Object.create(res, { - app: { configurable: true, enumerable: true, writable: true, value: app } - }) + if (previousValue) { + callback({ metric: previousValue }); + } - app.init(); - return app; + return getCleanupCallback(type, callback, stopOnCallback ? stopListening : undefined); } -/** - * Expose the prototypes. - */ +function instrumentPerformanceObserver(type) { + const options = {}; -exports.application = proto; -exports.request = req; -exports.response = res; + // Special per-type options we want to use + if (type === 'event') { + options.durationThreshold = 0; + } -/** - * Expose constructors. - */ + observe.observe( + type, + entries => { + triggerHandlers(type, { entries }); + }, + options, + ); +} -exports.Route = Route; -exports.Router = Router; +function addHandler(type, handler) { + handlers[type] = handlers[type] || []; + (handlers[type] ).push(handler); +} -/** - * Expose middleware - */ +// Get a callback which can be called to remove the instrumentation handler +function getCleanupCallback( + type, + callback, + stopListening, +) { + return () => { + if (stopListening) { + stopListening(); + } -exports.json = bodyParser.json -exports.query = __nccwpck_require__(90030); -exports.raw = bodyParser.raw -exports["static"] = __nccwpck_require__(65687); -exports.text = bodyParser.text -exports.urlencoded = bodyParser.urlencoded + const typeHandlers = handlers[type]; -/** - * Replace removed middleware with an appropriate error message. - */ + if (!typeHandlers) { + return; + } -var removedMiddlewares = [ - 'bodyParser', - 'compress', - 'cookieSession', - 'session', - 'logger', - 'cookieParser', - 'favicon', - 'responseTime', - 'errorHandler', - 'timeout', - 'methodOverride', - 'vhost', - 'csrf', - 'directory', - 'limit', - 'multipart', - 'staticCache' -] + const index = typeHandlers.indexOf(callback); + if (index !== -1) { + typeHandlers.splice(index, 1); + } + }; +} -removedMiddlewares.forEach(function (name) { - Object.defineProperty(exports, name, { - get: function () { - throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.'); - }, - configurable: true - }); -}); +exports.addClsInstrumentationHandler = addClsInstrumentationHandler; +exports.addFidInstrumentationHandler = addFidInstrumentationHandler; +exports.addInpInstrumentationHandler = addInpInstrumentationHandler; +exports.addLcpInstrumentationHandler = addLcpInstrumentationHandler; +exports.addPerformanceInstrumentationHandler = addPerformanceInstrumentationHandler; +exports.addTtfbInstrumentationHandler = addTtfbInstrumentationHandler; +//# sourceMappingURL=instrument.js.map /***/ }), -/***/ 95986: +/***/ 5479: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2013 Roman Shtylman - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const instrument = __nccwpck_require__(7380); +const types = __nccwpck_require__(49884); +const getVisibilityWatcher = __nccwpck_require__(82450); +const utils$1 = __nccwpck_require__(30802); +const getNavigationEntry = __nccwpck_require__(78640); +const MAX_INT_AS_BYTES = 2147483647; /** - * Module dependencies. - * @private + * Converts from milliseconds to seconds + * @param time time in ms */ +function msToSec(time) { + return time / 1000; +} -var setPrototypeOf = __nccwpck_require__(12516) +function getBrowserPerformanceAPI() { + // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are + return types.WINDOW && types.WINDOW.addEventListener && types.WINDOW.performance; +} + +let _performanceCursor = 0; + +let _measurements = {}; +let _lcpEntry; +let _clsEntry; /** - * Initialization middleware, exposing the - * request and response to each other, as well - * as defaulting the X-Powered-By header field. + * Start tracking web vitals. + * The callback returned by this function can be used to stop tracking & ensure all measurements are final & captured. * - * @param {Function} app - * @return {Function} - * @api private + * @returns A function that forces web vitals collection */ +function startTrackingWebVitals() { + const performance = getBrowserPerformanceAPI(); + if (performance && utils.browserPerformanceTimeOrigin) { + // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are + if (performance.mark) { + types.WINDOW.performance.mark('sentry-tracing-init'); + } + const fidCallback = _trackFID(); + const clsCallback = _trackCLS(); + const lcpCallback = _trackLCP(); + const ttfbCallback = _trackTtfb(); -exports.init = function(app){ - return function expressInit(req, res, next){ - if (app.enabled('x-powered-by')) res.setHeader('X-Powered-By', 'Express'); - req.res = res; - res.req = req; - req.next = next; + return () => { + fidCallback(); + clsCallback(); + lcpCallback(); + ttfbCallback(); + }; + } - setPrototypeOf(req, app.request) - setPrototypeOf(res, app.response) + return () => undefined; +} - res.locals = res.locals || Object.create(null); +/** + * Start tracking long tasks. + */ +function startTrackingLongTasks() { + instrument.addPerformanceInstrumentationHandler('longtask', ({ entries }) => { + for (const entry of entries) { + // eslint-disable-next-line deprecation/deprecation + const transaction = core.getActiveTransaction() ; + if (!transaction) { + return; + } + const startTime = msToSec((utils.browserPerformanceTimeOrigin ) + entry.startTime); + const duration = msToSec(entry.duration); - next(); - }; -}; + // eslint-disable-next-line deprecation/deprecation + transaction.startChild({ + description: 'Main UI thread blocked', + op: 'ui.long-task', + origin: 'auto.ui.browser.metrics', + startTimestamp: startTime, + endTimestamp: startTime + duration, + }); + } + }); +} +/** + * Start tracking interaction events. + */ +function startTrackingInteractions() { + instrument.addPerformanceInstrumentationHandler('event', ({ entries }) => { + for (const entry of entries) { + // eslint-disable-next-line deprecation/deprecation + const transaction = core.getActiveTransaction() ; + if (!transaction) { + return; + } + if (entry.name === 'click') { + const startTime = msToSec((utils.browserPerformanceTimeOrigin ) + entry.startTime); + const duration = msToSec(entry.duration); -/***/ }), + const span = { + description: utils.htmlTreeAsString(entry.target), + op: `ui.interaction.${entry.name}`, + origin: 'auto.ui.browser.metrics', + startTimestamp: startTime, + endTimestamp: startTime + duration, + }; -/***/ 90030: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const componentName = utils.getComponentName(entry.target); + if (componentName) { + span.attributes = { 'ui.component_name': componentName }; + } -"use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2013 Roman Shtylman - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed + // eslint-disable-next-line deprecation/deprecation + transaction.startChild(span); + } + } + }); +} + +/** + * Start tracking INP webvital events. */ +function startTrackingINP( + interactionIdtoRouteNameMapping, + interactionsSampleRate, +) { + const performance = getBrowserPerformanceAPI(); + if (performance && utils.browserPerformanceTimeOrigin) { + const inpCallback = _trackINP(interactionIdtoRouteNameMapping, interactionsSampleRate); + return () => { + inpCallback(); + }; + } + return () => undefined; +} -/** - * Module dependencies. - */ +/** Starts tracking the Cumulative Layout Shift on the current page. */ +function _trackCLS() { + return instrument.addClsInstrumentationHandler(({ metric }) => { + const entry = metric.entries[metric.entries.length - 1]; + if (!entry) { + return; + } -var merge = __nccwpck_require__(31657) -var parseUrl = __nccwpck_require__(23610); -var qs = __nccwpck_require__(91833); + debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding CLS'); + _measurements['cls'] = { value: metric.value, unit: '' }; + _clsEntry = entry ; + }, true); +} -/** - * @param {Object} options - * @return {Function} - * @api public - */ +/** Starts tracking the Largest Contentful Paint on the current page. */ +function _trackLCP() { + return instrument.addLcpInstrumentationHandler(({ metric }) => { + const entry = metric.entries[metric.entries.length - 1]; + if (!entry) { + return; + } -module.exports = function query(options) { - var opts = merge({}, options) - var queryparse = qs.parse; + debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding LCP'); + _measurements['lcp'] = { value: metric.value, unit: 'millisecond' }; + _lcpEntry = entry ; + }, true); +} - if (typeof options === 'function') { - queryparse = options; - opts = undefined; - } +/** Starts tracking the First Input Delay on the current page. */ +function _trackFID() { + return instrument.addFidInstrumentationHandler(({ metric }) => { + const entry = metric.entries[metric.entries.length - 1]; + if (!entry) { + return; + } - if (opts !== undefined && opts.allowPrototypes === undefined) { - // back-compat for qs module - opts.allowPrototypes = true; - } + const timeOrigin = msToSec(utils.browserPerformanceTimeOrigin ); + const startTime = msToSec(entry.startTime); + debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding FID'); + _measurements['fid'] = { value: metric.value, unit: 'millisecond' }; + _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' }; + }); +} - return function query(req, res, next){ - if (!req.query) { - var val = parseUrl(req).query; - req.query = queryparse(val, opts); +function _trackTtfb() { + return instrument.addTtfbInstrumentationHandler(({ metric }) => { + const entry = metric.entries[metric.entries.length - 1]; + if (!entry) { + return; } - next(); - }; + debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding TTFB'); + _measurements['ttfb'] = { value: metric.value, unit: 'millisecond' }; + }); +} + +const INP_ENTRY_MAP = { + click: 'click', + pointerdown: 'click', + pointerup: 'click', + mousedown: 'click', + mouseup: 'click', + touchstart: 'click', + touchend: 'click', + mouseover: 'hover', + mouseout: 'hover', + mouseenter: 'hover', + mouseleave: 'hover', + pointerover: 'hover', + pointerout: 'hover', + pointerenter: 'hover', + pointerleave: 'hover', + dragstart: 'drag', + dragend: 'drag', + drag: 'drag', + dragenter: 'drag', + dragleave: 'drag', + dragover: 'drag', + drop: 'drag', + keydown: 'press', + keyup: 'press', + keypress: 'press', + input: 'press', }; +/** Starts tracking the Interaction to Next Paint on the current page. */ +function _trackINP( + interactionIdToRouteNameMapping, + interactionsSampleRate, +) { + return instrument.addInpInstrumentationHandler(({ metric }) => { + if (metric.value === undefined) { + return; + } + const entry = metric.entries.find( + entry => entry.duration === metric.value && INP_ENTRY_MAP[entry.name] !== undefined, + ); + const client = core.getClient(); + if (!entry || !client) { + return; + } + const interactionType = INP_ENTRY_MAP[entry.name]; + const options = client.getOptions(); + /** Build the INP span, create an envelope from the span, and then send the envelope */ + const startTime = msToSec((utils.browserPerformanceTimeOrigin ) + entry.startTime); + const duration = msToSec(metric.value); + const interaction = + entry.interactionId !== undefined ? interactionIdToRouteNameMapping[entry.interactionId] : undefined; + if (interaction === undefined) { + return; + } + const { routeName, parentContext, activeTransaction, user, replayId } = interaction; + const userDisplay = user !== undefined ? user.email || user.id || user.ip_address : undefined; + // eslint-disable-next-line deprecation/deprecation + const profileId = activeTransaction !== undefined ? activeTransaction.getProfileId() : undefined; + const span = new core.Span({ + startTimestamp: startTime, + endTimestamp: startTime + duration, + op: `ui.interaction.${interactionType}`, + name: utils.htmlTreeAsString(entry.target), + attributes: { + release: options.release, + environment: options.environment, + transaction: routeName, + ...(userDisplay !== undefined && userDisplay !== '' ? { user: userDisplay } : {}), + ...(profileId !== undefined ? { profile_id: profileId } : {}), + ...(replayId !== undefined ? { replay_id: replayId } : {}), + }, + exclusiveTime: metric.value, + measurements: { + inp: { value: metric.value, unit: 'millisecond' }, + }, + }); -/***/ }), + /** Check to see if the span should be sampled */ + const sampleRate = getSampleRate(parentContext, options, interactionsSampleRate); -/***/ 83412: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!sampleRate) { + return; + } -"use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2013 Roman Shtylman - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ + if (Math.random() < (sampleRate )) { + const envelope = span ? core.createSpanEnvelope([span], client.getDsn()) : undefined; + const transport = client && client.getTransport(); + if (transport && envelope) { + transport.send(envelope).then(null, reason => { + debugBuild.DEBUG_BUILD && utils.logger.error('Error while sending interaction:', reason); + }); + } + return; + } + }); +} +/** Add performance related spans to a transaction */ +function addPerformanceEntries(transaction) { + const performance = getBrowserPerformanceAPI(); + if (!performance || !types.WINDOW.performance.getEntries || !utils.browserPerformanceTimeOrigin) { + // Gatekeeper if performance API not available + return; + } + debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] Adding & adjusting spans using Performance API'); + const timeOrigin = msToSec(utils.browserPerformanceTimeOrigin); -/** - * Module dependencies. - * @private - */ + const performanceEntries = performance.getEntries(); -var accepts = __nccwpck_require__(23693); -var deprecate = __nccwpck_require__(77267)('express'); -var isIP = (__nccwpck_require__(69278).isIP); -var typeis = __nccwpck_require__(54693); -var http = __nccwpck_require__(58611); -var fresh = __nccwpck_require__(42825); -var parseRange = __nccwpck_require__(56807); -var parse = __nccwpck_require__(23610); -var proxyaddr = __nccwpck_require__(83198); + const { op, start_timestamp: transactionStartTime } = core.spanToJSON(transaction); -/** - * Request prototype. - * @public - */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + performanceEntries.slice(_performanceCursor).forEach((entry) => { + const startTime = msToSec(entry.startTime); + const duration = msToSec(entry.duration); -var req = Object.create(http.IncomingMessage.prototype) + // eslint-disable-next-line deprecation/deprecation + if (transaction.op === 'navigation' && transactionStartTime && timeOrigin + startTime < transactionStartTime) { + return; + } -/** - * Module exports. - * @public - */ + switch (entry.entryType) { + case 'navigation': { + _addNavigationSpans(transaction, entry, timeOrigin); + break; + } + case 'mark': + case 'paint': + case 'measure': { + _addMeasureSpans(transaction, entry, startTime, duration, timeOrigin); -module.exports = req + // capture web vitals + const firstHidden = getVisibilityWatcher.getVisibilityWatcher(); + // Only report if the page wasn't hidden prior to the web vital. + const shouldRecord = entry.startTime < firstHidden.firstHiddenTime; -/** - * Return request header. - * - * The `Referrer` header field is special-cased, - * both `Referrer` and `Referer` are interchangeable. - * - * Examples: - * - * req.get('Content-Type'); - * // => "text/plain" - * - * req.get('content-type'); - * // => "text/plain" - * - * req.get('Something'); - * // => undefined - * - * Aliased as `req.header()`. - * - * @param {String} name - * @return {String} - * @public - */ + if (entry.name === 'first-paint' && shouldRecord) { + debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding FP'); + _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' }; + } + if (entry.name === 'first-contentful-paint' && shouldRecord) { + debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding FCP'); + _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' }; + } + break; + } + case 'resource': { + _addResourceSpans(transaction, entry, entry.name , startTime, duration, timeOrigin); + break; + } + // Ignore other entry types. + } + }); -req.get = -req.header = function header(name) { - if (!name) { - throw new TypeError('name argument is required to req.get'); - } + _performanceCursor = Math.max(performanceEntries.length - 1, 0); - if (typeof name !== 'string') { - throw new TypeError('name must be a string to req.get'); - } + _trackNavigator(transaction); - var lc = name.toLowerCase(); + // Measurements are only available for pageload transactions + if (op === 'pageload') { + _addTtfbRequestTimeToMeasurements(_measurements); - switch (lc) { - case 'referer': - case 'referrer': - return this.headers.referrer - || this.headers.referer; - default: - return this.headers[lc]; + ['fcp', 'fp', 'lcp'].forEach(name => { + if (!_measurements[name] || !transactionStartTime || timeOrigin >= transactionStartTime) { + return; + } + // The web vitals, fcp, fp, lcp, and ttfb, all measure relative to timeOrigin. + // Unfortunately, timeOrigin is not captured within the transaction span data, so these web vitals will need + // to be adjusted to be relative to transaction.startTimestamp. + const oldValue = _measurements[name].value; + const measurementTimestamp = timeOrigin + msToSec(oldValue); + + // normalizedValue should be in milliseconds + const normalizedValue = Math.abs((measurementTimestamp - transactionStartTime) * 1000); + const delta = normalizedValue - oldValue; + + debugBuild.DEBUG_BUILD && utils.logger.log(`[Measurements] Normalized ${name} from ${oldValue} to ${normalizedValue} (${delta})`); + _measurements[name].value = normalizedValue; + }); + + const fidMark = _measurements['mark.fid']; + if (fidMark && _measurements['fid']) { + // create span for FID + utils$1._startChild(transaction, { + description: 'first input delay', + endTimestamp: fidMark.value + msToSec(_measurements['fid'].value), + op: 'ui.action', + origin: 'auto.ui.browser.metrics', + startTimestamp: fidMark.value, + }); + + // Delete mark.fid as we don't want it to be part of final payload + delete _measurements['mark.fid']; + } + + // If FCP is not recorded we should not record the cls value + // according to the new definition of CLS. + if (!('fcp' in _measurements)) { + delete _measurements.cls; + } + + Object.keys(_measurements).forEach(measurementName => { + core.setMeasurement(measurementName, _measurements[measurementName].value, _measurements[measurementName].unit); + }); + + _tagMetricInfo(transaction); } -}; -/** - * To do: update docs. - * - * Check if the given `type(s)` is acceptable, returning - * the best match when true, otherwise `undefined`, in which - * case you should respond with 406 "Not Acceptable". - * - * The `type` value may be a single MIME type string - * such as "application/json", an extension name - * such as "json", a comma-delimited list such as "json, html, text/plain", - * an argument list such as `"json", "html", "text/plain"`, - * or an array `["json", "html", "text/plain"]`. When a list - * or array is given, the _best_ match, if any is returned. - * - * Examples: - * - * // Accept: text/html - * req.accepts('html'); - * // => "html" - * - * // Accept: text/*, application/json - * req.accepts('html'); - * // => "html" - * req.accepts('text/html'); - * // => "text/html" - * req.accepts('json, text'); - * // => "json" - * req.accepts('application/json'); - * // => "application/json" - * - * // Accept: text/*, application/json - * req.accepts('image/png'); - * req.accepts('png'); - * // => undefined - * - * // Accept: text/*;q=.5, application/json - * req.accepts(['html', 'json']); - * req.accepts('html', 'json'); - * req.accepts('html, json'); - * // => "json" - * - * @param {String|Array} type(s) - * @return {String|Array|Boolean} - * @public - */ + _lcpEntry = undefined; + _clsEntry = undefined; + _measurements = {}; +} -req.accepts = function(){ - var accept = accepts(this); - return accept.types.apply(accept, arguments); -}; +/** Create measure related spans */ +function _addMeasureSpans( + transaction, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + entry, + startTime, + duration, + timeOrigin, +) { + const measureStartTimestamp = timeOrigin + startTime; + const measureEndTimestamp = measureStartTimestamp + duration; + + utils$1._startChild(transaction, { + description: entry.name , + endTimestamp: measureEndTimestamp, + op: entry.entryType , + origin: 'auto.resource.browser.metrics', + startTimestamp: measureStartTimestamp, + }); -/** - * Check if the given `encoding`s are accepted. - * - * @param {String} ...encoding - * @return {String|Array} - * @public - */ + return measureStartTimestamp; +} -req.acceptsEncodings = function(){ - var accept = accepts(this); - return accept.encodings.apply(accept, arguments); -}; +/** Instrument navigation entries */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function _addNavigationSpans(transaction, entry, timeOrigin) { + ['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'].forEach(event => { + _addPerformanceNavigationTiming(transaction, entry, event, timeOrigin); + }); + _addPerformanceNavigationTiming(transaction, entry, 'secureConnection', timeOrigin, 'TLS/SSL', 'connectEnd'); + _addPerformanceNavigationTiming(transaction, entry, 'fetch', timeOrigin, 'cache', 'domainLookupStart'); + _addPerformanceNavigationTiming(transaction, entry, 'domainLookup', timeOrigin, 'DNS'); + _addRequest(transaction, entry, timeOrigin); +} + +/** Create performance navigation related spans */ +function _addPerformanceNavigationTiming( + transaction, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + entry, + event, + timeOrigin, + description, + eventEnd, +) { + const end = eventEnd ? (entry[eventEnd] ) : (entry[`${event}End`] ); + const start = entry[`${event}Start`] ; + if (!start || !end) { + return; + } + utils$1._startChild(transaction, { + op: 'browser', + origin: 'auto.browser.browser.metrics', + description: description || event, + startTimestamp: timeOrigin + msToSec(start), + endTimestamp: timeOrigin + msToSec(end), + }); +} -req.acceptsEncoding = deprecate.function(req.acceptsEncodings, - 'req.acceptsEncoding: Use acceptsEncodings instead'); +/** Create request and response related spans */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function _addRequest(transaction, entry, timeOrigin) { + if (entry.responseEnd) { + // It is possible that we are collecting these metrics when the page hasn't finished loading yet, for example when the HTML slowly streams in. + // In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0. + // In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect + // these spans when the responseEnd value is available. The backend (Relay) would drop the entire transaction if it contained faulty spans. + utils$1._startChild(transaction, { + op: 'browser', + origin: 'auto.browser.browser.metrics', + description: 'request', + startTimestamp: timeOrigin + msToSec(entry.requestStart ), + endTimestamp: timeOrigin + msToSec(entry.responseEnd ), + }); -/** - * Check if the given `charset`s are acceptable, - * otherwise you should respond with 406 "Not Acceptable". - * - * @param {String} ...charset - * @return {String|Array} - * @public - */ + utils$1._startChild(transaction, { + op: 'browser', + origin: 'auto.browser.browser.metrics', + description: 'response', + startTimestamp: timeOrigin + msToSec(entry.responseStart ), + endTimestamp: timeOrigin + msToSec(entry.responseEnd ), + }); + } +} -req.acceptsCharsets = function(){ - var accept = accepts(this); - return accept.charsets.apply(accept, arguments); -}; +/** Create resource-related spans */ +function _addResourceSpans( + transaction, + entry, + resourceUrl, + startTime, + duration, + timeOrigin, +) { + // we already instrument based on fetch and xhr, so we don't need to + // duplicate spans here. + if (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') { + return; + } -req.acceptsCharset = deprecate.function(req.acceptsCharsets, - 'req.acceptsCharset: Use acceptsCharsets instead'); + const parsedUrl = utils.parseUrl(resourceUrl); -/** - * Check if the given `lang`s are acceptable, - * otherwise you should respond with 406 "Not Acceptable". - * - * @param {String} ...lang - * @return {String|Array} - * @public - */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const data = {}; + setResourceEntrySizeData(data, entry, 'transferSize', 'http.response_transfer_size'); + setResourceEntrySizeData(data, entry, 'encodedBodySize', 'http.response_content_length'); + setResourceEntrySizeData(data, entry, 'decodedBodySize', 'http.decoded_response_content_length'); -req.acceptsLanguages = function(){ - var accept = accepts(this); - return accept.languages.apply(accept, arguments); -}; + if ('renderBlockingStatus' in entry) { + data['resource.render_blocking_status'] = entry.renderBlockingStatus; + } + if (parsedUrl.protocol) { + data['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it. + } -req.acceptsLanguage = deprecate.function(req.acceptsLanguages, - 'req.acceptsLanguage: Use acceptsLanguages instead'); + if (parsedUrl.host) { + data['server.address'] = parsedUrl.host; + } -/** - * Parse Range header field, capping to the given `size`. - * - * Unspecified ranges such as "0-" require knowledge of your resource length. In - * the case of a byte range this is of course the total number of bytes. If the - * Range header field is not given `undefined` is returned, `-1` when unsatisfiable, - * and `-2` when syntactically invalid. - * - * When ranges are returned, the array has a "type" property which is the type of - * range that is required (most commonly, "bytes"). Each array element is an object - * with a "start" and "end" property for the portion of the range. - * - * The "combine" option can be set to `true` and overlapping & adjacent ranges - * will be combined into a single range. - * - * NOTE: remember that ranges are inclusive, so for example "Range: users=0-3" - * should respond with 4 users when available, not 3. - * - * @param {number} size - * @param {object} [options] - * @param {boolean} [options.combine=false] - * @return {number|array} - * @public - */ + data['url.same_origin'] = resourceUrl.includes(types.WINDOW.location.origin); -req.range = function range(size, options) { - var range = this.get('Range'); - if (!range) return; - return parseRange(size, range, options); -}; + const startTimestamp = timeOrigin + startTime; + const endTimestamp = startTimestamp + duration; + + utils$1._startChild(transaction, { + description: resourceUrl.replace(types.WINDOW.location.origin, ''), + endTimestamp, + op: entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other', + origin: 'auto.resource.browser.metrics', + startTimestamp, + data, + }); +} /** - * Return the value of param `name` when present or `defaultValue`. - * - * - Checks route placeholders, ex: _/user/:id_ - * - Checks body params, ex: id=12, {"id":12} - * - Checks query string params, ex: ?id=12 - * - * To utilize request bodies, `req.body` - * should be an object. This can be done by using - * the `bodyParser()` middleware. - * - * @param {String} name - * @param {Mixed} [defaultValue] - * @return {String} - * @public + * Capture the information of the user agent. */ +function _trackNavigator(transaction) { + const navigator = types.WINDOW.navigator ; + if (!navigator) { + return; + } -req.param = function param(name, defaultValue) { - var params = this.params || {}; - var body = this.body || {}; - var query = this.query || {}; + // track network connectivity + const connection = navigator.connection; + if (connection) { + if (connection.effectiveType) { + // TODO: Can we rewrite this to an attribute? + // eslint-disable-next-line deprecation/deprecation + transaction.setTag('effectiveConnectionType', connection.effectiveType); + } - var args = arguments.length === 1 - ? 'name' - : 'name, default'; - deprecate('req.param(' + args + '): Use req.params, req.body, or req.query instead'); + if (connection.type) { + // TODO: Can we rewrite this to an attribute? + // eslint-disable-next-line deprecation/deprecation + transaction.setTag('connectionType', connection.type); + } - if (null != params[name] && params.hasOwnProperty(name)) return params[name]; - if (null != body[name]) return body[name]; - if (null != query[name]) return query[name]; + if (utils$1.isMeasurementValue(connection.rtt)) { + _measurements['connection.rtt'] = { value: connection.rtt, unit: 'millisecond' }; + } + } - return defaultValue; -}; + if (utils$1.isMeasurementValue(navigator.deviceMemory)) { + // TODO: Can we rewrite this to an attribute? + // eslint-disable-next-line deprecation/deprecation + transaction.setTag('deviceMemory', `${navigator.deviceMemory} GB`); + } -/** - * Check if the incoming request contains the "Content-Type" - * header field, and it contains the given mime `type`. - * - * Examples: - * - * // With Content-Type: text/html; charset=utf-8 - * req.is('html'); - * req.is('text/html'); - * req.is('text/*'); - * // => true - * - * // When Content-Type is application/json - * req.is('json'); - * req.is('application/json'); - * req.is('application/*'); - * // => true - * - * req.is('html'); - * // => false - * - * @param {String|Array} types... - * @return {String|false|null} - * @public - */ + if (utils$1.isMeasurementValue(navigator.hardwareConcurrency)) { + // TODO: Can we rewrite this to an attribute? + // eslint-disable-next-line deprecation/deprecation + transaction.setTag('hardwareConcurrency', String(navigator.hardwareConcurrency)); + } +} -req.is = function is(types) { - var arr = types; +/** Add LCP / CLS data to transaction to allow debugging */ +function _tagMetricInfo(transaction) { + if (_lcpEntry) { + debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding LCP Data'); - // support flattened arguments - if (!Array.isArray(types)) { - arr = new Array(arguments.length); - for (var i = 0; i < arr.length; i++) { - arr[i] = arguments[i]; + // Capture Properties of the LCP element that contributes to the LCP. + + if (_lcpEntry.element) { + // TODO: Can we rewrite this to an attribute? + // eslint-disable-next-line deprecation/deprecation + transaction.setTag('lcp.element', utils.htmlTreeAsString(_lcpEntry.element)); + } + + if (_lcpEntry.id) { + // TODO: Can we rewrite this to an attribute? + // eslint-disable-next-line deprecation/deprecation + transaction.setTag('lcp.id', _lcpEntry.id); + } + + if (_lcpEntry.url) { + // Trim URL to the first 200 characters. + // TODO: Can we rewrite this to an attribute? + // eslint-disable-next-line deprecation/deprecation + transaction.setTag('lcp.url', _lcpEntry.url.trim().slice(0, 200)); } + + // TODO: Can we rewrite this to an attribute? + // eslint-disable-next-line deprecation/deprecation + transaction.setTag('lcp.size', _lcpEntry.size); } - return typeis(this, arr); -}; + // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift + if (_clsEntry && _clsEntry.sources) { + debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding CLS Data'); + _clsEntry.sources.forEach((source, index) => + // TODO: Can we rewrite this to an attribute? + // eslint-disable-next-line deprecation/deprecation + transaction.setTag(`cls.source.${index + 1}`, utils.htmlTreeAsString(source.node)), + ); + } +} + +function setResourceEntrySizeData( + data, + entry, + key, + dataKey, +) { + const entryVal = entry[key]; + if (entryVal != null && entryVal < MAX_INT_AS_BYTES) { + data[dataKey] = entryVal; + } +} /** - * Return the protocol string "http" or "https" - * when requested with TLS. When the "trust proxy" - * setting trusts the socket address, the - * "X-Forwarded-Proto" header field will be trusted - * and used if present. + * Add ttfb request time information to measurements. * - * If you're running behind a reverse proxy that - * supplies https for you this may be enabled. - * - * @return {String} - * @public + * ttfb information is added via vendored web vitals library. */ +function _addTtfbRequestTimeToMeasurements(_measurements) { + const navEntry = getNavigationEntry.getNavigationEntry(); + if (!navEntry) { + return; + } -defineGetter(req, 'protocol', function protocol(){ - var proto = this.connection.encrypted - ? 'https' - : 'http'; - var trust = this.app.get('trust proxy fn'); + const { responseStart, requestStart } = navEntry; - if (!trust(this.connection.remoteAddress, 0)) { - return proto; + if (requestStart <= responseStart) { + debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding TTFB Request Time'); + _measurements['ttfb.requestTime'] = { + value: responseStart - requestStart, + unit: 'millisecond', + }; } +} - // Note: X-Forwarded-Proto is normally only ever a - // single value, but this is to be safe. - var header = this.get('X-Forwarded-Proto') || proto - var index = header.indexOf(',') +/** Taken from @sentry/core sampling.ts */ +function getSampleRate( + transactionContext, + options, + interactionsSampleRate, +) { + if (!core.hasTracingEnabled(options)) { + return false; + } + let sampleRate; + if (transactionContext !== undefined && typeof options.tracesSampler === 'function') { + sampleRate = options.tracesSampler({ + transactionContext, + name: transactionContext.name, + parentSampled: transactionContext.parentSampled, + attributes: { + // eslint-disable-next-line deprecation/deprecation + ...transactionContext.data, + ...transactionContext.attributes, + }, + location: types.WINDOW.location, + }); + } else if (transactionContext !== undefined && transactionContext.sampled !== undefined) { + sampleRate = transactionContext.sampled; + } else if (typeof options.tracesSampleRate !== 'undefined') { + sampleRate = options.tracesSampleRate; + } else { + sampleRate = 1; + } + if (!core.isValidSampleRate(sampleRate)) { + debugBuild.DEBUG_BUILD && utils.logger.warn('[Tracing] Discarding interaction span because of invalid sample rate.'); + return false; + } + if (sampleRate === true) { + return interactionsSampleRate; + } else if (sampleRate === false) { + return 0; + } + return sampleRate * interactionsSampleRate; +} - return index !== -1 - ? header.substring(0, index).trim() - : header.trim() -}); +exports._addMeasureSpans = _addMeasureSpans; +exports._addResourceSpans = _addResourceSpans; +exports.addPerformanceEntries = addPerformanceEntries; +exports.startTrackingINP = startTrackingINP; +exports.startTrackingInteractions = startTrackingInteractions; +exports.startTrackingLongTasks = startTrackingLongTasks; +exports.startTrackingWebVitals = startTrackingWebVitals; +//# sourceMappingURL=index.js.map -/** - * Short-hand for: - * - * req.protocol === 'https' - * - * @return {Boolean} - * @public - */ -defineGetter(req, 'secure', function secure(){ - return this.protocol === 'https'; -}); +/***/ }), + +/***/ 30802: +/***/ ((__unused_webpack_module, exports) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); /** - * Return the remote address from the trusted proxy. - * - * The is the remote address on the socket unless - * "trust proxy" is set. - * - * @return {String} - * @public + * Checks if a given value is a valid measurement value. */ - -defineGetter(req, 'ip', function ip(){ - var trust = this.app.get('trust proxy fn'); - return proxyaddr(this, trust); -}); +function isMeasurementValue(value) { + return typeof value === 'number' && isFinite(value); +} /** - * When "trust proxy" is set, trusted proxy addresses + client. - * - * For example if the value were "client, proxy1, proxy2" - * you would receive the array `["client", "proxy1", "proxy2"]` - * where "proxy2" is the furthest down-stream and "proxy1" and - * "proxy2" were trusted. + * Helper function to start child on transactions. This function will make sure that the transaction will + * use the start timestamp of the created child span if it is earlier than the transactions actual + * start timestamp. * - * @return {Array} - * @public + * Note: this will not be possible anymore in v8, + * unless we do some special handling for browser here... */ +function _startChild(transaction, { startTimestamp, ...ctx }) { + // eslint-disable-next-line deprecation/deprecation + if (startTimestamp && transaction.startTimestamp > startTimestamp) { + // eslint-disable-next-line deprecation/deprecation + transaction.startTimestamp = startTimestamp; + } -defineGetter(req, 'ips', function ips() { - var trust = this.app.get('trust proxy fn'); - var addrs = proxyaddr.all(this, trust); + // eslint-disable-next-line deprecation/deprecation + return transaction.startChild({ + startTimestamp, + ...ctx, + }); +} - // reverse the order (to farthest -> closest) - // and remove socket address - addrs.reverse().pop() +exports._startChild = _startChild; +exports.isMeasurementValue = isMeasurementValue; +//# sourceMappingURL=utils.js.map - return addrs -}); -/** - * Return subdomains as an array. - * - * Subdomains are the dot-separated parts of the host before the main domain of - * the app. By default, the domain of the app is assumed to be the last two - * parts of the host. This can be changed by setting "subdomain offset". - * - * For example, if the domain is "tobi.ferrets.example.com": - * If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`. - * If "subdomain offset" is 3, req.subdomains is `["tobi"]`. - * - * @return {Array} - * @public - */ +/***/ }), -defineGetter(req, 'subdomains', function subdomains() { - var hostname = this.hostname; +/***/ 26896: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (!hostname) return []; +Object.defineProperty(exports, "__esModule", ({ value: true })); - var offset = this.app.get('subdomain offset'); - var subdomains = !isIP(hostname) - ? hostname.split('.').reverse() - : [hostname]; +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const fetch = __nccwpck_require__(52574); +const instrument = __nccwpck_require__(7380); +const types = __nccwpck_require__(49884); - return subdomains.slice(offset); -}); +/* eslint-disable max-lines */ -/** - * Short-hand for `url.parse(req.url).pathname`. - * - * @return {String} - * @public - */ +const DEFAULT_TRACE_PROPAGATION_TARGETS = ['localhost', /^\/(?!\/)/]; -defineGetter(req, 'path', function path() { - return parse(this).pathname; -}); +/** Options for Request Instrumentation */ -/** - * Parse the "Host" header field to a hostname. - * - * When the "trust proxy" setting trusts the socket - * address, the "X-Forwarded-Host" header field will - * be trusted. - * - * @return {String} - * @public - */ +const defaultRequestInstrumentationOptions = { + traceFetch: true, + traceXHR: true, + enableHTTPTimings: true, + // TODO (v8): Remove this property + tracingOrigins: DEFAULT_TRACE_PROPAGATION_TARGETS, + tracePropagationTargets: DEFAULT_TRACE_PROPAGATION_TARGETS, +}; -defineGetter(req, 'hostname', function hostname(){ - var trust = this.app.get('trust proxy fn'); - var host = this.get('X-Forwarded-Host'); +/** Registers span creators for xhr and fetch requests */ +function instrumentOutgoingRequests(_options) { + const { + traceFetch, + traceXHR, + // eslint-disable-next-line deprecation/deprecation + tracePropagationTargets, + // eslint-disable-next-line deprecation/deprecation + tracingOrigins, + shouldCreateSpanForRequest, + enableHTTPTimings, + } = { + traceFetch: defaultRequestInstrumentationOptions.traceFetch, + traceXHR: defaultRequestInstrumentationOptions.traceXHR, + ..._options, + }; - if (!host || !trust(this.connection.remoteAddress, 0)) { - host = this.get('Host'); - } else if (host.indexOf(',') !== -1) { - // Note: X-Forwarded-Host is normally only ever a - // single value, but this is to be safe. - host = host.substring(0, host.indexOf(',')).trimRight() + const shouldCreateSpan = + typeof shouldCreateSpanForRequest === 'function' ? shouldCreateSpanForRequest : (_) => true; + + // TODO(v8) Remove tracingOrigins here + // The only reason we're passing it in here is because this instrumentOutgoingRequests function is publicly exported + // and we don't want to break the API. We can remove it in v8. + const shouldAttachHeadersWithTargets = (url) => + shouldAttachHeaders(url, tracePropagationTargets || tracingOrigins); + + const spans = {}; + + if (traceFetch) { + utils.addFetchInstrumentationHandler(handlerData => { + const createdSpan = fetch.instrumentFetchRequest(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans); + // We cannot use `window.location` in the generic fetch instrumentation, + // but we need it for reliable `server.address` attribute. + // so we extend this in here + if (createdSpan) { + const fullUrl = getFullURL(handlerData.fetchData.url); + const host = fullUrl ? utils.parseUrl(fullUrl).host : undefined; + createdSpan.setAttributes({ + 'http.url': fullUrl, + 'server.address': host, + }); + } + + if (enableHTTPTimings && createdSpan) { + addHTTPTimings(createdSpan); + } + }); } - if (!host) return; + if (traceXHR) { + utils.addXhrInstrumentationHandler(handlerData => { + const createdSpan = xhrCallback(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans); + if (enableHTTPTimings && createdSpan) { + addHTTPTimings(createdSpan); + } + }); + } +} - // IPv6 literal support - var offset = host[0] === '[' - ? host.indexOf(']') + 1 - : 0; - var index = host.indexOf(':', offset); +function isPerformanceResourceTiming(entry) { + return ( + entry.entryType === 'resource' && + 'initiatorType' in entry && + typeof (entry ).nextHopProtocol === 'string' && + (entry.initiatorType === 'fetch' || entry.initiatorType === 'xmlhttprequest') + ); +} - return index !== -1 - ? host.substring(0, index) - : host; -}); +/** + * Creates a temporary observer to listen to the next fetch/xhr resourcing timings, + * so that when timings hit their per-browser limit they don't need to be removed. + * + * @param span A span that has yet to be finished, must contain `url` on data. + */ +function addHTTPTimings(span) { + const { url } = core.spanToJSON(span).data || {}; -// TODO: change req.host to return host in next major + if (!url || typeof url !== 'string') { + return; + } -defineGetter(req, 'host', deprecate.function(function host(){ - return this.hostname; -}, 'req.host: Use req.hostname instead')); + const cleanup = instrument.addPerformanceInstrumentationHandler('resource', ({ entries }) => { + entries.forEach(entry => { + if (isPerformanceResourceTiming(entry) && entry.name.endsWith(url)) { + const spanData = resourceTimingEntryToSpanData(entry); + spanData.forEach(data => span.setAttribute(...data)); + // In the next tick, clean this handler up + // We have to wait here because otherwise this cleans itself up before it is fully done + setTimeout(cleanup); + } + }); + }); +} /** - * Check if the request is fresh, aka - * Last-Modified and/or the ETag - * still match. + * Converts ALPN protocol ids to name and version. * - * @return {Boolean} - * @public + * (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids) + * @param nextHopProtocol PerformanceResourceTiming.nextHopProtocol */ +function extractNetworkProtocol(nextHopProtocol) { + let name = 'unknown'; + let version = 'unknown'; + let _name = ''; + for (const char of nextHopProtocol) { + // http/1.1 etc. + if (char === '/') { + [name, version] = nextHopProtocol.split('/'); + break; + } + // h2, h3 etc. + if (!isNaN(Number(char))) { + name = _name === 'h' ? 'http' : _name; + version = nextHopProtocol.split(_name)[1]; + break; + } + _name += char; + } + if (_name === nextHopProtocol) { + // webrtc, ftp, etc. + name = _name; + } + return { name, version }; +} -defineGetter(req, 'fresh', function(){ - var method = this.method; - var res = this.res - var status = res.statusCode +function getAbsoluteTime(time = 0) { + return ((utils.browserPerformanceTimeOrigin || performance.timeOrigin) + time) / 1000; +} - // GET or HEAD for weak freshness validation only - if ('GET' !== method && 'HEAD' !== method) return false; +function resourceTimingEntryToSpanData(resourceTiming) { + const { name, version } = extractNetworkProtocol(resourceTiming.nextHopProtocol); - // 2xx or 304 as per rfc2616 14.26 - if ((status >= 200 && status < 300) || 304 === status) { - return fresh(this.headers, { - 'etag': res.get('ETag'), - 'last-modified': res.get('Last-Modified') - }) - } + const timingSpanData = []; - return false; -}); + timingSpanData.push(['network.protocol.version', version], ['network.protocol.name', name]); + + if (!utils.browserPerformanceTimeOrigin) { + return timingSpanData; + } + return [ + ...timingSpanData, + ['http.request.redirect_start', getAbsoluteTime(resourceTiming.redirectStart)], + ['http.request.fetch_start', getAbsoluteTime(resourceTiming.fetchStart)], + ['http.request.domain_lookup_start', getAbsoluteTime(resourceTiming.domainLookupStart)], + ['http.request.domain_lookup_end', getAbsoluteTime(resourceTiming.domainLookupEnd)], + ['http.request.connect_start', getAbsoluteTime(resourceTiming.connectStart)], + ['http.request.secure_connection_start', getAbsoluteTime(resourceTiming.secureConnectionStart)], + ['http.request.connection_end', getAbsoluteTime(resourceTiming.connectEnd)], + ['http.request.request_start', getAbsoluteTime(resourceTiming.requestStart)], + ['http.request.response_start', getAbsoluteTime(resourceTiming.responseStart)], + ['http.request.response_end', getAbsoluteTime(resourceTiming.responseEnd)], + ]; +} /** - * Check if the request is stale, aka - * "Last-Modified" and / or the "ETag" for the - * resource has changed. - * - * @return {Boolean} - * @public + * A function that determines whether to attach tracing headers to a request. + * This was extracted from `instrumentOutgoingRequests` to make it easier to test shouldAttachHeaders. + * We only export this fuction for testing purposes. */ - -defineGetter(req, 'stale', function stale(){ - return !this.fresh; -}); +function shouldAttachHeaders(url, tracePropagationTargets) { + return utils.stringMatchesSomePattern(url, tracePropagationTargets || DEFAULT_TRACE_PROPAGATION_TARGETS); +} /** - * Check if the request was an _XMLHttpRequest_. + * Create and track xhr request spans * - * @return {Boolean} - * @public + * @returns Span if a span was created, otherwise void. */ +// eslint-disable-next-line complexity +function xhrCallback( + handlerData, + shouldCreateSpan, + shouldAttachHeaders, + spans, +) { + const xhr = handlerData.xhr; + const sentryXhrData = xhr && xhr[utils.SENTRY_XHR_DATA_KEY]; -defineGetter(req, 'xhr', function xhr(){ - var val = this.get('X-Requested-With') || ''; - return val.toLowerCase() === 'xmlhttprequest'; -}); + if (!core.hasTracingEnabled() || !xhr || xhr.__sentry_own_request__ || !sentryXhrData) { + return undefined; + } -/** - * Helper function for creating a getter on an object. - * - * @param {Object} obj - * @param {String} name - * @param {Function} getter - * @private - */ -function defineGetter(obj, name, getter) { - Object.defineProperty(obj, name, { - configurable: true, - enumerable: true, - get: getter - }); -} + const shouldCreateSpanResult = shouldCreateSpan(sentryXhrData.url); + // check first if the request has finished and is tracked by an existing span which should now end + if (handlerData.endTimestamp && shouldCreateSpanResult) { + const spanId = xhr.__sentry_xhr_span_id__; + if (!spanId) return; -/***/ }), + const span = spans[spanId]; + if (span && sentryXhrData.status_code !== undefined) { + core.setHttpStatus(span, sentryXhrData.status_code); + span.end(); -/***/ 73606: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete spans[spanId]; + } + return undefined; + } -"use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ + const scope = core.getCurrentScope(); + const isolationScope = core.getIsolationScope(); + const fullUrl = getFullURL(sentryXhrData.url); + const host = fullUrl ? utils.parseUrl(fullUrl).host : undefined; + const span = shouldCreateSpanResult + ? core.startInactiveSpan({ + name: `${sentryXhrData.method} ${sentryXhrData.url}`, + onlyIfParent: true, + attributes: { + type: 'xhr', + 'http.method': sentryXhrData.method, + 'http.url': fullUrl, + url: sentryXhrData.url, + 'server.address': host, + [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser', + }, + op: 'http.client', + }) + : undefined; -/** - * Module dependencies. - * @private - */ + if (span) { + xhr.__sentry_xhr_span_id__ = span.spanContext().spanId; + spans[xhr.__sentry_xhr_span_id__] = span; + } -var Buffer = (__nccwpck_require__(26843).Buffer) -var contentDisposition = __nccwpck_require__(45942); -var createError = __nccwpck_require__(8927) -var deprecate = __nccwpck_require__(77267)('express'); -var encodeUrl = __nccwpck_require__(31449); -var escapeHtml = __nccwpck_require__(3385); -var http = __nccwpck_require__(58611); -var isAbsolute = (__nccwpck_require__(21596).isAbsolute); -var onFinished = __nccwpck_require__(96922); -var path = __nccwpck_require__(16928); -var statuses = __nccwpck_require__(53748) -var merge = __nccwpck_require__(31657); -var sign = (__nccwpck_require__(93628).sign); -var normalizeType = (__nccwpck_require__(21596).normalizeType); -var normalizeTypes = (__nccwpck_require__(21596).normalizeTypes); -var setCharset = (__nccwpck_require__(21596).setCharset); -var cookie = __nccwpck_require__(22975); -var send = __nccwpck_require__(15549); -var extname = path.extname; -var mime = send.mime; -var resolve = path.resolve; -var vary = __nccwpck_require__(25871); - -/** - * Response prototype. - * @public - */ + const client = core.getClient(); -var res = Object.create(http.ServerResponse.prototype) + if (xhr.setRequestHeader && shouldAttachHeaders(sentryXhrData.url) && client) { + const { traceId, spanId, sampled, dsc } = { + ...isolationScope.getPropagationContext(), + ...scope.getPropagationContext(), + }; -/** - * Module exports. - * @public - */ + const sentryTraceHeader = span ? core.spanToTraceHeader(span) : utils.generateSentryTraceHeader(traceId, spanId, sampled); -module.exports = res + const sentryBaggageHeader = utils.dynamicSamplingContextToSentryBaggageHeader( + dsc || + (span ? core.getDynamicSamplingContextFromSpan(span) : core.getDynamicSamplingContextFromClient(traceId, client, scope)), + ); -/** - * Module variables. - * @private - */ + setHeaderOnXhr(xhr, sentryTraceHeader, sentryBaggageHeader); + } -var charsetRegExp = /;\s*charset\s*=/; + return span; +} -/** - * Set status `code`. - * - * @param {Number} code - * @return {ServerResponse} - * @public - */ +function setHeaderOnXhr( + xhr, + sentryTraceHeader, + sentryBaggageHeader, +) { + try { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + xhr.setRequestHeader('sentry-trace', sentryTraceHeader); + if (sentryBaggageHeader) { + // From MDN: "If this method is called several times with the same header, the values are merged into one single request header." + // We can therefore simply set a baggage header without checking what was there before + // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + xhr.setRequestHeader(utils.BAGGAGE_HEADER_NAME, sentryBaggageHeader); + } + } catch (_) { + // Error: InvalidStateError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED. + } +} -res.status = function status(code) { - if ((typeof code === 'string' || Math.floor(code) !== code) && code > 99 && code < 1000) { - deprecate('res.status(' + JSON.stringify(code) + '): use res.status(' + Math.floor(code) + ') instead') +function getFullURL(url) { + try { + // By adding a base URL to new URL(), this will also work for relative urls + // If `url` is a full URL, the base URL is ignored anyhow + const parsed = new URL(url, types.WINDOW.location.origin); + return parsed.href; + } catch (e) { + return undefined; } - this.statusCode = code; - return this; -}; +} -/** - * Set Link header field with the given `links`. - * - * Examples: - * - * res.links({ - * next: 'http://api.example.com/users?page=2', - * last: 'http://api.example.com/users?page=5' - * }); - * - * @param {Object} links - * @return {ServerResponse} - * @public - */ +exports.DEFAULT_TRACE_PROPAGATION_TARGETS = DEFAULT_TRACE_PROPAGATION_TARGETS; +exports.defaultRequestInstrumentationOptions = defaultRequestInstrumentationOptions; +exports.extractNetworkProtocol = extractNetworkProtocol; +exports.instrumentOutgoingRequests = instrumentOutgoingRequests; +exports.shouldAttachHeaders = shouldAttachHeaders; +exports.xhrCallback = xhrCallback; +//# sourceMappingURL=request.js.map -res.links = function(links){ - var link = this.get('Link') || ''; - if (link) link += ', '; - return this.set('Link', link + Object.keys(links).map(function(rel){ - return '<' + links[rel] + '>; rel="' + rel + '"'; - }).join(', ')); -}; -/** - * Send a response. - * - * Examples: - * - * res.send(Buffer.from('wahoo')); - * res.send({ some: 'json' }); - * res.send('

some html

'); - * - * @param {string|number|boolean|object|Buffer} body - * @public - */ +/***/ }), -res.send = function send(body) { - var chunk = body; - var encoding; - var req = this.req; - var type; +/***/ 52828: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // settings - var app = this.app; +Object.defineProperty(exports, "__esModule", ({ value: true })); - // allow status / body - if (arguments.length === 2) { - // res.send(body, status) backwards compat - if (typeof arguments[0] !== 'number' && typeof arguments[1] === 'number') { - deprecate('res.send(body, status): Use res.status(status).send(body) instead'); - this.statusCode = arguments[1]; - } else { - deprecate('res.send(status, body): Use res.status(status).send(body) instead'); - this.statusCode = arguments[0]; - chunk = arguments[1]; - } +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const types = __nccwpck_require__(49884); + +/** + * Default function implementing pageload and navigation transactions + */ +function instrumentRoutingWithDefaults( + customStartTransaction, + startTransactionOnPageLoad = true, + startTransactionOnLocationChange = true, +) { + if (!types.WINDOW || !types.WINDOW.location) { + debugBuild.DEBUG_BUILD && utils.logger.warn('Could not initialize routing instrumentation due to invalid location'); + return; } - // disambiguate res.send(status) and res.send(status, num) - if (typeof chunk === 'number' && arguments.length === 1) { - // res.send(status) will set status message as text string - if (!this.get('Content-Type')) { - this.type('txt'); - } + let startingUrl = types.WINDOW.location.href; - deprecate('res.send(status): Use res.sendStatus(status) instead'); - this.statusCode = chunk; - chunk = statuses.message[chunk] + let activeTransaction; + if (startTransactionOnPageLoad) { + activeTransaction = customStartTransaction({ + name: types.WINDOW.location.pathname, + // pageload should always start at timeOrigin (and needs to be in s, not ms) + startTimestamp: utils.browserPerformanceTimeOrigin ? utils.browserPerformanceTimeOrigin / 1000 : undefined, + op: 'pageload', + origin: 'auto.pageload.browser', + metadata: { source: 'url' }, + }); } - switch (typeof chunk) { - // string defaulting to html - case 'string': - if (!this.get('Content-Type')) { - this.type('html'); + if (startTransactionOnLocationChange) { + utils.addHistoryInstrumentationHandler(({ to, from }) => { + /** + * This early return is there to account for some cases where a navigation transaction starts right after + * long-running pageload. We make sure that if `from` is undefined and a valid `startingURL` exists, we don't + * create an uneccessary navigation transaction. + * + * This was hard to duplicate, but this behavior stopped as soon as this fix was applied. This issue might also + * only be caused in certain development environments where the usage of a hot module reloader is causing + * errors. + */ + if (from === undefined && startingUrl && startingUrl.indexOf(to) !== -1) { + startingUrl = undefined; + return; } - break; - case 'boolean': - case 'number': - case 'object': - if (chunk === null) { - chunk = ''; - } else if (Buffer.isBuffer(chunk)) { - if (!this.get('Content-Type')) { - this.type('bin'); + + if (from !== to) { + startingUrl = undefined; + if (activeTransaction) { + debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Finishing current transaction with op: ${activeTransaction.op}`); + // If there's an open transaction on the scope, we need to finish it before creating an new one. + activeTransaction.end(); } - } else { - return this.json(chunk); + activeTransaction = customStartTransaction({ + name: types.WINDOW.location.pathname, + op: 'navigation', + origin: 'auto.navigation.browser', + metadata: { source: 'url' }, + }); } - break; + }); } +} - // write strings in utf-8 - if (typeof chunk === 'string') { - encoding = 'utf8'; - type = this.get('Content-Type'); +exports.instrumentRoutingWithDefaults = instrumentRoutingWithDefaults; +//# sourceMappingURL=router.js.map - // reflect this in content-type - if (typeof type === 'string') { - this.set('Content-Type', setCharset(type, 'utf-8')); - } - } - // determine if ETag should be generated - var etagFn = app.get('etag fn') - var generateETag = !this.get('ETag') && typeof etagFn === 'function' +/***/ }), - // populate Content-Length - var len - if (chunk !== undefined) { - if (Buffer.isBuffer(chunk)) { - // get length of Buffer - len = chunk.length - } else if (!generateETag && chunk.length < 1000) { - // just calculate length when no ETag + small chunk - len = Buffer.byteLength(chunk, encoding) - } else { - // convert chunk to Buffer and calculate - chunk = Buffer.from(chunk, encoding) - encoding = undefined; - len = chunk.length - } +/***/ 49884: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - this.set('Content-Length', len); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - // populate ETag - var etag; - if (generateETag && len !== undefined) { - if ((etag = etagFn(chunk, encoding))) { - this.set('ETag', etag); - } - } +const utils = __nccwpck_require__(57540); - // freshness - if (req.fresh) this.statusCode = 304; +const WINDOW = utils.GLOBAL_OBJ - // strip irrelevant headers - if (204 === this.statusCode || 304 === this.statusCode) { - this.removeHeader('Content-Type'); - this.removeHeader('Content-Length'); - this.removeHeader('Transfer-Encoding'); - chunk = ''; - } +; - // alter headers for 205 - if (this.statusCode === 205) { - this.set('Content-Length', '0') - this.removeHeader('Transfer-Encoding') - chunk = '' - } +exports.WINDOW = WINDOW; +//# sourceMappingURL=types.js.map - if (req.method === 'HEAD') { - // skip body for HEAD - this.end(); - } else { - // respond - this.end(chunk, encoding); + +/***/ }), + +/***/ 61330: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const bindReporter = __nccwpck_require__(88172); +const initMetric = __nccwpck_require__(87112); +const observe = __nccwpck_require__(70248); +const onHidden = __nccwpck_require__(81031); + +/* + * Copyright 2020 Google LLC + * + * 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 + * + * https://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. + */ + +/** + * Calculates the [CLS](https://web.dev/cls/) value for the current page and + * calls the `callback` function once the value is ready to be reported, along + * with all `layout-shift` performance entries that were used in the metric + * value calculation. The reported value is a `double` (corresponding to a + * [layout shift score](https://web.dev/cls/#layout-shift-score)). + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called as soon as the value is initially + * determined as well as any time the value changes throughout the page + * lifespan. + * + * _**Important:** CLS should be continually monitored for changes throughout + * the entire lifespan of a page—including if the user returns to the page after + * it's been hidden/backgrounded. However, since browsers often [will not fire + * additional callbacks once the user has backgrounded a + * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden), + * `callback` is always called when the page's visibility state changes to + * hidden. As a result, the `callback` function might be called multiple times + * during the same page load._ + */ +const onCLS = ( + onReport, + options = {}, +) => { + const metric = initMetric.initMetric('CLS', 0); + let report; + + let sessionValue = 0; + let sessionEntries = []; + + // const handleEntries = (entries: Metric['entries']) => { + const handleEntries = (entries) => { + entries.forEach(entry => { + // Only count layout shifts without recent user input. + if (!entry.hadRecentInput) { + const firstSessionEntry = sessionEntries[0]; + const lastSessionEntry = sessionEntries[sessionEntries.length - 1]; + + // If the entry occurred less than 1 second after the previous entry and + // less than 5 seconds after the first entry in the session, include the + // entry in the current session. Otherwise, start a new session. + if ( + sessionValue && + sessionEntries.length !== 0 && + entry.startTime - lastSessionEntry.startTime < 1000 && + entry.startTime - firstSessionEntry.startTime < 5000 + ) { + sessionValue += entry.value; + sessionEntries.push(entry); + } else { + sessionValue = entry.value; + sessionEntries = [entry]; + } + + // If the current session value is larger than the current CLS value, + // update CLS and the entries contributing to it. + if (sessionValue > metric.value) { + metric.value = sessionValue; + metric.entries = sessionEntries; + if (report) { + report(); + } + } + } + }); + }; + + const po = observe.observe('layout-shift', handleEntries); + if (po) { + report = bindReporter.bindReporter(onReport, metric, options.reportAllChanges); + + const stopListening = () => { + handleEntries(po.takeRecords() ); + report(true); + }; + + onHidden.onHidden(stopListening); + + return stopListening; } - return this; + return; }; -/** - * Send JSON response. +exports.onCLS = onCLS; +//# sourceMappingURL=getCLS.js.map + + +/***/ }), + +/***/ 22641: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const bindReporter = __nccwpck_require__(88172); +const getVisibilityWatcher = __nccwpck_require__(82450); +const initMetric = __nccwpck_require__(87112); +const observe = __nccwpck_require__(70248); +const onHidden = __nccwpck_require__(81031); + +/* + * Copyright 2020 Google LLC * - * Examples: + * 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 * - * res.json(null); - * res.json({ user: 'tj' }); + * https://www.apache.org/licenses/LICENSE-2.0 * - * @param {string|number|boolean|object} obj - * @public + * 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. */ -res.json = function json(obj) { - var val = obj; +/** + * Calculates the [FID](https://web.dev/fid/) value for the current page and + * calls the `callback` function once the value is ready, along with the + * relevant `first-input` performance entry used to determine the value. The + * reported value is a `DOMHighResTimeStamp`. + * + * _**Important:** since FID is only reported after the user interacts with the + * page, it's possible that it will not be reported for some page loads._ + */ +const onFID = (onReport) => { + const visibilityWatcher = getVisibilityWatcher.getVisibilityWatcher(); + const metric = initMetric.initMetric('FID'); + // eslint-disable-next-line prefer-const + let report; - // allow status / body - if (arguments.length === 2) { - // res.json(body, status) backwards compat - if (typeof arguments[1] === 'number') { - deprecate('res.json(obj, status): Use res.status(status).json(obj) instead'); - this.statusCode = arguments[1]; - } else { - deprecate('res.json(status, obj): Use res.status(status).json(obj) instead'); - this.statusCode = arguments[0]; - val = arguments[1]; + const handleEntry = (entry) => { + // Only report if the page wasn't hidden prior to the first input. + if (entry.startTime < visibilityWatcher.firstHiddenTime) { + metric.value = entry.processingStart - entry.startTime; + metric.entries.push(entry); + report(true); } - } + }; - // settings - var app = this.app; - var escape = app.get('json escape') - var replacer = app.get('json replacer'); - var spaces = app.get('json spaces'); - var body = stringify(val, replacer, spaces, escape) + const handleEntries = (entries) => { + (entries ).forEach(handleEntry); + }; - // content-type - if (!this.get('Content-Type')) { - this.set('Content-Type', 'application/json'); - } + const po = observe.observe('first-input', handleEntries); + report = bindReporter.bindReporter(onReport, metric); - return this.send(body); + if (po) { + onHidden.onHidden(() => { + handleEntries(po.takeRecords() ); + po.disconnect(); + }, true); + } }; -/** - * Send JSON response with JSONP callback support. +exports.onFID = onFID; +//# sourceMappingURL=getFID.js.map + + +/***/ }), + +/***/ 843: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const bindReporter = __nccwpck_require__(88172); +const initMetric = __nccwpck_require__(87112); +const observe = __nccwpck_require__(70248); +const onHidden = __nccwpck_require__(81031); +const interactionCountPolyfill = __nccwpck_require__(31411); + +/* + * Copyright 2022 Google LLC * - * Examples: + * 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 * - * res.jsonp(null); - * res.jsonp({ user: 'tj' }); + * https://www.apache.org/licenses/LICENSE-2.0 * - * @param {string|number|boolean|object} obj - * @public + * 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. */ -res.jsonp = function jsonp(obj) { - var val = obj; +/** + * Returns the interaction count since the last bfcache restore (or for the + * full page lifecycle if there were no bfcache restores). + */ +const getInteractionCountForNavigation = () => { + return interactionCountPolyfill.getInteractionCount(); +}; - // allow status / body - if (arguments.length === 2) { - // res.jsonp(body, status) backwards compat - if (typeof arguments[1] === 'number') { - deprecate('res.jsonp(obj, status): Use res.status(status).jsonp(obj) instead'); - this.statusCode = arguments[1]; +// To prevent unnecessary memory usage on pages with lots of interactions, +// store at most 10 of the longest interactions to consider as INP candidates. +const MAX_INTERACTIONS_TO_CONSIDER = 10; + +// A list of longest interactions on the page (by latency) sorted so the +// longest one is first. The list is as most MAX_INTERACTIONS_TO_CONSIDER long. +const longestInteractionList = []; + +// A mapping of longest interactions by their interaction ID. +// This is used for faster lookup. +const longestInteractionMap = {}; + +/** + * Takes a performance entry and adds it to the list of worst interactions + * if its duration is long enough to make it among the worst. If the + * entry is part of an existing interaction, it is merged and the latency + * and entries list is updated as needed. + */ +const processEntry = (entry) => { + // The least-long of the 10 longest interactions. + const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1]; + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const existingInteraction = longestInteractionMap[entry.interactionId]; + + // Only process the entry if it's possibly one of the ten longest, + // or if it's part of an existing interaction. + if ( + existingInteraction || + longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER || + entry.duration > minLongestInteraction.latency + ) { + // If the interaction already exists, update it. Otherwise create one. + if (existingInteraction) { + existingInteraction.entries.push(entry); + existingInteraction.latency = Math.max(existingInteraction.latency, entry.duration); } else { - deprecate('res.jsonp(status, obj): Use res.status(status).jsonp(obj) instead'); - this.statusCode = arguments[0]; - val = arguments[1]; + const interaction = { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + id: entry.interactionId, + latency: entry.duration, + entries: [entry], + }; + longestInteractionMap[interaction.id] = interaction; + longestInteractionList.push(interaction); } + + // Sort the entries by latency (descending) and keep only the top ten. + longestInteractionList.sort((a, b) => b.latency - a.latency); + longestInteractionList.splice(MAX_INTERACTIONS_TO_CONSIDER).forEach(i => { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete longestInteractionMap[i.id]; + }); } +}; - // settings - var app = this.app; - var escape = app.get('json escape') - var replacer = app.get('json replacer'); - var spaces = app.get('json spaces'); - var body = stringify(val, replacer, spaces, escape) - var callback = this.req.query[app.get('jsonp callback name')]; +/** + * Returns the estimated p98 longest interaction based on the stored + * interaction candidates and the interaction count for the current page. + */ +const estimateP98LongestInteraction = () => { + const candidateInteractionIndex = Math.min( + longestInteractionList.length - 1, + Math.floor(getInteractionCountForNavigation() / 50), + ); - // content-type - if (!this.get('Content-Type')) { - this.set('X-Content-Type-Options', 'nosniff'); - this.set('Content-Type', 'application/json'); - } + return longestInteractionList[candidateInteractionIndex]; +}; - // fixup callback - if (Array.isArray(callback)) { - callback = callback[0]; - } +/** + * Calculates the [INP](https://web.dev/responsiveness/) value for the current + * page and calls the `callback` function once the value is ready, along with + * the `event` performance entries reported for that interaction. The reported + * value is a `DOMHighResTimeStamp`. + * + * A custom `durationThreshold` configuration option can optionally be passed to + * control what `event-timing` entries are considered for INP reporting. The + * default threshold is `40`, which means INP scores of less than 40 are + * reported as 0. Note that this will not affect your 75th percentile INP value + * unless that value is also less than 40 (well below the recommended + * [good](https://web.dev/inp/#what-is-a-good-inp-score) threshold). + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called as soon as the value is initially + * determined as well as any time the value changes throughout the page + * lifespan. + * + * _**Important:** INP should be continually monitored for changes throughout + * the entire lifespan of a page—including if the user returns to the page after + * it's been hidden/backgrounded. However, since browsers often [will not fire + * additional callbacks once the user has backgrounded a + * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden), + * `callback` is always called when the page's visibility state changes to + * hidden. As a result, the `callback` function might be called multiple times + * during the same page load._ + */ +const onINP = (onReport, opts) => { + // Set defaults + // eslint-disable-next-line no-param-reassign + opts = opts || {}; - // jsonp - if (typeof callback === 'string' && callback.length !== 0) { - this.set('X-Content-Type-Options', 'nosniff'); - this.set('Content-Type', 'text/javascript'); + // https://web.dev/inp/#what's-a-%22good%22-inp-value + // const thresholds = [200, 500]; + + // TODO(philipwalton): remove once the polyfill is no longer needed. + interactionCountPolyfill.initInteractionCountPolyfill(); + + const metric = initMetric.initMetric('INP'); + // eslint-disable-next-line prefer-const + let report; + + const handleEntries = (entries) => { + entries.forEach(entry => { + if (entry.interactionId) { + processEntry(entry); + } + + // Entries of type `first-input` don't currently have an `interactionId`, + // so to consider them in INP we have to first check that an existing + // entry doesn't match the `duration` and `startTime`. + // Note that this logic assumes that `event` entries are dispatched + // before `first-input` entries. This is true in Chrome but it is not + // true in Firefox; however, Firefox doesn't support interactionId, so + // it's not an issue at the moment. + // TODO(philipwalton): remove once crbug.com/1325826 is fixed. + if (entry.entryType === 'first-input') { + const noMatchingEntry = !longestInteractionList.some(interaction => { + return interaction.entries.some(prevEntry => { + return entry.duration === prevEntry.duration && entry.startTime === prevEntry.startTime; + }); + }); + if (noMatchingEntry) { + processEntry(entry); + } + } + }); - // restrict callback charset - callback = callback.replace(/[^\[\]\w$.]/g, ''); + const inp = estimateP98LongestInteraction(); - if (body === undefined) { - // empty argument - body = '' - } else if (typeof body === 'string') { - // replace chars not allowed in JavaScript that are in JSON - body = body - .replace(/\u2028/g, '\\u2028') - .replace(/\u2029/g, '\\u2029') + if (inp && inp.latency !== metric.value) { + metric.value = inp.latency; + metric.entries = inp.entries; + report(); } + }; - // the /**/ is a specific security mitigation for "Rosetta Flash JSONP abuse" - // the typeof check is just to reduce client error noise - body = '/**/ typeof ' + callback + ' === \'function\' && ' + callback + '(' + body + ');'; - } + const po = observe.observe('event', handleEntries, { + // Event Timing entries have their durations rounded to the nearest 8ms, + // so a duration of 40ms would be any event that spans 2.5 or more frames + // at 60Hz. This threshold is chosen to strike a balance between usefulness + // and performance. Running this callback for any interaction that spans + // just one or two frames is likely not worth the insight that could be + // gained. + durationThreshold: opts.durationThreshold || 40, + } ); - return this.send(body); -}; + report = bindReporter.bindReporter(onReport, metric, opts.reportAllChanges); -/** - * Send given HTTP status code. - * - * Sets the response status to `statusCode` and the body of the - * response to the standard description from node's http.STATUS_CODES - * or the statusCode number if no description. - * - * Examples: - * - * res.sendStatus(200); - * - * @param {number} statusCode - * @public - */ + if (po) { + // Also observe entries of type `first-input`. This is useful in cases + // where the first interaction is less than the `durationThreshold`. + po.observe({ type: 'first-input', buffered: true }); -res.sendStatus = function sendStatus(statusCode) { - var body = statuses.message[statusCode] || String(statusCode) + onHidden.onHidden(() => { + handleEntries(po.takeRecords() ); - this.statusCode = statusCode; - this.type('txt'); + // If the interaction count shows that there were interactions but + // none were captured by the PerformanceObserver, report a latency of 0. + if (metric.value < 0 && getInteractionCountForNavigation() > 0) { + metric.value = 0; + metric.entries = []; + } - return this.send(body); + report(true); + }); + } }; -/** - * Transfer the file at the given `path`. - * - * Automatically sets the _Content-Type_ response header field. - * The callback `callback(err)` is invoked when the transfer is complete - * or when an error occurs. Be sure to check `res.headersSent` - * if you wish to attempt responding, as the header and some data - * may have already been transferred. - * - * Options: - * - * - `maxAge` defaulting to 0 (can be string converted by `ms`) - * - `root` root directory for relative filenames - * - `headers` object of headers to serve with file - * - `dotfiles` serve dotfiles, defaulting to false; can be `"allow"` to send them - * - * Other options are passed along to `send`. - * - * Examples: - * - * The following example illustrates how `res.sendFile()` may - * be used as an alternative for the `static()` middleware for - * dynamic situations. The code backing `res.sendFile()` is actually - * the same code, so HTTP cache support etc is identical. +exports.onINP = onINP; +//# sourceMappingURL=getINP.js.map + + +/***/ }), + +/***/ 67077: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const types = __nccwpck_require__(49884); +const bindReporter = __nccwpck_require__(88172); +const getActivationStart = __nccwpck_require__(95578); +const getVisibilityWatcher = __nccwpck_require__(82450); +const initMetric = __nccwpck_require__(87112); +const observe = __nccwpck_require__(70248); +const onHidden = __nccwpck_require__(81031); + +/* + * Copyright 2020 Google LLC * - * app.get('/user/:uid/photos/:file', function(req, res){ - * var uid = req.params.uid - * , file = req.params.file; + * 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 * - * req.user.mayViewFilesFrom(uid, function(yes){ - * if (yes) { - * res.sendFile('/uploads/' + uid + '/' + file); - * } else { - * res.send(403, 'Sorry! you cant see that.'); - * } - * }); - * }); + * https://www.apache.org/licenses/LICENSE-2.0 * - * @public + * 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. */ -res.sendFile = function sendFile(path, options, callback) { - var done = callback; - var req = this.req; - var res = this; - var next = req.next; - var opts = options || {}; +const reportedMetricIDs = {}; - if (!path) { - throw new TypeError('path argument is required to res.sendFile'); - } +/** + * Calculates the [LCP](https://web.dev/lcp/) value for the current page and + * calls the `callback` function once the value is ready (along with the + * relevant `largest-contentful-paint` performance entry used to determine the + * value). The reported value is a `DOMHighResTimeStamp`. + */ +const onLCP = (onReport) => { + const visibilityWatcher = getVisibilityWatcher.getVisibilityWatcher(); + const metric = initMetric.initMetric('LCP'); + let report; - if (typeof path !== 'string') { - throw new TypeError('path must be a string to res.sendFile') - } + const handleEntries = (entries) => { + const lastEntry = entries[entries.length - 1] ; + if (lastEntry) { + // The startTime attribute returns the value of the renderTime if it is + // not 0, and the value of the loadTime otherwise. The activationStart + // reference is used because LCP should be relative to page activation + // rather than navigation start if the page was prerendered. + const value = Math.max(lastEntry.startTime - getActivationStart.getActivationStart(), 0); - // support function as second arg - if (typeof options === 'function') { - done = options; - opts = {}; - } + // Only report if the page wasn't hidden prior to LCP. + if (value < visibilityWatcher.firstHiddenTime) { + metric.value = value; + metric.entries = [lastEntry]; + report(); + } + } + }; - if (!opts.root && !isAbsolute(path)) { - throw new TypeError('path must be absolute or specify root to res.sendFile'); + const po = observe.observe('largest-contentful-paint', handleEntries); + + if (po) { + report = bindReporter.bindReporter(onReport, metric); + + const stopListening = () => { + if (!reportedMetricIDs[metric.id]) { + handleEntries(po.takeRecords() ); + po.disconnect(); + reportedMetricIDs[metric.id] = true; + report(true); + } + }; + + // Stop listening after input. Note: while scrolling is an input that + // stop LCP observation, it's unreliable since it can be programmatically + // generated. See: https://github.com/GoogleChrome/web-vitals/issues/75 + ['keydown', 'click'].forEach(type => { + if (types.WINDOW.document) { + addEventListener(type, stopListening, { once: true, capture: true }); + } + }); + + onHidden.onHidden(stopListening, true); + + return stopListening; } - // create file stream - var pathname = encodeURI(path); - var file = send(req, pathname, opts); + return; +}; - // transfer - sendfile(res, file, opts, function (err) { - if (done) return done(err); - if (err && err.code === 'EISDIR') return next(); +exports.onLCP = onLCP; +//# sourceMappingURL=getLCP.js.map - // next() all but write errors - if (err && err.code !== 'ECONNABORTED' && err.syscall !== 'write') { - next(err); + +/***/ }), + +/***/ 88172: +/***/ ((__unused_webpack_module, exports) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const bindReporter = ( + callback, + metric, + reportAllChanges, +) => { + let prevValue; + let delta; + return (forceReport) => { + if (metric.value >= 0) { + if (forceReport || reportAllChanges) { + delta = metric.value - (prevValue || 0); + + // Report the metric if there's a non-zero delta or if no previous + // value exists (which can happen in the case of the document becoming + // hidden when the metric value is 0). + // See: https://github.com/GoogleChrome/web-vitals/issues/14 + if (delta || prevValue === undefined) { + prevValue = metric.value; + metric.delta = delta; + callback(metric); + } + } } - }); + }; }; -/** - * Transfer the file at the given `path`. +exports.bindReporter = bindReporter; +//# sourceMappingURL=bindReporter.js.map + + +/***/ }), + +/***/ 8963: +/***/ ((__unused_webpack_module, exports) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/* + * Copyright 2020 Google LLC * - * Automatically sets the _Content-Type_ response header field. - * The callback `callback(err)` is invoked when the transfer is complete - * or when an error occurs. Be sure to check `res.headersSent` - * if you wish to attempt responding, as the header and some data - * may have already been transferred. - * - * Options: - * - * - `maxAge` defaulting to 0 (can be string converted by `ms`) - * - `root` root directory for relative filenames - * - `headers` object of headers to serve with file - * - `dotfiles` serve dotfiles, defaulting to false; can be `"allow"` to send them - * - * Other options are passed along to `send`. - * - * Examples: - * - * The following example illustrates how `res.sendfile()` may - * be used as an alternative for the `static()` middleware for - * dynamic situations. The code backing `res.sendfile()` is actually - * the same code, so HTTP cache support etc is identical. - * - * app.get('/user/:uid/photos/:file', function(req, res){ - * var uid = req.params.uid - * , file = req.params.file; + * 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 * - * req.user.mayViewFilesFrom(uid, function(yes){ - * if (yes) { - * res.sendfile('/uploads/' + uid + '/' + file); - * } else { - * res.send(403, 'Sorry! you cant see that.'); - * } - * }); - * }); + * https://www.apache.org/licenses/LICENSE-2.0 * - * @public + * 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. */ -res.sendfile = function (path, options, callback) { - var done = callback; - var req = this.req; - var res = this; - var next = req.next; - var opts = options || {}; +/** + * Performantly generate a unique, 30-char string by combining a version + * number, the current timestamp with a 13-digit number integer. + * @return {string} + */ +const generateUniqueID = () => { + return `v3-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`; +}; - // support function as second arg - if (typeof options === 'function') { - done = options; - opts = {}; - } +exports.generateUniqueID = generateUniqueID; +//# sourceMappingURL=generateUniqueID.js.map - // create file stream - var file = send(req, path, opts); - // transfer - sendfile(res, file, opts, function (err) { - if (done) return done(err); - if (err && err.code === 'EISDIR') return next(); +/***/ }), - // next() all but write errors - if (err && err.code !== 'ECONNABORTED' && err.syscall !== 'write') { - next(err); - } - }); -}; +/***/ 95578: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -res.sendfile = deprecate.function(res.sendfile, - 'res.sendfile: Use res.sendFile instead'); +Object.defineProperty(exports, "__esModule", ({ value: true })); -/** - * Transfer the file at the given `path` as an attachment. - * - * Optionally providing an alternate attachment `filename`, - * and optional callback `callback(err)`. The callback is invoked - * when the data transfer is complete, or when an error has - * occurred. Be sure to check `res.headersSent` if you plan to respond. +const getNavigationEntry = __nccwpck_require__(78640); + +/* + * Copyright 2022 Google LLC * - * Optionally providing an `options` object to use with `res.sendFile()`. - * This function will set the `Content-Disposition` header, overriding - * any `Content-Disposition` header passed as header options in order - * to set the attachment and filename. + * 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 * - * This method uses `res.sendFile()`. + * https://www.apache.org/licenses/LICENSE-2.0 * - * @public + * 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. */ -res.download = function download (path, filename, options, callback) { - var done = callback; - var name = filename; - var opts = options || null - - // support function as second or third arg - if (typeof filename === 'function') { - done = filename; - name = null; - opts = null - } else if (typeof options === 'function') { - done = options - opts = null - } +const getActivationStart = () => { + const navEntry = getNavigationEntry.getNavigationEntry(); + return (navEntry && navEntry.activationStart) || 0; +}; - // support optional filename, where options may be in it's place - if (typeof filename === 'object' && - (typeof options === 'function' || options === undefined)) { - name = null - opts = filename - } +exports.getActivationStart = getActivationStart; +//# sourceMappingURL=getActivationStart.js.map - // set Content-Disposition when file is sent - var headers = { - 'Content-Disposition': contentDisposition(name || path) - }; - // merge user-provided headers - if (opts && opts.headers) { - var keys = Object.keys(opts.headers) - for (var i = 0; i < keys.length; i++) { - var key = keys[i] - if (key.toLowerCase() !== 'content-disposition') { - headers[key] = opts.headers[key] - } - } - } +/***/ }), - // merge user-provided options - opts = Object.create(opts) - opts.headers = headers +/***/ 78640: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // Resolve the full path for sendFile - var fullPath = !opts.root - ? resolve(path) - : path +Object.defineProperty(exports, "__esModule", ({ value: true })); - // send file - return this.sendFile(fullPath, opts, done) -}; +const types = __nccwpck_require__(49884); -/** - * Set _Content-Type_ response header with `type` through `mime.lookup()` - * when it does not contain "/", or set the Content-Type to `type` otherwise. +/* + * Copyright 2022 Google LLC * - * Examples: + * 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 * - * res.type('.html'); - * res.type('html'); - * res.type('json'); - * res.type('application/json'); - * res.type('png'); + * https://www.apache.org/licenses/LICENSE-2.0 * - * @param {String} type - * @return {ServerResponse} for chaining - * @public + * 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. */ -res.contentType = -res.type = function contentType(type) { - var ct = type.indexOf('/') === -1 - ? mime.lookup(type) - : type; +const getNavigationEntryFromPerformanceTiming = () => { + // eslint-disable-next-line deprecation/deprecation + const timing = types.WINDOW.performance.timing; + // eslint-disable-next-line deprecation/deprecation + const type = types.WINDOW.performance.navigation.type; - return this.set('Content-Type', ct); + const navigationEntry = { + entryType: 'navigation', + startTime: 0, + type: type == 2 ? 'back_forward' : type === 1 ? 'reload' : 'navigate', + }; + + for (const key in timing) { + if (key !== 'navigationStart' && key !== 'toJSON') { + // eslint-disable-next-line deprecation/deprecation + navigationEntry[key] = Math.max((timing[key ] ) - timing.navigationStart, 0); + } + } + return navigationEntry ; }; -/** - * Respond to the Acceptable formats using an `obj` - * of mime-type callbacks. - * - * This method uses `req.accepted`, an array of - * acceptable types ordered by their quality values. - * When "Accept" is not present the _first_ callback - * is invoked, otherwise the first match is used. When - * no match is performed the server responds with - * 406 "Not Acceptable". - * - * Content-Type is set for you, however if you choose - * you may alter this within the callback using `res.type()` - * or `res.set('Content-Type', ...)`. - * - * res.format({ - * 'text/plain': function(){ - * res.send('hey'); - * }, - * - * 'text/html': function(){ - * res.send('

hey

'); - * }, - * - * 'application/json': function () { - * res.send({ message: 'hey' }); - * } - * }); - * - * In addition to canonicalized MIME types you may - * also use extnames mapped to these types: - * - * res.format({ - * text: function(){ - * res.send('hey'); - * }, - * - * html: function(){ - * res.send('

hey

'); - * }, +const getNavigationEntry = () => { + if (types.WINDOW.__WEB_VITALS_POLYFILL__) { + return ( + types.WINDOW.performance && + ((performance.getEntriesByType && performance.getEntriesByType('navigation')[0]) || + getNavigationEntryFromPerformanceTiming()) + ); + } else { + return types.WINDOW.performance && performance.getEntriesByType && performance.getEntriesByType('navigation')[0]; + } +}; + +exports.getNavigationEntry = getNavigationEntry; +//# sourceMappingURL=getNavigationEntry.js.map + + +/***/ }), + +/***/ 82450: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const types = __nccwpck_require__(49884); +const onHidden = __nccwpck_require__(81031); + +/* + * Copyright 2020 Google LLC * - * json: function(){ - * res.send({ message: 'hey' }); - * } - * }); + * 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 * - * By default Express passes an `Error` - * with a `.status` of 406 to `next(err)` - * if a match is not made. If you provide - * a `.default` callback it will be invoked - * instead. + * https://www.apache.org/licenses/LICENSE-2.0 * - * @param {Object} obj - * @return {ServerResponse} for chaining - * @public + * 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. */ -res.format = function(obj){ - var req = this.req; - var next = req.next; +let firstHiddenTime = -1; - var keys = Object.keys(obj) - .filter(function (v) { return v !== 'default' }) +const initHiddenTime = () => { + // If the document is hidden and not prerendering, assume it was always + // hidden and the page was loaded in the background. + if (types.WINDOW.document && types.WINDOW.document.visibilityState) { + firstHiddenTime = types.WINDOW.document.visibilityState === 'hidden' && !types.WINDOW.document.prerendering ? 0 : Infinity; + } +}; - var key = keys.length > 0 - ? req.accepts(keys) - : false; +const trackChanges = () => { + // Update the time if/when the document becomes hidden. + onHidden.onHidden(({ timeStamp }) => { + firstHiddenTime = timeStamp; + }, true); +}; - this.vary("Accept"); +const getVisibilityWatcher = ( - if (key) { - this.set('Content-Type', normalizeType(key).value); - obj[key](req, this, next); - } else if (obj.default) { - obj.default(req, this, next) - } else { - next(createError(406, { - types: normalizeTypes(keys).map(function (o) { return o.value }) - })) +) => { + if (firstHiddenTime < 0) { + // If the document is hidden when this code runs, assume it was hidden + // since navigation start. This isn't a perfect heuristic, but it's the + // best we can do until an API is available to support querying past + // visibilityState. + initHiddenTime(); + trackChanges(); } - - return this; + return { + get firstHiddenTime() { + return firstHiddenTime; + }, + }; }; -/** - * Set _Content-Disposition_ header to _attachment_ with optional `filename`. - * - * @param {String} filename - * @return {ServerResponse} - * @public - */ +exports.getVisibilityWatcher = getVisibilityWatcher; +//# sourceMappingURL=getVisibilityWatcher.js.map -res.attachment = function attachment(filename) { - if (filename) { - this.type(extname(filename)); - } - this.set('Content-Disposition', contentDisposition(filename)); +/***/ }), - return this; -}; +/***/ 87112: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/** - * Append additional header `field` with value `val`. +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const types = __nccwpck_require__(49884); +const generateUniqueID = __nccwpck_require__(8963); +const getActivationStart = __nccwpck_require__(95578); +const getNavigationEntry = __nccwpck_require__(78640); + +/* + * Copyright 2020 Google LLC * - * Example: + * 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 * - * res.append('Link', ['', '']); - * res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly'); - * res.append('Warning', '199 Miscellaneous warning'); + * https://www.apache.org/licenses/LICENSE-2.0 * - * @param {String} field - * @param {String|Array} val - * @return {ServerResponse} for chaining - * @public + * 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. */ -res.append = function append(field, val) { - var prev = this.get(field); - var value = val; +const initMetric = (name, value) => { + const navEntry = getNavigationEntry.getNavigationEntry(); + let navigationType = 'navigate'; - if (prev) { - // concat the new and prev vals - value = Array.isArray(prev) ? prev.concat(val) - : Array.isArray(val) ? [prev].concat(val) - : [prev, val] + if (navEntry) { + if ((types.WINDOW.document && types.WINDOW.document.prerendering) || getActivationStart.getActivationStart() > 0) { + navigationType = 'prerender'; + } else { + navigationType = navEntry.type.replace(/_/g, '-') ; + } } - return this.set(field, value); + return { + name, + value: typeof value === 'undefined' ? -1 : value, + rating: 'good', // Will be updated if the value changes. + delta: 0, + entries: [], + id: generateUniqueID.generateUniqueID(), + navigationType, + }; }; +exports.initMetric = initMetric; +//# sourceMappingURL=initMetric.js.map + + +/***/ }), + +/***/ 70248: +/***/ ((__unused_webpack_module, exports) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + /** - * Set header `field` to `val`, or pass - * an object of header fields. + * Takes a performance entry type and a callback function, and creates a + * `PerformanceObserver` instance that will observe the specified entry type + * with buffering enabled and call the callback _for each entry_. * - * Examples: + * This function also feature-detects entry support and wraps the logic in a + * try/catch to avoid errors in unsupporting browsers. + */ +const observe = ( + type, + callback, + opts, +) => { + try { + if (PerformanceObserver.supportedEntryTypes.includes(type)) { + const po = new PerformanceObserver(list => { + callback(list.getEntries() ); + }); + po.observe( + Object.assign( + { + type, + buffered: true, + }, + opts || {}, + ) , + ); + return po; + } + } catch (e) { + // Do nothing. + } + return; +}; + +exports.observe = observe; +//# sourceMappingURL=observe.js.map + + +/***/ }), + +/***/ 81031: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const types = __nccwpck_require__(49884); + +/* + * Copyright 2020 Google LLC * - * res.set('Foo', ['bar', 'baz']); - * res.set('Accept', 'application/json'); - * res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' }); + * 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 * - * Aliased as `res.header()`. + * https://www.apache.org/licenses/LICENSE-2.0 * - * @param {String|Object} field - * @param {String|Array} val - * @return {ServerResponse} for chaining - * @public + * 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. */ -res.set = -res.header = function header(field, val) { - if (arguments.length === 2) { - var value = Array.isArray(val) - ? val.map(String) - : String(val); - - // add charset to content-type - if (field.toLowerCase() === 'content-type') { - if (Array.isArray(value)) { - throw new TypeError('Content-Type cannot be set to an Array'); - } - if (!charsetRegExp.test(value)) { - var charset = mime.charsets.lookup(value.split(';')[0]); - if (charset) value += '; charset=' + charset.toLowerCase(); +const onHidden = (cb, once) => { + const onHiddenOrPageHide = (event) => { + if (event.type === 'pagehide' || types.WINDOW.document.visibilityState === 'hidden') { + cb(event); + if (once) { + removeEventListener('visibilitychange', onHiddenOrPageHide, true); + removeEventListener('pagehide', onHiddenOrPageHide, true); } } + }; - this.setHeader(field, value); - } else { - for (var key in field) { - this.set(key, field[key]); - } + if (types.WINDOW.document) { + addEventListener('visibilitychange', onHiddenOrPageHide, true); + // Some browsers have buggy implementations of visibilitychange, + // so we use pagehide in addition, just to be safe. + addEventListener('pagehide', onHiddenOrPageHide, true); } - return this; }; +exports.onHidden = onHidden; +//# sourceMappingURL=onHidden.js.map + + +/***/ }), + +/***/ 31411: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const observe = __nccwpck_require__(70248); + +let interactionCountEstimate = 0; +let minKnownInteractionId = Infinity; +let maxKnownInteractionId = 0; + +const updateEstimate = (entries) => { + (entries ).forEach(e => { + if (e.interactionId) { + minKnownInteractionId = Math.min(minKnownInteractionId, e.interactionId); + maxKnownInteractionId = Math.max(maxKnownInteractionId, e.interactionId); + + interactionCountEstimate = maxKnownInteractionId ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1 : 0; + } + }); +}; + +let po; + /** - * Get value for header `field`. - * - * @param {String} field - * @return {String} - * @public + * Returns the `interactionCount` value using the native API (if available) + * or the polyfill estimate in this module. */ - -res.get = function(field){ - return this.getHeader(field); +const getInteractionCount = () => { + return po ? interactionCountEstimate : performance.interactionCount || 0; }; /** - * Clear cookie `name`. + * Feature detects native support or initializes the polyfill if needed. + */ +const initInteractionCountPolyfill = () => { + if ('interactionCount' in performance || po) return; + + po = observe.observe('event', updateEstimate, { + type: 'event', + buffered: true, + durationThreshold: 0, + } ); +}; + +exports.getInteractionCount = getInteractionCount; +exports.initInteractionCountPolyfill = initInteractionCountPolyfill; +//# sourceMappingURL=interactionCountPolyfill.js.map + + +/***/ }), + +/***/ 54255: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const types = __nccwpck_require__(49884); +const bindReporter = __nccwpck_require__(88172); +const getActivationStart = __nccwpck_require__(95578); +const getNavigationEntry = __nccwpck_require__(78640); +const initMetric = __nccwpck_require__(87112); + +/* + * Copyright 2020 Google LLC * - * @param {String} name - * @param {Object} [options] - * @return {ServerResponse} for chaining - * @public + * 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 + * + * https://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. */ -res.clearCookie = function clearCookie(name, options) { - if (options) { - if (options.maxAge) { - deprecate('res.clearCookie: Passing "options.maxAge" is deprecated. In v5.0.0 of Express, this option will be ignored, as res.clearCookie will automatically set cookies to expire immediately. Please update your code to omit this option.'); - } - if (options.expires) { - deprecate('res.clearCookie: Passing "options.expires" is deprecated. In v5.0.0 of Express, this option will be ignored, as res.clearCookie will automatically set cookies to expire immediately. Please update your code to omit this option.'); - } +/** + * Runs in the next task after the page is done loading and/or prerendering. + * @param callback + */ +const whenReady = (callback) => { + if (!types.WINDOW.document) { + return; } - var opts = merge({ expires: new Date(1), path: '/' }, options); - return this.cookie(name, '', opts); + if (types.WINDOW.document.prerendering) { + addEventListener('prerenderingchange', () => whenReady(callback), true); + } else if (types.WINDOW.document.readyState !== 'complete') { + addEventListener('load', () => whenReady(callback), true); + } else { + // Queue a task so the callback runs after `loadEventEnd`. + setTimeout(callback, 0); + } }; /** - * Set cookie `name` to `value`, with the given `options`. - * - * Options: - * - * - `maxAge` max-age in milliseconds, converted to `expires` - * - `signed` sign the cookie - * - `path` defaults to "/" - * - * Examples: - * - * // "Remember Me" for 15 minutes - * res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true }); - * - * // same as above - * res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true }) + * Calculates the [TTFB](https://web.dev/time-to-first-byte/) value for the + * current page and calls the `callback` function once the page has loaded, + * along with the relevant `navigation` performance entry used to determine the + * value. The reported value is a `DOMHighResTimeStamp`. * - * @param {String} name - * @param {String|Object} value - * @param {Object} [options] - * @return {ServerResponse} for chaining - * @public + * Note, this function waits until after the page is loaded to call `callback` + * in order to ensure all properties of the `navigation` entry are populated. + * This is useful if you want to report on other metrics exposed by the + * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For + * example, the TTFB metric starts from the page's [time + * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it + * includes time spent on DNS lookup, connection negotiation, network latency, + * and server processing time. */ +const onTTFB = (onReport, opts) => { + // Set defaults + // eslint-disable-next-line no-param-reassign + opts = opts || {}; -res.cookie = function (name, value, options) { - var opts = merge({}, options); - var secret = this.req.secret; - var signed = opts.signed; + // https://web.dev/ttfb/#what-is-a-good-ttfb-score + // const thresholds = [800, 1800]; - if (signed && !secret) { - throw new Error('cookieParser("secret") required for signed cookies'); - } + const metric = initMetric.initMetric('TTFB'); + const report = bindReporter.bindReporter(onReport, metric, opts.reportAllChanges); - var val = typeof value === 'object' - ? 'j:' + JSON.stringify(value) - : String(value); + whenReady(() => { + const navEntry = getNavigationEntry.getNavigationEntry() ; - if (signed) { - val = 's:' + sign(val, secret); - } + if (navEntry) { + // The activationStart reference is used because TTFB should be + // relative to page activation rather than navigation start if the + // page was prerendered. But in cases where `activationStart` occurs + // after the first byte is received, this time should be clamped at 0. + metric.value = Math.max(navEntry.responseStart - getActivationStart.getActivationStart(), 0); - if (opts.maxAge != null) { - var maxAge = opts.maxAge - 0 + // In some cases the value reported is negative or is larger + // than the current page time. Ignore these cases: + // https://github.com/GoogleChrome/web-vitals/issues/137 + // https://github.com/GoogleChrome/web-vitals/issues/162 + if (metric.value < 0 || metric.value > performance.now()) return; - if (!isNaN(maxAge)) { - opts.expires = new Date(Date.now() + maxAge) - opts.maxAge = Math.floor(maxAge / 1000) + metric.entries = [navEntry]; + + report(true); } - } + }); +}; - if (opts.path == null) { - opts.path = '/'; - } +exports.onTTFB = onTTFB; +//# sourceMappingURL=onTTFB.js.map - this.append('Set-Cookie', cookie.serialize(name, String(val), opts)); - return this; -}; +/***/ }), + +/***/ 14208: +/***/ ((__unused_webpack_module, exports) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); /** - * Set the location header to `url`. - * - * The given `url` can also be "back", which redirects - * to the _Referrer_ or _Referer_ headers or "/". - * - * Examples: - * - * res.location('/foo/bar').; - * res.location('http://example.com'); - * res.location('../login'); + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. * - * @param {String} url - * @return {ServerResponse} for chaining - * @public + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. */ +const DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__); -res.location = function location(url) { - var loc; +exports.DEBUG_BUILD = DEBUG_BUILD; +//# sourceMappingURL=debug-build.js.map - // "back" is an alias for the referrer - if (url === 'back') { - deprecate('res.location("back"): use res.location(req.get("Referrer") || "/") and refer to https://dub.sh/security-redirect for best practices'); - loc = this.req.get('Referrer') || '/'; - } else { - loc = String(url); - } - return this.set('Location', encodeUrl(loc)); -}; +/***/ }), + +/***/ 52574: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); /** - * Redirect to the given `url` with optional response `status` - * defaulting to 302. - * - * The resulting `url` is determined by `res.location()`, so - * it will play nicely with mounted apps, relative paths, - * `"back"` etc. - * - * Examples: - * - * res.redirect('/foo/bar'); - * res.redirect('http://example.com'); - * res.redirect(301, 'http://example.com'); - * res.redirect('../login'); // /blog/post/1 -> /blog/login + * Create and track fetch request spans for usage in combination with `addInstrumentationHandler`. * - * @public + * @returns Span if a span was created, otherwise void. */ +function instrumentFetchRequest( + handlerData, + shouldCreateSpan, + shouldAttachHeaders, + spans, + spanOrigin = 'auto.http.browser', +) { + if (!core.hasTracingEnabled() || !handlerData.fetchData) { + return undefined; + } -res.redirect = function redirect(url) { - var address = url; - var body; - var status = 302; + const shouldCreateSpanResult = shouldCreateSpan(handlerData.fetchData.url); - // allow status / url - if (arguments.length === 2) { - if (typeof arguments[0] === 'number') { - status = arguments[0]; - address = arguments[1]; - } else { - deprecate('res.redirect(url, status): Use res.redirect(status, url) instead'); - status = arguments[1]; + if (handlerData.endTimestamp && shouldCreateSpanResult) { + const spanId = handlerData.fetchData.__span; + if (!spanId) return; + + const span = spans[spanId]; + if (span) { + endSpan(span, handlerData); + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete spans[spanId]; } + return undefined; } - // Set location header - address = this.location(address).get('Location'); - - // Support text/{plain,html} by default - this.format({ - text: function(){ - body = statuses.message[status] + '. Redirecting to ' + address - }, + const scope = core.getCurrentScope(); + const client = core.getClient(); - html: function(){ - var u = escapeHtml(address); - body = '

' + statuses.message[status] + '. Redirecting to ' + u + '

' - }, + const { method, url } = handlerData.fetchData; - default: function(){ - body = ''; - } - }); + const fullUrl = getFullURL(url); + const host = fullUrl ? utils.parseUrl(fullUrl).host : undefined; - // Respond - this.statusCode = status; - this.set('Content-Length', Buffer.byteLength(body)); + const span = shouldCreateSpanResult + ? core.startInactiveSpan({ + name: `${method} ${url}`, + onlyIfParent: true, + attributes: { + url, + type: 'fetch', + 'http.method': method, + 'http.url': fullUrl, + 'server.address': host, + [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanOrigin, + }, + op: 'http.client', + }) + : undefined; - if (this.req.method === 'HEAD') { - this.end(); - } else { - this.end(body); + if (span) { + handlerData.fetchData.__span = span.spanContext().spanId; + spans[span.spanContext().spanId] = span; } -}; -/** - * Add `field` to Vary. If already present in the Vary set, then - * this call is simply ignored. - * - * @param {Array|String} field - * @return {ServerResponse} for chaining - * @public - */ + if (shouldAttachHeaders(handlerData.fetchData.url) && client) { + const request = handlerData.args[0]; -res.vary = function(field){ - // checks for back-compat - if (!field || (Array.isArray(field) && !field.length)) { - deprecate('res.vary(): Provide a field name'); - return this; - } + // In case the user hasn't set the second argument of a fetch call we default it to `{}`. + handlerData.args[1] = handlerData.args[1] || {}; - vary(this, field); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const options = handlerData.args[1]; - return this; -}; + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access + options.headers = addTracingHeadersToFetchRequest(request, client, scope, options, span); + } + + return span; +} /** - * Render `view` with the given `options` and optional callback `fn`. - * When a callback function is given a response will _not_ be made - * automatically, otherwise a response of _200_ and _text/html_ is given. - * - * Options: - * - * - `cache` boolean hinting to the engine it should cache - * - `filename` filename of the view being rendered - * - * @public + * Adds sentry-trace and baggage headers to the various forms of fetch headers */ +function addTracingHeadersToFetchRequest( + request, // unknown is actually type Request but we can't export DOM types from this package, + client, + scope, + options -res.render = function render(view, options, callback) { - var app = this.req.app; - var done = callback; - var opts = options || {}; - var req = this.req; - var self = this; - - // support callback function as second arg - if (typeof options === 'function') { - done = options; - opts = {}; - } +, + requestSpan, +) { + // eslint-disable-next-line deprecation/deprecation + const span = requestSpan || scope.getSpan(); - // merge res.locals - opts._locals = self.locals; + const isolationScope = core.getIsolationScope(); - // default callback to respond - done = done || function (err, str) { - if (err) return req.next(err); - self.send(str); + const { traceId, spanId, sampled, dsc } = { + ...isolationScope.getPropagationContext(), + ...scope.getPropagationContext(), }; - // render - app.render(view, opts, done); -}; + const sentryTraceHeader = span ? core.spanToTraceHeader(span) : utils.generateSentryTraceHeader(traceId, spanId, sampled); -// pipe the send file stream -function sendfile(res, file, options, callback) { - var done = false; - var streaming; + const sentryBaggageHeader = utils.dynamicSamplingContextToSentryBaggageHeader( + dsc || + (span ? core.getDynamicSamplingContextFromSpan(span) : core.getDynamicSamplingContextFromClient(traceId, client, scope)), + ); - // request aborted - function onaborted() { - if (done) return; - done = true; + const headers = + options.headers || + (typeof Request !== 'undefined' && utils.isInstanceOf(request, Request) ? (request ).headers : undefined); - var err = new Error('Request aborted'); - err.code = 'ECONNABORTED'; - callback(err); - } + if (!headers) { + return { 'sentry-trace': sentryTraceHeader, baggage: sentryBaggageHeader }; + } else if (typeof Headers !== 'undefined' && utils.isInstanceOf(headers, Headers)) { + const newHeaders = new Headers(headers ); - // directory - function ondirectory() { - if (done) return; - done = true; + newHeaders.append('sentry-trace', sentryTraceHeader); - var err = new Error('EISDIR, read'); - err.code = 'EISDIR'; - callback(err); - } + if (sentryBaggageHeader) { + // If the same header is appended multiple times the browser will merge the values into a single request header. + // Its therefore safe to simply push a "baggage" entry, even though there might already be another baggage header. + newHeaders.append(utils.BAGGAGE_HEADER_NAME, sentryBaggageHeader); + } - // errors - function onerror(err) { - if (done) return; - done = true; - callback(err); - } + return newHeaders ; + } else if (Array.isArray(headers)) { + const newHeaders = [...headers, ['sentry-trace', sentryTraceHeader]]; - // ended - function onend() { - if (done) return; - done = true; - callback(); - } + if (sentryBaggageHeader) { + // If there are multiple entries with the same key, the browser will merge the values into a single request header. + // Its therefore safe to simply push a "baggage" entry, even though there might already be another baggage header. + newHeaders.push([utils.BAGGAGE_HEADER_NAME, sentryBaggageHeader]); + } - // file - function onfile() { - streaming = false; - } + return newHeaders ; + } else { + const existingBaggageHeader = 'baggage' in headers ? headers.baggage : undefined; + const newBaggageHeaders = []; - // finished - function onfinish(err) { - if (err && err.code === 'ECONNRESET') return onaborted(); - if (err) return onerror(err); - if (done) return; + if (Array.isArray(existingBaggageHeader)) { + newBaggageHeaders.push(...existingBaggageHeader); + } else if (existingBaggageHeader) { + newBaggageHeaders.push(existingBaggageHeader); + } - setImmediate(function () { - if (streaming !== false && !done) { - onaborted(); - return; - } + if (sentryBaggageHeader) { + newBaggageHeaders.push(sentryBaggageHeader); + } - if (done) return; - done = true; - callback(); - }); + return { + ...(headers ), + 'sentry-trace': sentryTraceHeader, + baggage: newBaggageHeaders.length > 0 ? newBaggageHeaders.join(',') : undefined, + }; } +} - // streaming - function onstream() { - streaming = true; +function getFullURL(url) { + try { + const parsed = new URL(url); + return parsed.href; + } catch (e) { + return undefined; } +} - file.on('directory', ondirectory); - file.on('end', onend); - file.on('error', onerror); - file.on('file', onfile); - file.on('stream', onstream); - onFinished(res, onfinish); +function endSpan(span, handlerData) { + if (handlerData.response) { + core.setHttpStatus(span, handlerData.response.status); - if (options.headers) { - // set headers on successful transfer - file.on('headers', function headers(res) { - var obj = options.headers; - var keys = Object.keys(obj); + const contentLength = + handlerData.response && handlerData.response.headers && handlerData.response.headers.get('content-length'); - for (var i = 0; i < keys.length; i++) { - var k = keys[i]; - res.setHeader(k, obj[k]); + if (contentLength) { + const contentLengthNum = parseInt(contentLength); + if (contentLengthNum > 0) { + span.setAttribute('http.response_content_length', contentLengthNum); } - }); + } + } else if (handlerData.error) { + span.setStatus('internal_error'); } - - // pipe - file.pipe(res); + span.end(); } +exports.addTracingHeadersToFetchRequest = addTracingHeadersToFetchRequest; +exports.instrumentFetchRequest = instrumentFetchRequest; +//# sourceMappingURL=fetch.js.map + + +/***/ }), + +/***/ 50026: +/***/ ((module, exports, __nccwpck_require__) => { + +/* module decorator */ module = __nccwpck_require__.nmd(module); +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); + /** - * Stringify JSON, like JSON.stringify, but v8 optimized, with the - * ability to escape characters that can trigger HTML sniffing. - * - * @param {*} value - * @param {function} replacer - * @param {number} spaces - * @param {boolean} escape - * @returns {string} * @private */ - -function stringify (value, replacer, spaces, escape) { - // v8 checks arguments.length for optimizing simple call - // https://bugs.chromium.org/p/v8/issues/detail?id=4730 - var json = replacer || spaces - ? JSON.stringify(value, replacer, spaces) - : JSON.stringify(value); - - if (escape && typeof json === 'string') { - json = json.replace(/[<>&]/g, function (c) { - switch (c.charCodeAt(0)) { - case 0x3c: - return '\\u003c' - case 0x3e: - return '\\u003e' - case 0x26: - return '\\u0026' - /* istanbul ignore next: unreachable default */ - default: - return c - } - }) +function _autoloadDatabaseIntegrations() { + const carrier = core.getMainCarrier(); + if (!carrier.__SENTRY__) { + return; } - return json -} + const packageToIntegrationMapping = { + mongodb() { + const integration = utils.dynamicRequire(module, './node/integrations/mongo') +; + return new integration.Mongo(); + }, + mongoose() { + const integration = utils.dynamicRequire(module, './node/integrations/mongo') -/***/ }), +; + return new integration.Mongo(); + }, + mysql() { + const integration = utils.dynamicRequire(module, './node/integrations/mysql') -/***/ 85055: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +; + return new integration.Mysql(); + }, + pg() { + const integration = utils.dynamicRequire(module, './node/integrations/postgres') -"use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2013 Roman Shtylman - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ +; + return new integration.Postgres(); + }, + }; + const mappedPackages = Object.keys(packageToIntegrationMapping) + .filter(moduleName => !!utils.loadModule(moduleName)) + .map(pkg => { + try { + return packageToIntegrationMapping[pkg](); + } catch (e) { + return undefined; + } + }) + .filter(p => p) ; + if (mappedPackages.length > 0) { + carrier.__SENTRY__.integrations = [...(carrier.__SENTRY__.integrations || []), ...mappedPackages]; + } +} /** - * Module dependencies. - * @private + * This patches the global object and injects the Tracing extensions methods */ +function addExtensionMethods() { + core.addTracingExtensions(); -var Route = __nccwpck_require__(67178); -var Layer = __nccwpck_require__(38210); -var methods = __nccwpck_require__(84283); -var mixin = __nccwpck_require__(31657); -var debug = __nccwpck_require__(66515)('express:router'); -var deprecate = __nccwpck_require__(77267)('express'); -var flatten = __nccwpck_require__(35698); -var parseUrl = __nccwpck_require__(23610); -var setPrototypeOf = __nccwpck_require__(12516) + // Detect and automatically load specified integrations. + if (utils.isNodeEnv()) { + _autoloadDatabaseIntegrations(); + } +} -/** - * Module variables. - * @private - */ +exports.addExtensionMethods = addExtensionMethods; +//# sourceMappingURL=extensions.js.map -var objectRegExp = /^\[object (\S+)\]$/; -var slice = Array.prototype.slice; -var toString = Object.prototype.toString; -/** - * Initialize a new `Router` with the given `options`. - * - * @param {Object} [options] - * @return {Router} which is a callable function - * @public - */ +/***/ }), -var proto = module.exports = function(options) { - var opts = options || {}; +/***/ 69846: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - function router(req, res, next) { - router.handle(req, res, next); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - // mixin Router class functions - setPrototypeOf(router, proto) +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const express = __nccwpck_require__(86943); +const postgres = __nccwpck_require__(43224); +const mysql = __nccwpck_require__(88965); +const mongo = __nccwpck_require__(10275); +const prisma = __nccwpck_require__(23639); +const graphql = __nccwpck_require__(80422); +const apollo = __nccwpck_require__(58664); +const lazy = __nccwpck_require__(88073); +const browsertracing = __nccwpck_require__(6087); +const browserTracingIntegration = __nccwpck_require__(49293); +const request = __nccwpck_require__(26896); +const instrument = __nccwpck_require__(7380); +const fetch = __nccwpck_require__(52574); +const extensions = __nccwpck_require__(50026); + + + +exports.IdleTransaction = core.IdleTransaction; +exports.Span = core.Span; +exports.SpanStatus = core.SpanStatus; +exports.Transaction = core.Transaction; +exports.extractTraceparentData = core.extractTraceparentData; +exports.getActiveTransaction = core.getActiveTransaction; +exports.hasTracingEnabled = core.hasTracingEnabled; +exports.spanStatusfromHttpCode = core.spanStatusfromHttpCode; +exports.startIdleTransaction = core.startIdleTransaction; +exports.TRACEPARENT_REGEXP = utils.TRACEPARENT_REGEXP; +exports.stripUrlQueryAndFragment = utils.stripUrlQueryAndFragment; +exports.Express = express.Express; +exports.Postgres = postgres.Postgres; +exports.Mysql = mysql.Mysql; +exports.Mongo = mongo.Mongo; +exports.Prisma = prisma.Prisma; +exports.GraphQL = graphql.GraphQL; +exports.Apollo = apollo.Apollo; +exports.lazyLoadedNodePerformanceMonitoringIntegrations = lazy.lazyLoadedNodePerformanceMonitoringIntegrations; +exports.BROWSER_TRACING_INTEGRATION_ID = browsertracing.BROWSER_TRACING_INTEGRATION_ID; +exports.BrowserTracing = browsertracing.BrowserTracing; +exports.browserTracingIntegration = browserTracingIntegration.browserTracingIntegration; +exports.startBrowserTracingNavigationSpan = browserTracingIntegration.startBrowserTracingNavigationSpan; +exports.startBrowserTracingPageLoadSpan = browserTracingIntegration.startBrowserTracingPageLoadSpan; +exports.defaultRequestInstrumentationOptions = request.defaultRequestInstrumentationOptions; +exports.instrumentOutgoingRequests = request.instrumentOutgoingRequests; +exports.addClsInstrumentationHandler = instrument.addClsInstrumentationHandler; +exports.addFidInstrumentationHandler = instrument.addFidInstrumentationHandler; +exports.addLcpInstrumentationHandler = instrument.addLcpInstrumentationHandler; +exports.addPerformanceInstrumentationHandler = instrument.addPerformanceInstrumentationHandler; +exports.addTracingHeadersToFetchRequest = fetch.addTracingHeadersToFetchRequest; +exports.instrumentFetchRequest = fetch.instrumentFetchRequest; +exports.addExtensionMethods = extensions.addExtensionMethods; +//# sourceMappingURL=index.js.map - router.params = {}; - router._params = []; - router.caseSensitive = opts.caseSensitive; - router.mergeParams = opts.mergeParams; - router.strict = opts.strict; - router.stack = []; - return router; -}; +/***/ }), -/** - * Map the given param placeholder `name`(s) to the given callback. - * - * Parameter mapping is used to provide pre-conditions to routes - * which use normalized placeholders. For example a _:user_id_ parameter - * could automatically load a user's information from the database without - * any additional code, - * - * The callback uses the same signature as middleware, the only difference - * being that the value of the placeholder is passed, in this case the _id_ - * of the user. Once the `next()` function is invoked, just like middleware - * it will continue on to execute the route, or subsequent parameter functions. - * - * Just like in middleware, you must either respond to the request or call next - * to avoid stalling the request. - * - * app.param('user_id', function(req, res, next, id){ - * User.find(id, function(err, user){ - * if (err) { - * return next(err); - * } else if (!user) { - * return next(new Error('failed to load user')); - * } - * req.user = user; - * next(); - * }); - * }); - * - * @param {String} name - * @param {Function} fn - * @return {app} for chaining - * @public - */ +/***/ 58664: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -proto.param = function param(name, fn) { - // param logic - if (typeof name === 'function') { - deprecate('router.param(fn): Refactor to use path params'); - this._params.push(name); - return; - } +var { + _optionalChain +} = __nccwpck_require__(57540); - // apply param functions - var params = this._params; - var len = params.length; - var ret; +Object.defineProperty(exports, "__esModule", ({ value: true })); - if (name[0] === ':') { - deprecate('router.param(' + JSON.stringify(name) + ', fn): Use router.param(' + JSON.stringify(name.slice(1)) + ', fn) instead') - name = name.slice(1) +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const nodeUtils = __nccwpck_require__(40325); + +/** Tracing integration for Apollo */ +class Apollo { + /** + * @inheritDoc + */ + static __initStatic() {this.id = 'Apollo';} + + /** + * @inheritDoc + */ + + /** + * @inheritDoc + */ + constructor( + options = { + useNestjs: false, + }, + ) { + this.name = Apollo.id; + this._useNest = !!options.useNestjs; } - for (var i = 0; i < len; ++i) { - if (ret = params[i](name, fn)) { - fn = ret; + /** @inheritdoc */ + loadDependency() { + if (this._useNest) { + this._module = this._module || utils.loadModule('@nestjs/graphql'); + } else { + this._module = this._module || utils.loadModule('apollo-server-core'); } - } - // ensure we end up with a - // middleware function - if ('function' !== typeof fn) { - throw new Error('invalid param() call for ' + name + ', got ' + fn); + return this._module; } - (this.params[name] = this.params[name] || []).push(fn); - return this; -}; + /** + * @inheritDoc + */ + // eslint-disable-next-line deprecation/deprecation + setupOnce(_, getCurrentHub) { + if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) { + debugBuild.DEBUG_BUILD && utils.logger.log('Apollo Integration is skipped because of instrumenter configuration.'); + return; + } -/** - * Dispatch a req, res into the router. - * @private - */ + if (this._useNest) { + const pkg = this.loadDependency(); -proto.handle = function handle(req, res, out) { - var self = this; + if (!pkg) { + debugBuild.DEBUG_BUILD && utils.logger.error('Apollo-NestJS Integration was unable to require @nestjs/graphql package.'); + return; + } - debug('dispatching %s %s', req.method, req.url); + /** + * Iterate over resolvers of NestJS ResolversExplorerService before schemas are constructed. + */ + utils.fill( + pkg.GraphQLFactory.prototype, + 'mergeWithSchema', + function (orig) { + return function ( + + ...args + ) { + utils.fill(this.resolversExplorerService, 'explore', function (orig) { + return function () { + const resolvers = utils.arrayify(orig.call(this)); - var idx = 0; - var protohost = getProtohost(req.url) || '' - var removed = ''; - var slashAdded = false; - var sync = 0 - var paramcalled = {}; + const instrumentedResolvers = instrumentResolvers(resolvers, getCurrentHub); - // store options for OPTIONS request - // only used if OPTIONS request - var options = []; + return instrumentedResolvers; + }; + }); - // middleware and routes - var stack = self.stack; + return orig.call(this, ...args); + }; + }, + ); + } else { + const pkg = this.loadDependency(); - // manage inter-router variables - var parentParams = req.params; - var parentUrl = req.baseUrl || ''; - var done = restore(out, req, 'baseUrl', 'next', 'params'); + if (!pkg) { + debugBuild.DEBUG_BUILD && utils.logger.error('Apollo Integration was unable to require apollo-server-core package.'); + return; + } - // setup next layer - req.next = next; + /** + * Iterate over resolvers of the ApolloServer instance before schemas are constructed. + */ + utils.fill(pkg.ApolloServerBase.prototype, 'constructSchema', function (orig) { + return function ( - // for options requests, respond with a default if nothing else responds - if (req.method === 'OPTIONS') { - done = wrap(done, function(old, err) { - if (err || options.length === 0) return old(err); - sendOptionsResponse(res, options, old); - }); - } +) { + if (!this.config.resolvers) { + if (debugBuild.DEBUG_BUILD) { + if (this.config.schema) { + utils.logger.warn( + 'Apollo integration is not able to trace `ApolloServer` instances constructed via `schema` property.' + + 'If you are using NestJS with Apollo, please use `Sentry.Integrations.Apollo({ useNestjs: true })` instead.', + ); + utils.logger.warn(); + } else if (this.config.modules) { + utils.logger.warn( + 'Apollo integration is not able to trace `ApolloServer` instances constructed via `modules` property.', + ); + } - // setup basic req values - req.baseUrl = parentUrl; - req.originalUrl = req.originalUrl || req.url; + utils.logger.error('Skipping tracing as no resolvers found on the `ApolloServer` instance.'); + } - next(); + return orig.call(this); + } - function next(err) { - var layerError = err === 'route' - ? null - : err; + const resolvers = utils.arrayify(this.config.resolvers); - // remove added slash - if (slashAdded) { - req.url = req.url.slice(1) - slashAdded = false; - } + this.config.resolvers = instrumentResolvers(resolvers, getCurrentHub); - // restore altered req.url - if (removed.length !== 0) { - req.baseUrl = parentUrl; - req.url = protohost + removed + req.url.slice(protohost.length) - removed = ''; + return orig.call(this); + }; + }); } + } +}Apollo.__initStatic(); - // signal to exit router - if (layerError === 'router') { - setImmediate(done, null) - return - } +// eslint-disable-next-line deprecation/deprecation +function instrumentResolvers(resolvers, getCurrentHub) { + return resolvers.map(model => { + Object.keys(model).forEach(resolverGroupName => { + Object.keys(model[resolverGroupName]).forEach(resolverName => { + if (typeof model[resolverGroupName][resolverName] !== 'function') { + return; + } - // no more matching layers - if (idx >= stack.length) { - setImmediate(done, layerError); - return; - } + wrapResolver(model, resolverGroupName, resolverName, getCurrentHub); + }); + }); - // max sync stack - if (++sync > 100) { - return setImmediate(next, err) - } + return model; + }); +} - // get pathname of request - var path = getPathname(req); +/** + * Wrap a single resolver which can be a parent of other resolvers and/or db operations. + */ +function wrapResolver( + model, + resolverGroupName, + resolverName, + // eslint-disable-next-line deprecation/deprecation + getCurrentHub, +) { + utils.fill(model[resolverGroupName], resolverName, function (orig) { + return function ( ...args) { + // eslint-disable-next-line deprecation/deprecation + const scope = getCurrentHub().getScope(); + // eslint-disable-next-line deprecation/deprecation + const parentSpan = scope.getSpan(); + // eslint-disable-next-line deprecation/deprecation + const span = _optionalChain([parentSpan, 'optionalAccess', _2 => _2.startChild, 'call', _3 => _3({ + description: `${resolverGroupName}.${resolverName}`, + op: 'graphql.resolve', + origin: 'auto.graphql.apollo', + })]); + + const rv = orig.call(this, ...args); + + if (utils.isThenable(rv)) { + return rv.then((res) => { + _optionalChain([span, 'optionalAccess', _4 => _4.end, 'call', _5 => _5()]); + return res; + }); + } - if (path == null) { - return done(layerError); - } + _optionalChain([span, 'optionalAccess', _6 => _6.end, 'call', _7 => _7()]); - // find next matching layer - var layer; - var match; - var route; + return rv; + }; + }); +} - while (match !== true && idx < stack.length) { - layer = stack[idx++]; - match = matchLayer(layer, path); - route = layer.route; +exports.Apollo = Apollo; +//# sourceMappingURL=apollo.js.map - if (typeof match !== 'boolean') { - // hold on to layerError - layerError = layerError || match; - } - if (match !== true) { - continue; - } +/***/ }), - if (!route) { - // process non-route handlers normally - continue; - } +/***/ 86943: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (layerError) { - // routes do not match with a pending error - match = false; - continue; - } +var { + _optionalChain +} = __nccwpck_require__(57540); - var method = req.method; - var has_method = route._handles_method(method); +Object.defineProperty(exports, "__esModule", ({ value: true })); - // build up automatic options response - if (!has_method && method === 'OPTIONS') { - appendMethods(options, route._options()); - } +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const nodeUtils = __nccwpck_require__(40325); - // don't even bother matching route - if (!has_method && method !== 'HEAD') { - match = false; - } - } +/* eslint-disable max-lines */ - // no match - if (match !== true) { - return done(layerError); - } - - // store route for dispatch on change - if (route) { - req.route = route; - } +/** + * Express integration + * + * Provides an request and error handler for Express framework as well as tracing capabilities + */ +class Express { + /** + * @inheritDoc + */ + static __initStatic() {this.id = 'Express';} - // Capture one-time layer values - req.params = self.mergeParams - ? mergeParams(layer.params, parentParams) - : layer.params; - var layerPath = layer.path; + /** + * @inheritDoc + */ - // this should be done for the layer - self.process_params(layer, paramcalled, req, res, function (err) { - if (err) { - next(layerError || err) - } else if (route) { - layer.handle_request(req, res, next) - } else { - trim_prefix(layer, layerError, layerPath, path) - } + /** + * Express App instance + */ - sync = 0 - }); + /** + * @inheritDoc + */ + constructor(options = {}) { + this.name = Express.id; + this._router = options.router || options.app; + this._methods = (Array.isArray(options.methods) ? options.methods : []).concat('use'); } - function trim_prefix(layer, layerError, layerPath, path) { - if (layerPath.length !== 0) { - // Validate path is a prefix match - if (layerPath !== path.slice(0, layerPath.length)) { - next(layerError) - return - } - - // Validate path breaks on a path separator - var c = path[layerPath.length] - if (c && c !== '/' && c !== '.') return next(layerError) - - // Trim off the part of the url that matches the route - // middleware (.use stuff) needs to have the path stripped - debug('trim prefix (%s) from url %s', layerPath, req.url); - removed = layerPath; - req.url = protohost + req.url.slice(protohost.length + removed.length) - - // Ensure leading slash - if (!protohost && req.url[0] !== '/') { - req.url = '/' + req.url; - slashAdded = true; - } - - // Setup base URL (no trailing slash) - req.baseUrl = parentUrl + (removed[removed.length - 1] === '/' - ? removed.substring(0, removed.length - 1) - : removed); + /** + * @inheritDoc + */ + // eslint-disable-next-line deprecation/deprecation + setupOnce(_, getCurrentHub) { + if (!this._router) { + debugBuild.DEBUG_BUILD && utils.logger.error('ExpressIntegration is missing an Express instance'); + return; } - debug('%s %s : %s', layer.name, layerPath, req.originalUrl); - - if (layerError) { - layer.handle_error(layerError, req, res, next); - } else { - layer.handle_request(req, res, next); + if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) { + debugBuild.DEBUG_BUILD && utils.logger.log('Express Integration is skipped because of instrumenter configuration.'); + return; } + + instrumentMiddlewares(this._router, this._methods); + instrumentRouter(this._router ); } -}; +}Express.__initStatic(); /** - * Process any parameters for the layer. - * @private + * Wraps original middleware function in a tracing call, which stores the info about the call as a span, + * and finishes it once the middleware is done invoking. + * + * Express middlewares have 3 various forms, thus we have to take care of all of them: + * // sync + * app.use(function (req, res) { ... }) + * // async + * app.use(function (req, res, next) { ... }) + * // error handler + * app.use(function (err, req, res, next) { ... }) + * + * They all internally delegate to the `router[method]` of the given application instance. */ +// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any +function wrap(fn, method) { + const arity = fn.length; -proto.process_params = function process_params(layer, called, req, res, done) { - var params = this.params; + switch (arity) { + case 2: { + return function ( req, res) { + const transaction = res.__sentry_transaction; + if (transaction) { + // eslint-disable-next-line deprecation/deprecation + const span = transaction.startChild({ + description: fn.name, + op: `middleware.express.${method}`, + origin: 'auto.middleware.express', + }); + res.once('finish', () => { + span.end(); + }); + } + return fn.call(this, req, res); + }; + } + case 3: { + return function ( - // captured parameters from the layer, keys and values - var keys = layer.keys; + req, + res, + next, + ) { + const transaction = res.__sentry_transaction; + // eslint-disable-next-line deprecation/deprecation + const span = _optionalChain([transaction, 'optionalAccess', _2 => _2.startChild, 'call', _3 => _3({ + description: fn.name, + op: `middleware.express.${method}`, + origin: 'auto.middleware.express', + })]); + fn.call(this, req, res, function ( ...args) { + _optionalChain([span, 'optionalAccess', _4 => _4.end, 'call', _5 => _5()]); + next.call(this, ...args); + }); + }; + } + case 4: { + return function ( - // fast track - if (!keys || keys.length === 0) { - return done(); + err, + req, + res, + next, + ) { + const transaction = res.__sentry_transaction; + // eslint-disable-next-line deprecation/deprecation + const span = _optionalChain([transaction, 'optionalAccess', _6 => _6.startChild, 'call', _7 => _7({ + description: fn.name, + op: `middleware.express.${method}`, + origin: 'auto.middleware.express', + })]); + fn.call(this, err, req, res, function ( ...args) { + _optionalChain([span, 'optionalAccess', _8 => _8.end, 'call', _9 => _9()]); + next.call(this, ...args); + }); + }; + } + default: { + throw new Error(`Express middleware takes 2-4 arguments. Got: ${arity}`); + } } +} - var i = 0; - var name; - var paramIndex = 0; - var key; - var paramVal; - var paramCallbacks; - var paramCalled; - - // process params in order - // param callbacks can be async - function param(err) { - if (err) { - return done(err); +/** + * Takes all the function arguments passed to the original `app` or `router` method, eg. `app.use` or `router.use` + * and wraps every function, as well as array of functions with a call to our `wrap` method. + * We have to take care of the arrays as well as iterate over all of the arguments, + * as `app.use` can accept middlewares in few various forms. + * + * app.use([], ) + * app.use([], , ...) + * app.use([], ...[]) + */ +function wrapMiddlewareArgs(args, method) { + return args.map((arg) => { + if (typeof arg === 'function') { + return wrap(arg, method); } - if (i >= keys.length ) { - return done(); + if (Array.isArray(arg)) { + return arg.map((a) => { + if (typeof a === 'function') { + return wrap(a, method); + } + return a; + }); } - paramIndex = 0; - key = keys[i++]; - name = key.name; - paramVal = req.params[name]; - paramCallbacks = params[name]; - paramCalled = called[name]; + return arg; + }); +} - if (paramVal === undefined || !paramCallbacks) { - return param(); - } +/** + * Patches original router to utilize our tracing functionality + */ +function patchMiddleware(router, method) { + const originalCallback = router[method]; - // param previously called with same value or error occurred - if (paramCalled && (paramCalled.match === paramVal - || (paramCalled.error && paramCalled.error !== 'route'))) { - // restore value - req.params[name] = paramCalled.value; + router[method] = function (...args) { + return originalCallback.call(this, ...wrapMiddlewareArgs(args, method)); + }; - // next param - return param(paramCalled.error); - } + return router; +} - called[name] = paramCalled = { - error: null, - match: paramVal, - value: paramVal - }; +/** + * Patches original router methods + */ +function instrumentMiddlewares(router, methods = []) { + methods.forEach((method) => patchMiddleware(router, method)); +} - paramCallback(); +/** + * Patches the prototype of Express.Router to accumulate the resolved route + * if a layer instance's `match` function was called and it returned a successful match. + * + * @see https://github.com/expressjs/express/blob/master/lib/router/index.js + * + * @param appOrRouter the router instance which can either be an app (i.e. top-level) or a (nested) router. + */ +function instrumentRouter(appOrRouter) { + // This is how we can distinguish between app and routers + const isApp = 'settings' in appOrRouter; + + // In case the app's top-level router hasn't been initialized yet, we have to do it now + if (isApp && appOrRouter._router === undefined && appOrRouter.lazyrouter) { + appOrRouter.lazyrouter(); } - // single param callbacks - function paramCallback(err) { - var fn = paramCallbacks[paramIndex++]; + const router = isApp ? appOrRouter._router : appOrRouter; - // store updated value - paramCalled.value = req.params[key.name]; + if (!router) { + /* + If we end up here, this means likely that this integration is used with Express 3 or Express 5. + For now, we don't support these versions (3 is very old and 5 is still in beta). To support Express 5, + we'd need to make more changes to the routing instrumentation because the router is no longer part of + the Express core package but maintained in its own package. The new router has different function + signatures and works slightly differently, demanding more changes than just taking the router from + `app.router` instead of `app._router`. + @see https://github.com/pillarjs/router + + TODO: Proper Express 5 support + */ + debugBuild.DEBUG_BUILD && utils.logger.debug('Cannot instrument router for URL Parameterization (did not find a valid router).'); + debugBuild.DEBUG_BUILD && utils.logger.debug('Routing instrumentation is currently only supported in Express 4.'); + return; + } - if (err) { - // store error - paramCalled.error = err; - param(err); - return; + const routerProto = Object.getPrototypeOf(router) ; + + const originalProcessParams = routerProto.process_params; + routerProto.process_params = function process_params( + layer, + called, + req, + res, + done, + ) { + // Base case: We're in the first part of the URL (thus we start with the root '/') + if (!req._reconstructedRoute) { + req._reconstructedRoute = ''; } - if (!fn) return param(); + // If the layer's partial route has params, is a regex or an array, the route is stored in layer.route. + const { layerRoutePath, isRegex, isArray, numExtraSegments } = getLayerRoutePathInfo(layer); - try { - fn(req, res, paramCallback, paramVal, key.name); - } catch (e) { - paramCallback(e); + if (layerRoutePath || isRegex || isArray) { + req._hasParameters = true; } - } - param(); -}; + // Otherwise, the hardcoded path (i.e. a partial route without params) is stored in layer.path + let partialRoute; + + if (layerRoutePath) { + partialRoute = layerRoutePath; + } else { + /** + * prevent duplicate segment in _reconstructedRoute param if router match multiple routes before final path + * example: + * original url: /api/v1/1234 + * prevent: /api/api/v1/:userId + * router structure + * /api -> middleware + * /api/v1 -> middleware + * /1234 -> endpoint with param :userId + * final _reconstructedRoute is /api/v1/:userId + */ + partialRoute = preventDuplicateSegments(req.originalUrl, req._reconstructedRoute, layer.path) || ''; + } + + // Normalize the partial route so that it doesn't contain leading or trailing slashes + // and exclude empty or '*' wildcard routes. + // The exclusion of '*' routes is our best effort to not "pollute" the transaction name + // with interim handlers (e.g. ones that check authentication or do other middleware stuff). + // We want to end up with the parameterized URL of the incoming request without any extraneous path segments. + const finalPartialRoute = partialRoute + .split('/') + .filter(segment => segment.length > 0 && (isRegex || isArray || !segment.includes('*'))) + .join('/'); + + // If we found a valid partial URL, we append it to the reconstructed route + if (finalPartialRoute && finalPartialRoute.length > 0) { + // If the partial route is from a regex route, we append a '/' to close the regex + req._reconstructedRoute += `/${finalPartialRoute}${isRegex ? '/' : ''}`; + } + + // Now we check if we are in the "last" part of the route. We determine this by comparing the + // number of URL segments from the original URL to that of our reconstructed parameterized URL. + // If we've reached our final destination, we update the transaction name. + const urlLength = utils.getNumberOfUrlSegments(utils.stripUrlQueryAndFragment(req.originalUrl || '')) + numExtraSegments; + const routeLength = utils.getNumberOfUrlSegments(req._reconstructedRoute); + + if (urlLength === routeLength) { + if (!req._hasParameters) { + if (req._reconstructedRoute !== req.originalUrl) { + req._reconstructedRoute = req.originalUrl ? utils.stripUrlQueryAndFragment(req.originalUrl) : req.originalUrl; + } + } + + const transaction = res.__sentry_transaction; + const attributes = (transaction && core.spanToJSON(transaction).data) || {}; + if (transaction && attributes[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] !== 'custom') { + // If the request URL is '/' or empty, the reconstructed route will be empty. + // Therefore, we fall back to setting the final route to '/' in this case. + const finalRoute = req._reconstructedRoute || '/'; + + const [name, source] = utils.extractPathForTransaction(req, { path: true, method: true, customRoute: finalRoute }); + transaction.updateName(name); + transaction.setAttribute(core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source); + } + } + + return originalProcessParams.call(this, layer, called, req, res, done); + }; +} /** - * Use the given middleware function, with optional path, defaulting to "/". - * - * Use (like `.all`) will run for any http METHOD, but it will not add - * handlers for those methods so OPTIONS requests will not consider `.use` - * functions even if they could respond. + * Recreate layer.route.path from layer.regexp and layer.keys. + * Works until express.js used package path-to-regexp@0.1.7 + * or until layer.keys contain offset attribute * - * The other difference is that _route_ path is stripped and not visible - * to the handler function. The main effect of this feature is that mounted - * handlers can operate without any code changes regardless of the "prefix" - * pathname. + * @param layer the layer to extract the stringified route from * - * @public + * @returns string in layer.route.path structure 'router/:pathParam' or undefined */ +const extractOriginalRoute = ( + path, + regexp, + keys, +) => { + if (!path || !regexp || !keys || Object.keys(keys).length === 0 || !_optionalChain([keys, 'access', _10 => _10[0], 'optionalAccess', _11 => _11.offset])) { + return undefined; + } -proto.use = function use(fn) { - var offset = 0; - var path = '/'; - - // default path to '/' - // disambiguate router.use([fn]) - if (typeof fn !== 'function') { - var arg = fn; + const orderedKeys = keys.sort((a, b) => a.offset - b.offset); - while (Array.isArray(arg) && arg.length !== 0) { - arg = arg[0]; - } + // add d flag for getting indices from regexp result + // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- regexp comes from express.js + const pathRegex = new RegExp(regexp, `${regexp.flags}d`); + /** + * use custom type cause of TS error with missing indices in RegExpExecArray + */ + const execResult = pathRegex.exec(path) ; - // first arg is the path - if (typeof arg !== 'function') { - offset = 1; - path = fn; - } + if (!execResult || !execResult.indices) { + return undefined; } + /** + * remove first match from regex cause contain whole layer.path + */ + const [, ...paramIndices] = execResult.indices; - var callbacks = flatten(slice.call(arguments, offset)); - - if (callbacks.length === 0) { - throw new TypeError('Router.use() requires a middleware function') + if (paramIndices.length !== orderedKeys.length) { + return undefined; } + let resultPath = path; + let indexShift = 0; - for (var i = 0; i < callbacks.length; i++) { - var fn = callbacks[i]; - - if (typeof fn !== 'function') { - throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn)) - } - - // add the middleware - debug('use %o %s', path, fn.name || '') + /** + * iterate param matches from regexp.exec + */ + paramIndices.forEach((item, index) => { + /** check if offsets is define because in some cases regex d flag returns undefined */ + if (item) { + const [startOffset, endOffset] = item; + /** + * isolate part before param + */ + const substr1 = resultPath.substring(0, startOffset - indexShift); + /** + * define paramName as replacement in format :pathParam + */ + const replacement = `:${orderedKeys[index].name}`; - var layer = new Layer(path, { - sensitive: this.caseSensitive, - strict: false, - end: false - }, fn); + /** + * isolate part after param + */ + const substr2 = resultPath.substring(endOffset - indexShift); - layer.route = undefined; + /** + * recreate original path but with param replacement + */ + resultPath = substr1 + replacement + substr2; - this.stack.push(layer); - } + /** + * calculate new index shift after resultPath was modified + */ + indexShift = indexShift + (endOffset - startOffset - replacement.length); + } + }); - return this; + return resultPath; }; /** - * Create a new Route for the given path. - * - * Each route contains a separate middleware stack and VERB handlers. + * Extracts and stringifies the layer's route which can either be a string with parameters (`users/:id`), + * a RegEx (`/test/`) or an array of strings and regexes (`['/path1', /\/path[2-5]/, /path/:id]`). Additionally + * returns extra information about the route, such as if the route is defined as regex or as an array. * - * See the Route api documentation for details on adding handlers - * and middleware to routes. + * @param layer the layer to extract the stringified route from * - * @param {String} path - * @return {Route} - * @public + * @returns an object containing the stringified route, a flag determining if the route was a regex + * and the number of extra segments to the matched path that are additionally in the route, + * if the route was an array (defaults to 0). */ +function getLayerRoutePathInfo(layer) { + let lrp = _optionalChain([layer, 'access', _12 => _12.route, 'optionalAccess', _13 => _13.path]); -proto.route = function route(path) { - var route = new Route(path); - - var layer = new Layer(path, { - sensitive: this.caseSensitive, - strict: this.strict, - end: true - }, route.dispatch.bind(route)); - - layer.route = route; - - this.stack.push(layer); - return route; -}; + const isRegex = utils.isRegExp(lrp); + const isArray = Array.isArray(lrp); -// create Router#VERB functions -methods.concat('all').forEach(function(method){ - proto[method] = function(path){ - var route = this.route(path) - route[method].apply(route, slice.call(arguments, 1)); - return this; - }; -}); + if (!lrp) { + // parse node.js major version + // Next.js will complain if we directly use `proces.versions` here because of edge runtime. + const [major] = (utils.GLOBAL_OBJ ).process.versions.node.split('.').map(Number); -// append methods to a list of methods -function appendMethods(list, addition) { - for (var i = 0; i < addition.length; i++) { - var method = addition[i]; - if (list.indexOf(method) === -1) { - list.push(method); + // allow call extractOriginalRoute only if node version support Regex d flag, node 16+ + if (major >= 16) { + /** + * If lrp does not exist try to recreate original layer path from route regexp + */ + lrp = extractOriginalRoute(layer.path, layer.regexp, layer.keys); } } -} -// get pathname of request -function getPathname(req) { - try { - return parseUrl(req).pathname; - } catch (err) { - return undefined; + if (!lrp) { + return { isRegex, isArray, numExtraSegments: 0 }; } -} -// Get get protocol + host for a URL -function getProtohost(url) { - if (typeof url !== 'string' || url.length === 0 || url[0] === '/') { - return undefined - } + const numExtraSegments = isArray + ? Math.max(getNumberOfArrayUrlSegments(lrp ) - utils.getNumberOfUrlSegments(layer.path || ''), 0) + : 0; - var searchIndex = url.indexOf('?') - var pathLength = searchIndex !== -1 - ? searchIndex - : url.length - var fqdnIndex = url.slice(0, pathLength).indexOf('://') + const layerRoutePath = getLayerRoutePathString(isArray, lrp); - return fqdnIndex !== -1 - ? url.substring(0, url.indexOf('/', 3 + fqdnIndex)) - : undefined + return { layerRoutePath, isRegex, isArray, numExtraSegments }; } -// get type for error message -function gettype(obj) { - var type = typeof obj; +/** + * Returns the number of URL segments in an array of routes + * + * Example: ['/api/test', /\/api\/post[0-9]/, '/users/:id/details`] -> 7 + */ +function getNumberOfArrayUrlSegments(routesArray) { + return routesArray.reduce((accNumSegments, currentRoute) => { + // array members can be a RegEx -> convert them toString + return accNumSegments + utils.getNumberOfUrlSegments(currentRoute.toString()); + }, 0); +} - if (type !== 'object') { - return type; +/** + * Extracts and returns the stringified version of the layers route path + * Handles route arrays (by joining the paths together) as well as RegExp and normal + * string values (in the latter case the toString conversion is technically unnecessary but + * it doesn't hurt us either). + */ +function getLayerRoutePathString(isArray, lrp) { + if (isArray) { + return (lrp ).map(r => r.toString()).join(','); } - - // inspect [[Class]] for objects - return toString.call(obj) - .replace(objectRegExp, '$1'); + return lrp && lrp.toString(); } /** - * Match path to a layer. - * - * @param {Layer} layer - * @param {string} path - * @private + * remove duplicate segment contain in layerPath against reconstructedRoute, + * and return only unique segment that can be added into reconstructedRoute */ - -function matchLayer(layer, path) { - try { - return layer.match(path); - } catch (err) { - return err; - } +function preventDuplicateSegments( + originalUrl, + reconstructedRoute, + layerPath, +) { + // filter query params + const normalizeURL = utils.stripUrlQueryAndFragment(originalUrl || ''); + const originalUrlSplit = _optionalChain([normalizeURL, 'optionalAccess', _14 => _14.split, 'call', _15 => _15('/'), 'access', _16 => _16.filter, 'call', _17 => _17(v => !!v)]); + let tempCounter = 0; + const currentOffset = _optionalChain([reconstructedRoute, 'optionalAccess', _18 => _18.split, 'call', _19 => _19('/'), 'access', _20 => _20.filter, 'call', _21 => _21(v => !!v), 'access', _22 => _22.length]) || 0; + const result = _optionalChain([layerPath +, 'optionalAccess', _23 => _23.split, 'call', _24 => _24('/') +, 'access', _25 => _25.filter, 'call', _26 => _26(segment => { + if (_optionalChain([originalUrlSplit, 'optionalAccess', _27 => _27[currentOffset + tempCounter]]) === segment) { + tempCounter += 1; + return true; + } + return false; + }) +, 'access', _28 => _28.join, 'call', _29 => _29('/')]); + return result; } -// merge params with parent params -function mergeParams(params, parent) { - if (typeof parent !== 'object' || !parent) { - return params; - } +exports.Express = Express; +exports.extractOriginalRoute = extractOriginalRoute; +exports.preventDuplicateSegments = preventDuplicateSegments; +//# sourceMappingURL=express.js.map - // make copy of parent for base - var obj = mixin({}, parent); - // simple non-numeric merging - if (!(0 in params) || !(0 in parent)) { - return mixin(obj, params); - } +/***/ }), - var i = 0; - var o = 0; +/***/ 80422: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // determine numeric gaps - while (i in params) { - i++; - } +var { + _optionalChain +} = __nccwpck_require__(57540); - while (o in parent) { - o++; - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - // offset numeric indices in params before merge - for (i--; i >= 0; i--) { - params[i + o] = params[i]; +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const nodeUtils = __nccwpck_require__(40325); - // create holes for the merge when necessary - if (i < o) { - delete params[i]; - } - } +/** Tracing integration for graphql package */ +class GraphQL { + /** + * @inheritDoc + */ + static __initStatic() {this.id = 'GraphQL';} - return mixin(obj, params); -} + /** + * @inheritDoc + */ -// restore obj props after function -function restore(fn, obj) { - var props = new Array(arguments.length - 2); - var vals = new Array(arguments.length - 2); + constructor() { + this.name = GraphQL.id; + } - for (var i = 0; i < props.length; i++) { - props[i] = arguments[i + 2]; - vals[i] = obj[props[i]]; + /** @inheritdoc */ + loadDependency() { + return (this._module = this._module || utils.loadModule('graphql/execution/execute.js')); } - return function () { - // restore vals - for (var i = 0; i < props.length; i++) { - obj[props[i]] = vals[i]; + /** + * @inheritDoc + */ + // eslint-disable-next-line deprecation/deprecation + setupOnce(_, getCurrentHub) { + if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) { + debugBuild.DEBUG_BUILD && utils.logger.log('GraphQL Integration is skipped because of instrumenter configuration.'); + return; } - return fn.apply(this, arguments); - }; -} + const pkg = this.loadDependency(); -// send an OPTIONS response -function sendOptionsResponse(res, options, next) { - try { - var body = options.join(','); - res.set('Allow', body); - res.send(body); - } catch (err) { - next(err); - } -} + if (!pkg) { + debugBuild.DEBUG_BUILD && utils.logger.error('GraphQL Integration was unable to require graphql/execution package.'); + return; + } -// wrap a function -function wrap(old, fn) { - return function proxy() { - var args = new Array(arguments.length + 1); + utils.fill(pkg, 'execute', function (orig) { + return function ( ...args) { + // eslint-disable-next-line deprecation/deprecation + const scope = getCurrentHub().getScope(); + // eslint-disable-next-line deprecation/deprecation + const parentSpan = scope.getSpan(); - args[0] = old; - for (var i = 0, len = arguments.length; i < len; i++) { - args[i + 1] = arguments[i]; - } + // eslint-disable-next-line deprecation/deprecation + const span = _optionalChain([parentSpan, 'optionalAccess', _2 => _2.startChild, 'call', _3 => _3({ + description: 'execute', + op: 'graphql.execute', + origin: 'auto.graphql.graphql', + })]); - fn.apply(this, args); - }; -} + // eslint-disable-next-line deprecation/deprecation + _optionalChain([scope, 'optionalAccess', _4 => _4.setSpan, 'call', _5 => _5(span)]); + const rv = orig.call(this, ...args); -/***/ }), + if (utils.isThenable(rv)) { + return rv.then((res) => { + _optionalChain([span, 'optionalAccess', _6 => _6.end, 'call', _7 => _7()]); + // eslint-disable-next-line deprecation/deprecation + _optionalChain([scope, 'optionalAccess', _8 => _8.setSpan, 'call', _9 => _9(parentSpan)]); -/***/ 38210: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return res; + }); + } -"use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2013 Roman Shtylman - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ + _optionalChain([span, 'optionalAccess', _10 => _10.end, 'call', _11 => _11()]); + // eslint-disable-next-line deprecation/deprecation + _optionalChain([scope, 'optionalAccess', _12 => _12.setSpan, 'call', _13 => _13(parentSpan)]); + return rv; + }; + }); + } +}GraphQL.__initStatic(); +exports.GraphQL = GraphQL; +//# sourceMappingURL=graphql.js.map -/** - * Module dependencies. - * @private - */ +/***/ }), -var pathRegexp = __nccwpck_require__(9585); -var debug = __nccwpck_require__(66515)('express:router:layer'); +/***/ 88073: +/***/ ((module, exports, __nccwpck_require__) => { -/** - * Module variables. - * @private - */ +/* module decorator */ module = __nccwpck_require__.nmd(module); +Object.defineProperty(exports, "__esModule", ({ value: true })); -var hasOwnProperty = Object.prototype.hasOwnProperty; +const utils = __nccwpck_require__(57540); -/** - * Module exports. - * @public - */ +const lazyLoadedNodePerformanceMonitoringIntegrations = [ + () => { + const integration = utils.dynamicRequire(module, './apollo') -module.exports = Layer; +; + return new integration.Apollo(); + }, + () => { + const integration = utils.dynamicRequire(module, './apollo') -function Layer(path, options, fn) { - if (!(this instanceof Layer)) { - return new Layer(path, options, fn); - } +; + return new integration.Apollo({ useNestjs: true }); + }, + () => { + const integration = utils.dynamicRequire(module, './graphql') - debug('new %o', path) - var opts = options || {}; +; + return new integration.GraphQL(); + }, + () => { + const integration = utils.dynamicRequire(module, './mongo') - this.handle = fn; - this.name = fn.name || ''; - this.params = undefined; - this.path = undefined; - this.regexp = pathRegexp(path, this.keys = [], opts); +; + return new integration.Mongo(); + }, + () => { + const integration = utils.dynamicRequire(module, './mongo') - // set fast path flags - this.regexp.fast_star = path === '*' - this.regexp.fast_slash = path === '/' && opts.end === false -} +; + return new integration.Mongo({ mongoose: true }); + }, + () => { + const integration = utils.dynamicRequire(module, './mysql') -/** - * Handle the error for the layer. - * - * @param {Error} error - * @param {Request} req - * @param {Response} res - * @param {function} next - * @api private - */ +; + return new integration.Mysql(); + }, + () => { + const integration = utils.dynamicRequire(module, './postgres') -Layer.prototype.handle_error = function handle_error(error, req, res, next) { - var fn = this.handle; +; + return new integration.Postgres(); + }, +]; - if (fn.length !== 4) { - // not a standard error handler - return next(error); - } +exports.lazyLoadedNodePerformanceMonitoringIntegrations = lazyLoadedNodePerformanceMonitoringIntegrations; +//# sourceMappingURL=lazy.js.map - try { - fn(error, req, res, next); - } catch (err) { - next(err); - } -}; -/** - * Handle the request for the layer. - * - * @param {Request} req - * @param {Response} res - * @param {function} next - * @api private - */ +/***/ }), -Layer.prototype.handle_request = function handle(req, res, next) { - var fn = this.handle; +/***/ 10275: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (fn.length > 3) { - // not a standard request handler - return next(); - } +var { + _optionalChain +} = __nccwpck_require__(57540); - try { - fn(req, res, next); - } catch (err) { - next(err); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const nodeUtils = __nccwpck_require__(40325); + +// This allows us to use the same array for both defaults options and the type itself. +// (note `as const` at the end to make it a union of string literal types (i.e. "a" | "b" | ... ) +// and not just a string[]) + +const OPERATIONS = [ + 'aggregate', // aggregate(pipeline, options, callback) + 'bulkWrite', // bulkWrite(operations, options, callback) + 'countDocuments', // countDocuments(query, options, callback) + 'createIndex', // createIndex(fieldOrSpec, options, callback) + 'createIndexes', // createIndexes(indexSpecs, options, callback) + 'deleteMany', // deleteMany(filter, options, callback) + 'deleteOne', // deleteOne(filter, options, callback) + 'distinct', // distinct(key, query, options, callback) + 'drop', // drop(options, callback) + 'dropIndex', // dropIndex(indexName, options, callback) + 'dropIndexes', // dropIndexes(options, callback) + 'estimatedDocumentCount', // estimatedDocumentCount(options, callback) + 'find', // find(query, options, callback) + 'findOne', // findOne(query, options, callback) + 'findOneAndDelete', // findOneAndDelete(filter, options, callback) + 'findOneAndReplace', // findOneAndReplace(filter, replacement, options, callback) + 'findOneAndUpdate', // findOneAndUpdate(filter, update, options, callback) + 'indexes', // indexes(options, callback) + 'indexExists', // indexExists(indexes, options, callback) + 'indexInformation', // indexInformation(options, callback) + 'initializeOrderedBulkOp', // initializeOrderedBulkOp(options, callback) + 'insertMany', // insertMany(docs, options, callback) + 'insertOne', // insertOne(doc, options, callback) + 'isCapped', // isCapped(options, callback) + 'mapReduce', // mapReduce(map, reduce, options, callback) + 'options', // options(options, callback) + 'parallelCollectionScan', // parallelCollectionScan(options, callback) + 'rename', // rename(newName, options, callback) + 'replaceOne', // replaceOne(filter, doc, options, callback) + 'stats', // stats(options, callback) + 'updateMany', // updateMany(filter, update, options, callback) + 'updateOne', // updateOne(filter, update, options, callback) +] ; + +// All of the operations above take `options` and `callback` as their final parameters, but some of them +// take additional parameters as well. For those operations, this is a map of +// { : [] }, as a way to know what to call the operation's +// positional arguments when we add them to the span's `data` object later +const OPERATION_SIGNATURES + + = { + // aggregate intentionally not included because `pipeline` arguments are too complex to serialize well + // see https://github.com/getsentry/sentry-javascript/pull/3102 + bulkWrite: ['operations'], + countDocuments: ['query'], + createIndex: ['fieldOrSpec'], + createIndexes: ['indexSpecs'], + deleteMany: ['filter'], + deleteOne: ['filter'], + distinct: ['key', 'query'], + dropIndex: ['indexName'], + find: ['query'], + findOne: ['query'], + findOneAndDelete: ['filter'], + findOneAndReplace: ['filter', 'replacement'], + findOneAndUpdate: ['filter', 'update'], + indexExists: ['indexes'], + insertMany: ['docs'], + insertOne: ['doc'], + mapReduce: ['map', 'reduce'], + rename: ['newName'], + replaceOne: ['filter', 'doc'], + updateMany: ['filter', 'update'], + updateOne: ['filter', 'update'], }; -/** - * Check if this route matches `path`, if so - * populate `.params`. - * - * @param {String} path - * @return {Boolean} - * @api private - */ +function isCursor(maybeCursor) { + return maybeCursor && typeof maybeCursor === 'object' && maybeCursor.once && typeof maybeCursor.once === 'function'; +} -Layer.prototype.match = function match(path) { - var match +/** Tracing integration for mongo package */ +class Mongo { + /** + * @inheritDoc + */ + static __initStatic() {this.id = 'Mongo';} - if (path != null) { - // fast path non-ending match for / (any path matches) - if (this.regexp.fast_slash) { - this.params = {} - this.path = '' - return true + /** + * @inheritDoc + */ + + /** + * @inheritDoc + */ + constructor(options = {}) { + this.name = Mongo.id; + this._operations = Array.isArray(options.operations) ? options.operations : (OPERATIONS ); + this._describeOperations = 'describeOperations' in options ? options.describeOperations : true; + this._useMongoose = !!options.useMongoose; + } + + /** @inheritdoc */ + loadDependency() { + const moduleName = this._useMongoose ? 'mongoose' : 'mongodb'; + return (this._module = this._module || utils.loadModule(moduleName)); + } + + /** + * @inheritDoc + */ + // eslint-disable-next-line deprecation/deprecation + setupOnce(_, getCurrentHub) { + if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) { + debugBuild.DEBUG_BUILD && utils.logger.log('Mongo Integration is skipped because of instrumenter configuration.'); + return; } - // fast path for * (everything matched in a param) - if (this.regexp.fast_star) { - this.params = {'0': decode_param(path)} - this.path = path - return true + const pkg = this.loadDependency(); + + if (!pkg) { + const moduleName = this._useMongoose ? 'mongoose' : 'mongodb'; + debugBuild.DEBUG_BUILD && utils.logger.error(`Mongo Integration was unable to require \`${moduleName}\` package.`); + return; } - // match the path - match = this.regexp.exec(path) + this._instrumentOperations(pkg.Collection, this._operations, getCurrentHub); } - if (!match) { - this.params = undefined; - this.path = undefined; - return false; + /** + * Patches original collection methods + */ + // eslint-disable-next-line deprecation/deprecation + _instrumentOperations(collection, operations, getCurrentHub) { + operations.forEach((operation) => this._patchOperation(collection, operation, getCurrentHub)); } - // store values - this.params = {}; - this.path = match[0] + /** + * Patches original collection to utilize our tracing functionality + */ + // eslint-disable-next-line deprecation/deprecation + _patchOperation(collection, operation, getCurrentHub) { + if (!(operation in collection.prototype)) return; - var keys = this.keys; - var params = this.params; + const getSpanContext = this._getSpanContextFromOperationArguments.bind(this); - for (var i = 1; i < match.length; i++) { - var key = keys[i - 1]; - var prop = key.name; - var val = decode_param(match[i]) + utils.fill(collection.prototype, operation, function (orig) { + return function ( ...args) { + const lastArg = args[args.length - 1]; + // eslint-disable-next-line deprecation/deprecation + const hub = getCurrentHub(); + // eslint-disable-next-line deprecation/deprecation + const scope = hub.getScope(); + // eslint-disable-next-line deprecation/deprecation + const client = hub.getClient(); + // eslint-disable-next-line deprecation/deprecation + const parentSpan = scope.getSpan(); - if (val !== undefined || !(hasOwnProperty.call(params, prop))) { - params[prop] = val; - } - } + const sendDefaultPii = _optionalChain([client, 'optionalAccess', _2 => _2.getOptions, 'call', _3 => _3(), 'access', _4 => _4.sendDefaultPii]); - return true; -}; + // Check if the operation was passed a callback. (mapReduce requires a different check, as + // its (non-callback) arguments can also be functions.) + if (typeof lastArg !== 'function' || (operation === 'mapReduce' && args.length === 2)) { + // eslint-disable-next-line deprecation/deprecation + const span = _optionalChain([parentSpan, 'optionalAccess', _5 => _5.startChild, 'call', _6 => _6(getSpanContext(this, operation, args, sendDefaultPii))]); + const maybePromiseOrCursor = orig.call(this, ...args); -/** - * Decode param value. - * - * @param {string} val - * @return {string} - * @private - */ + if (utils.isThenable(maybePromiseOrCursor)) { + return maybePromiseOrCursor.then((res) => { + _optionalChain([span, 'optionalAccess', _7 => _7.end, 'call', _8 => _8()]); + return res; + }); + } + // If the operation returns a Cursor + // we need to attach a listener to it to finish the span when the cursor is closed. + else if (isCursor(maybePromiseOrCursor)) { + const cursor = maybePromiseOrCursor ; -function decode_param(val) { - if (typeof val !== 'string' || val.length === 0) { - return val; + try { + cursor.once('close', () => { + _optionalChain([span, 'optionalAccess', _9 => _9.end, 'call', _10 => _10()]); + }); + } catch (e) { + // If the cursor is already closed, `once` will throw an error. In that case, we can + // finish the span immediately. + _optionalChain([span, 'optionalAccess', _11 => _11.end, 'call', _12 => _12()]); + } + + return cursor; + } else { + _optionalChain([span, 'optionalAccess', _13 => _13.end, 'call', _14 => _14()]); + return maybePromiseOrCursor; + } + } + + // eslint-disable-next-line deprecation/deprecation + const span = _optionalChain([parentSpan, 'optionalAccess', _15 => _15.startChild, 'call', _16 => _16(getSpanContext(this, operation, args.slice(0, -1)))]); + + return orig.call(this, ...args.slice(0, -1), function (err, result) { + _optionalChain([span, 'optionalAccess', _17 => _17.end, 'call', _18 => _18()]); + lastArg(err, result); + }); + }; + }); } - try { - return decodeURIComponent(val); - } catch (err) { - if (err instanceof URIError) { - err.message = 'Failed to decode param \'' + val + '\''; - err.status = err.statusCode = 400; + /** + * Form a SpanContext based on the user input to a given operation. + */ + _getSpanContextFromOperationArguments( + collection, + operation, + args, + sendDefaultPii = false, + ) { + const data = { + 'db.system': 'mongodb', + 'db.name': collection.dbName, + 'db.operation': operation, + 'db.mongodb.collection': collection.collectionName, + }; + const spanContext = { + op: 'db', + // TODO v8: Use `${collection.collectionName}.${operation}` + origin: 'auto.db.mongo', + description: operation, + data, + }; + + // If the operation takes no arguments besides `options` and `callback`, or if argument + // collection is disabled for this operation, just return early. + const signature = OPERATION_SIGNATURES[operation]; + const shouldDescribe = Array.isArray(this._describeOperations) + ? this._describeOperations.includes(operation) + : this._describeOperations; + + if (!signature || !shouldDescribe || !sendDefaultPii) { + return spanContext; } - throw err; + try { + // Special case for `mapReduce`, as the only one accepting functions as arguments. + if (operation === 'mapReduce') { + const [map, reduce] = args ; + data[signature[0]] = typeof map === 'string' ? map : map.name || ''; + data[signature[1]] = typeof reduce === 'string' ? reduce : reduce.name || ''; + } else { + for (let i = 0; i < signature.length; i++) { + data[`db.mongodb.${signature[i]}`] = JSON.stringify(args[i]); + } + } + } catch (_oO) { + // no-empty + } + + return spanContext; } -} +}Mongo.__initStatic(); + +exports.Mongo = Mongo; +//# sourceMappingURL=mongo.js.map /***/ }), -/***/ 67178: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 88965: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2013 Roman Shtylman - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ +var { + _optionalChain +} = __nccwpck_require__(57540); +Object.defineProperty(exports, "__esModule", ({ value: true })); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const nodeUtils = __nccwpck_require__(40325); -/** - * Module dependencies. - * @private - */ +/** Tracing integration for node-mysql package */ +class Mysql { + /** + * @inheritDoc + */ + static __initStatic() {this.id = 'Mysql';} -var debug = __nccwpck_require__(66515)('express:router:route'); -var flatten = __nccwpck_require__(35698); -var Layer = __nccwpck_require__(38210); -var methods = __nccwpck_require__(84283); + /** + * @inheritDoc + */ -/** - * Module variables. - * @private - */ + constructor() { + this.name = Mysql.id; + } -var slice = Array.prototype.slice; -var toString = Object.prototype.toString; + /** @inheritdoc */ + loadDependency() { + return (this._module = this._module || utils.loadModule('mysql/lib/Connection.js')); + } -/** - * Module exports. - * @public - */ + /** + * @inheritDoc + */ + // eslint-disable-next-line deprecation/deprecation + setupOnce(_, getCurrentHub) { + if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) { + debugBuild.DEBUG_BUILD && utils.logger.log('Mysql Integration is skipped because of instrumenter configuration.'); + return; + } -module.exports = Route; + const pkg = this.loadDependency(); -/** - * Initialize `Route` with the given `path`, - * - * @param {String} path - * @public - */ + if (!pkg) { + debugBuild.DEBUG_BUILD && utils.logger.error('Mysql Integration was unable to require `mysql` package.'); + return; + } -function Route(path) { - this.path = path; - this.stack = []; + let mySqlConfig = undefined; - debug('new %o', path) + try { + pkg.prototype.connect = new Proxy(pkg.prototype.connect, { + apply(wrappingTarget, thisArg, args) { + if (!mySqlConfig) { + mySqlConfig = thisArg.config; + } + return wrappingTarget.apply(thisArg, args); + }, + }); + } catch (e) { + debugBuild.DEBUG_BUILD && utils.logger.error('Mysql Integration was unable to instrument `mysql` config.'); + } - // route handlers for various http methods - this.methods = {}; -} + function spanDataFromConfig() { + if (!mySqlConfig) { + return {}; + } + return { + 'server.address': mySqlConfig.host, + 'server.port': mySqlConfig.port, + 'db.user': mySqlConfig.user, + }; + } -/** - * Determine if the route handles a given method. - * @private - */ + function finishSpan(span) { + if (!span) { + return; + } -Route.prototype._handles_method = function _handles_method(method) { - if (this.methods._all) { - return true; - } + const data = spanDataFromConfig(); + Object.keys(data).forEach(key => { + span.setAttribute(key, data[key]); + }); - // normalize name - var name = typeof method === 'string' - ? method.toLowerCase() - : method + span.end(); + } - if (name === 'head' && !this.methods['head']) { - name = 'get'; - } + // The original function will have one of these signatures: + // function (callback) => void + // function (options, callback) => void + // function (options, values, callback) => void + utils.fill(pkg, 'createQuery', function (orig) { + return function ( options, values, callback) { + // eslint-disable-next-line deprecation/deprecation + const scope = getCurrentHub().getScope(); + // eslint-disable-next-line deprecation/deprecation + const parentSpan = scope.getSpan(); - return Boolean(this.methods[name]); -}; + // eslint-disable-next-line deprecation/deprecation + const span = _optionalChain([parentSpan, 'optionalAccess', _2 => _2.startChild, 'call', _3 => _3({ + description: typeof options === 'string' ? options : (options ).sql, + op: 'db', + origin: 'auto.db.mysql', + data: { + 'db.system': 'mysql', + }, + })]); -/** - * @return {Array} supported HTTP methods - * @private - */ + if (typeof callback === 'function') { + return orig.call(this, options, values, function (err, result, fields) { + finishSpan(span); + callback(err, result, fields); + }); + } -Route.prototype._options = function _options() { - var methods = Object.keys(this.methods); + if (typeof values === 'function') { + return orig.call(this, options, function (err, result, fields) { + finishSpan(span); + values(err, result, fields); + }); + } - // append automatic head - if (this.methods.get && !this.methods.head) { - methods.push('head'); - } + // streaming, no callback! + const query = orig.call(this, options, values) ; - for (var i = 0; i < methods.length; i++) { - // make upper case - methods[i] = methods[i].toUpperCase(); + query.on('end', () => { + finishSpan(span); + }); + + return query; + }; + }); } +}Mysql.__initStatic(); - return methods; -}; +exports.Mysql = Mysql; +//# sourceMappingURL=mysql.js.map -/** - * dispatch req, res into this route - * @private - */ -Route.prototype.dispatch = function dispatch(req, res, done) { - var idx = 0; - var stack = this.stack; - var sync = 0 +/***/ }), - if (stack.length === 0) { - return done(); +/***/ 43224: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +var { + _optionalChain +} = __nccwpck_require__(57540); + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const nodeUtils = __nccwpck_require__(40325); + +/** Tracing integration for node-postgres package */ +class Postgres { + /** + * @inheritDoc + */ + static __initStatic() {this.id = 'Postgres';} + + /** + * @inheritDoc + */ + + constructor(options = {}) { + this.name = Postgres.id; + this._usePgNative = !!options.usePgNative; + this._module = options.module; } - var method = typeof req.method === 'string' - ? req.method.toLowerCase() - : req.method - if (method === 'head' && !this.methods['head']) { - method = 'get'; + /** @inheritdoc */ + loadDependency() { + return (this._module = this._module || utils.loadModule('pg')); } - req.route = this; + /** + * @inheritDoc + */ + // eslint-disable-next-line deprecation/deprecation + setupOnce(_, getCurrentHub) { + if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) { + debugBuild.DEBUG_BUILD && utils.logger.log('Postgres Integration is skipped because of instrumenter configuration.'); + return; + } - next(); + const pkg = this.loadDependency(); - function next(err) { - // signal to exit route - if (err && err === 'route') { - return done(); + if (!pkg) { + debugBuild.DEBUG_BUILD && utils.logger.error('Postgres Integration was unable to require `pg` package.'); + return; } - // signal to exit router - if (err && err === 'router') { - return done(err) - } + const Client = this._usePgNative ? _optionalChain([pkg, 'access', _2 => _2.native, 'optionalAccess', _3 => _3.Client]) : pkg.Client; - // max sync stack - if (++sync > 100) { - return setImmediate(next, err) + if (!Client) { + debugBuild.DEBUG_BUILD && utils.logger.error("Postgres Integration was unable to access 'pg-native' bindings."); + return; } - var layer = stack[idx++] + /** + * function (query, callback) => void + * function (query, params, callback) => void + * function (query) => Promise + * function (query, params) => Promise + * function (pg.Cursor) => pg.Cursor + */ + utils.fill(Client.prototype, 'query', function (orig) { + return function ( config, values, callback) { + // eslint-disable-next-line deprecation/deprecation + const scope = getCurrentHub().getScope(); + // eslint-disable-next-line deprecation/deprecation + const parentSpan = scope.getSpan(); - // end of layers - if (!layer) { - return done(err) - } + const data = { + 'db.system': 'postgresql', + }; - if (layer.method && layer.method !== method) { - next(err) - } else if (err) { - layer.handle_error(err, req, res, next); - } else { - layer.handle_request(req, res, next); - } + try { + if (this.database) { + data['db.name'] = this.database; + } + if (this.host) { + data['server.address'] = this.host; + } + if (this.port) { + data['server.port'] = this.port; + } + if (this.user) { + data['db.user'] = this.user; + } + } catch (e) { + // ignore + } - sync = 0 + // eslint-disable-next-line deprecation/deprecation + const span = _optionalChain([parentSpan, 'optionalAccess', _4 => _4.startChild, 'call', _5 => _5({ + description: typeof config === 'string' ? config : (config ).text, + op: 'db', + origin: 'auto.db.postgres', + data, + })]); + + if (typeof callback === 'function') { + return orig.call(this, config, values, function (err, result) { + _optionalChain([span, 'optionalAccess', _6 => _6.end, 'call', _7 => _7()]); + callback(err, result); + }); + } + + if (typeof values === 'function') { + return orig.call(this, config, function (err, result) { + _optionalChain([span, 'optionalAccess', _8 => _8.end, 'call', _9 => _9()]); + values(err, result); + }); + } + + const rv = typeof values !== 'undefined' ? orig.call(this, config, values) : orig.call(this, config); + + if (utils.isThenable(rv)) { + return rv.then((res) => { + _optionalChain([span, 'optionalAccess', _10 => _10.end, 'call', _11 => _11()]); + return res; + }); + } + + _optionalChain([span, 'optionalAccess', _12 => _12.end, 'call', _13 => _13()]); + return rv; + }; + }); } -}; +}Postgres.__initStatic(); -/** - * Add a handler for all HTTP verbs to this route. - * - * Behaves just like middleware and can respond or call `next` - * to continue processing. - * - * You can use multiple `.all` call to add multiple handlers. - * - * function check_something(req, res, next){ - * next(); - * }; - * - * function validate_user(req, res, next){ - * next(); - * }; - * - * route - * .all(validate_user) - * .all(check_something) - * .get(function(req, res, next){ - * res.send('hello world'); - * }); - * - * @param {function} handler - * @return {Route} for chaining - * @api public - */ +exports.Postgres = Postgres; +//# sourceMappingURL=postgres.js.map -Route.prototype.all = function all() { - var handles = flatten(slice.call(arguments)); - for (var i = 0; i < handles.length; i++) { - var handle = handles[i]; +/***/ }), - if (typeof handle !== 'function') { - var type = toString.call(handle); - var msg = 'Route.all() requires a callback function but got a ' + type - throw new TypeError(msg); - } +/***/ 23639: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var layer = Layer('/', {}, handle); - layer.method = undefined; +Object.defineProperty(exports, "__esModule", ({ value: true })); - this.methods._all = true; - this.stack.push(layer); - } +const core = __nccwpck_require__(75442); +const utils = __nccwpck_require__(57540); +const debugBuild = __nccwpck_require__(14208); +const nodeUtils = __nccwpck_require__(40325); - return this; -}; +function isValidPrismaClient(possibleClient) { + return !!possibleClient && !!(possibleClient )['$use']; +} -methods.forEach(function(method){ - Route.prototype[method] = function(){ - var handles = flatten(slice.call(arguments)); +/** Tracing integration for @prisma/client package */ +class Prisma { + /** + * @inheritDoc + */ + static __initStatic() {this.id = 'Prisma';} - for (var i = 0; i < handles.length; i++) { - var handle = handles[i]; + /** + * @inheritDoc + */ - if (typeof handle !== 'function') { - var type = toString.call(handle); - var msg = 'Route.' + method + '() requires a callback function but got a ' + type - throw new Error(msg); + /** + * @inheritDoc + */ + constructor(options = {}) { + this.name = Prisma.id; + + // We instrument the PrismaClient inside the constructor and not inside `setupOnce` because in some cases of server-side + // bundling (Next.js) multiple Prisma clients can be instantiated, even though users don't intend to. When instrumenting + // in setupOnce we can only ever instrument one client. + // https://github.com/getsentry/sentry-javascript/issues/7216#issuecomment-1602375012 + // In the future we might explore providing a dedicated PrismaClient middleware instead of this hack. + if (isValidPrismaClient(options.client) && !options.client._sentryInstrumented) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + utils.addNonEnumerableProperty(options.client , '_sentryInstrumented', true); + + const clientData = {}; + try { + const engineConfig = (options.client )._engineConfig; + if (engineConfig) { + const { activeProvider, clientVersion } = engineConfig; + if (activeProvider) { + clientData['db.system'] = activeProvider; + } + if (clientVersion) { + clientData['db.prisma.version'] = clientVersion; + } + } + } catch (e) { + // ignore } - debug('%s %o', method, this.path) + options.client.$use((params, next) => { + // eslint-disable-next-line deprecation/deprecation + if (nodeUtils.shouldDisableAutoInstrumentation(core.getCurrentHub)) { + return next(params); + } - var layer = Layer('/', {}, handle); - layer.method = method; + const action = params.action; + const model = params.model; - this.methods[method] = true; - this.stack.push(layer); + return core.startSpan( + { + name: model ? `${model} ${action}` : action, + onlyIfParent: true, + op: 'db.prisma', + attributes: { + [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.prisma', + }, + data: { ...clientData, 'db.operation': action }, + }, + () => next(params), + ); + }); + } else { + debugBuild.DEBUG_BUILD && + utils.logger.warn('Unsupported Prisma client provided to PrismaIntegration. Provided client:', options.client); } + } - return this; - }; -}); + /** + * @inheritDoc + */ + setupOnce() { + // Noop - here for backwards compatibility + } +} Prisma.__initStatic(); + +exports.Prisma = Prisma; +//# sourceMappingURL=prisma.js.map /***/ }), -/***/ 21596: +/***/ 40325: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +var { + _optionalChain +} = __nccwpck_require__(57540); + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/** + * Check if Sentry auto-instrumentation should be disabled. + * + * @param getCurrentHub A method to fetch the current hub + * @returns boolean + */ +// eslint-disable-next-line deprecation/deprecation +function shouldDisableAutoInstrumentation(getCurrentHub) { + // eslint-disable-next-line deprecation/deprecation + const clientOptions = _optionalChain([getCurrentHub, 'call', _ => _(), 'access', _2 => _2.getClient, 'call', _3 => _3(), 'optionalAccess', _4 => _4.getOptions, 'call', _5 => _5()]); + const instrumenter = _optionalChain([clientOptions, 'optionalAccess', _6 => _6.instrumenter]) || 'sentry'; + + return instrumenter !== 'sentry'; +} + +exports.shouldDisableAutoInstrumentation = shouldDisableAutoInstrumentation; +//# sourceMappingURL=node-utils.js.map + + +/***/ }), + +/***/ 23693: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + "use strict"; /*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2014-2015 Douglas Christopher Wilson + * accepts + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson * MIT Licensed */ @@ -35914,1459 +39475,1230 @@ methods.forEach(function(method){ /** * Module dependencies. - * @api private + * @private */ -var Buffer = (__nccwpck_require__(26843).Buffer) -var contentDisposition = __nccwpck_require__(45942); -var contentType = __nccwpck_require__(22541); -var deprecate = __nccwpck_require__(77267)('express'); -var flatten = __nccwpck_require__(35698); -var mime = (__nccwpck_require__(15549).mime); -var etag = __nccwpck_require__(71389); -var proxyaddr = __nccwpck_require__(83198); -var qs = __nccwpck_require__(91833); -var querystring = __nccwpck_require__(83480); +var Negotiator = __nccwpck_require__(12662) +var mime = __nccwpck_require__(20332) /** - * Return strong ETag for `body`. - * - * @param {String|Buffer} body - * @param {String} [encoding] - * @return {String} - * @api private + * Module exports. + * @public */ -exports.etag = createETagGenerator({ weak: false }) +module.exports = Accepts /** - * Return weak ETag for `body`. + * Create a new Accepts object for the given req. * - * @param {String|Buffer} body - * @param {String} [encoding] - * @return {String} - * @api private + * @param {object} req + * @public */ -exports.wetag = createETagGenerator({ weak: true }) - -/** - * Check if `path` looks absolute. - * - * @param {String} path - * @return {Boolean} - * @api private - */ +function Accepts (req) { + if (!(this instanceof Accepts)) { + return new Accepts(req) + } -exports.isAbsolute = function(path){ - if ('/' === path[0]) return true; - if (':' === path[1] && ('\\' === path[2] || '/' === path[2])) return true; // Windows device path - if ('\\\\' === path.substring(0, 2)) return true; // Microsoft Azure absolute path -}; + this.headers = req.headers + this.negotiator = new Negotiator(req) +} /** - * Flatten the given `arr`. - * - * @param {Array} arr - * @return {Array} - * @api private - */ - -exports.flatten = deprecate.function(flatten, - 'utils.flatten: use array-flatten npm module instead'); - -/** - * Normalize the given `type`, for example "html" becomes "text/html". + * Check if the given `type(s)` is acceptable, returning + * the best match when true, otherwise `undefined`, in which + * case you should respond with 406 "Not Acceptable". * - * @param {String} type - * @return {Object} - * @api private - */ - -exports.normalizeType = function(type){ - return ~type.indexOf('/') - ? acceptParams(type) - : { value: mime.lookup(type), params: {} }; -}; - -/** - * Normalize `types`, for example "html" becomes "text/html". + * The `type` value may be a single mime type string + * such as "application/json", the extension name + * such as "json" or an array `["json", "html", "text/plain"]`. When a list + * or array is given the _best_ match, if any is returned. * - * @param {Array} types - * @return {Array} - * @api private - */ - -exports.normalizeTypes = function(types){ - var ret = []; - - for (var i = 0; i < types.length; ++i) { - ret.push(exports.normalizeType(types[i])); - } - - return ret; -}; - -/** - * Generate Content-Disposition header appropriate for the filename. - * non-ascii filenames are urlencoded and a filename* parameter is added + * Examples: * - * @param {String} filename - * @return {String} - * @api private - */ - -exports.contentDisposition = deprecate.function(contentDisposition, - 'utils.contentDisposition: use content-disposition npm module instead'); - -/** - * Parse accept params `str` returning an - * object with `.value`, `.quality` and `.params`. + * // Accept: text/html + * this.types('html'); + * // => "html" * - * @param {String} str - * @return {Object} - * @api private + * // Accept: text/*, application/json + * this.types('html'); + * // => "html" + * this.types('text/html'); + * // => "text/html" + * this.types('json', 'text'); + * // => "json" + * this.types('application/json'); + * // => "application/json" + * + * // Accept: text/*, application/json + * this.types('image/png'); + * this.types('png'); + * // => undefined + * + * // Accept: text/*;q=.5, application/json + * this.types(['html', 'json']); + * this.types('html', 'json'); + * // => "json" + * + * @param {String|Array} types... + * @return {String|Array|Boolean} + * @public */ -function acceptParams (str) { - var parts = str.split(/ *; */); - var ret = { value: parts[0], quality: 1, params: {} } +Accepts.prototype.type = +Accepts.prototype.types = function (types_) { + var types = types_ - for (var i = 1; i < parts.length; ++i) { - var pms = parts[i].split(/ *= */); - if ('q' === pms[0]) { - ret.quality = parseFloat(pms[1]); - } else { - ret.params[pms[0]] = pms[1]; + // support flattened arguments + if (types && !Array.isArray(types)) { + types = new Array(arguments.length) + for (var i = 0; i < types.length; i++) { + types[i] = arguments[i] } } - return ret; + // no types, return all requested types + if (!types || types.length === 0) { + return this.negotiator.mediaTypes() + } + + // no accept header, return first given type + if (!this.headers.accept) { + return types[0] + } + + var mimes = types.map(extToMime) + var accepts = this.negotiator.mediaTypes(mimes.filter(validMime)) + var first = accepts[0] + + return first + ? types[mimes.indexOf(first)] + : false } /** - * Compile "etag" value to function. + * Return accepted encodings or best fit based on `encodings`. * - * @param {Boolean|String|Function} val - * @return {Function} - * @api private + * Given `Accept-Encoding: gzip, deflate` + * an array sorted by quality is returned: + * + * ['gzip', 'deflate'] + * + * @param {String|Array} encodings... + * @return {String|Array} + * @public */ -exports.compileETag = function(val) { - var fn; +Accepts.prototype.encoding = +Accepts.prototype.encodings = function (encodings_) { + var encodings = encodings_ - if (typeof val === 'function') { - return val; + // support flattened arguments + if (encodings && !Array.isArray(encodings)) { + encodings = new Array(arguments.length) + for (var i = 0; i < encodings.length; i++) { + encodings[i] = arguments[i] + } } - switch (val) { - case true: - case 'weak': - fn = exports.wetag; - break; - case false: - break; - case 'strong': - fn = exports.etag; - break; - default: - throw new TypeError('unknown value for etag function: ' + val); + // no encodings, return all requested encodings + if (!encodings || encodings.length === 0) { + return this.negotiator.encodings() } - return fn; + return this.negotiator.encodings(encodings)[0] || false } /** - * Compile "query parser" value to function. + * Return accepted charsets or best fit based on `charsets`. * - * @param {String|Function} val - * @return {Function} - * @api private + * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5` + * an array sorted by quality is returned: + * + * ['utf-8', 'utf-7', 'iso-8859-1'] + * + * @param {String|Array} charsets... + * @return {String|Array} + * @public */ -exports.compileQueryParser = function compileQueryParser(val) { - var fn; +Accepts.prototype.charset = +Accepts.prototype.charsets = function (charsets_) { + var charsets = charsets_ - if (typeof val === 'function') { - return val; + // support flattened arguments + if (charsets && !Array.isArray(charsets)) { + charsets = new Array(arguments.length) + for (var i = 0; i < charsets.length; i++) { + charsets[i] = arguments[i] + } } - switch (val) { - case true: - case 'simple': - fn = querystring.parse; - break; - case false: - fn = newObject; - break; - case 'extended': - fn = parseExtendedQueryString; - break; - default: - throw new TypeError('unknown value for query parser function: ' + val); + // no charsets, return all requested charsets + if (!charsets || charsets.length === 0) { + return this.negotiator.charsets() } - return fn; + return this.negotiator.charsets(charsets)[0] || false } /** - * Compile "proxy trust" value to function. + * Return accepted languages or best fit based on `langs`. * - * @param {Boolean|String|Number|Array|Function} val - * @return {Function} - * @api private + * Given `Accept-Language: en;q=0.8, es, pt` + * an array sorted by quality is returned: + * + * ['es', 'pt', 'en'] + * + * @param {String|Array} langs... + * @return {Array|String} + * @public */ -exports.compileTrust = function(val) { - if (typeof val === 'function') return val; - - if (val === true) { - // Support plain true/false - return function(){ return true }; - } +Accepts.prototype.lang = +Accepts.prototype.langs = +Accepts.prototype.language = +Accepts.prototype.languages = function (languages_) { + var languages = languages_ - if (typeof val === 'number') { - // Support trusting hop count - return function(a, i){ return i < val }; + // support flattened arguments + if (languages && !Array.isArray(languages)) { + languages = new Array(arguments.length) + for (var i = 0; i < languages.length; i++) { + languages[i] = arguments[i] + } } - if (typeof val === 'string') { - // Support comma-separated values - val = val.split(',') - .map(function (v) { return v.trim() }) + // no languages, return all requested languages + if (!languages || languages.length === 0) { + return this.negotiator.languages() } - return proxyaddr.compile(val || []); + return this.negotiator.languages(languages)[0] || false } /** - * Set the charset in a given Content-Type string. + * Convert extnames to mime. * * @param {String} type - * @param {String} charset * @return {String} - * @api private - */ - -exports.setCharset = function setCharset(type, charset) { - if (!type || !charset) { - return type; - } - - // parse type - var parsed = contentType.parse(type); - - // set charset - parsed.parameters.charset = charset; - - // format type - return contentType.format(parsed); -}; - -/** - * Create an ETag generator function, generating ETags with - * the given options. - * - * @param {object} options - * @return {function} * @private */ -function createETagGenerator (options) { - return function generateETag (body, encoding) { - var buf = !Buffer.isBuffer(body) - ? Buffer.from(body, encoding) - : body - - return etag(buf, options) - } +function extToMime (type) { + return type.indexOf('/') === -1 + ? mime.lookup(type) + : type } /** - * Parse an extended query string with qs. + * Check if mime is valid. * - * @param {String} str - * @return {Object} + * @param {String} type + * @return {String} * @private */ -function parseExtendedQueryString(str) { - return qs.parse(str, { - allowPrototypes: true - }); -} - -/** - * Return new empty object. - * - * @return {Object} - * @api private - */ - -function newObject() { - return {}; +function validMime (type) { + return typeof type === 'string' } /***/ }), -/***/ 53800: +/***/ 59683: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -/*! - * express - * Copyright(c) 2009-2013 TJ Holowaychuk - * Copyright(c) 2013 Roman Shtylman - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ +const indentString = __nccwpck_require__(40865); +const cleanStack = __nccwpck_require__(71649); +const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); -/** - * Module dependencies. - * @private - */ +class AggregateError extends Error { + constructor(errors) { + if (!Array.isArray(errors)) { + throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); + } -var debug = __nccwpck_require__(66515)('express:view'); -var path = __nccwpck_require__(16928); -var fs = __nccwpck_require__(79896); + errors = [...errors].map(error => { + if (error instanceof Error) { + return error; + } -/** - * Module variables. - * @private - */ + if (error !== null && typeof error === 'object') { + // Handle plain error objects with message property and/or possibly other metadata + return Object.assign(new Error(error.message), error); + } -var dirname = path.dirname; -var basename = path.basename; -var extname = path.extname; -var join = path.join; -var resolve = path.resolve; + return new Error(error); + }); -/** - * Module exports. - * @public - */ + let message = errors + .map(error => { + // The `stack` property is not standardized, so we can't assume it exists + return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error); + }) + .join('\n'); + message = '\n' + indentString(message, 4); + super(message); -module.exports = View; + this.name = 'AggregateError'; -/** - * Initialize a new `View` with the given `name`. - * - * Options: - * - * - `defaultEngine` the default template engine name - * - `engines` template engine require() cache - * - `root` root path for view lookup - * - * @param {string} name - * @param {object} options - * @public - */ + Object.defineProperty(this, '_errors', {value: errors}); + } -function View(name, options) { - var opts = options || {}; + * [Symbol.iterator]() { + for (const error of this._errors) { + yield error; + } + } +} - this.defaultEngine = opts.defaultEngine; - this.ext = extname(name); - this.name = name; - this.root = opts.root; +module.exports = AggregateError; - if (!this.ext && !this.defaultEngine) { - throw new Error('No default engine was specified and no extension was provided.'); - } - var fileName = name; +/***/ }), - if (!this.ext) { - // get extension from default engine name - this.ext = this.defaultEngine[0] !== '.' - ? '.' + this.defaultEngine - : this.defaultEngine; +/***/ 35698: +/***/ ((module) => { - fileName += this.ext; - } +"use strict"; - if (!opts.engines[this.ext]) { - // load engine - var mod = this.ext.slice(1) - debug('require "%s"', mod) - // default engine export - var fn = require(mod).__express +/** + * Expose `arrayFlatten`. + */ +module.exports = arrayFlatten - if (typeof fn !== 'function') { - throw new Error('Module "' + mod + '" does not provide a view engine.') - } +/** + * Recursive flatten function with depth. + * + * @param {Array} array + * @param {Array} result + * @param {Number} depth + * @return {Array} + */ +function flattenWithDepth (array, result, depth) { + for (var i = 0; i < array.length; i++) { + var value = array[i] - opts.engines[this.ext] = fn + if (depth > 0 && Array.isArray(value)) { + flattenWithDepth(value, result, depth - 1) + } else { + result.push(value) + } } - // store loaded engine - this.engine = opts.engines[this.ext]; - - // lookup path - this.path = this.lookup(fileName); + return result } /** - * Lookup view by the given `name` + * Recursive flatten function. Omitting depth is slightly faster. * - * @param {string} name - * @private + * @param {Array} array + * @param {Array} result + * @return {Array} */ +function flattenForever (array, result) { + for (var i = 0; i < array.length; i++) { + var value = array[i] -View.prototype.lookup = function lookup(name) { - var path; - var roots = [].concat(this.root); - - debug('lookup "%s"', name); - - for (var i = 0; i < roots.length && !path; i++) { - var root = roots[i]; - - // resolve the path - var loc = resolve(root, name); - var dir = dirname(loc); - var file = basename(loc); - - // resolve the file - path = this.resolve(dir, file); + if (Array.isArray(value)) { + flattenForever(value, result) + } else { + result.push(value) + } } - return path; -}; + return result +} /** - * Render with the given options. + * Flatten an array, with the ability to define a depth. * - * @param {object} options - * @param {function} callback - * @private + * @param {Array} array + * @param {Number} depth + * @return {Array} */ +function arrayFlatten (array, depth) { + if (depth == null) { + return flattenForever(array, []) + } -View.prototype.render = function render(options, callback) { - debug('render "%s"', this.path); - this.engine(this.path, options, callback); -}; + return flattenWithDepth(array, [], depth) +} -/** - * Resolve the file within the given directory. - * - * @param {string} dir - * @param {string} file - * @private - */ -View.prototype.resolve = function resolve(dir, file) { - var ext = this.ext; +/***/ }), - // . - var path = join(dir, file); - var stat = tryStat(path); +/***/ 25826: +/***/ ((module) => { - if (stat && stat.isFile()) { - return path; - } +"use strict"; - // /index. - path = join(dir, basename(file, ext), 'index' + ext); - stat = tryStat(path); - if (stat && stat.isFile()) { - return path; - } -}; +/* global SharedArrayBuffer, Atomics */ -/** - * Return a stat, maybe. - * - * @param {string} path - * @return {fs.Stats} - * @private - */ +if (typeof SharedArrayBuffer !== 'undefined' && typeof Atomics !== 'undefined') { + const nil = new Int32Array(new SharedArrayBuffer(4)) -function tryStat(path) { - debug('stat "%s"', path); + function sleep (ms) { + // also filters out NaN, non-number types, including empty strings, but allows bigints + const valid = ms > 0 && ms < Infinity + if (valid === false) { + if (typeof ms !== 'number' && typeof ms !== 'bigint') { + throw TypeError('sleep: ms must be a number') + } + throw RangeError('sleep: ms must be a number that is greater than 0 but less than Infinity') + } - try { - return fs.statSync(path); - } catch (e) { - return undefined; + Atomics.wait(nil, 0, 0, Number(ms)) + } + module.exports = sleep +} else { + + function sleep (ms) { + // also filters out NaN, non-number types, including empty strings, but allows bigints + const valid = ms > 0 && ms < Infinity + if (valid === false) { + if (typeof ms !== 'number' && typeof ms !== 'bigint') { + throw TypeError('sleep: ms must be a number') + } + throw RangeError('sleep: ms must be a number that is greater than 0 but less than Infinity') + } + const target = Date.now() + Number(ms) + while (target > Date.now()){} } + + module.exports = sleep + } /***/ }), -/***/ 59343: +/***/ 29922: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; - - -const validator = __nccwpck_require__(94437) -const parse = __nccwpck_require__(94744) -const redactor = __nccwpck_require__(83255) -const restorer = __nccwpck_require__(51339) -const { groupRedact, nestedRedact } = __nccwpck_require__(21797) -const state = __nccwpck_require__(18370) -const rx = __nccwpck_require__(51865) -const validate = validator() -const noop = (o) => o -noop.restore = noop +var register = __nccwpck_require__(70773); +var addHook = __nccwpck_require__(97477); +var removeHook = __nccwpck_require__(8944); -const DEFAULT_CENSOR = '[REDACTED]' -fastRedact.rx = rx -fastRedact.validator = validator +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind; +var bindable = bind.bind(bind); -module.exports = fastRedact +function bindApi(hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply( + null, + name ? [state, name] : [state] + ); + hook.api = { remove: removeHookRef }; + hook.remove = removeHookRef; + ["before", "error", "after", "wrap"].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind]; + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args); + }); +} -function fastRedact (opts = {}) { - const paths = Array.from(new Set(opts.paths || [])) - const serialize = 'serialize' in opts ? ( - opts.serialize === false ? opts.serialize - : (typeof opts.serialize === 'function' ? opts.serialize : JSON.stringify) - ) : JSON.stringify - const remove = opts.remove - if (remove === true && serialize !== JSON.stringify) { - throw Error('fast-redact – remove option may only be set when serializer is JSON.stringify') - } - const censor = remove === true - ? undefined - : 'censor' in opts ? opts.censor : DEFAULT_CENSOR +function HookSingular() { + var singularHookName = "h"; + var singularHookState = { + registry: {}, + }; + var singularHook = register.bind(null, singularHookState, singularHookName); + bindApi(singularHook, singularHookState, singularHookName); + return singularHook; +} - const isCensorFct = typeof censor === 'function' - const censorFctTakesPath = isCensorFct && censor.length > 1 +function HookCollection() { + var state = { + registry: {}, + }; - if (paths.length === 0) return serialize || noop + var hook = register.bind(null, state); + bindApi(hook, state); - validate({ paths, serialize, censor }) + return hook; +} - const { wildcards, wcLen, secret } = parse({ paths, censor }) +var collectionHookDeprecationMessageDisplayed = false; +function Hook() { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn( + '[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4' + ); + collectionHookDeprecationMessageDisplayed = true; + } + return HookCollection(); +} - const compileRestore = restorer() - const strict = 'strict' in opts ? opts.strict : true +Hook.Singular = HookSingular.bind(); +Hook.Collection = HookCollection.bind(); - return redactor({ secret, wcLen, serialize, strict, isCensorFct, censorFctTakesPath }, state({ - secret, - censor, - compileRestore, - serialize, - groupRedact, - nestedRedact, - wildcards, - wcLen - })) -} +module.exports = Hook; +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook; +module.exports.Singular = Hook.Singular; +module.exports.Collection = Hook.Collection; /***/ }), -/***/ 21797: +/***/ 97477: /***/ ((module) => { -"use strict"; +module.exports = addHook; +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; + } -module.exports = { - groupRedact, - groupRestore, - nestedRedact, - nestedRestore -} + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; + } -function groupRestore ({ keys, values, target }) { - if (target == null || typeof target === 'string') return - const length = keys.length - for (var i = 0; i < length; i++) { - const k = keys[i] - target[k] = values[i] + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; + } + + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; } + + state.registry[name].push({ + hook: hook, + orig: orig, + }); } -function groupRedact (o, path, censor, isCensorFct, censorFctTakesPath) { - const target = get(o, path) - if (target == null || typeof target === 'string') return { keys: null, values: null, target, flat: true } - const keys = Object.keys(target) - const keysLength = keys.length - const pathLength = path.length - const pathWithKey = censorFctTakesPath ? [...path] : undefined - const values = new Array(keysLength) - for (var i = 0; i < keysLength; i++) { - const key = keys[i] - values[i] = target[key] +/***/ }), - if (censorFctTakesPath) { - pathWithKey[pathLength] = key - target[key] = censor(target[key], pathWithKey) - } else if (isCensorFct) { - target[key] = censor(target[key]) - } else { - target[key] = censor - } - } - return { keys, values, target, flat: true } -} +/***/ 70773: +/***/ ((module) => { -/** - * @param {RestoreInstruction[]} instructions a set of instructions for restoring values to objects - */ -function nestedRestore (instructions) { - for (let i = 0; i < instructions.length; i++) { - const { target, path, value } = instructions[i] - let current = target - for (let i = path.length - 1; i > 0; i--) { - current = current[path[i]] - } - current[path[0]] = value +module.exports = register; + +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); } -} -function nestedRedact (store, o, path, ns, censor, isCensorFct, censorFctTakesPath) { - const target = get(o, path) - if (target == null) return - const keys = Object.keys(target) - const keysLength = keys.length - for (var i = 0; i < keysLength; i++) { - const key = keys[i] - specialSet(store, target, key, path, ns, censor, isCensorFct, censorFctTakesPath) + if (!options) { + options = {}; } - return store -} -function has (obj, prop) { - return obj !== undefined && obj !== null - ? ('hasOwn' in Object ? Object.hasOwn(obj, prop) : Object.prototype.hasOwnProperty.call(obj, prop)) - : false -} + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } -function specialSet (store, o, k, path, afterPath, censor, isCensorFct, censorFctTakesPath) { - const afterPathLen = afterPath.length - const lastPathIndex = afterPathLen - 1 - const originalKey = k - var i = -1 - var n - var nv - var ov - var oov = null - var wc = null - var kIsWc - var wcov - var consecutive = false - var level = 0 - // need to track depth of the `redactPath` tree - var depth = 0 - var redactPathCurrent = tree() - ov = n = o[k] - if (typeof n !== 'object') return - while (n != null && ++i < afterPathLen) { - depth += 1 - k = afterPath[i] - oov = ov - if (k !== '*' && !wc && !(typeof n === 'object' && k in n)) { - break - } - if (k === '*') { - if (wc === '*') { - consecutive = true - } - wc = k - if (i !== lastPathIndex) { - continue - } - } - if (wc) { - const wcKeys = Object.keys(n) - for (var j = 0; j < wcKeys.length; j++) { - const wck = wcKeys[j] - wcov = n[wck] - kIsWc = k === '*' - if (consecutive) { - redactPathCurrent = node(redactPathCurrent, wck, depth) - level = i - ov = iterateNthLevel(wcov, level - 1, k, path, afterPath, censor, isCensorFct, censorFctTakesPath, originalKey, n, nv, ov, kIsWc, wck, i, lastPathIndex, redactPathCurrent, store, o[originalKey], depth + 1) - } else { - if (kIsWc || (typeof wcov === 'object' && wcov !== null && k in wcov)) { - if (kIsWc) { - ov = wcov - } else { - ov = wcov[k] - } - nv = (i !== lastPathIndex) - ? ov - : (isCensorFct - ? (censorFctTakesPath ? censor(ov, [...path, originalKey, ...afterPath]) : censor(ov)) - : censor) - if (kIsWc) { - const rv = restoreInstr(node(redactPathCurrent, wck, depth), ov, o[originalKey]) - store.push(rv) - n[wck] = nv - } else { - if (wcov[k] === nv) { - // pass - } else if ((nv === undefined && censor !== undefined) || (has(wcov, k) && nv === ov)) { - redactPathCurrent = node(redactPathCurrent, wck, depth) - } else { - redactPathCurrent = node(redactPathCurrent, wck, depth) - const rv = restoreInstr(node(redactPathCurrent, k, depth + 1), ov, o[originalKey]) - store.push(rv) - wcov[k] = nv - } - } - } - } - } - wc = null - } else { - ov = n[k] - redactPathCurrent = node(redactPathCurrent, k, depth) - nv = (i !== lastPathIndex) - ? ov - : (isCensorFct - ? (censorFctTakesPath ? censor(ov, [...path, originalKey, ...afterPath]) : censor(ov)) - : censor) - if ((has(n, k) && nv === ov) || (nv === undefined && censor !== undefined)) { - // pass - } else { - const rv = restoreInstr(redactPathCurrent, ov, o[originalKey]) - store.push(rv) - n[k] = nv - } - n = n[k] - } - if (typeof n !== 'object') break - // prevent circular structure, see https://github.com/pinojs/pino/issues/1513 - if (ov === oov || typeof ov === 'undefined') { - // pass + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); } - } -} -function get (o, p) { - var i = -1 - var l = p.length - var n = o - while (n != null && ++i < l) { - n = n[p[i]] - } - return n + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); } -function iterateNthLevel (wcov, level, k, path, afterPath, censor, isCensorFct, censorFctTakesPath, originalKey, n, nv, ov, kIsWc, wck, i, lastPathIndex, redactPathCurrent, store, parent, depth) { - if (level === 0) { - if (kIsWc || (typeof wcov === 'object' && wcov !== null && k in wcov)) { - if (kIsWc) { - ov = wcov - } else { - ov = wcov[k] - } - nv = (i !== lastPathIndex) - ? ov - : (isCensorFct - ? (censorFctTakesPath ? censor(ov, [...path, originalKey, ...afterPath]) : censor(ov)) - : censor) - if (kIsWc) { - const rv = restoreInstr(redactPathCurrent, ov, parent) - store.push(rv) - n[wck] = nv - } else { - if (wcov[k] === nv) { - // pass - } else if ((nv === undefined && censor !== undefined) || (has(wcov, k) && nv === ov)) { - // pass - } else { - const rv = restoreInstr(node(redactPathCurrent, k, depth + 1), ov, parent) - store.push(rv) - wcov[k] = nv - } - } - } + +/***/ }), + +/***/ 8944: +/***/ ((module) => { + +module.exports = removeHook; + +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; } - for (const key in wcov) { - if (typeof wcov[key] === 'object') { - redactPathCurrent = node(redactPathCurrent, key, depth) - iterateNthLevel(wcov[key], level - 1, k, path, afterPath, censor, isCensorFct, censorFctTakesPath, originalKey, n, nv, ov, kIsWc, wck, i, lastPathIndex, redactPathCurrent, store, parent, depth + 1) - } + + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); + + if (index === -1) { + return; } + + state.registry[name].splice(index, 1); } -/** - * @typedef {object} TreeNode - * @prop {TreeNode} [parent] reference to the parent of this node in the tree, or `null` if there is no parent - * @prop {string} key the key that this node represents (key here being part of the path being redacted - * @prop {TreeNode[]} children the child nodes of this node - * @prop {number} depth the depth of this node in the tree - */ -/** - * instantiate a new, empty tree - * @returns {TreeNode} - */ -function tree () { - return { parent: null, key: null, children: [], depth: 0 } -} +/***/ }), -/** - * creates a new node in the tree, attaching it as a child of the provided parent node - * if the specified depth matches the parent depth, adds the new node as a _sibling_ of the parent instead - * @param {TreeNode} parent the parent node to add a new node to (if the parent depth matches the provided `depth` value, will instead add as a sibling of this - * @param {string} key the key that the new node represents (key here being part of the path being redacted) - * @param {number} depth the depth of the new node in the tree - used to determing whether to add the new node as a child or sibling of the provided `parent` node - * @returns {TreeNode} a reference to the newly created node in the tree +/***/ 40129: +/***/ ((module, exports, __nccwpck_require__) => { + +"use strict"; +/*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed */ -function node (parent, key, depth) { - if (parent.depth === depth) { - return node(parent.parent, key, depth) - } - var child = { - parent, - key, - depth, - children: [] - } - parent.children.push(child) - return child -} +/** + * Module dependencies. + * @private + */ + +var deprecate = __nccwpck_require__(77267)('body-parser') /** - * @typedef {object} RestoreInstruction - * @prop {string[]} path a reverse-order path that can be used to find the correct insertion point to restore a `value` for the given `parent` object - * @prop {*} value the value to restore - * @prop {object} target the object to restore the `value` in + * Cache of loaded parsers. + * @private */ +var parsers = Object.create(null) + /** - * create a restore instruction for the given redactPath node - * generates a path in reverse order by walking up the redactPath tree - * @param {TreeNode} node a tree node that should be at the bottom of the redact path (i.e. have no children) - this will be used to walk up the redact path tree to construct the path needed to restore - * @param {*} value the value to restore - * @param {object} target a reference to the parent object to apply the restore instruction to - * @returns {RestoreInstruction} an instruction used to restore a nested value for a specific object + * @typedef Parsers + * @type {function} + * @property {function} json + * @property {function} raw + * @property {function} text + * @property {function} urlencoded */ -function restoreInstr (node, value, target) { - let current = node - const path = [] - do { - path.push(current.key) - current = current.parent - } while (current.parent != null) - - return { path, value, target } -} - - -/***/ }), - -/***/ 94744: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; - - -const rx = __nccwpck_require__(51865) +/** + * Module exports. + * @type {Parsers} + */ -module.exports = parse +exports = module.exports = deprecate.function(bodyParser, + 'bodyParser: use individual json/urlencoded middlewares') -function parse ({ paths }) { - const wildcards = [] - var wcLen = 0 - const secret = paths.reduce(function (o, strPath, ix) { - var path = strPath.match(rx).map((p) => p.replace(/'|"|`/g, '')) - const leadingBracket = strPath[0] === '[' - path = path.map((p) => { - if (p[0] === '[') return p.substr(1, p.length - 2) - else return p - }) - const star = path.indexOf('*') - if (star > -1) { - const before = path.slice(0, star) - const beforeStr = before.join('.') - const after = path.slice(star + 1, path.length) - const nested = after.length > 0 - wcLen++ - wildcards.push({ - before, - beforeStr, - after, - nested - }) - } else { - o[strPath] = { - path: path, - val: undefined, - precensored: false, - circle: '', - escPath: JSON.stringify(strPath), - leadingBracket: leadingBracket - } - } - return o - }, {}) +/** + * JSON parser. + * @public + */ - return { wildcards, wcLen, secret } -} +Object.defineProperty(exports, "json", ({ + configurable: true, + enumerable: true, + get: createParserGetter('json') +})) +/** + * Raw parser. + * @public + */ -/***/ }), +Object.defineProperty(exports, "raw", ({ + configurable: true, + enumerable: true, + get: createParserGetter('raw') +})) -/***/ 83255: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/** + * Text parser. + * @public + */ -"use strict"; +Object.defineProperty(exports, "text", ({ + configurable: true, + enumerable: true, + get: createParserGetter('text') +})) +/** + * URL-encoded parser. + * @public + */ -const rx = __nccwpck_require__(51865) +Object.defineProperty(exports, "urlencoded", ({ + configurable: true, + enumerable: true, + get: createParserGetter('urlencoded') +})) -module.exports = redactor +/** + * Create a middleware to parse json and urlencoded bodies. + * + * @param {object} [options] + * @return {function} + * @deprecated + * @public + */ -function redactor ({ secret, serialize, wcLen, strict, isCensorFct, censorFctTakesPath }, state) { - /* eslint-disable-next-line */ - const redact = Function('o', ` - if (typeof o !== 'object' || o == null) { - ${strictImpl(strict, serialize)} - } - const { censor, secret } = this - const originalSecret = {} - const secretKeys = Object.keys(secret) - for (var i = 0; i < secretKeys.length; i++) { - originalSecret[secretKeys[i]] = secret[secretKeys[i]] +function bodyParser (options) { + // use default type for parsers + var opts = Object.create(options || null, { + type: { + configurable: true, + enumerable: true, + value: undefined, + writable: true } + }) - ${redactTmpl(secret, isCensorFct, censorFctTakesPath)} - this.compileRestore() - ${dynamicRedactTmpl(wcLen > 0, isCensorFct, censorFctTakesPath)} - this.secret = originalSecret - ${resultTmpl(serialize)} - `).bind(state) - - redact.state = state + var _urlencoded = exports.urlencoded(opts) + var _json = exports.json(opts) - if (serialize === false) { - redact.restore = (o) => state.restore(o) + return function bodyParser (req, res, next) { + _json(req, res, function (err) { + if (err) return next(err) + _urlencoded(req, res, next) + }) } - - return redact } -function redactTmpl (secret, isCensorFct, censorFctTakesPath) { - return Object.keys(secret).map((path) => { - const { escPath, leadingBracket, path: arrPath } = secret[path] - const skip = leadingBracket ? 1 : 0 - const delim = leadingBracket ? '' : '.' - const hops = [] - var match - while ((match = rx.exec(path)) !== null) { - const [ , ix ] = match - const { index, input } = match - if (index > skip) hops.push(input.substring(0, index - (ix ? 0 : 1))) - } - var existence = hops.map((p) => `o${delim}${p}`).join(' && ') - if (existence.length === 0) existence += `o${delim}${path} != null` - else existence += ` && o${delim}${path} != null` +/** + * Create a getter for loading a parser. + * @private + */ - const circularDetection = ` - switch (true) { - ${hops.reverse().map((p) => ` - case o${delim}${p} === censor: - secret[${escPath}].circle = ${JSON.stringify(p)} - break - `).join('\n')} - } - ` +function createParserGetter (name) { + return function get () { + return loadParser(name) + } +} - const censorArgs = censorFctTakesPath - ? `val, ${JSON.stringify(arrPath)}` - : `val` +/** + * Load a parser module. + * @private + */ - return ` - if (${existence}) { - const val = o${delim}${path} - if (val === censor) { - secret[${escPath}].precensored = true - } else { - secret[${escPath}].val = val - o${delim}${path} = ${isCensorFct ? `censor(${censorArgs})` : 'censor'} - ${circularDetection} - } - } - ` - }).join('\n') -} +function loadParser (parserName) { + var parser = parsers[parserName] -function dynamicRedactTmpl (hasWildcards, isCensorFct, censorFctTakesPath) { - return hasWildcards === true ? ` - { - const { wildcards, wcLen, groupRedact, nestedRedact } = this - for (var i = 0; i < wcLen; i++) { - const { before, beforeStr, after, nested } = wildcards[i] - if (nested === true) { - secret[beforeStr] = secret[beforeStr] || [] - nestedRedact(secret[beforeStr], o, before, after, censor, ${isCensorFct}, ${censorFctTakesPath}) - } else secret[beforeStr] = groupRedact(o, before, censor, ${isCensorFct}, ${censorFctTakesPath}) - } - } - ` : '' -} + if (parser !== undefined) { + return parser + } -function resultTmpl (serialize) { - return serialize === false ? `return o` : ` - var s = this.serialize(o) - this.restore(o) - return s - ` -} + // this uses a switch for static require analysis + switch (parserName) { + case 'json': + parser = __nccwpck_require__(39121) + break + case 'raw': + parser = __nccwpck_require__(87661) + break + case 'text': + parser = __nccwpck_require__(49488) + break + case 'urlencoded': + parser = __nccwpck_require__(55514) + break + } -function strictImpl (strict, serialize) { - return strict === true - ? `throw Error('fast-redact: primitives cannot be redacted')` - : serialize === false ? `return o` : `return this.serialize(o)` + // store to prevent invoking require() + return (parsers[parserName] = parser) } /***/ }), -/***/ 51339: +/***/ 45109: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; +/*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ -const { groupRestore, nestedRestore } = __nccwpck_require__(21797) -module.exports = restorer +/** + * Module dependencies. + * @private + */ -function restorer () { - return function compileRestore () { - if (this.restore) { - this.restore.state.secret = this.secret - return - } - const { secret, wcLen } = this - const paths = Object.keys(secret) - const resetters = resetTmpl(secret, paths) - const hasWildcards = wcLen > 0 - const state = hasWildcards ? { secret, groupRestore, nestedRestore } : { secret } - /* eslint-disable-next-line */ - this.restore = Function( - 'o', - restoreTmpl(resetters, paths, hasWildcards) - ).bind(state) - this.restore.state = state - } -} +var createError = __nccwpck_require__(8927) +var destroy = __nccwpck_require__(14802) +var getBody = __nccwpck_require__(24378) +var iconv = __nccwpck_require__(81241) +var onFinished = __nccwpck_require__(96922) +var unpipe = __nccwpck_require__(77962) +var zlib = __nccwpck_require__(43106) /** - * Mutates the original object to be censored by restoring its original values - * prior to censoring. - * - * @param {object} secret Compiled object describing which target fields should - * be censored and the field states. - * @param {string[]} paths The list of paths to censor as provided at - * initialization time. - * - * @returns {string} String of JavaScript to be used by `Function()`. The - * string compiles to the function that does the work in the description. + * Module exports. */ -function resetTmpl (secret, paths) { - return paths.map((path) => { - const { circle, escPath, leadingBracket } = secret[path] - const delim = leadingBracket ? '' : '.' - const reset = circle - ? `o.${circle} = secret[${escPath}].val` - : `o${delim}${path} = secret[${escPath}].val` - const clear = `secret[${escPath}].val = undefined` - return ` - if (secret[${escPath}].val !== undefined) { - try { ${reset} } catch (e) {} - ${clear} - } - ` - }).join('') -} + +module.exports = read /** - * Creates the body of the restore function - * - * Restoration of the redacted object happens - * backwards, in reverse order of redactions, - * so that repeated redactions on the same object - * property can be eventually rolled back to the - * original value. - * - * This way dynamic redactions are restored first, - * starting from the last one working backwards and - * followed by the static ones. + * Read a request into a buffer and parse. * - * @returns {string} the body of the restore function + * @param {object} req + * @param {object} res + * @param {function} next + * @param {function} parse + * @param {function} debug + * @param {object} options + * @private */ -function restoreTmpl (resetters, paths, hasWildcards) { - const dynamicReset = hasWildcards === true ? ` - const keys = Object.keys(secret) - const len = keys.length - for (var i = len - 1; i >= ${paths.length}; i--) { - const k = keys[i] - const o = secret[k] - if (o) { - if (o.flat === true) this.groupRestore(o) - else this.nestedRestore(o) - secret[k] = null - } - } - ` : '' - return ` - const secret = this.secret - ${dynamicReset} - ${resetters} - return o - ` -} +function read (req, res, next, parse, debug, options) { + var length + var opts = options + var stream + // flag as parsed + req._body = true -/***/ }), + // read options + var encoding = opts.encoding !== null + ? opts.encoding + : null + var verify = opts.verify -/***/ 51865: -/***/ ((module) => { + try { + // get the content stream + stream = contentstream(req, debug, opts.inflate) + length = stream.length + stream.length = undefined + } catch (err) { + return next(err) + } -"use strict"; + // set raw-body options + opts.length = length + opts.encoding = verify + ? null + : encoding + // assert charset is supported + if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { + return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { + charset: encoding.toLowerCase(), + type: 'charset.unsupported' + })) + } -module.exports = /[^.[\]]+|\[((?:.)*?)\]/g + // read body + debug('read body') + getBody(stream, opts, function (error, body) { + if (error) { + var _error -/* -Regular expression explanation: + if (error.type === 'encoding.unsupported') { + // echo back charset + _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { + charset: encoding.toLowerCase(), + type: 'charset.unsupported' + }) + } else { + // set status code on error + _error = createError(400, error) + } -Alt 1: /[^.[\]]+/ - Match one or more characters that are *not* a dot (.) - opening square bracket ([) or closing square bracket (]) + // unpipe from stream and destroy + if (stream !== req) { + unpipe(req) + destroy(stream, true) + } -Alt 2: /\[((?:.)*?)\]/ - If the char IS dot or square bracket, then create a capture - group (which will be capture group $1) that matches anything - within square brackets. Expansion is lazy so it will - stop matching as soon as the first closing bracket is met `]` - (rather than continuing to match until the final closing bracket). -*/ + // read off entire request + dump(req, function onfinished () { + next(createError(400, _error)) + }) + return + } + // verify + if (verify) { + try { + debug('verify body') + verify(req, res, body, encoding) + } catch (err) { + next(createError(403, err, { + body: body, + type: err.type || 'entity.verify.failed' + })) + return + } + } -/***/ }), + // parse + var str = body + try { + debug('parse body') + str = typeof body !== 'string' && encoding !== null + ? iconv.decode(body, encoding) + : body + req.body = parse(str) + } catch (err) { + next(createError(400, err, { + body: str, + type: err.type || 'entity.parse.failed' + })) + return + } -/***/ 18370: -/***/ ((module) => { + next() + }) +} -"use strict"; +/** + * Get the content stream of the request. + * + * @param {object} req + * @param {function} debug + * @param {boolean} [inflate=true] + * @return {object} + * @api private + */ +function contentstream (req, debug, inflate) { + var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() + var length = req.headers['content-length'] + var stream -module.exports = state + debug('content-encoding "%s"', encoding) -function state (o) { - const { - secret, - censor, - compileRestore, - serialize, - groupRedact, - nestedRedact, - wildcards, - wcLen - } = o - const builder = [{ secret, censor, compileRestore }] - if (serialize !== false) builder.push({ serialize }) - if (wcLen > 0) builder.push({ groupRedact, nestedRedact, wildcards, wcLen }) - return Object.assign(...builder) + if (inflate === false && encoding !== 'identity') { + throw createError(415, 'content encoding unsupported', { + encoding: encoding, + type: 'encoding.unsupported' + }) + } + + switch (encoding) { + case 'deflate': + stream = zlib.createInflate() + debug('inflate body') + req.pipe(stream) + break + case 'gzip': + stream = zlib.createGunzip() + debug('gunzip body') + req.pipe(stream) + break + case 'identity': + stream = req + stream.length = length + break + default: + throw createError(415, 'unsupported content encoding "' + encoding + '"', { + encoding: encoding, + type: 'encoding.unsupported' + }) + } + + return stream +} + +/** + * Dump the contents of a request. + * + * @param {object} req + * @param {function} callback + * @api private + */ + +function dump (req, callback) { + if (onFinished.isFinished(req)) { + callback(null) + } else { + onFinished(req, callback) + req.resume() + } } /***/ }), -/***/ 94437: -/***/ ((module) => { +/***/ 39121: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; +/*! + * body-parser + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ -module.exports = validator -function validator (opts = {}) { - const { - ERR_PATHS_MUST_BE_STRINGS = () => 'fast-redact - Paths must be (non-empty) strings', - ERR_INVALID_PATH = (s) => `fast-redact – Invalid path (${s})` - } = opts +/** + * Module dependencies. + * @private + */ - return function validate ({ paths }) { - paths.forEach((s) => { - if (typeof s !== 'string') { - throw Error(ERR_PATHS_MUST_BE_STRINGS()) - } - try { - if (/〇/.test(s)) throw Error() - const expr = (s[0] === '[' ? '' : '.') + s.replace(/^\*/, '〇').replace(/\.\*/g, '.〇').replace(/\[\*\]/g, '[〇]') - if (/\n|\r|;/.test(expr)) throw Error() - if (/\/\*/.test(expr)) throw Error() - /* eslint-disable-next-line */ - Function(` - 'use strict' - const o = new Proxy({}, { get: () => o, set: () => { throw Error() } }); - const 〇 = null; - o${expr} - if ([o${expr}].length !== 1) throw Error()`)() - } catch (e) { - throw Error(ERR_INVALID_PATH(s)) - } - }) - } -} +var bytes = __nccwpck_require__(89015) +var contentType = __nccwpck_require__(22541) +var createError = __nccwpck_require__(8927) +var debug = __nccwpck_require__(66515)('body-parser:json') +var read = __nccwpck_require__(45109) +var typeis = __nccwpck_require__(54693) +/** + * Module exports. + */ -/***/ }), +module.exports = json -/***/ 6315: -/***/ ((module) => { +/** + * RegExp to match the first non-space in a string. + * + * Allowed whitespace is defined in RFC 7159: + * + * ws = *( + * %x20 / ; Space + * %x09 / ; Horizontal tab + * %x0A / ; Line feed or New line + * %x0D ) ; Carriage return + */ -module.exports = stringify -stringify.default = stringify -stringify.stable = deterministicStringify -stringify.stableStringify = deterministicStringify +var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/ // eslint-disable-line no-control-regex -var LIMIT_REPLACE_NODE = '[...]' -var CIRCULAR_REPLACE_NODE = '[Circular]' +var JSON_SYNTAX_CHAR = '#' +var JSON_SYNTAX_REGEXP = /#+/g -var arr = [] -var replacerStack = [] +/** + * Create a middleware to parse JSON bodies. + * + * @param {object} [options] + * @return {function} + * @public + */ -function defaultOptions () { - return { - depthLimit: Number.MAX_SAFE_INTEGER, - edgesLimit: Number.MAX_SAFE_INTEGER - } -} +function json (options) { + var opts = options || {} -// Regular stringify -function stringify (obj, replacer, spacer, options) { - if (typeof options === 'undefined') { - options = defaultOptions() + var limit = typeof opts.limit !== 'number' + ? bytes.parse(opts.limit || '100kb') + : opts.limit + var inflate = opts.inflate !== false + var reviver = opts.reviver + var strict = opts.strict !== false + var type = opts.type || 'application/json' + var verify = opts.verify || false + + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function') } - decirc(obj, '', 0, [], undefined, 0, options) - var res - try { - if (replacerStack.length === 0) { - res = JSON.stringify(obj, replacer, spacer) - } else { - res = JSON.stringify(obj, replaceGetterValues(replacer), spacer) + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' + ? typeChecker(type) + : type + + function parse (body) { + if (body.length === 0) { + // special-case empty json body, as it's a common client-side mistake + // TODO: maybe make this configurable or part of "strict" option + return {} } - } catch (_) { - return JSON.stringify('[unable to serialize, circular reference is too complex to analyze]') - } finally { - while (arr.length !== 0) { - var part = arr.pop() - if (part.length === 4) { - Object.defineProperty(part[0], part[1], part[3]) - } else { - part[0][part[1]] = part[2] + + if (strict) { + var first = firstchar(body) + + if (first !== '{' && first !== '[') { + debug('strict violation') + throw createStrictSyntaxError(body, first) } } - } - return res -} -function setReplace (replace, val, k, parent) { - var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k) - if (propertyDescriptor.get !== undefined) { - if (propertyDescriptor.configurable) { - Object.defineProperty(parent, k, { value: replace }) - arr.push([parent, k, val, propertyDescriptor]) - } else { - replacerStack.push([val, k, replace]) + try { + debug('parse json') + return JSON.parse(body, reviver) + } catch (e) { + throw normalizeJsonSyntaxError(e, { + message: e.message, + stack: e.stack + }) } - } else { - parent[k] = replace - arr.push([parent, k, val]) } -} -function decirc (val, k, edgeIndex, stack, parent, depth, options) { - depth += 1 - var i - if (typeof val === 'object' && val !== null) { - for (i = 0; i < stack.length; i++) { - if (stack[i] === val) { - setReplace(CIRCULAR_REPLACE_NODE, val, k, parent) - return - } + return function jsonParser (req, res, next) { + if (req._body) { + debug('body already parsed') + next() + return } - if ( - typeof options.depthLimit !== 'undefined' && - depth > options.depthLimit - ) { - setReplace(LIMIT_REPLACE_NODE, val, k, parent) + req.body = req.body || {} + + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body') + next() return } - if ( - typeof options.edgesLimit !== 'undefined' && - edgeIndex + 1 > options.edgesLimit - ) { - setReplace(LIMIT_REPLACE_NODE, val, k, parent) + debug('content-type %j', req.headers['content-type']) + + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing') + next() return } - stack.push(val) - // Optimize for Arrays. Big arrays could kill the performance otherwise! - if (Array.isArray(val)) { - for (i = 0; i < val.length; i++) { - decirc(val[i], i, i, stack, val, depth, options) - } - } else { - var keys = Object.keys(val) - for (i = 0; i < keys.length; i++) { - var key = keys[i] - decirc(val[key], key, i, stack, val, depth, options) - } + // assert charset per RFC 7159 sec 8.1 + var charset = getCharset(req) || 'utf-8' + if (charset.slice(0, 4) !== 'utf-') { + debug('invalid charset') + next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset: charset, + type: 'charset.unsupported' + })) + return } - stack.pop() + + // read + read(req, res, next, parse, debug, { + encoding: charset, + inflate: inflate, + limit: limit, + verify: verify + }) } } -// Stable-stringify -function compareFunction (a, b) { - if (a < b) { - return -1 +/** + * Create strict violation syntax error matching native error. + * + * @param {string} str + * @param {string} char + * @return {Error} + * @private + */ + +function createStrictSyntaxError (str, char) { + var index = str.indexOf(char) + var partial = '' + + if (index !== -1) { + partial = str.substring(0, index) + JSON_SYNTAX_CHAR + + for (var i = index + 1; i < str.length; i++) { + partial += JSON_SYNTAX_CHAR + } } - if (a > b) { - return 1 + + try { + JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation') + } catch (e) { + return normalizeJsonSyntaxError(e, { + message: e.message.replace(JSON_SYNTAX_REGEXP, function (placeholder) { + return str.substring(index, index + placeholder.length) + }), + stack: e.stack + }) } - return 0 } -function deterministicStringify (obj, replacer, spacer, options) { - if (typeof options === 'undefined') { - options = defaultOptions() - } +/** + * Get the first non-whitespace character in a string. + * + * @param {string} str + * @return {function} + * @private + */ - var tmp = deterministicDecirc(obj, '', 0, [], undefined, 0, options) || obj - var res +function firstchar (str) { + var match = FIRST_CHAR_REGEXP.exec(str) + + return match + ? match[1] + : undefined +} + +/** + * Get the charset of a request. + * + * @param {object} req + * @api private + */ + +function getCharset (req) { try { - if (replacerStack.length === 0) { - res = JSON.stringify(tmp, replacer, spacer) - } else { - res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer) - } - } catch (_) { - return JSON.stringify('[unable to serialize, circular reference is too complex to analyze]') - } finally { - // Ensure that we restore the object as it was. - while (arr.length !== 0) { - var part = arr.pop() - if (part.length === 4) { - Object.defineProperty(part[0], part[1], part[3]) - } else { - part[0][part[1]] = part[2] - } - } + return (contentType.parse(req).parameters.charset || '').toLowerCase() + } catch (e) { + return undefined } - return res } -function deterministicDecirc (val, k, edgeIndex, stack, parent, depth, options) { - depth += 1 - var i - if (typeof val === 'object' && val !== null) { - for (i = 0; i < stack.length; i++) { - if (stack[i] === val) { - setReplace(CIRCULAR_REPLACE_NODE, val, k, parent) - return - } - } - try { - if (typeof val.toJSON === 'function') { - return - } - } catch (_) { - return - } - - if ( - typeof options.depthLimit !== 'undefined' && - depth > options.depthLimit - ) { - setReplace(LIMIT_REPLACE_NODE, val, k, parent) - return - } +/** + * Normalize a SyntaxError for JSON.parse. + * + * @param {SyntaxError} error + * @param {object} obj + * @return {SyntaxError} + */ - if ( - typeof options.edgesLimit !== 'undefined' && - edgeIndex + 1 > options.edgesLimit - ) { - setReplace(LIMIT_REPLACE_NODE, val, k, parent) - return - } +function normalizeJsonSyntaxError (error, obj) { + var keys = Object.getOwnPropertyNames(error) - stack.push(val) - // Optimize for Arrays. Big arrays could kill the performance otherwise! - if (Array.isArray(val)) { - for (i = 0; i < val.length; i++) { - deterministicDecirc(val[i], i, i, stack, val, depth, options) - } - } else { - // Create a temporary object in the required way - var tmp = {} - var keys = Object.keys(val).sort(compareFunction) - for (i = 0; i < keys.length; i++) { - var key = keys[i] - deterministicDecirc(val[key], key, i, stack, val, depth, options) - tmp[key] = val[key] - } - if (typeof parent !== 'undefined') { - arr.push([parent, k, val]) - parent[k] = tmp - } else { - return tmp - } + for (var i = 0; i < keys.length; i++) { + var key = keys[i] + if (key !== 'stack' && key !== 'message') { + delete error[key] } - stack.pop() } + + // replace stack before message for Node.js 0.10 and below + error.stack = obj.stack.replace(error.message, obj.message) + error.message = obj.message + + return error } -// wraps replacer function to handle values we couldn't replace -// and mark them as replaced value -function replaceGetterValues (replacer) { - replacer = - typeof replacer !== 'undefined' - ? replacer - : function (k, v) { - return v - } - return function (key, val) { - if (replacerStack.length > 0) { - for (var i = 0; i < replacerStack.length; i++) { - var part = replacerStack[i] - if (part[1] === key && part[0] === val) { - val = part[2] - replacerStack.splice(i, 1) - break - } - } - } - return replacer.call(this, key, val) +/** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + +function typeChecker (type) { + return function checkType (req) { + return Boolean(typeis(req, type)) } } /***/ }), -/***/ 1136: +/***/ 87661: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; /*! - * finalhandler - * Copyright(c) 2014-2022 Douglas Christopher Wilson + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ @@ -37374,18775 +40706,37445 @@ function replaceGetterValues (replacer) { /** * Module dependencies. - * @private */ -var debug = __nccwpck_require__(66515)('finalhandler') -var encodeUrl = __nccwpck_require__(31449) -var escapeHtml = __nccwpck_require__(3385) -var onFinished = __nccwpck_require__(96922) -var parseUrl = __nccwpck_require__(23610) -var statuses = __nccwpck_require__(53748) -var unpipe = __nccwpck_require__(77962) +var bytes = __nccwpck_require__(89015) +var debug = __nccwpck_require__(66515)('body-parser:raw') +var read = __nccwpck_require__(45109) +var typeis = __nccwpck_require__(54693) /** - * Module variables. - * @private + * Module exports. */ -var DOUBLE_SPACE_REGEXP = /\x20{2}/g -var NEWLINE_REGEXP = /\n/g - -/* istanbul ignore next */ -var defer = typeof setImmediate === 'function' - ? setImmediate - : function (fn) { process.nextTick(fn.bind.apply(fn, arguments)) } -var isFinished = onFinished.isFinished +module.exports = raw /** - * Create a minimal HTML document. + * Create a middleware to parse raw bodies. * - * @param {string} message - * @private + * @param {object} [options] + * @return {function} + * @api public */ -function createHtmlDocument (message) { - var body = escapeHtml(message) - .replace(NEWLINE_REGEXP, '
') - .replace(DOUBLE_SPACE_REGEXP, '  ') +function raw (options) { + var opts = options || {} - return '\n' + - '\n' + - '\n' + - '\n' + - 'Error\n' + - '\n' + - '\n' + - '
' + body + '
\n' + - '\n' + - '\n' -} - -/** - * Module exports. - * @public - */ - -module.exports = finalhandler - -/** - * Create a function to handle the final response. - * - * @param {Request} req - * @param {Response} res - * @param {Object} [options] - * @return {Function} - * @public - */ - -function finalhandler (req, res, options) { - var opts = options || {} + var inflate = opts.inflate !== false + var limit = typeof opts.limit !== 'number' + ? bytes.parse(opts.limit || '100kb') + : opts.limit + var type = opts.type || 'application/octet-stream' + var verify = opts.verify || false - // get environment - var env = opts.env || process.env.NODE_ENV || 'development' + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function') + } - // get error callback - var onerror = opts.onerror + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' + ? typeChecker(type) + : type - return function (err) { - var headers - var msg - var status + function parse (buf) { + return buf + } - // ignore 404 on in-flight response - if (!err && headersSent(res)) { - debug('cannot 404 after headers sent') + return function rawParser (req, res, next) { + if (req._body) { + debug('body already parsed') + next() return } - // unhandled error - if (err) { - // respect status code from error - status = getErrorStatusCode(err) - - if (status === undefined) { - // fallback to status code on response - status = getResponseStatusCode(res) - } else { - // respect headers from error - headers = getErrorHeaders(err) - } + req.body = req.body || {} - // get error message - msg = getErrorMessage(err, status, env) - } else { - // not found - status = 404 - msg = 'Cannot ' + req.method + ' ' + encodeUrl(getResourceName(req)) + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body') + next() + return } - debug('default %s', status) - - // schedule onerror callback - if (err && onerror) { - defer(onerror, err, req, res) - } + debug('content-type %j', req.headers['content-type']) - // cannot actually respond - if (headersSent(res)) { - debug('cannot %d after headers sent', status) - if (req.socket) { - req.socket.destroy() - } + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing') + next() return } - // send response - send(req, res, status, headers, msg) + // read + read(req, res, next, parse, debug, { + encoding: null, + inflate: inflate, + limit: limit, + verify: verify + }) } } /** - * Get headers from Error object. + * Get the simple type checker. * - * @param {Error} err - * @return {object} - * @private + * @param {string} type + * @return {function} */ -function getErrorHeaders (err) { - if (!err.headers || typeof err.headers !== 'object') { - return undefined - } - - var headers = Object.create(null) - var keys = Object.keys(err.headers) - - for (var i = 0; i < keys.length; i++) { - var key = keys[i] - headers[key] = err.headers[key] +function typeChecker (type) { + return function checkType (req) { + return Boolean(typeis(req, type)) } - - return headers } -/** - * Get message from Error object, fallback to status message. - * - * @param {Error} err - * @param {number} status - * @param {string} env - * @return {string} - * @private - */ - -function getErrorMessage (err, status, env) { - var msg - - if (env !== 'production') { - // use err.stack, which typically includes err.message - msg = err.stack - // fallback to err.toString() when possible - if (!msg && typeof err.toString === 'function') { - msg = err.toString() - } - } +/***/ }), - return msg || statuses.message[status] -} +/***/ 49488: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -/** - * Get status code from Error object. - * - * @param {Error} err - * @return {number} - * @private +"use strict"; +/*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed */ -function getErrorStatusCode (err) { - // check err.status - if (typeof err.status === 'number' && err.status >= 400 && err.status < 600) { - return err.status - } - - // check err.statusCode - if (typeof err.statusCode === 'number' && err.statusCode >= 400 && err.statusCode < 600) { - return err.statusCode - } - return undefined -} /** - * Get resource name for the request. - * - * This is typically just the original pathname of the request - * but will fallback to "resource" is that cannot be determined. - * - * @param {IncomingMessage} req - * @return {string} - * @private + * Module dependencies. */ -function getResourceName (req) { - try { - return parseUrl.original(req).pathname - } catch (e) { - return 'resource' - } -} +var bytes = __nccwpck_require__(89015) +var contentType = __nccwpck_require__(22541) +var debug = __nccwpck_require__(66515)('body-parser:text') +var read = __nccwpck_require__(45109) +var typeis = __nccwpck_require__(54693) /** - * Get status code from response. - * - * @param {OutgoingMessage} res - * @return {number} - * @private + * Module exports. */ -function getResponseStatusCode (res) { - var status = res.statusCode - - // default status code to 500 if outside valid range - if (typeof status !== 'number' || status < 400 || status > 599) { - status = 500 - } - - return status -} +module.exports = text /** - * Determine if the response headers have been sent. + * Create a middleware to parse text bodies. * - * @param {object} res - * @returns {boolean} - * @private + * @param {object} [options] + * @return {function} + * @api public */ -function headersSent (res) { - return typeof res.headersSent !== 'boolean' - ? Boolean(res._header) - : res.headersSent -} +function text (options) { + var opts = options || {} -/** - * Send response. - * - * @param {IncomingMessage} req - * @param {OutgoingMessage} res - * @param {number} status - * @param {object} headers - * @param {string} message - * @private - */ + var defaultCharset = opts.defaultCharset || 'utf-8' + var inflate = opts.inflate !== false + var limit = typeof opts.limit !== 'number' + ? bytes.parse(opts.limit || '100kb') + : opts.limit + var type = opts.type || 'text/plain' + var verify = opts.verify || false -function send (req, res, status, headers, message) { - function write () { - // response body - var body = createHtmlDocument(message) + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function') + } - // response status - res.statusCode = status + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' + ? typeChecker(type) + : type - if (req.httpVersionMajor < 2) { - res.statusMessage = statuses.message[status] - } + function parse (buf) { + return buf + } - // remove any content headers - res.removeHeader('Content-Encoding') - res.removeHeader('Content-Language') - res.removeHeader('Content-Range') + return function textParser (req, res, next) { + if (req._body) { + debug('body already parsed') + next() + return + } - // response headers - setHeaders(res, headers) + req.body = req.body || {} - // security headers - res.setHeader('Content-Security-Policy', "default-src 'none'") - res.setHeader('X-Content-Type-Options', 'nosniff') + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body') + next() + return + } - // standard headers - res.setHeader('Content-Type', 'text/html; charset=utf-8') - res.setHeader('Content-Length', Buffer.byteLength(body, 'utf8')) + debug('content-type %j', req.headers['content-type']) - if (req.method === 'HEAD') { - res.end() + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing') + next() return } - res.end(body, 'utf8') - } + // get charset + var charset = getCharset(req) || defaultCharset - if (isFinished(req)) { - write() - return + // read + read(req, res, next, parse, debug, { + encoding: charset, + inflate: inflate, + limit: limit, + verify: verify + }) } - - // unpipe everything from the request - unpipe(req) - - // flush the request - onFinished(req, write) - req.resume() } /** - * Set response headers from an object. + * Get the charset of a request. * - * @param {OutgoingMessage} res - * @param {object} headers - * @private + * @param {object} req + * @api private */ -function setHeaders (res, headers) { - if (!headers) { - return +function getCharset (req) { + try { + return (contentType.parse(req).parameters.charset || '').toLowerCase() + } catch (e) { + return undefined } +} - var keys = Object.keys(headers) - for (var i = 0; i < keys.length; i++) { - var key = keys[i] - res.setHeader(key, headers[key]) +/** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + +function typeChecker (type) { + return function checkType (req) { + return Boolean(typeis(req, type)) } } /***/ }), -/***/ 48240: +/***/ 55514: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; - -const path = __nccwpck_require__(16928); -const locatePath = __nccwpck_require__(53254); - -module.exports = (filename, opts = {}) => { - const startDir = path.resolve(opts.cwd || ''); - const {root} = path.parse(startDir); - - const filenames = [].concat(filename); - - return new Promise(resolve => { - (function find(dir) { - locatePath(filenames, {cwd: dir}).then(file => { - if (file) { - resolve(path.join(dir, file)); - } else if (dir === root) { - resolve(null); - } else { - find(path.dirname(dir)); - } - }); - })(startDir); - }); -}; - -module.exports.sync = (filename, opts = {}) => { - let dir = path.resolve(opts.cwd || ''); - const {root} = path.parse(dir); - - const filenames = [].concat(filename); - - // eslint-disable-next-line no-constant-condition - while (true) { - const file = locatePath.sync(filenames, {cwd: dir}); - - if (file) { - return path.join(dir, file); - } - - if (dir === root) { - return null; - } - - dir = path.dirname(dir); - } -}; - - -/***/ }), - -/***/ 21735: -/***/ ((module) => { - "use strict"; /*! - * forwarded - * Copyright(c) 2014-2017 Douglas Christopher Wilson + * body-parser + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ /** - * Module exports. - * @public + * Module dependencies. + * @private */ -module.exports = forwarded +var bytes = __nccwpck_require__(89015) +var contentType = __nccwpck_require__(22541) +var createError = __nccwpck_require__(8927) +var debug = __nccwpck_require__(66515)('body-parser:urlencoded') +var deprecate = __nccwpck_require__(77267)('body-parser') +var read = __nccwpck_require__(45109) +var typeis = __nccwpck_require__(54693) /** - * Get all addresses in the request, using the `X-Forwarded-For` header. - * - * @param {object} req - * @return {array} - * @public + * Module exports. */ -function forwarded (req) { - if (!req) { - throw new TypeError('argument req is required') - } - - // simple header parsing - var proxyAddrs = parse(req.headers['x-forwarded-for'] || '') - var socketAddr = getSocketAddr(req) - var addrs = [socketAddr].concat(proxyAddrs) - - // return all addresses - return addrs -} +module.exports = urlencoded /** - * Get the socket address for a request. - * - * @param {object} req - * @return {string} - * @private + * Cache of parser modules. */ -function getSocketAddr (req) { - return req.socket - ? req.socket.remoteAddress - : req.connection.remoteAddress -} +var parsers = Object.create(null) /** - * Parse the X-Forwarded-For header. + * Create a middleware to parse urlencoded bodies. * - * @param {string} header - * @private + * @param {object} [options] + * @return {function} + * @public */ -function parse (header) { - var end = header.length - var list = [] - var start = header.length +function urlencoded (options) { + var opts = options || {} - // gather addresses, backwards - for (var i = header.length - 1; i >= 0; i--) { - switch (header.charCodeAt(i)) { - case 0x20: /* */ - if (start === end) { - start = end = i - } - break - case 0x2c: /* , */ - if (start !== end) { - list.push(header.substring(start, end)) - } - start = end = i - break - default: - start = i - break - } + // notice because option default will flip in next major + if (opts.extended === undefined) { + deprecate('undefined extended: provide extended option') } - // final address - if (start !== end) { - list.push(header.substring(start, end)) - } + var extended = opts.extended !== false + var inflate = opts.inflate !== false + var limit = typeof opts.limit !== 'number' + ? bytes.parse(opts.limit || '100kb') + : opts.limit + var type = opts.type || 'application/x-www-form-urlencoded' + var verify = opts.verify || false + var depth = typeof opts.depth !== 'number' + ? Number(opts.depth || 32) + : opts.depth - return list -} + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function') + } + // create the appropriate query parser + var queryparse = extended + ? extendedparser(opts) + : simpleparser(opts) -/***/ }), + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' + ? typeChecker(type) + : type -/***/ 42825: -/***/ ((module) => { + function parse (body) { + return body.length + ? queryparse(body) + : {} + } -"use strict"; -/*! - * fresh - * Copyright(c) 2012 TJ Holowaychuk - * Copyright(c) 2016-2017 Douglas Christopher Wilson - * MIT Licensed - */ + return function urlencodedParser (req, res, next) { + if (req._body) { + debug('body already parsed') + next() + return + } + req.body = req.body || {} + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body') + next() + return + } -/** - * RegExp to check for no-cache token in Cache-Control. - * @private - */ + debug('content-type %j', req.headers['content-type']) -var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/ + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing') + next() + return + } -/** - * Module exports. - * @public - */ + // assert charset + var charset = getCharset(req) || 'utf-8' + if (charset !== 'utf-8') { + debug('invalid charset') + next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset: charset, + type: 'charset.unsupported' + })) + return + } -module.exports = fresh + // read + read(req, res, next, parse, debug, { + debug: debug, + encoding: charset, + inflate: inflate, + limit: limit, + verify: verify, + depth: depth + }) + } +} /** - * Check freshness of the response using request and response headers. + * Get the extended query parser. * - * @param {Object} reqHeaders - * @param {Object} resHeaders - * @return {Boolean} - * @public + * @param {object} options */ -function fresh (reqHeaders, resHeaders) { - // fields - var modifiedSince = reqHeaders['if-modified-since'] - var noneMatch = reqHeaders['if-none-match'] +function extendedparser (options) { + var parameterLimit = options.parameterLimit !== undefined + ? options.parameterLimit + : 1000 - // unconditional request - if (!modifiedSince && !noneMatch) { - return false + var depth = typeof options.depth !== 'number' + ? Number(options.depth || 32) + : options.depth + var parse = parser('qs') + + if (isNaN(parameterLimit) || parameterLimit < 1) { + throw new TypeError('option parameterLimit must be a positive number') } - // Always return stale when Cache-Control: no-cache - // to support end-to-end reload requests - // https://tools.ietf.org/html/rfc2616#section-14.9.4 - var cacheControl = reqHeaders['cache-control'] - if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) { - return false + if (isNaN(depth) || depth < 0) { + throw new TypeError('option depth must be a zero or a positive number') } - // if-none-match - if (noneMatch && noneMatch !== '*') { - var etag = resHeaders['etag'] + if (isFinite(parameterLimit)) { + parameterLimit = parameterLimit | 0 + } - if (!etag) { - return false + return function queryparse (body) { + var paramCount = parameterCount(body, parameterLimit) + + if (paramCount === undefined) { + debug('too many parameters') + throw createError(413, 'too many parameters', { + type: 'parameters.too.many' + }) } - var etagStale = true - var matches = parseTokenList(noneMatch) - for (var i = 0; i < matches.length; i++) { - var match = matches[i] - if (match === etag || match === 'W/' + etag || 'W/' + match === etag) { - etagStale = false - break + var arrayLimit = Math.max(100, paramCount) + + debug('parse extended urlencoding') + try { + return parse(body, { + allowPrototypes: true, + arrayLimit: arrayLimit, + depth: depth, + strictDepth: true, + parameterLimit: parameterLimit + }) + } catch (err) { + if (err instanceof RangeError) { + throw createError(400, 'The input exceeded the depth', { + type: 'querystring.parse.rangeError' + }) + } else { + throw err } } + } +} - if (etagStale) { - return false - } +/** + * Get the charset of a request. + * + * @param {object} req + * @api private + */ + +function getCharset (req) { + try { + return (contentType.parse(req).parameters.charset || '').toLowerCase() + } catch (e) { + return undefined } +} - // if-modified-since - if (modifiedSince) { - var lastModified = resHeaders['last-modified'] - var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince)) +/** + * Count the number of parameters, stopping once limit reached + * + * @param {string} body + * @param {number} limit + * @api private + */ - if (modifiedStale) { - return false +function parameterCount (body, limit) { + var count = 0 + var index = 0 + + while ((index = body.indexOf('&', index)) !== -1) { + count++ + index++ + + if (count === limit) { + return undefined } } - return true + return count } /** - * Parse an HTTP Date into a number. + * Get parser for module name dynamically. * - * @param {string} date - * @private + * @param {string} name + * @return {function} + * @api private */ -function parseHttpDate (date) { - var timestamp = date && Date.parse(date) +function parser (name) { + var mod = parsers[name] - // istanbul ignore next: guard against date.js Date.parse patching - return typeof timestamp === 'number' - ? timestamp - : NaN + if (mod !== undefined) { + return mod.parse + } + + // this uses a switch for static require analysis + switch (name) { + case 'qs': + mod = __nccwpck_require__(91833) + break + case 'querystring': + mod = __nccwpck_require__(83480) + break + } + + // store to prevent invoking require() + parsers[name] = mod + + return mod.parse } /** - * Parse a HTTP token list. + * Get the simple query parser. * - * @param {string} str - * @private + * @param {object} options */ -function parseTokenList (str) { - var end = 0 - var list = [] - var start = 0 +function simpleparser (options) { + var parameterLimit = options.parameterLimit !== undefined + ? options.parameterLimit + : 1000 + var parse = parser('querystring') - // gather tokens - for (var i = 0, len = str.length; i < len; i++) { - switch (str.charCodeAt(i)) { - case 0x20: /* */ - if (start === end) { - start = end = i + 1 - } - break - case 0x2c: /* , */ - list.push(str.substring(start, end)) - start = end = i + 1 - break - default: - end = i + 1 - break + if (isNaN(parameterLimit) || parameterLimit < 1) { + throw new TypeError('option parameterLimit must be a positive number') + } + + if (isFinite(parameterLimit)) { + parameterLimit = parameterLimit | 0 + } + + return function queryparse (body) { + var paramCount = parameterCount(body, parameterLimit) + + if (paramCount === undefined) { + debug('too many parameters') + throw createError(413, 'too many parameters', { + type: 'parameters.too.many' + }) } + + debug('parse urlencoding') + return parse(body, undefined, undefined, { maxKeys: parameterLimit }) } +} - // final token - list.push(str.substring(start, end)) +/** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ - return list +function typeChecker (type) { + return function checkType (req) { + return Boolean(typeis(req, type)) + } } /***/ }), -/***/ 57109: -/***/ ((module) => { +/***/ 60777: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -/* eslint no-invalid-this: 1 */ +var Batcher, Events, parser; +parser = __nccwpck_require__(90651); +Events = __nccwpck_require__(81065); -var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible '; -var toStr = Object.prototype.toString; -var max = Math.max; -var funcType = '[object Function]'; +Batcher = function () { + class Batcher { + constructor(options = {}) { + this.options = options; + parser.load(this.options, this.defaults, this); + this.Events = new Events(this); + this._arr = []; -var concatty = function concatty(a, b) { - var arr = []; + this._resetPromise(); - for (var i = 0; i < a.length; i += 1) { - arr[i] = a[i]; - } - for (var j = 0; j < b.length; j += 1) { - arr[j + a.length] = b[j]; + this._lastFlush = Date.now(); } - return arr; -}; - -var slicy = function slicy(arrLike, offset) { - var arr = []; - for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) { - arr[j] = arrLike[i]; + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); } - return arr; -}; -var joiny = function (arr, joiner) { - var str = ''; - for (var i = 0; i < arr.length; i += 1) { - str += arr[i]; - if (i + 1 < arr.length) { - str += joiner; - } - } - return str; -}; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); -module.exports = function bind(that) { - var target = this; - if (typeof target !== 'function' || toStr.apply(target) !== funcType) { - throw new TypeError(ERROR_MESSAGE + target); + this._resolve(); + + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); } - var args = slicy(arguments, 1); - var bound; - var binder = function () { - if (this instanceof bound) { - var result = target.apply( - this, - concatty(args, arguments) - ); - if (Object(result) === result) { - return result; - } - return this; - } - return target.apply( - that, - concatty(args, arguments) - ); + add(data) { + var ret; - }; + this._arr.push(data); - var boundLength = max(0, target.length - args.length); - var boundArgs = []; - for (var i = 0; i < boundLength; i++) { - boundArgs[i] = '$' + i; - } + ret = this._promise; - bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder); + if (this._arr.length === this.maxSize) { + this._flush(); + } else if (this.maxTime != null && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } - if (target.prototype) { - var Empty = function Empty() {}; - Empty.prototype = target.prototype; - bound.prototype = new Empty(); - Empty.prototype = null; + return ret; } - return bound; -}; + } + + ; + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; + return Batcher; +}.call(void 0); +module.exports = Batcher; /***/ }), -/***/ 58115: +/***/ 29263: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -var implementation = __nccwpck_require__(57109); - -module.exports = Function.prototype.bind || implementation; +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } +function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } -/***/ }), +function _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest(); } -/***/ 56196: -/***/ ((module) => { +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } -"use strict"; +function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } -// Call this function in a another function to find out the file from -// which that function was called from. (Inspects the v8 stack trace) -// -// Inspired by http://stackoverflow.com/questions/13227489 -module.exports = function getCallerFile(position) { - if (position === void 0) { position = 2; } - if (position >= Error.stackTraceLimit) { - throw new TypeError('getCallerFile(position) requires position be less then Error.stackTraceLimit but position was: `' + position + '` and Error.stackTraceLimit was: `' + Error.stackTraceLimit + '`'); - } - var oldPrepareStackTrace = Error.prepareStackTrace; - Error.prepareStackTrace = function (_, stack) { return stack; }; - var stack = new Error().stack; - Error.prepareStackTrace = oldPrepareStackTrace; - if (stack !== null && typeof stack === 'object') { - // stack[0] holds this file - // stack[1] holds where this function was called - // stack[2] holds the file we're interested in - return stack[position] ? stack[position].getFileName() : undefined; - } -}; -//# sourceMappingURL=index.js.map +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } -/***/ }), +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } -/***/ 36546: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } -"use strict"; +var Bottleneck, + DEFAULT_PRIORITY, + Events, + Job, + LocalDatastore, + NUM_PRIORITIES, + Queues, + RedisDatastore, + States, + Sync, + parser, + splice = [].splice; +NUM_PRIORITIES = 10; +DEFAULT_PRIORITY = 5; +parser = __nccwpck_require__(90651); +Queues = __nccwpck_require__(61944); +Job = __nccwpck_require__(73549); +LocalDatastore = __nccwpck_require__(4104); +RedisDatastore = __nccwpck_require__(35068); +Events = __nccwpck_require__(81065); +States = __nccwpck_require__(72878); +Sync = __nccwpck_require__(33923); +Bottleneck = function () { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); -var undefined; + this._validateOptions(options, invalid); -var $Error = __nccwpck_require__(90867); -var $EvalError = __nccwpck_require__(93241); -var $RangeError = __nccwpck_require__(79078); -var $ReferenceError = __nccwpck_require__(74310); -var $SyntaxError = __nccwpck_require__(48640); -var $TypeError = __nccwpck_require__(78279); -var $URIError = __nccwpck_require__(54573); + parser.load(options, this.instanceDefaults, this); + this._queues = new Queues(NUM_PRIORITIES); + this._scheduled = {}; + this._states = new States(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events(this); + this._submitLock = new Sync("submit", this.Promise); + this._registerLock = new Sync("register", this.Promise); + storeOptions = parser.load(options, this.storeDefaults, {}); -var $Function = Function; + this._store = function () { + if (this.datastore === "redis" || this.datastore === "ioredis" || this.connection != null) { + storeInstanceOptions = parser.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser.load(options, this.localStoreDefaults, {}); + return new LocalDatastore(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }.call(this); -// eslint-disable-next-line consistent-return -var getEvalledConstructor = function (expressionSyntax) { - try { - return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')(); - } catch (e) {} -}; + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); -var $gOPD = Object.getOwnPropertyDescriptor; -if ($gOPD) { - try { - $gOPD({}, ''); - } catch (e) { - $gOPD = null; // this is IE 8, which has a broken gOPD - } -} - -var throwTypeError = function () { - throw new $TypeError(); -}; -var ThrowTypeError = $gOPD - ? (function () { - try { - // eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties - arguments.callee; // IE 8 does not throw here - return throwTypeError; - } catch (calleeThrows) { - try { - // IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '') - return $gOPD(arguments, 'callee').get; - } catch (gOPDthrows) { - return throwTypeError; - } - } - }()) - : throwTypeError; + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } -var hasSymbols = __nccwpck_require__(51991)(); -var hasProto = __nccwpck_require__(16233)(); + _validateOptions(options, invalid) { + if (!(options != null && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } -var getProto = Object.getPrototypeOf || ( - hasProto - ? function (x) { return x.__proto__; } // eslint-disable-line no-proto - : null -); + ready() { + return this._store.ready; + } -var needsEval = {}; + clients() { + return this._store.clients; + } -var TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined : getProto(Uint8Array); + channel() { + return `b_${this.id}`; + } -var INTRINSICS = { - __proto__: null, - '%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError, - '%Array%': Array, - '%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer, - '%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined, - '%AsyncFromSyncIteratorPrototype%': undefined, - '%AsyncFunction%': needsEval, - '%AsyncGenerator%': needsEval, - '%AsyncGeneratorFunction%': needsEval, - '%AsyncIteratorPrototype%': needsEval, - '%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics, - '%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt, - '%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined : BigInt64Array, - '%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined : BigUint64Array, - '%Boolean%': Boolean, - '%DataView%': typeof DataView === 'undefined' ? undefined : DataView, - '%Date%': Date, - '%decodeURI%': decodeURI, - '%decodeURIComponent%': decodeURIComponent, - '%encodeURI%': encodeURI, - '%encodeURIComponent%': encodeURIComponent, - '%Error%': $Error, - '%eval%': eval, // eslint-disable-line no-eval - '%EvalError%': $EvalError, - '%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array, - '%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array, - '%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry, - '%Function%': $Function, - '%GeneratorFunction%': needsEval, - '%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array, - '%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array, - '%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array, - '%isFinite%': isFinite, - '%isNaN%': isNaN, - '%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined, - '%JSON%': typeof JSON === 'object' ? JSON : undefined, - '%Map%': typeof Map === 'undefined' ? undefined : Map, - '%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Map()[Symbol.iterator]()), - '%Math%': Math, - '%Number%': Number, - '%Object%': Object, - '%parseFloat%': parseFloat, - '%parseInt%': parseInt, - '%Promise%': typeof Promise === 'undefined' ? undefined : Promise, - '%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy, - '%RangeError%': $RangeError, - '%ReferenceError%': $ReferenceError, - '%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect, - '%RegExp%': RegExp, - '%Set%': typeof Set === 'undefined' ? undefined : Set, - '%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Set()[Symbol.iterator]()), - '%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer, - '%String%': String, - '%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined, - '%Symbol%': hasSymbols ? Symbol : undefined, - '%SyntaxError%': $SyntaxError, - '%ThrowTypeError%': ThrowTypeError, - '%TypedArray%': TypedArray, - '%TypeError%': $TypeError, - '%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array, - '%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray, - '%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array, - '%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array, - '%URIError%': $URIError, - '%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap, - '%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef, - '%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet -}; + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -if (getProto) { - try { - null.error; // eslint-disable-line no-unused-expressions - } catch (e) { - // https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229 - var errorProto = getProto(getProto(e)); - INTRINSICS['%Error.prototype%'] = errorProto; - } -} + publish(message) { + return this._store.__publish__(message); + } -var doEval = function doEval(name) { - var value; - if (name === '%AsyncFunction%') { - value = getEvalledConstructor('async function () {}'); - } else if (name === '%GeneratorFunction%') { - value = getEvalledConstructor('function* () {}'); - } else if (name === '%AsyncGeneratorFunction%') { - value = getEvalledConstructor('async function* () {}'); - } else if (name === '%AsyncGenerator%') { - var fn = doEval('%AsyncGeneratorFunction%'); - if (fn) { - value = fn.prototype; - } - } else if (name === '%AsyncIteratorPrototype%') { - var gen = doEval('%AsyncGenerator%'); - if (gen && getProto) { - value = getProto(gen.prototype); - } - } + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } - INTRINSICS[name] = value; + chain(_limiter) { + this._limiter = _limiter; + return this; + } - return value; -}; + queued(priority) { + return this._queues.queued(priority); + } -var LEGACY_ALIASES = { - __proto__: null, - '%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'], - '%ArrayPrototype%': ['Array', 'prototype'], - '%ArrayProto_entries%': ['Array', 'prototype', 'entries'], - '%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'], - '%ArrayProto_keys%': ['Array', 'prototype', 'keys'], - '%ArrayProto_values%': ['Array', 'prototype', 'values'], - '%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'], - '%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'], - '%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'], - '%BooleanPrototype%': ['Boolean', 'prototype'], - '%DataViewPrototype%': ['DataView', 'prototype'], - '%DatePrototype%': ['Date', 'prototype'], - '%ErrorPrototype%': ['Error', 'prototype'], - '%EvalErrorPrototype%': ['EvalError', 'prototype'], - '%Float32ArrayPrototype%': ['Float32Array', 'prototype'], - '%Float64ArrayPrototype%': ['Float64Array', 'prototype'], - '%FunctionPrototype%': ['Function', 'prototype'], - '%Generator%': ['GeneratorFunction', 'prototype'], - '%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'], - '%Int8ArrayPrototype%': ['Int8Array', 'prototype'], - '%Int16ArrayPrototype%': ['Int16Array', 'prototype'], - '%Int32ArrayPrototype%': ['Int32Array', 'prototype'], - '%JSONParse%': ['JSON', 'parse'], - '%JSONStringify%': ['JSON', 'stringify'], - '%MapPrototype%': ['Map', 'prototype'], - '%NumberPrototype%': ['Number', 'prototype'], - '%ObjectPrototype%': ['Object', 'prototype'], - '%ObjProto_toString%': ['Object', 'prototype', 'toString'], - '%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'], - '%PromisePrototype%': ['Promise', 'prototype'], - '%PromiseProto_then%': ['Promise', 'prototype', 'then'], - '%Promise_all%': ['Promise', 'all'], - '%Promise_reject%': ['Promise', 'reject'], - '%Promise_resolve%': ['Promise', 'resolve'], - '%RangeErrorPrototype%': ['RangeError', 'prototype'], - '%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'], - '%RegExpPrototype%': ['RegExp', 'prototype'], - '%SetPrototype%': ['Set', 'prototype'], - '%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'], - '%StringPrototype%': ['String', 'prototype'], - '%SymbolPrototype%': ['Symbol', 'prototype'], - '%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'], - '%TypedArrayPrototype%': ['TypedArray', 'prototype'], - '%TypeErrorPrototype%': ['TypeError', 'prototype'], - '%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'], - '%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'], - '%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'], - '%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'], - '%URIErrorPrototype%': ['URIError', 'prototype'], - '%WeakMapPrototype%': ['WeakMap', 'prototype'], - '%WeakSetPrototype%': ['WeakSet', 'prototype'] -}; + clusterQueued() { + return this._store.__queued__(); + } -var bind = __nccwpck_require__(58115); -var hasOwn = __nccwpck_require__(11681); -var $concat = bind.call(Function.call, Array.prototype.concat); -var $spliceApply = bind.call(Function.apply, Array.prototype.splice); -var $replace = bind.call(Function.call, String.prototype.replace); -var $strSlice = bind.call(Function.call, String.prototype.slice); -var $exec = bind.call(Function.call, RegExp.prototype.exec); + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } -/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */ -var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g; -var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */ -var stringToPath = function stringToPath(string) { - var first = $strSlice(string, 0, 1); - var last = $strSlice(string, -1); - if (first === '%' && last !== '%') { - throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`'); - } else if (last === '%' && first !== '%') { - throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`'); - } - var result = []; - $replace(string, rePropName, function (match, number, quote, subString) { - result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match; - }); - return result; -}; -/* end adaptation */ + running() { + return this._store.__running__(); + } -var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) { - var intrinsicName = name; - var alias; - if (hasOwn(LEGACY_ALIASES, intrinsicName)) { - alias = LEGACY_ALIASES[intrinsicName]; - intrinsicName = '%' + alias[0] + '%'; - } + done() { + return this._store.__done__(); + } - if (hasOwn(INTRINSICS, intrinsicName)) { - var value = INTRINSICS[intrinsicName]; - if (value === needsEval) { - value = doEval(intrinsicName); - } - if (typeof value === 'undefined' && !allowMissing) { - throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!'); - } + jobStatus(id) { + return this._states.jobStatus(id); + } - return { - alias: alias, - name: intrinsicName, - value: value - }; - } + jobs(status) { + return this._states.statusJobs(status); + } - throw new $SyntaxError('intrinsic ' + name + ' does not exist!'); -}; + counts() { + return this._states.statusCounts(); + } -module.exports = function GetIntrinsic(name, allowMissing) { - if (typeof name !== 'string' || name.length === 0) { - throw new $TypeError('intrinsic name must be a non-empty string'); - } - if (arguments.length > 1 && typeof allowMissing !== 'boolean') { - throw new $TypeError('"allowMissing" argument must be a boolean'); - } + _randomIndex() { + return Math.random().toString(36).slice(2); + } - if ($exec(/^%?[^%]*%?$/, name) === null) { - throw new $SyntaxError('`%` may not be present anywhere but at the beginning and end of the intrinsic name'); - } - var parts = stringToPath(name); - var intrinsicBaseName = parts.length > 0 ? parts[0] : ''; + check(weight = 1) { + return this._store.__check__(weight); + } - var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing); - var intrinsicRealName = intrinsic.name; - var value = intrinsic.value; - var skipFurtherCaching = false; + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } - var alias = intrinsic.alias; - if (alias) { - intrinsicBaseName = alias[0]; - $spliceApply(parts, $concat([0, 1], alias)); - } + _free(index, job, options, eventInfo) { + var _this = this; - for (var i = 1, isOwn = true; i < parts.length; i += 1) { - var part = parts[i]; - var first = $strSlice(part, 0, 1); - var last = $strSlice(part, -1); - if ( - ( - (first === '"' || first === "'" || first === '`') - || (last === '"' || last === "'" || last === '`') - ) - && first !== last - ) { - throw new $SyntaxError('property names with quotes must have matching quotes'); - } - if (part === 'constructor' || !isOwn) { - skipFurtherCaching = true; - } + return _asyncToGenerator(function* () { + var e, running; - intrinsicBaseName += '.' + part; - intrinsicRealName = '%' + intrinsicBaseName + '%'; + try { + var _ref = yield _this._store.__free__(index, options.weight); - if (hasOwn(INTRINSICS, intrinsicRealName)) { - value = INTRINSICS[intrinsicRealName]; - } else if (value != null) { - if (!(part in value)) { - if (!allowMissing) { - throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.'); - } - return void undefined; - } - if ($gOPD && (i + 1) >= parts.length) { - var desc = $gOPD(value, part); - isOwn = !!desc; + running = _ref.running; - // By convention, when a data property is converted to an accessor - // property to emulate a data property that does not suffer from - // the override mistake, that accessor's getter is marked with - // an `originalValue` property. Here, when we detect this, we - // uphold the illusion by pretending to see that original data - // property, i.e., returning the value rather than the getter - // itself. - if (isOwn && 'get' in desc && !('originalValue' in desc.get)) { - value = desc.get; - } else { - value = value[part]; - } - } else { - isOwn = hasOwn(value, part); - value = value[part]; - } + _this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (isOwn && !skipFurtherCaching) { - INTRINSICS[intrinsicRealName] = value; - } - } - } - return value; -}; + if (running === 0 && _this.empty()) { + return _this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return _this.Events.trigger("error", e); + } + })(); + } + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function () { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } -/***/ }), + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; -/***/ 12321: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (this.queued() === 0) { + return this.Promise.resolve(null); + } -"use strict"; + queue = this._queues.getFirst(); + var _next2 = next = queue.first(); -var GetIntrinsic = __nccwpck_require__(36546); + options = _next2.options; + args = _next2.args; -var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true); + if (capacity != null && options.weight > capacity) { + return this.Promise.resolve(null); + } -if ($gOPD) { - try { - $gOPD([], 'length'); - } catch (e) { - // IE 8 has a broken gOPD - $gOPD = null; - } -} + this.Events.trigger("debug", `Draining ${options.id}`, { + args, + options + }); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({ + success, + wait, + reservoir + }) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, { + success, + args, + options + }); -module.exports = $gOPD; + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } -/***/ }), + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } -/***/ 43394: -/***/ ((module) => { + this._run(index, next, wait); -"use strict"; + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then(drained => { + var newCapacity; -module.exports = clone + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch(e => { + return this.Events.trigger("error", e); + }); + } -var getPrototypeOf = Object.getPrototypeOf || function (obj) { - return obj.__proto__ -} + _dropAllQueued(message) { + return this._queues.shiftAll(function (job) { + return job.doDrop({ + message + }); + }); + } -function clone (obj) { - if (obj === null || typeof obj !== 'object') - return obj + stop(options = {}) { + var done, waitForExecuting; + options = parser.load(options, this.stopDefaults); - if (obj instanceof Object) - var copy = { __proto__: getPrototypeOf(obj) } - else - var copy = Object.create(null) - - Object.getOwnPropertyNames(obj).forEach(function (key) { - Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) - }) - - return copy -} - - -/***/ }), - -/***/ 59306: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + waitForExecuting = at => { + var finished; -var fs = __nccwpck_require__(79896) -var polyfills = __nccwpck_require__(19747) -var legacy = __nccwpck_require__(50624) -var clone = __nccwpck_require__(43394) + finished = () => { + var counts; + counts = this._states.counts; + return counts[0] + counts[1] + counts[2] + counts[3] === at; + }; -var util = __nccwpck_require__(39023) + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; -/* istanbul ignore next - node 0.x polyfill */ -var gracefulQueue -var previousSymbol + done = options.dropWaitingJobs ? (this._run = function (index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; -/* istanbul ignore else - node 0.x polyfill */ -if (typeof Symbol === 'function' && typeof Symbol.for === 'function') { - gracefulQueue = Symbol.for('graceful-fs.queue') - // This is used in testing by future versions - previousSymbol = Symbol.for('graceful-fs.previous') -} else { - gracefulQueue = '___graceful-fs.queue' - previousSymbol = '___graceful-fs.previous' -} + for (k in ref) { + v = ref[k]; -function noop () {} + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } -function publishQueue(context, queue) { - Object.defineProperty(context, gracefulQueue, { - get: function() { - return queue - } - }) -} + this._dropAllQueued(options.dropErrorMessage); -var debug = noop -if (util.debuglog) - debug = util.debuglog('gfs4') -else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) - debug = function() { - var m = util.format.apply(util, arguments) - m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') - console.error(m) - } + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); -// Once time initialization -if (!fs[gracefulQueue]) { - // This queue can be shared by multiple loaded instances - var queue = global[gracefulQueue] || [] - publishQueue(fs, queue) + this._receive = function (job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; - // Patch fs.close/closeSync to shared queue version, because we need - // to retry() whenever a close happens *anywhere* in the program. - // This is essential when multiple graceful-fs instances are - // in play at the same time. - fs.close = (function (fs$close) { - function close (fd, cb) { - return fs$close.call(fs, fd, function (err) { - // This function uses the graceful-fs shared queue - if (!err) { - resetQueue() - } + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; - if (typeof cb === 'function') - cb.apply(this, arguments) - }) + return done; } - Object.defineProperty(close, previousSymbol, { - value: fs$close - }) - return close - })(fs.close) + _addToQueue(job) { + var _this2 = this; - fs.closeSync = (function (fs$closeSync) { - function closeSync (fd) { - // This function uses the graceful-fs shared queue - fs$closeSync.apply(fs, arguments) - resetQueue() - } + return _asyncToGenerator(function* () { + var args, blocked, error, options, reachedHWM, shifted, strategy; + args = job.args; + options = job.options; - Object.defineProperty(closeSync, previousSymbol, { - value: fs$closeSync - }) - return closeSync - })(fs.closeSync) + try { + var _ref2 = yield _this2._store.__submit__(_this2.queued(), options.weight); - if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { - process.on('exit', function() { - debug(fs[gracefulQueue]) - __nccwpck_require__(42613).equal(fs[gracefulQueue].length, 0) - }) - } -} + reachedHWM = _ref2.reachedHWM; + blocked = _ref2.blocked; + strategy = _ref2.strategy; + } catch (error1) { + error = error1; -if (!global[gracefulQueue]) { - publishQueue(global, fs[gracefulQueue]); -} + _this2.Events.trigger("debug", `Could not queue ${options.id}`, { + args, + options, + error + }); -module.exports = patch(clone(fs)) -if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { - module.exports = patch(fs) - fs.__patched = true; -} + job.doDrop({ + error + }); + return false; + } -function patch (fs) { - // Everything that references the open() function needs to be in here - polyfills(fs) - fs.gracefulify = patch + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? _this2._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? _this2._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - fs.createReadStream = createReadStream - fs.createWriteStream = createWriteStream - var fs$readFile = fs.readFile - fs.readFile = readFile - function readFile (path, options, cb) { - if (typeof options === 'function') - cb = options, options = null + if (shifted != null) { + shifted.doDrop(); + } - return go$readFile(path, options, cb) + if (shifted == null || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } - function go$readFile (path, options, cb, startTime) { - return fs$readFile(path, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readFile, [path, options, cb], err, startTime || Date.now(), Date.now()]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) + return reachedHWM; + } } - }) - } - } - var fs$writeFile = fs.writeFile - fs.writeFile = writeFile - function writeFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + job.doQueue(reachedHWM, blocked); - return go$writeFile(path, data, options, cb) + _this2._queues.push(job); - function go$writeFile (path, data, options, cb, startTime) { - return fs$writeFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$writeFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - } - }) + yield _this2._drainAll(); + return reachedHWM; + })(); } - } - - var fs$appendFile = fs.appendFile - if (fs$appendFile) - fs.appendFile = appendFile - function appendFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null - return go$appendFile(path, data, options, cb) + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - function go$appendFile (path, data, options, cb, startTime) { - return fs$appendFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$appendFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - } - }) + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } } - } - var fs$copyFile = fs.copyFile - if (fs$copyFile) - fs.copyFile = copyFile - function copyFile (src, dest, flags, cb) { - if (typeof flags === 'function') { - cb = flags - flags = 0 - } - return go$copyFile(src, dest, flags, cb) + submit(...args) { + var cb, fn, job, options, ref, ref1, task; - function go$copyFile (src, dest, flags, cb, startTime) { - return fs$copyFile(src, dest, flags, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$copyFile, [src, dest, flags, cb], err, startTime || Date.now(), Date.now()]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - } - }) - } - } + if (typeof args[0] === "function") { + var _ref3, _ref4, _splice$call, _splice$call2; - var fs$readdir = fs.readdir - fs.readdir = readdir - var noReaddirOptionVersions = /^v[0-5]\./ - function readdir (path, options, cb) { - if (typeof options === 'function') - cb = options, options = null + ref = args, (_ref3 = ref, _ref4 = _toArray(_ref3), fn = _ref4[0], args = _ref4.slice(1), _ref3), (_splice$call = splice.call(args, -1), _splice$call2 = _slicedToArray(_splice$call, 1), cb = _splice$call2[0], _splice$call); + options = parser.load({}, this.jobDefaults); + } else { + var _ref5, _ref6, _splice$call3, _splice$call4; - var go$readdir = noReaddirOptionVersions.test(process.version) - ? function go$readdir (path, options, cb, startTime) { - return fs$readdir(path, fs$readdirCallback( - path, options, cb, startTime - )) - } - : function go$readdir (path, options, cb, startTime) { - return fs$readdir(path, options, fs$readdirCallback( - path, options, cb, startTime - )) + ref1 = args, (_ref5 = ref1, _ref6 = _toArray(_ref5), options = _ref6[0], fn = _ref6[1], args = _ref6.slice(2), _ref5), (_splice$call3 = splice.call(args, -1), _splice$call4 = _slicedToArray(_splice$call3, 1), cb = _splice$call4[0], _splice$call3); + options = parser.load(options, this.jobDefaults); } - return go$readdir(path, options, cb) - - function fs$readdirCallback (path, options, cb, startTime) { - return function (err, files) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([ - go$readdir, - [path, options, cb], - err, - startTime || Date.now(), - Date.now() - ]) - else { - if (files && files.sort) - files.sort() + task = (...args) => { + return new this.Promise(function (resolve, reject) { + return fn(...args, function (...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; - if (typeof cb === 'function') - cb.call(this, err, files) + job = new Job(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function (args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function (args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; } - } + }); + return this._receive(job); } - } - - if (process.version.substr(0, 4) === 'v0.8') { - var legStreams = legacy(fs) - ReadStream = legStreams.ReadStream - WriteStream = legStreams.WriteStream - } - - var fs$ReadStream = fs.ReadStream - if (fs$ReadStream) { - ReadStream.prototype = Object.create(fs$ReadStream.prototype) - ReadStream.prototype.open = ReadStream$open - } - var fs$WriteStream = fs.WriteStream - if (fs$WriteStream) { - WriteStream.prototype = Object.create(fs$WriteStream.prototype) - WriteStream.prototype.open = WriteStream$open - } + schedule(...args) { + var job, options, task; - Object.defineProperty(fs, 'ReadStream', { - get: function () { - return ReadStream - }, - set: function (val) { - ReadStream = val - }, - enumerable: true, - configurable: true - }) - Object.defineProperty(fs, 'WriteStream', { - get: function () { - return WriteStream - }, - set: function (val) { - WriteStream = val - }, - enumerable: true, - configurable: true - }) + if (typeof args[0] === "function") { + var _args = args; - // legacy names - var FileReadStream = ReadStream - Object.defineProperty(fs, 'FileReadStream', { - get: function () { - return FileReadStream - }, - set: function (val) { - FileReadStream = val - }, - enumerable: true, - configurable: true - }) - var FileWriteStream = WriteStream - Object.defineProperty(fs, 'FileWriteStream', { - get: function () { - return FileWriteStream - }, - set: function (val) { - FileWriteStream = val - }, - enumerable: true, - configurable: true - }) + var _args2 = _toArray(_args); - function ReadStream (path, options) { - if (this instanceof ReadStream) - return fs$ReadStream.apply(this, arguments), this - else - return ReadStream.apply(Object.create(ReadStream.prototype), arguments) - } + task = _args2[0]; + args = _args2.slice(1); + options = {}; + } else { + var _args3 = args; - function ReadStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - if (that.autoClose) - that.destroy() + var _args4 = _toArray(_args3); - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - that.read() + options = _args4[0]; + task = _args4[1]; + args = _args4.slice(2); } - }) - } - function WriteStream (path, options) { - if (this instanceof WriteStream) - return fs$WriteStream.apply(this, arguments), this - else - return WriteStream.apply(Object.create(WriteStream.prototype), arguments) - } + job = new Job(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - function WriteStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - that.destroy() - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - } - }) - } + this._receive(job); - function createReadStream (path, options) { - return new fs.ReadStream(path, options) - } + return job.promise; + } - function createWriteStream (path, options) { - return new fs.WriteStream(path, options) - } + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); - var fs$open = fs.open - fs.open = open - function open (path, flags, mode, cb) { - if (typeof mode === 'function') - cb = mode, mode = null + wrapped = function wrapped(...args) { + return schedule(fn.bind(this), ...args); + }; - return go$open(path, flags, mode, cb) + wrapped.withOptions = function (options, ...args) { + return schedule(options, fn, ...args); + }; - function go$open (path, flags, mode, cb, startTime) { - return fs$open(path, flags, mode, function (err, fd) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$open, [path, flags, mode, cb], err, startTime || Date.now(), Date.now()]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - } - }) + return wrapped; } - } - return fs -} + updateSettings(options = {}) { + var _this3 = this; -function enqueue (elem) { - debug('ENQUEUE', elem[0].name, elem[1]) - fs[gracefulQueue].push(elem) - retry() -} + return _asyncToGenerator(function* () { + yield _this3._store.__updateSettings__(parser.overwrite(options, _this3.storeDefaults)); + parser.overwrite(options, _this3.instanceDefaults, _this3); + return _this3; + })(); + } -// keep track of the timeout between retry() calls -var retryTimer + currentReservoir() { + return this._store.__currentReservoir__(); + } -// reset the startTime and lastTime to now -// this resets the start of the 60 second overall timeout as well as the -// delay between attempts so that we'll retry these jobs sooner -function resetQueue () { - var now = Date.now() - for (var i = 0; i < fs[gracefulQueue].length; ++i) { - // entries that are only a length of 2 are from an older version, don't - // bother modifying those since they'll be retried anyway. - if (fs[gracefulQueue][i].length > 2) { - fs[gracefulQueue][i][3] = now // startTime - fs[gracefulQueue][i][4] = now // lastTime + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); } + } - // call retry to make sure we're actively processing the queue - retry() -} -function retry () { - // clear the timer and remove it to help prevent unintended concurrency - clearTimeout(retryTimer) - retryTimer = undefined + ; + Bottleneck.default = Bottleneck; + Bottleneck.Events = Events; + Bottleneck.version = Bottleneck.prototype.version = (__nccwpck_require__(96701)/* .version */ .r); + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = __nccwpck_require__(88185); + Bottleneck.Group = Bottleneck.prototype.Group = __nccwpck_require__(11213); + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = __nccwpck_require__(28037); + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = __nccwpck_require__(41725); + Bottleneck.Batcher = Bottleneck.prototype.Batcher = __nccwpck_require__(60777); + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY, + weight: 1, + expiration: null, + id: "" + }; + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; + return Bottleneck; +}.call(void 0); - if (fs[gracefulQueue].length === 0) - return +module.exports = Bottleneck; - var elem = fs[gracefulQueue].shift() - var fn = elem[0] - var args = elem[1] - // these items may be unset if they were added by an older graceful-fs - var err = elem[2] - var startTime = elem[3] - var lastTime = elem[4] +/***/ }), - // if we don't have a startTime we have no way of knowing if we've waited - // long enough, so go ahead and retry this item now - if (startTime === undefined) { - debug('RETRY', fn.name, args) - fn.apply(null, args) - } else if (Date.now() - startTime >= 60000) { - // it's been more than 60 seconds total, bail now - debug('TIMEOUT', fn.name, args) - var cb = args.pop() - if (typeof cb === 'function') - cb.call(null, err) - } else { - // the amount of time between the last attempt and right now - var sinceAttempt = Date.now() - lastTime - // the amount of time between when we first tried, and when we last tried - // rounded up to at least 1 - var sinceStart = Math.max(lastTime - startTime, 1) - // backoff. wait longer than the total time we've been retrying, but only - // up to a maximum of 100ms - var desiredDelay = Math.min(sinceStart * 1.2, 100) - // it's been long enough since the last retry, do it again - if (sinceAttempt >= desiredDelay) { - debug('RETRY', fn.name, args) - fn.apply(null, args.concat([startTime])) - } else { - // if we can't do this job yet, push it to the end of the queue - // and let the next iteration check again - fs[gracefulQueue].push(elem) - } - } +/***/ 88185: +/***/ ((module) => { + +"use strict"; - // schedule our next run if one isn't already scheduled - if (retryTimer === undefined) { - retryTimer = setTimeout(retry, 0) - } -} +var BottleneckError; +BottleneckError = class BottleneckError extends Error {}; +module.exports = BottleneckError; /***/ }), -/***/ 50624: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 64792: +/***/ ((module) => { -var Stream = (__nccwpck_require__(2203).Stream) +"use strict"; -module.exports = legacy -function legacy (fs) { - return { - ReadStream: ReadStream, - WriteStream: WriteStream +var DLList; +DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; } - function ReadStream (path, options) { - if (!(this instanceof ReadStream)) return new ReadStream(path, options); + push(value) { + var node; + this.length++; - Stream.call(this); + if (typeof this.incr === "function") { + this.incr(); + } - var self = this; + node = { + value, + prev: this._last, + next: null + }; - this.path = path; - this.fd = null; - this.readable = true; - this.paused = false; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } - this.flags = 'r'; - this.mode = 438; /*=0666*/ - this.bufferSize = 64 * 1024; + return void 0; + } - options = options || {}; + shift() { + var value; - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; + if (this._first == null) { + return; + } else { + this.length--; + + if (typeof this.decr === "function") { + this.decr(); + } } - if (this.encoding) this.setEncoding(this.encoding); + value = this._first.value; - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } - if (this.start > this.end) { - throw new Error('start must be <= end'); - } + return value; + } - this.pos = this.start; + first() { + if (this._first != null) { + return this._first.value; } + } - if (this.fd !== null) { - process.nextTick(function() { - self._read(); - }); - return; + getArray() { + var node, ref, results; + node = this._first; + results = []; + + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); } - fs.open(this.path, this.flags, this.mode, function (err, fd) { - if (err) { - self.emit('error', err); - self.readable = false; - return; - } + return results; + } - self.fd = fd; - self.emit('open', fd); - self._read(); - }) + forEachShift(cb) { + var node; + node = this.shift(); + + while (node != null) { + cb(node), node = this.shift(); + } + + return void 0; } - function WriteStream (path, options) { - if (!(this instanceof WriteStream)) return new WriteStream(path, options); + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; - Stream.call(this); + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } - this.path = path; - this.fd = null; - this.writable = true; + return results; + } - this.flags = 'w'; - this.encoding = 'binary'; - this.mode = 438; /*=0666*/ - this.bytesWritten = 0; +}; +module.exports = DLList; - options = options || {}; +/***/ }), - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; +/***/ 81065: +/***/ ((module) => { + +"use strict"; + + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +var Events; +Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + + if (this.instance.on != null || this.instance.once != null || this.instance.removeAllListeners != null) { + throw new Error("An Emitter already exists for this object"); } - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; } + }; + } - this.pos = this.start; + _addListener(name, status, cb) { + var base; + + if ((base = this._events)[name] == null) { + base[name] = []; } - this.busy = false; - this._queue = []; + this._events[name].push({ + cb, + status + }); - if (this.fd === null) { - this._open = fs.open; - this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); - this.flush(); + return this.instance; + } + + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; } } -} + trigger(name, ...args) { + var _this = this; -/***/ }), + return _asyncToGenerator(function* () { + var e, promises; -/***/ 19747: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + try { + if (name !== "debug") { + _this.trigger("debug", `Event triggered: ${name}`, args); + } -var constants = __nccwpck_require__(49140) + if (_this._events[name] == null) { + return; + } -var origCwd = process.cwd -var cwd = null + _this._events[name] = _this._events[name].filter(function (listener) { + return listener.status !== "none"; + }); + promises = _this._events[name].map( + /*#__PURE__*/ + function () { + var _ref = _asyncToGenerator(function* (listener) { + var e, returned; -var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform + if (listener.status === "none") { + return; + } -process.cwd = function() { - if (!cwd) - cwd = origCwd.call(process) - return cwd -} -try { - process.cwd() -} catch (er) {} + if (listener.status === "once") { + listener.status = "none"; + } -// This check is needed until node.js 12 is required -if (typeof process.chdir === 'function') { - var chdir = process.chdir - process.chdir = function (d) { - cwd = null - chdir.call(process, d) - } - if (Object.setPrototypeOf) Object.setPrototypeOf(process.chdir, chdir) -} + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; -module.exports = patch + if (typeof (returned != null ? returned.then : void 0) === "function") { + return yield returned; + } else { + return returned; + } + } catch (error) { + e = error; -function patch (fs) { - // (re-)implement some things that are known busted or missing. + if (true) { + _this.trigger("error", e); + } - // lchmod, broken prior to 0.6.2 - // back-port the fix here. - if (constants.hasOwnProperty('O_SYMLINK') && - process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { - patchLchmod(fs) - } + return null; + } + }); - // lutimes implementation, or no-op - if (!fs.lutimes) { - patchLutimes(fs) + return function (_x) { + return _ref.apply(this, arguments); + }; + }()); + return (yield Promise.all(promises)).find(function (x) { + return x != null; + }); + } catch (error) { + e = error; + + if (true) { + _this.trigger("error", e); + } + + return null; + } + })(); } - // https://github.com/isaacs/node-graceful-fs/issues/4 - // Chown should not fail on einval or eperm if non-root. - // It should not fail on enosys ever, as this just indicates - // that a fs doesn't support the intended operation. +}; +module.exports = Events; - fs.chown = chownFix(fs.chown) - fs.fchown = chownFix(fs.fchown) - fs.lchown = chownFix(fs.lchown) +/***/ }), - fs.chmod = chmodFix(fs.chmod) - fs.fchmod = chmodFix(fs.fchmod) - fs.lchmod = chmodFix(fs.lchmod) +/***/ 11213: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - fs.chownSync = chownFixSync(fs.chownSync) - fs.fchownSync = chownFixSync(fs.fchownSync) - fs.lchownSync = chownFixSync(fs.lchownSync) +"use strict"; - fs.chmodSync = chmodFixSync(fs.chmodSync) - fs.fchmodSync = chmodFixSync(fs.fchmodSync) - fs.lchmodSync = chmodFixSync(fs.lchmodSync) - fs.stat = statFix(fs.stat) - fs.fstat = statFix(fs.fstat) - fs.lstat = statFix(fs.lstat) +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } - fs.statSync = statFixSync(fs.statSync) - fs.fstatSync = statFixSync(fs.fstatSync) - fs.lstatSync = statFixSync(fs.lstatSync) +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } - // if lchmod/lchown do not exist, then make them no-ops - if (fs.chmod && !fs.lchmod) { - fs.lchmod = function (path, mode, cb) { - if (cb) process.nextTick(cb) - } - fs.lchmodSync = function () {} - } - if (fs.chown && !fs.lchown) { - fs.lchown = function (path, uid, gid, cb) { - if (cb) process.nextTick(cb) - } - fs.lchownSync = function () {} - } +function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } - // on Windows, A/V software can lock the directory, causing this - // to fail with an EACCES or EPERM if the directory contains newly - // created files. Try again on failure, for up to 60 seconds. +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } - // Set the timeout this long because some Windows Anti-Virus, such as Parity - // bit9, may lock files for up to a minute, causing npm package install - // failures. Also, take care to yield the scheduler. Windows scheduling gives - // CPU to a busy looping process, which can cause the program causing the lock - // contention to be starved of CPU by node, so the contention doesn't resolve. - if (platform === "win32") { - fs.rename = typeof fs.rename !== 'function' ? fs.rename - : (function (fs$rename) { - function rename (from, to, cb) { - var start = Date.now() - var backoff = 0; - fs$rename(from, to, function CB (er) { - if (er - && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") - && Date.now() - start < 60000) { - setTimeout(function() { - fs.stat(to, function (stater, st) { - if (stater && stater.code === "ENOENT") - fs$rename(from, to, CB); - else - cb(er) - }) - }, backoff) - if (backoff < 100) - backoff += 10; - return; - } - if (cb) cb(er) - }) - } - if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename) - return rename - })(fs.rename) - } +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } - // if read() returns EAGAIN, then just try it again. - fs.read = typeof fs.read !== 'function' ? fs.read - : (function (fs$read) { - function read (fd, buffer, offset, length, position, callback_) { - var callback - if (callback_ && typeof callback_ === 'function') { - var eagCounter = 0 - callback = function (er, _, __) { - if (er && er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - } - callback_.apply(this, arguments) - } - } - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - } +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } - // This ensures `util.promisify` works as it does for native `fs.read`. - if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read) - return read - })(fs.read) +var Events, Group, IORedisConnection, RedisConnection, Scripts, parser; +parser = __nccwpck_require__(90651); +Events = __nccwpck_require__(81065); +RedisConnection = __nccwpck_require__(28037); +IORedisConnection = __nccwpck_require__(41725); +Scripts = __nccwpck_require__(65206); - fs.readSync = typeof fs.readSync !== 'function' ? fs.readSync - : (function (fs$readSync) { return function (fd, buffer, offset, length, position) { - var eagCounter = 0 - while (true) { - try { - return fs$readSync.call(fs, fd, buffer, offset, length, position) - } catch (er) { - if (er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - continue +Group = function () { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser.load(this.limiterOptions, this.defaults, this); + this.Events = new Events(this); + this.instances = {}; + this.Bottleneck = __nccwpck_require__(29263); + + this._startAutoCleanup(); + + this.sharedConnection = this.connection != null; + + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection(Object.assign({}, this.limiterOptions, { + Events: this.Events + })); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection(Object.assign({}, this.limiterOptions, { + Events: this.Events + })); } - throw er } } - }})(fs.readSync) - function patchLchmod (fs) { - fs.lchmod = function (path, mode, callback) { - fs.open( path - , constants.O_WRONLY | constants.O_SYMLINK - , mode - , function (err, fd) { - if (err) { - if (callback) callback(err) - return - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function (err) { - fs.close(fd, function(err2) { - if (callback) callback(err || err2) - }) - }) - }) + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); } - fs.lchmodSync = function (path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) + deleteKey(key = "") { + var _this = this; - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var threw = true - var ret - try { - ret = fs.fchmodSync(fd, mode) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) + return _asyncToGenerator(function* () { + var deleted, instance; + instance = _this.instances[key]; + + if (_this.connection) { + deleted = yield _this.connection.__runCommand__(['del', ...Scripts.allKeys(`${_this.id}-${key}`)]); } - } - return ret + + if (instance != null) { + delete _this.instances[key]; + yield instance.disconnect(); + } + + return instance != null || deleted > 0; + })(); } - } - function patchLutimes (fs) { - if (constants.hasOwnProperty("O_SYMLINK") && fs.futimes) { - fs.lutimes = function (path, at, mt, cb) { - fs.open(path, constants.O_SYMLINK, function (er, fd) { - if (er) { - if (cb) cb(er) - return - } - fs.futimes(fd, at, mt, function (er) { - fs.close(fd, function (er2) { - if (cb) cb(er || er2) - }) - }) - }) - } + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; - fs.lutimesSync = function (path, at, mt) { - var fd = fs.openSync(path, constants.O_SYMLINK) - var ret - var threw = true - try { - ret = fs.futimesSync(fd, at, mt) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); } - } else if (fs.futimes) { - fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } - fs.lutimesSync = function () {} + return results; } - } - function chmodFix (orig) { - if (!orig) return orig - return function (target, mode, cb) { - return orig.call(fs, target, mode, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) + keys() { + return Object.keys(this.instances); } - } - function chmodFixSync (orig) { - if (!orig) return orig - return function (target, mode) { - try { - return orig.call(fs, target, mode) - } catch (er) { - if (!chownErOk(er)) throw er - } - } - } + clusterKeys() { + var _this2 = this; + return _asyncToGenerator(function* () { + var cursor, end, found, i, k, keys, len, next, start; - function chownFix (orig) { - if (!orig) return orig - return function (target, uid, gid, cb) { - return orig.call(fs, target, uid, gid, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) - } - } + if (_this2.connection == null) { + return _this2.Promise.resolve(_this2.keys()); + } - function chownFixSync (orig) { - if (!orig) return orig - return function (target, uid, gid) { - try { - return orig.call(fs, target, uid, gid) - } catch (er) { - if (!chownErOk(er)) throw er - } - } - } + keys = []; + cursor = null; + start = `b_${_this2.id}-`.length; + end = "_settings".length; - function statFix (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - function callback (er, stats) { - if (stats) { - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 + while (cursor !== 0) { + var _ref = yield _this2.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${_this2.id}-*_settings`, "count", 10000]); + + var _ref2 = _slicedToArray(_ref, 2); + + next = _ref2[0]; + found = _ref2[1]; + cursor = ~~next; + + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } } - if (cb) cb.apply(this, arguments) - } - return options ? orig.call(fs, target, options, callback) - : orig.call(fs, target, callback) - } - } - function statFixSync (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, options) { - var stats = options ? orig.call(fs, target, options) - : orig.call(fs, target) - if (stats) { - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - } - return stats; + return keys; + })(); } - } - // ENOSYS means that the fs doesn't support the op. Just ignore - // that, because it doesn't matter. - // - // if there's no getuid, or if getuid() is something other - // than 0, and the error is EINVAL or EPERM, then just ignore - // it. - // - // This specific case is a silent failure in cp, install, tar, - // and most other unix tools that manage permissions. - // - // When running as root, or if other types of errors are - // encountered, then it's strict. - function chownErOk (er) { - if (!er) - return true + _startAutoCleanup() { + var _this3 = this; - if (er.code === "ENOSYS") - return true + var base; + clearInterval(this.interval); + return typeof (base = this.interval = setInterval( + /*#__PURE__*/ + _asyncToGenerator(function* () { + var e, k, ref, results, time, v; + time = Date.now(); + ref = _this3.instances; + results = []; - var nonroot = !process.getuid || process.getuid() !== 0 - if (nonroot) { - if (er.code === "EINVAL" || er.code === "EPERM") - return true + for (k in ref) { + v = ref[k]; + + try { + if (yield v._store.__groupCheck__(time)) { + results.push(_this3.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + + return results; + }), this.timeout / 2)).unref === "function" ? base.unref() : void 0; } - return false - } -} + updateSettings(options = {}) { + parser.overwrite(options, this.defaults, this); + parser.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -/***/ }), + disconnect(flush = true) { + var ref; -/***/ 54320: -/***/ ((module) => { + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -"use strict"; + } -module.exports = (flag, argv) => { - argv = argv || process.argv; - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const pos = argv.indexOf(prefix + flag); - const terminatorPos = argv.indexOf('--'); - return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); -}; + ; + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; + return Group; +}.call(void 0); +module.exports = Group; /***/ }), -/***/ 82600: +/***/ 41725: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -var $defineProperty = __nccwpck_require__(21410); +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } -var hasPropertyDescriptors = function hasPropertyDescriptors() { - return !!$defineProperty; -}; +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } -hasPropertyDescriptors.hasArrayLengthDefineBug = function hasArrayLengthDefineBug() { - // node v0.6 has a bug where array lengths can be Set but not Defined - if (!$defineProperty) { - return null; - } - try { - return $defineProperty([], 'length', { value: 1 }).length !== 1; - } catch (e) { - // In Firefox 4-22, defining length on an array throws an exception. - return true; - } -}; +function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } -module.exports = hasPropertyDescriptors; +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } -/***/ }), +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } -/***/ 16233: -/***/ ((module) => { +var Events, IORedisConnection, Scripts, parser; +parser = __nccwpck_require__(90651); +Events = __nccwpck_require__(81065); +Scripts = __nccwpck_require__(65206); -"use strict"; +IORedisConnection = function () { + class IORedisConnection { + constructor(options = {}) { + parser.load(options, this.defaults, this); + if (this.Redis == null) { + this.Redis = eval("require")("ioredis"); // Obfuscated or else Webpack/Angular will try to inline the optional ioredis module. To override this behavior: pass the ioredis module to Bottleneck as the 'Redis' option. + } -var test = { - __proto__: null, - foo: {} -}; + if (this.Events == null) { + this.Events = new Events(this); + } -var $Object = Object; + this.terminated = false; -/** @type {import('.')} */ -module.exports = function hasProto() { - // @ts-expect-error: TS errors on an inherited property for some reason - return { __proto__: test }.foo === test.foo - && !(test instanceof $Object); -}; + if (this.clusterNodes != null) { + this.client = new this.Redis.Cluster(this.clusterNodes, this.clientOptions); + this.subscriber = new this.Redis.Cluster(this.clusterNodes, this.clientOptions); + } else if (this.client != null && this.client.duplicate == null) { + this.subscriber = new this.Redis.Cluster(this.client.startupNodes, this.client.options); + } else { + if (this.client == null) { + this.client = new this.Redis(this.clientOptions); + } + this.subscriber = this.client.duplicate(); + } -/***/ }), + this.limiters = {}; + this.ready = this.Promise.all([this._setup(this.client, false), this._setup(this.subscriber, true)]).then(() => { + this._loadScripts(); -/***/ 51991: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return { + client: this.client, + subscriber: this.subscriber + }; + }); + } -"use strict"; + _setup(client, sub) { + client.setMaxListeners(0); + return new this.Promise((resolve, reject) => { + client.on("error", e => { + return this.Events.trigger("error", e); + }); + if (sub) { + client.on("message", (channel, message) => { + var ref; + return (ref = this.limiters[channel]) != null ? ref._store.onMessage(channel, message) : void 0; + }); + } -var origSymbol = typeof Symbol !== 'undefined' && Symbol; -var hasSymbolSham = __nccwpck_require__(2341); + if (client.status === "ready") { + return resolve(); + } else { + return client.once("ready", resolve); + } + }); + } -module.exports = function hasNativeSymbols() { - if (typeof origSymbol !== 'function') { return false; } - if (typeof Symbol !== 'function') { return false; } - if (typeof origSymbol('foo') !== 'symbol') { return false; } - if (typeof Symbol('bar') !== 'symbol') { return false; } + _loadScripts() { + return Scripts.names.forEach(name => { + return this.client.defineCommand(name, { + lua: Scripts.payload(name) + }); + }); + } - return hasSymbolSham(); -}; + __runCommand__(cmd) { + var _this = this; + return _asyncToGenerator(function* () { + var _, deleted; -/***/ }), + yield _this.ready; -/***/ 2341: -/***/ ((module) => { + var _ref = yield _this.client.pipeline([cmd]).exec(); -"use strict"; + var _ref2 = _slicedToArray(_ref, 1); + var _ref2$ = _slicedToArray(_ref2[0], 2); -/* eslint complexity: [2, 18], max-statements: [2, 33] */ -module.exports = function hasSymbols() { - if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; } - if (typeof Symbol.iterator === 'symbol') { return true; } - - var obj = {}; - var sym = Symbol('test'); - var symObj = Object(sym); - if (typeof sym === 'string') { return false; } - - if (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; } - if (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; } - - // temp disabled per https://github.com/ljharb/object.assign/issues/17 - // if (sym instanceof Symbol) { return false; } - // temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4 - // if (!(symObj instanceof Symbol)) { return false; } - - // if (typeof Symbol.prototype.toString !== 'function') { return false; } - // if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; } + _ = _ref2$[0]; + deleted = _ref2$[1]; + return deleted; + })(); + } - var symVal = 42; - obj[sym] = symVal; - for (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop - if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; } + __addLimiter__(instance) { + return this.Promise.all([instance.channel(), instance.channel_client()].map(channel => { + return new this.Promise((resolve, reject) => { + return this.subscriber.subscribe(channel, () => { + this.limiters[channel] = instance; + return resolve(); + }); + }); + })); + } - if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; } + __removeLimiter__(instance) { + var _this2 = this; - var syms = Object.getOwnPropertySymbols(obj); - if (syms.length !== 1 || syms[0] !== sym) { return false; } + return [instance.channel(), instance.channel_client()].forEach( + /*#__PURE__*/ + function () { + var _ref3 = _asyncToGenerator(function* (channel) { + if (!_this2.terminated) { + yield _this2.subscriber.unsubscribe(channel); + } - if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; } + return delete _this2.limiters[channel]; + }); - if (typeof Object.getOwnPropertyDescriptor === 'function') { - var descriptor = Object.getOwnPropertyDescriptor(obj, sym); - if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; } - } + return function (_x) { + return _ref3.apply(this, arguments); + }; + }()); + } - return true; -}; + __scriptArgs__(name, id, args, cb) { + var keys; + keys = Scripts.keys(name, id); + return [keys.length].concat(keys, args, cb); + } + __scriptFn__(name) { + return this.client[name].bind(this.client); + } -/***/ }), + disconnect(flush = true) { + var i, k, len, ref; + ref = Object.keys(this.limiters); -/***/ 11681: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + for (i = 0, len = ref.length; i < len; i++) { + k = ref[i]; + clearInterval(this.limiters[k]._store.heartbeat); + } -"use strict"; + this.limiters = {}; + this.terminated = true; + if (flush) { + return this.Promise.all([this.client.quit(), this.subscriber.quit()]); + } else { + this.client.disconnect(); + this.subscriber.disconnect(); + return this.Promise.resolve(); + } + } -var call = Function.prototype.call; -var $hasOwn = Object.prototype.hasOwnProperty; -var bind = __nccwpck_require__(58115); + } -/** @type {import('.')} */ -module.exports = bind.call(call, $hasOwn); + ; + IORedisConnection.prototype.datastore = "ioredis"; + IORedisConnection.prototype.defaults = { + Redis: null, + clientOptions: {}, + clusterNodes: null, + client: null, + Promise: Promise, + Events: null + }; + return IORedisConnection; +}.call(void 0); +module.exports = IORedisConnection; /***/ }), -/***/ 8927: +/***/ 73549: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -/*! - * http-errors - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2016 Douglas Christopher Wilson - * MIT Licensed - */ - - - -/** - * Module dependencies. - * @private - */ -var deprecate = __nccwpck_require__(77267)('http-errors') -var setPrototypeOf = __nccwpck_require__(12516) -var statuses = __nccwpck_require__(53748) -var inherits = __nccwpck_require__(34383) -var toIdentifier = __nccwpck_require__(29577) -/** - * Module exports. - * @public - */ +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } -module.exports = createError -module.exports.HttpError = createHttpErrorConstructor() -module.exports.isHttpError = createIsHttpErrorFunction(module.exports.HttpError) +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } -// Populate exports for all constructors -populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError) +var BottleneckError, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser; +NUM_PRIORITIES = 10; +DEFAULT_PRIORITY = 5; +parser = __nccwpck_require__(90651); +BottleneckError = __nccwpck_require__(88185); +Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); -/** - * Get the code class of a status code. - * @private - */ + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } -function codeClass (status) { - return Number(String(status).charAt(0) + '00') -} + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } -/** - * Create a new HTTP Error. - * - * @returns {Error} - * @public - */ + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; -function createError () { - // so much arity going on ~_~ - var err - var msg - var status = 500 - var props = {} - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i] - var type = typeof arg - if (type === 'object' && arg instanceof Error) { - err = arg - status = err.status || err.statusCode || status - } else if (type === 'number' && i === 0) { - status = arg - } else if (type === 'string') { - msg = arg - } else if (type === 'object') { - props = arg + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; } else { - throw new TypeError('argument #' + (i + 1) + ' unsupported type ' + type) + return sProperty; } } - if (typeof status === 'number' && (status < 400 || status >= 600)) { - deprecate('non-error status code; use only 4xx or 5xx status codes') - } - - if (typeof status !== 'number' || - (!statuses.message[status] && (status < 400 || status >= 600))) { - status = 500 + _randomIndex() { + return Math.random().toString(36).slice(2); } - // constructor - var HttpError = createError[status] || createError[codeClass(status)] + doDrop({ + error, + message = "This job has been dropped by Bottleneck" + } = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError(message)); + } - if (!err) { - // create error - err = HttpError - ? new HttpError(msg) - : new Error(msg || statuses.message[status]) - Error.captureStackTrace(err, createError) + this.Events.trigger("dropped", { + args: this.args, + options: this.options, + task: this.task, + promise: this.promise + }); + return true; + } else { + return false; + } } - if (!HttpError || !(err instanceof HttpError) || err.status !== status) { - // add properties to generic error - err.expose = status < 500 - err.status = err.statusCode = status - } + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); - for (var key in props) { - if (key !== 'status' && key !== 'statusCode') { - err[key] = props[key] + if (!(status === expected || expected === "DONE" && status === null)) { + throw new BottleneckError(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); } } - return err -} - -/** - * Create HTTP error abstract base class. - * @private - */ + doReceive() { + this._states.start(this.options.id); -function createHttpErrorConstructor () { - function HttpError () { - throw new TypeError('cannot construct abstract class') + return this.Events.trigger("received", { + args: this.args, + options: this.options + }); } - inherits(HttpError, Error) + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); - return HttpError -} + this._states.next(this.options.id); -/** - * Create a constructor for a client error. - * @private - */ + return this.Events.trigger("queued", { + args: this.args, + options: this.options, + reachedHWM, + blocked + }); + } -function createClientErrorConstructor (HttpError, name, code) { - var className = toClassName(name) + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); - function ClientError (message) { - // create the error object - var msg = message != null ? message : statuses.message[code] - var err = new Error(msg) + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } - // capture a stack trace to the construction point - Error.captureStackTrace(err, ClientError) + return this.Events.trigger("scheduled", { + args: this.args, + options: this.options + }); + } - // adjust the [[Prototype]] - setPrototypeOf(err, ClientError.prototype) + doExecute(chained, clearGlobalState, run, free) { + var _this = this; - // redefine the error message - Object.defineProperty(err, 'message', { - enumerable: true, - configurable: true, - value: msg, - writable: true - }) + return _asyncToGenerator(function* () { + var error, eventInfo, passed; - // redefine the error name - Object.defineProperty(err, 'name', { - enumerable: false, - configurable: true, - value: className, - writable: true - }) + if (_this.retryCount === 0) { + _this._assertStatus("RUNNING"); - return err - } + _this._states.next(_this.options.id); + } else { + _this._assertStatus("EXECUTING"); + } - inherits(ClientError, HttpError) - nameFunc(ClientError, className) + eventInfo = { + args: _this.args, + options: _this.options, + retryCount: _this.retryCount + }; - ClientError.prototype.status = code - ClientError.prototype.statusCode = code - ClientError.prototype.expose = true + _this.Events.trigger("executing", eventInfo); - return ClientError -} + try { + passed = yield chained != null ? chained.schedule(_this.options, _this.task, ..._this.args) : _this.task(..._this.args); -/** - * Create function to test is a value is a HttpError. - * @private - */ + if (clearGlobalState()) { + _this.doDone(eventInfo); -function createIsHttpErrorFunction (HttpError) { - return function isHttpError (val) { - if (!val || typeof val !== 'object') { - return false - } + yield free(_this.options, eventInfo); - if (val instanceof HttpError) { - return true - } + _this._assertStatus("DONE"); - return val instanceof Error && - typeof val.expose === 'boolean' && - typeof val.statusCode === 'number' && val.status === val.statusCode + return _this._resolve(passed); + } + } catch (error1) { + error = error1; + return _this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + })(); } -} - -/** - * Create a constructor for a server error. - * @private - */ -function createServerErrorConstructor (HttpError, name, code) { - var className = toClassName(name) + doExpire(clearGlobalState, run, free) { + var error, eventInfo; - function ServerError (message) { - // create the error object - var msg = message != null ? message : statuses.message[code] - var err = new Error(msg) + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } - // capture a stack trace to the construction point - Error.captureStackTrace(err, ServerError) + this._assertStatus("EXECUTING"); - // adjust the [[Prototype]] - setPrototypeOf(err, ServerError.prototype) + eventInfo = { + args: this.args, + options: this.options, + retryCount: this.retryCount + }; + error = new BottleneckError(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } - // redefine the error message - Object.defineProperty(err, 'message', { - enumerable: true, - configurable: true, - value: msg, - writable: true - }) + _onFailure(error, eventInfo, clearGlobalState, run, free) { + var _this2 = this; - // redefine the error name - Object.defineProperty(err, 'name', { - enumerable: false, - configurable: true, - value: className, - writable: true - }) + return _asyncToGenerator(function* () { + var retry, retryAfter; - return err - } + if (clearGlobalState()) { + retry = yield _this2.Events.trigger("failed", error, eventInfo); - inherits(ServerError, HttpError) - nameFunc(ServerError, className) + if (retry != null) { + retryAfter = ~~retry; - ServerError.prototype.status = code - ServerError.prototype.statusCode = code - ServerError.prototype.expose = false + _this2.Events.trigger("retry", `Retrying ${_this2.options.id} after ${retryAfter} ms`, eventInfo); - return ServerError -} + _this2.retryCount++; + return run(retryAfter); + } else { + _this2.doDone(eventInfo); -/** - * Set the name of a function, if possible. - * @private - */ + yield free(_this2.options, eventInfo); -function nameFunc (func, name) { - var desc = Object.getOwnPropertyDescriptor(func, 'name') + _this2._assertStatus("DONE"); - if (desc && desc.configurable) { - desc.value = name - Object.defineProperty(func, 'name', desc) + return _this2._reject(error); + } + } + })(); } -} -/** - * Populate the exports object with constructors for every error class. - * @private - */ + doDone(eventInfo) { + this._assertStatus("EXECUTING"); -function populateConstructorExports (exports, codes, HttpError) { - codes.forEach(function forEachCode (code) { - var CodeError - var name = toIdentifier(statuses.message[code]) + this._states.next(this.options.id); - switch (codeClass(code)) { - case 400: - CodeError = createClientErrorConstructor(HttpError, name, code) - break - case 500: - CodeError = createServerErrorConstructor(HttpError, name, code) - break - } + return this.Events.trigger("done", eventInfo); + } - if (CodeError) { - // export the constructor - exports[code] = CodeError - exports[name] = CodeError - } - }) -} +}; +module.exports = Job; -/** - * Get a class name from a name identifier. - * @private - */ +/***/ }), -function toClassName (name) { - return name.substr(-5) !== 'Error' - ? name + 'Error' - : name -} +/***/ 4104: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +"use strict"; -/***/ }), -/***/ 73051: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } -"use strict"; +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } -var __awaiter = (this && this.__awaiter) || function (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()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -const net_1 = __importDefault(__nccwpck_require__(69278)); -const tls_1 = __importDefault(__nccwpck_require__(64756)); -const url_1 = __importDefault(__nccwpck_require__(87016)); -const assert_1 = __importDefault(__nccwpck_require__(42613)); -const debug_1 = __importDefault(__nccwpck_require__(78382)); -const agent_base_1 = __nccwpck_require__(10803); -const parse_proxy_response_1 = __importDefault(__nccwpck_require__(32038)); -const debug = debug_1.default('https-proxy-agent:agent'); -/** - * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to - * the specified "HTTP(s) proxy server" in order to proxy HTTPS requests. - * - * Outgoing HTTP requests are first tunneled through the proxy server using the - * `CONNECT` HTTP request method to establish a connection to the proxy server, - * and then the proxy server connects to the destination target and issues the - * HTTP request from the proxy server. - * - * `https:` requests have their socket connection upgraded to TLS once - * the connection to the proxy server has been established. - * - * @api public - */ -class HttpsProxyAgent extends agent_base_1.Agent { - constructor(_opts) { - let opts; - if (typeof _opts === 'string') { - opts = url_1.default.parse(_opts); - } - else { - opts = _opts; - } - if (!opts) { - throw new Error('an HTTP(S) proxy server `host` and `port` must be specified!'); - } - debug('creating new HttpsProxyAgent instance: %o', opts); - super(opts); - const proxy = Object.assign({}, opts); - // If `true`, then connect to the proxy server over TLS. - // Defaults to `false`. - this.secureProxy = opts.secureProxy || isHTTPS(proxy.protocol); - // Prefer `hostname` over `host`, and set the `port` if needed. - proxy.host = proxy.hostname || proxy.host; - if (typeof proxy.port === 'string') { - proxy.port = parseInt(proxy.port, 10); - } - if (!proxy.port && proxy.host) { - proxy.port = this.secureProxy ? 443 : 80; - } - // ALPN is supported by Node.js >= v5. - // attempt to negotiate http/1.1 for proxy servers that support http/2 - if (this.secureProxy && !('ALPNProtocols' in proxy)) { - proxy.ALPNProtocols = ['http 1.1']; - } - if (proxy.host && proxy.path) { - // If both a `host` and `path` are specified then it's most likely - // the result of a `url.parse()` call... we need to remove the - // `path` portion so that `net.connect()` doesn't attempt to open - // that as a Unix socket file. - delete proxy.path; - delete proxy.pathname; - } - this.proxy = proxy; - } - /** - * Called when the node-core HTTP client library is creating a - * new HTTP request. - * - * @api protected - */ - callback(req, opts) { - return __awaiter(this, void 0, void 0, function* () { - const { proxy, secureProxy } = this; - // Create a socket connection to the proxy server. - let socket; - if (secureProxy) { - debug('Creating `tls.Socket`: %o', proxy); - socket = tls_1.default.connect(proxy); - } - else { - debug('Creating `net.Socket`: %o', proxy); - socket = net_1.default.connect(proxy); - } - const headers = Object.assign({}, proxy.headers); - const hostname = `${opts.host}:${opts.port}`; - let payload = `CONNECT ${hostname} HTTP/1.1\r\n`; - // Inject the `Proxy-Authorization` header if necessary. - if (proxy.auth) { - headers['Proxy-Authorization'] = `Basic ${Buffer.from(proxy.auth).toString('base64')}`; - } - // The `Host` header should only include the port - // number when it is not the default port. - let { host, port, secureEndpoint } = opts; - if (!isDefaultPort(port, secureEndpoint)) { - host += `:${port}`; - } - headers.Host = host; - headers.Connection = 'close'; - for (const name of Object.keys(headers)) { - payload += `${name}: ${headers[name]}\r\n`; - } - const proxyResponsePromise = parse_proxy_response_1.default(socket); - socket.write(`${payload}\r\n`); - const { statusCode, buffered } = yield proxyResponsePromise; - if (statusCode === 200) { - req.once('socket', resume); - if (opts.secureEndpoint) { - // The proxy is connecting to a TLS server, so upgrade - // this socket connection to a TLS connection. - debug('Upgrading socket connection to TLS'); - const servername = opts.servername || opts.host; - return tls_1.default.connect(Object.assign(Object.assign({}, omit(opts, 'host', 'hostname', 'path', 'port')), { socket, - servername })); - } - return socket; - } - // Some other status code that's not 200... need to re-play the HTTP - // header "data" events onto the socket once the HTTP machinery is - // attached so that the node core `http` can parse and handle the - // error status code. - // Close the original socket, and a new "fake" socket is returned - // instead, so that the proxy doesn't get the HTTP request - // written to it (which may contain `Authorization` headers or other - // sensitive data). - // - // See: https://hackerone.com/reports/541502 - socket.destroy(); - const fakeSocket = new net_1.default.Socket({ writable: false }); - fakeSocket.readable = true; - // Need to wait for the "socket" event to re-play the "data" events. - req.once('socket', (s) => { - debug('replaying proxy buffer for failed request'); - assert_1.default(s.listenerCount('data') > 0); - // Replay the "buffered" Buffer onto the fake `socket`, since at - // this point the HTTP module machinery has been hooked up for - // the user. - s.push(buffered); - s.push(null); - }); - return fakeSocket; - }); - } -} -exports["default"] = HttpsProxyAgent; -function resume(socket) { - socket.resume(); -} -function isDefaultPort(port, secure) { - return Boolean((!secure && port === 80) || (secure && port === 443)); -} -function isHTTPS(protocol) { - return typeof protocol === 'string' ? /^https:?$/i.test(protocol) : false; -} -function omit(obj, ...keys) { - const ret = {}; - let key; - for (key in obj) { - if (!keys.includes(key)) { - ret[key] = obj[key]; - } - } - return ret; -} -//# sourceMappingURL=agent.js.map - -/***/ }), +var BottleneckError, LocalDatastore, parser; +parser = __nccwpck_require__(90651); +BottleneckError = __nccwpck_require__(88185); +LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; -/***/ 42926: -/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) { + this._startHeartbeat(); + } -"use strict"; + _startHeartbeat() { + var base; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -const agent_1 = __importDefault(__nccwpck_require__(73051)); -function createHttpsProxyAgent(opts) { - return new agent_1.default(opts); -} -(function (createHttpsProxyAgent) { - createHttpsProxyAgent.HttpsProxyAgent = agent_1.default; - createHttpsProxyAgent.prototype = agent_1.default.prototype; -})(createHttpsProxyAgent || (createHttpsProxyAgent = {})); -module.exports = createHttpsProxyAgent; -//# sourceMappingURL=index.js.map + if (this.heartbeat == null && (this.storeOptions.reservoirRefreshInterval != null && this.storeOptions.reservoirRefreshAmount != null || this.storeOptions.reservoirIncreaseInterval != null && this.storeOptions.reservoirIncreaseAmount != null)) { + return typeof (base = this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); -/***/ }), + if (this.storeOptions.reservoirRefreshInterval != null && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; -/***/ 32038: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + this.instance._drainAll(this.computeCapacity()); + } -"use strict"; + if (this.storeOptions.reservoirIncreaseInterval != null && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + var _this$storeOptions = this.storeOptions; + amount = _this$storeOptions.reservoirIncreaseAmount; + maximum = _this$storeOptions.reservoirIncreaseMaximum; + reservoir = _this$storeOptions.reservoir; + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -const debug_1 = __importDefault(__nccwpck_require__(78382)); -const debug = debug_1.default('https-proxy-agent:parse-proxy-response'); -function parseProxyResponse(socket) { - return new Promise((resolve, reject) => { - // we need to buffer any HTTP traffic that happens with the proxy before we get - // the CONNECT response, so that if the response is anything other than an "200" - // response code, then we can re-play the "data" events on the socket once the - // HTTP parser is hooked up... - let buffersLength = 0; - const buffers = []; - function read() { - const b = socket.read(); - if (b) - ondata(b); - else - socket.once('readable', read); - } - function cleanup() { - socket.removeListener('end', onend); - socket.removeListener('error', onerror); - socket.removeListener('close', onclose); - socket.removeListener('readable', read); - } - function onclose(err) { - debug('onclose had error %o', err); - } - function onend() { - debug('onend'); - } - function onerror(err) { - cleanup(); - debug('onerror %o', err); - reject(err); - } - function ondata(b) { - buffers.push(b); - buffersLength += b.length; - const buffered = Buffer.concat(buffers, buffersLength); - const endOfHeaders = buffered.indexOf('\r\n\r\n'); - if (endOfHeaders === -1) { - // keep buffering - debug('have not received end of HTTP headers yet...'); - read(); - return; - } - const firstLine = buffered.toString('ascii', 0, buffered.indexOf('\r\n')); - const statusCode = +firstLine.split(' ')[1]; - debug('got proxy server response: %o', firstLine); - resolve({ - statusCode, - buffered - }); + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } } - socket.on('error', onerror); - socket.on('close', onclose); - socket.on('end', onend); - read(); - }); -} -exports["default"] = parseProxyResponse; -//# sourceMappingURL=parse-proxy-response.js.map + }, this.heartbeatInterval)).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } -/***/ }), + __publish__(message) { + var _this = this; -/***/ 80961: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + return _asyncToGenerator(function* () { + yield _this.yieldLoop(); + return _this.instance.Events.trigger("message", message.toString()); + })(); + } -"use strict"; + __disconnect__(flush) { + var _this2 = this; -var Buffer = (__nccwpck_require__(70159).Buffer); + return _asyncToGenerator(function* () { + yield _this2.yieldLoop(); + clearInterval(_this2.heartbeat); + return _this2.Promise.resolve(); + })(); + } -// Multibyte codec. In this scheme, a character is represented by 1 or more bytes. -// Our codec supports UTF-16 surrogates, extensions for GB18030 and unicode sequences. -// To save memory and loading time, we read table files only when requested. + yieldLoop(t = 0) { + return new this.Promise(function (resolve, reject) { + return setTimeout(resolve, t); + }); + } -exports._dbcs = DBCSCodec; + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : 15 * this.storeOptions.minTime || 5000; + } -var UNASSIGNED = -1, - GB18030_CODE = -2, - SEQ_START = -10, - NODE_START = -1000, - UNASSIGNED_NODE = new Array(0x100), - DEF_CHAR = -1; + __updateSettings__(options) { + var _this3 = this; -for (var i = 0; i < 0x100; i++) - UNASSIGNED_NODE[i] = UNASSIGNED; + return _asyncToGenerator(function* () { + yield _this3.yieldLoop(); + parser.overwrite(options, options, _this3.storeOptions); + _this3._startHeartbeat(); -// Class DBCSCodec reads and initializes mapping tables. -function DBCSCodec(codecOptions, iconv) { - this.encodingName = codecOptions.encodingName; - if (!codecOptions) - throw new Error("DBCS codec is called without the data.") - if (!codecOptions.table) - throw new Error("Encoding '" + this.encodingName + "' has no data."); + _this3.instance._drainAll(_this3.computeCapacity()); - // Load tables. - var mappingTable = codecOptions.table(); + return true; + })(); + } + __running__() { + var _this4 = this; - // Decode tables: MBCS -> Unicode. + return _asyncToGenerator(function* () { + yield _this4.yieldLoop(); + return _this4._running; + })(); + } - // decodeTables is a trie, encoded as an array of arrays of integers. Internal arrays are trie nodes and all have len = 256. - // Trie root is decodeTables[0]. - // Values: >= 0 -> unicode character code. can be > 0xFFFF - // == UNASSIGNED -> unknown/unassigned sequence. - // == GB18030_CODE -> this is the end of a GB18030 4-byte sequence. - // <= NODE_START -> index of the next node in our trie to process next byte. - // <= SEQ_START -> index of the start of a character code sequence, in decodeTableSeq. - this.decodeTables = []; - this.decodeTables[0] = UNASSIGNED_NODE.slice(0); // Create root node. + __queued__() { + var _this5 = this; - // Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here. - this.decodeTableSeq = []; + return _asyncToGenerator(function* () { + yield _this5.yieldLoop(); + return _this5.instance.queued(); + })(); + } - // Actual mapping tables consist of chunks. Use them to fill up decode tables. - for (var i = 0; i < mappingTable.length; i++) - this._addDecodeChunk(mappingTable[i]); + __done__() { + var _this6 = this; - this.defaultCharUnicode = iconv.defaultCharUnicode; + return _asyncToGenerator(function* () { + yield _this6.yieldLoop(); + return _this6._done; + })(); + } - - // Encode tables: Unicode -> DBCS. + __groupCheck__(time) { + var _this7 = this; - // `encodeTable` is array mapping from unicode char to encoded char. All its values are integers for performance. - // Because it can be sparse, it is represented as array of buckets by 256 chars each. Bucket can be null. - // Values: >= 0 -> it is a normal char. Write the value (if <=256 then 1 byte, if <=65536 then 2 bytes, etc.). - // == UNASSIGNED -> no conversion found. Output a default char. - // <= SEQ_START -> it's an index in encodeTableSeq, see below. The character starts a sequence. - this.encodeTable = []; - - // `encodeTableSeq` is used when a sequence of unicode characters is encoded as a single code. We use a tree of - // objects where keys correspond to characters in sequence and leafs are the encoded dbcs values. A special DEF_CHAR key - // means end of sequence (needed when one sequence is a strict subsequence of another). - // Objects are kept separately from encodeTable to increase performance. - this.encodeTableSeq = []; + return _asyncToGenerator(function* () { + yield _this7.yieldLoop(); + return _this7._nextRequest + _this7.timeout < time; + })(); + } - // Some chars can be decoded, but need not be encoded. - var skipEncodeChars = {}; - if (codecOptions.encodeSkipVals) - for (var i = 0; i < codecOptions.encodeSkipVals.length; i++) { - var val = codecOptions.encodeSkipVals[i]; - if (typeof val === 'number') - skipEncodeChars[val] = true; - else - for (var j = val.from; j <= val.to; j++) - skipEncodeChars[j] = true; - } - - // Use decode trie to recursively fill out encode tables. - this._fillEncodeTable(0, 0, skipEncodeChars); + computeCapacity() { + var maxConcurrent, reservoir; + var _this$storeOptions2 = this.storeOptions; + maxConcurrent = _this$storeOptions2.maxConcurrent; + reservoir = _this$storeOptions2.reservoir; - // Add more encoding pairs when needed. - if (codecOptions.encodeAdd) { - for (var uChar in codecOptions.encodeAdd) - if (Object.prototype.hasOwnProperty.call(codecOptions.encodeAdd, uChar)) - this._setEncodeChar(uChar.charCodeAt(0), codecOptions.encodeAdd[uChar]); + if (maxConcurrent != null && reservoir != null) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; } + } - this.defCharSB = this.encodeTable[0][iconv.defaultCharSingleByte.charCodeAt(0)]; - if (this.defCharSB === UNASSIGNED) this.defCharSB = this.encodeTable[0]['?']; - if (this.defCharSB === UNASSIGNED) this.defCharSB = "?".charCodeAt(0); + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return capacity == null || weight <= capacity; + } + __incrementReservoir__(incr) { + var _this8 = this; - // Load & create GB18030 tables when needed. - if (typeof codecOptions.gb18030 === 'function') { - this.gb18030 = codecOptions.gb18030(); // Load GB18030 ranges. + return _asyncToGenerator(function* () { + var reservoir; + yield _this8.yieldLoop(); + reservoir = _this8.storeOptions.reservoir += incr; - // Add GB18030 decode tables. - var thirdByteNodeIdx = this.decodeTables.length; - var thirdByteNode = this.decodeTables[thirdByteNodeIdx] = UNASSIGNED_NODE.slice(0); + _this8.instance._drainAll(_this8.computeCapacity()); - var fourthByteNodeIdx = this.decodeTables.length; - var fourthByteNode = this.decodeTables[fourthByteNodeIdx] = UNASSIGNED_NODE.slice(0); + return reservoir; + })(); + } - for (var i = 0x81; i <= 0xFE; i++) { - var secondByteNodeIdx = NODE_START - this.decodeTables[0][i]; - var secondByteNode = this.decodeTables[secondByteNodeIdx]; - for (var j = 0x30; j <= 0x39; j++) - secondByteNode[j] = NODE_START - thirdByteNodeIdx; - } - for (var i = 0x81; i <= 0xFE; i++) - thirdByteNode[i] = NODE_START - fourthByteNodeIdx; - for (var i = 0x30; i <= 0x39; i++) - fourthByteNode[i] = GB18030_CODE - } -} + __currentReservoir__() { + var _this9 = this; -DBCSCodec.prototype.encoder = DBCSEncoder; -DBCSCodec.prototype.decoder = DBCSDecoder; + return _asyncToGenerator(function* () { + yield _this9.yieldLoop(); + return _this9.storeOptions.reservoir; + })(); + } -// Decoder helpers -DBCSCodec.prototype._getDecodeTrieNode = function(addr) { - var bytes = []; - for (; addr > 0; addr >>= 8) - bytes.push(addr & 0xFF); - if (bytes.length == 0) - bytes.push(0); + isBlocked(now) { + return this._unblockTime >= now; + } - var node = this.decodeTables[0]; - for (var i = bytes.length-1; i > 0; i--) { // Traverse nodes deeper into the trie. - var val = node[bytes[i]]; + check(weight, now) { + return this.conditionsCheck(weight) && this._nextRequest - now <= 0; + } - if (val == UNASSIGNED) { // Create new node. - node[bytes[i]] = NODE_START - this.decodeTables.length; - this.decodeTables.push(node = UNASSIGNED_NODE.slice(0)); - } - else if (val <= NODE_START) { // Existing node. - node = this.decodeTables[NODE_START - val]; - } - else - throw new Error("Overwrite byte in " + this.encodingName + ", addr: " + addr.toString(16)); - } - return node; -} + __check__(weight) { + var _this10 = this; + return _asyncToGenerator(function* () { + var now; + yield _this10.yieldLoop(); + now = Date.now(); + return _this10.check(weight, now); + })(); + } -DBCSCodec.prototype._addDecodeChunk = function(chunk) { - // First element of chunk is the hex mbcs code where we start. - var curAddr = parseInt(chunk[0], 16); + __register__(index, weight, expiration) { + var _this11 = this; - // Choose the decoding node where we'll write our chars. - var writeTable = this._getDecodeTrieNode(curAddr); - curAddr = curAddr & 0xFF; + return _asyncToGenerator(function* () { + var now, wait; + yield _this11.yieldLoop(); + now = Date.now(); - // Write all other elements of the chunk to the table. - for (var k = 1; k < chunk.length; k++) { - var part = chunk[k]; - if (typeof part === "string") { // String, write as-is. - for (var l = 0; l < part.length;) { - var code = part.charCodeAt(l++); - if (0xD800 <= code && code < 0xDC00) { // Decode surrogate - var codeTrail = part.charCodeAt(l++); - if (0xDC00 <= codeTrail && codeTrail < 0xE000) - writeTable[curAddr++] = 0x10000 + (code - 0xD800) * 0x400 + (codeTrail - 0xDC00); - else - throw new Error("Incorrect surrogate pair in " + this.encodingName + " at chunk " + chunk[0]); - } - else if (0x0FF0 < code && code <= 0x0FFF) { // Character sequence (our own encoding used) - var len = 0xFFF - code + 2; - var seq = []; - for (var m = 0; m < len; m++) - seq.push(part.charCodeAt(l++)); // Simple variation: don't support surrogates or subsequences in seq. + if (_this11.conditionsCheck(weight)) { + _this11._running += weight; - writeTable[curAddr++] = SEQ_START - this.decodeTableSeq.length; - this.decodeTableSeq.push(seq); - } - else - writeTable[curAddr++] = code; // Basic char - } - } - else if (typeof part === "number") { // Integer, meaning increasing sequence starting with prev character. - var charCode = writeTable[curAddr - 1] + 1; - for (var l = 0; l < part; l++) - writeTable[curAddr++] = charCode++; + if (_this11.storeOptions.reservoir != null) { + _this11.storeOptions.reservoir -= weight; } - else - throw new Error("Incorrect type '" + typeof part + "' given in " + this.encodingName + " at chunk " + chunk[0]); - } - if (curAddr > 0xFF) - throw new Error("Incorrect chunk in " + this.encodingName + " at addr " + chunk[0] + ": too long" + curAddr); -} - -// Encoder helpers -DBCSCodec.prototype._getEncodeBucket = function(uCode) { - var high = uCode >> 8; // This could be > 0xFF because of astral characters. - if (this.encodeTable[high] === undefined) - this.encodeTable[high] = UNASSIGNED_NODE.slice(0); // Create bucket on demand. - return this.encodeTable[high]; -} -DBCSCodec.prototype._setEncodeChar = function(uCode, dbcsCode) { - var bucket = this._getEncodeBucket(uCode); - var low = uCode & 0xFF; - if (bucket[low] <= SEQ_START) - this.encodeTableSeq[SEQ_START-bucket[low]][DEF_CHAR] = dbcsCode; // There's already a sequence, set a single-char subsequence of it. - else if (bucket[low] == UNASSIGNED) - bucket[low] = dbcsCode; -} + wait = Math.max(_this11._nextRequest - now, 0); + _this11._nextRequest = now + wait + _this11.storeOptions.minTime; + return { + success: true, + wait, + reservoir: _this11.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + })(); + } -DBCSCodec.prototype._setEncodeSequence = function(seq, dbcsCode) { - - // Get the root of character tree according to first character of the sequence. - var uCode = seq[0]; - var bucket = this._getEncodeBucket(uCode); - var low = uCode & 0xFF; + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } - var node; - if (bucket[low] <= SEQ_START) { - // There's already a sequence with - use it. - node = this.encodeTableSeq[SEQ_START-bucket[low]]; - } - else { - // There was no sequence object - allocate a new one. - node = {}; - if (bucket[low] !== UNASSIGNED) node[DEF_CHAR] = bucket[low]; // If a char was set before - make it a single-char subsequence. - bucket[low] = SEQ_START - this.encodeTableSeq.length; - this.encodeTableSeq.push(node); - } + __submit__(queueLength, weight) { + var _this12 = this; - // Traverse the character tree, allocating new nodes as needed. - for (var j = 1; j < seq.length-1; j++) { - var oldVal = node[uCode]; - if (typeof oldVal === 'object') - node = oldVal; - else { - node = node[uCode] = {} - if (oldVal !== undefined) - node[DEF_CHAR] = oldVal - } - } + return _asyncToGenerator(function* () { + var blocked, now, reachedHWM; + yield _this12.yieldLoop(); - // Set the leaf to given dbcsCode. - uCode = seq[seq.length-1]; - node[uCode] = dbcsCode; -} + if (_this12.storeOptions.maxConcurrent != null && weight > _this12.storeOptions.maxConcurrent) { + throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${_this12.storeOptions.maxConcurrent}`); + } -DBCSCodec.prototype._fillEncodeTable = function(nodeIdx, prefix, skipEncodeChars) { - var node = this.decodeTables[nodeIdx]; - for (var i = 0; i < 0x100; i++) { - var uCode = node[i]; - var mbCode = prefix + i; - if (skipEncodeChars[mbCode]) - continue; + now = Date.now(); + reachedHWM = _this12.storeOptions.highWater != null && queueLength === _this12.storeOptions.highWater && !_this12.check(weight, now); + blocked = _this12.strategyIsBlock() && (reachedHWM || _this12.isBlocked(now)); - if (uCode >= 0) - this._setEncodeChar(uCode, mbCode); - else if (uCode <= NODE_START) - this._fillEncodeTable(NODE_START - uCode, mbCode << 8, skipEncodeChars); - else if (uCode <= SEQ_START) - this._setEncodeSequence(this.decodeTableSeq[SEQ_START - uCode], mbCode); - } -} + if (blocked) { + _this12._unblockTime = now + _this12.computePenalty(); + _this12._nextRequest = _this12._unblockTime + _this12.storeOptions.minTime; + _this12.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: _this12.storeOptions.strategy + }; + })(); + } -// == Encoder ================================================================== + __free__(index, weight) { + var _this13 = this; -function DBCSEncoder(options, codec) { - // Encoder state - this.leadSurrogate = -1; - this.seqObj = undefined; - - // Static data - this.encodeTable = codec.encodeTable; - this.encodeTableSeq = codec.encodeTableSeq; - this.defaultCharSingleByte = codec.defCharSB; - this.gb18030 = codec.gb18030; -} + return _asyncToGenerator(function* () { + yield _this13.yieldLoop(); + _this13._running -= weight; + _this13._done += weight; -DBCSEncoder.prototype.write = function(str) { - var newBuf = Buffer.alloc(str.length * (this.gb18030 ? 4 : 3)), - leadSurrogate = this.leadSurrogate, - seqObj = this.seqObj, nextChar = -1, - i = 0, j = 0; + _this13.instance._drainAll(_this13.computeCapacity()); - while (true) { - // 0. Get next character. - if (nextChar === -1) { - if (i == str.length) break; - var uCode = str.charCodeAt(i++); - } - else { - var uCode = nextChar; - nextChar = -1; - } + return { + running: _this13._running + }; + })(); + } - // 1. Handle surrogates. - if (0xD800 <= uCode && uCode < 0xE000) { // Char is one of surrogates. - if (uCode < 0xDC00) { // We've got lead surrogate. - if (leadSurrogate === -1) { - leadSurrogate = uCode; - continue; - } else { - leadSurrogate = uCode; - // Double lead surrogate found. - uCode = UNASSIGNED; - } - } else { // We've got trail surrogate. - if (leadSurrogate !== -1) { - uCode = 0x10000 + (leadSurrogate - 0xD800) * 0x400 + (uCode - 0xDC00); - leadSurrogate = -1; - } else { - // Incomplete surrogate pair - only trail surrogate found. - uCode = UNASSIGNED; - } - - } - } - else if (leadSurrogate !== -1) { - // Incomplete surrogate pair - only lead surrogate found. - nextChar = uCode; uCode = UNASSIGNED; // Write an error, then current char. - leadSurrogate = -1; - } +}; +module.exports = LocalDatastore; - // 2. Convert uCode character. - var dbcsCode = UNASSIGNED; - if (seqObj !== undefined && uCode != UNASSIGNED) { // We are in the middle of the sequence - var resCode = seqObj[uCode]; - if (typeof resCode === 'object') { // Sequence continues. - seqObj = resCode; - continue; +/***/ }), - } else if (typeof resCode == 'number') { // Sequence finished. Write it. - dbcsCode = resCode; +/***/ 61944: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - } else if (resCode == undefined) { // Current character is not part of the sequence. +"use strict"; - // Try default character for this sequence - resCode = seqObj[DEF_CHAR]; - if (resCode !== undefined) { - dbcsCode = resCode; // Found. Write it. - nextChar = uCode; // Current character will be written too in the next iteration. - } else { - // TODO: What if we have no default? (resCode == undefined) - // Then, we should write first char of the sequence as-is and try the rest recursively. - // Didn't do it for now because no encoding has this situation yet. - // Currently, just skip the sequence and write current char. - } - } - seqObj = undefined; - } - else if (uCode >= 0) { // Regular character - var subtable = this.encodeTable[uCode >> 8]; - if (subtable !== undefined) - dbcsCode = subtable[uCode & 0xFF]; - - if (dbcsCode <= SEQ_START) { // Sequence start - seqObj = this.encodeTableSeq[SEQ_START-dbcsCode]; - continue; - } +var DLList, Events, Queues; +DLList = __nccwpck_require__(64792); +Events = __nccwpck_require__(81065); +Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events(this); + this._length = 0; - if (dbcsCode == UNASSIGNED && this.gb18030) { - // Use GB18030 algorithm to find character(s) to write. - var idx = findIdx(this.gb18030.uChars, uCode); - if (idx != -1) { - var dbcsCode = this.gb18030.gbChars[idx] + (uCode - this.gb18030.uChars[idx]); - newBuf[j++] = 0x81 + Math.floor(dbcsCode / 12600); dbcsCode = dbcsCode % 12600; - newBuf[j++] = 0x30 + Math.floor(dbcsCode / 1260); dbcsCode = dbcsCode % 1260; - newBuf[j++] = 0x81 + Math.floor(dbcsCode / 10); dbcsCode = dbcsCode % 10; - newBuf[j++] = 0x30 + dbcsCode; - continue; - } - } - } + this._lists = function () { + var j, ref, results; + results = []; - // 3. Write dbcsCode character. - if (dbcsCode === UNASSIGNED) - dbcsCode = this.defaultCharSingleByte; - - if (dbcsCode < 0x100) { - newBuf[j++] = dbcsCode; - } - else if (dbcsCode < 0x10000) { - newBuf[j++] = dbcsCode >> 8; // high byte - newBuf[j++] = dbcsCode & 0xFF; // low byte - } - else { - newBuf[j++] = dbcsCode >> 16; - newBuf[j++] = (dbcsCode >> 8) & 0xFF; - newBuf[j++] = dbcsCode & 0xFF; - } - } + for (i = j = 1, ref = num_priorities; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { + results.push(new DLList(() => { + return this.incr(); + }, () => { + return this.decr(); + })); + } - this.seqObj = seqObj; - this.leadSurrogate = leadSurrogate; - return newBuf.slice(0, j); -} + return results; + }.call(this); + } -DBCSEncoder.prototype.end = function() { - if (this.leadSurrogate === -1 && this.seqObj === undefined) - return; // All clean. Most often case. + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } - var newBuf = Buffer.alloc(10), j = 0; + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } - if (this.seqObj) { // We're in the sequence. - var dbcsCode = this.seqObj[DEF_CHAR]; - if (dbcsCode !== undefined) { // Write beginning of the sequence. - if (dbcsCode < 0x100) { - newBuf[j++] = dbcsCode; - } - else { - newBuf[j++] = dbcsCode >> 8; // high byte - newBuf[j++] = dbcsCode & 0xFF; // low byte - } - } else { - // See todo above. - } - this.seqObj = undefined; + push(job) { + return this._lists[job.options.priority].push(job); + } + + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; } + } - if (this.leadSurrogate !== -1) { - // Incomplete surrogate pair - only lead surrogate found. - newBuf[j++] = this.defaultCharSingleByte; - this.leadSurrogate = -1; + shiftAll(fn) { + return this._lists.forEach(function (list) { + return list.forEachShift(fn); + }); + } + + getFirst(arr = this._lists) { + var j, len, list; + + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + + if (list.length > 0) { + return list; + } } - - return newBuf.slice(0, j); -} -// Export for testing -DBCSEncoder.prototype.findIdx = findIdx; + return []; + } + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -// == Decoder ================================================================== +}; +module.exports = Queues; -function DBCSDecoder(options, codec) { - // Decoder state - this.nodeIdx = 0; - this.prevBuf = Buffer.alloc(0); +/***/ }), - // Static data - this.decodeTables = codec.decodeTables; - this.decodeTableSeq = codec.decodeTableSeq; - this.defaultCharUnicode = codec.defaultCharUnicode; - this.gb18030 = codec.gb18030; -} +/***/ 28037: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -DBCSDecoder.prototype.write = function(buf) { - var newBuf = Buffer.alloc(buf.length*2), - nodeIdx = this.nodeIdx, - prevBuf = this.prevBuf, prevBufOffset = this.prevBuf.length, - seqStart = -this.prevBuf.length, // idx of the start of current parsed sequence. - uCode; +"use strict"; - if (prevBufOffset > 0) // Make prev buf overlap a little to make it easier to slice later. - prevBuf = Buffer.concat([prevBuf, buf.slice(0, 10)]); - - for (var i = 0, j = 0; i < buf.length; i++) { - var curByte = (i >= 0) ? buf[i] : prevBuf[i + prevBufOffset]; - // Lookup in current trie node. - var uCode = this.decodeTables[nodeIdx][curByte]; +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } - if (uCode >= 0) { - // Normal character, just use it. - } - else if (uCode === UNASSIGNED) { // Unknown char. - // TODO: Callback with seq. - //var curSeq = (seqStart >= 0) ? buf.slice(seqStart, i+1) : prevBuf.slice(seqStart + prevBufOffset, i+1 + prevBufOffset); - i = seqStart; // Try to parse again, after skipping first byte of the sequence ('i' will be incremented by 'for' cycle). - uCode = this.defaultCharUnicode.charCodeAt(0); - } - else if (uCode === GB18030_CODE) { - var curSeq = (seqStart >= 0) ? buf.slice(seqStart, i+1) : prevBuf.slice(seqStart + prevBufOffset, i+1 + prevBufOffset); - var ptr = (curSeq[0]-0x81)*12600 + (curSeq[1]-0x30)*1260 + (curSeq[2]-0x81)*10 + (curSeq[3]-0x30); - var idx = findIdx(this.gb18030.gbChars, ptr); - uCode = this.gb18030.uChars[idx] + ptr - this.gb18030.gbChars[idx]; +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +var Events, RedisConnection, Scripts, parser; +parser = __nccwpck_require__(90651); +Events = __nccwpck_require__(81065); +Scripts = __nccwpck_require__(65206); + +RedisConnection = function () { + class RedisConnection { + constructor(options = {}) { + parser.load(options, this.defaults, this); + + if (this.Redis == null) { + this.Redis = eval("require")("redis"); // Obfuscated or else Webpack/Angular will try to inline the optional redis module. To override this behavior: pass the redis module to Bottleneck as the 'Redis' option. + } + + if (this.Events == null) { + this.Events = new Events(this); + } + + this.terminated = false; + + if (this.client == null) { + this.client = this.Redis.createClient(this.clientOptions); + } + + this.subscriber = this.client.duplicate(); + this.limiters = {}; + this.shas = {}; + this.ready = this.Promise.all([this._setup(this.client, false), this._setup(this.subscriber, true)]).then(() => { + return this._loadScripts(); + }).then(() => { + return { + client: this.client, + subscriber: this.subscriber + }; + }); + } + + _setup(client, sub) { + client.setMaxListeners(0); + return new this.Promise((resolve, reject) => { + client.on("error", e => { + return this.Events.trigger("error", e); + }); + + if (sub) { + client.on("message", (channel, message) => { + var ref; + return (ref = this.limiters[channel]) != null ? ref._store.onMessage(channel, message) : void 0; + }); } - else if (uCode <= NODE_START) { // Go to next trie node. - nodeIdx = NODE_START - uCode; - continue; + + if (client.ready) { + return resolve(); + } else { + return client.once("ready", resolve); } - else if (uCode <= SEQ_START) { // Output a sequence of chars. - var seq = this.decodeTableSeq[SEQ_START - uCode]; - for (var k = 0; k < seq.length - 1; k++) { - uCode = seq[k]; - newBuf[j++] = uCode & 0xFF; - newBuf[j++] = uCode >> 8; + }); + } + + _loadScript(name) { + return new this.Promise((resolve, reject) => { + var payload; + payload = Scripts.payload(name); + return this.client.multi([["script", "load", payload]]).exec((err, replies) => { + if (err != null) { + return reject(err); + } + + this.shas[name] = replies[0]; + return resolve(replies[0]); + }); + }); + } + + _loadScripts() { + return this.Promise.all(Scripts.names.map(k => { + return this._loadScript(k); + })); + } + + __runCommand__(cmd) { + var _this = this; + + return _asyncToGenerator(function* () { + yield _this.ready; + return new _this.Promise((resolve, reject) => { + return _this.client.multi([cmd]).exec_atomic(function (err, replies) { + if (err != null) { + return reject(err); + } else { + return resolve(replies[0]); } - uCode = seq[seq.length-1]; - } - else - throw new Error("iconv-lite internal error: invalid decoding table value " + uCode + " at " + nodeIdx + "/" + curByte); + }); + }); + })(); + } - // Write the character to buffer, handling higher planes using surrogate pair. - if (uCode > 0xFFFF) { - uCode -= 0x10000; - var uCodeLead = 0xD800 + Math.floor(uCode / 0x400); - newBuf[j++] = uCodeLead & 0xFF; - newBuf[j++] = uCodeLead >> 8; + __addLimiter__(instance) { + return this.Promise.all([instance.channel(), instance.channel_client()].map(channel => { + return new this.Promise((resolve, reject) => { + var handler; - uCode = 0xDC00 + uCode % 0x400; - } - newBuf[j++] = uCode & 0xFF; - newBuf[j++] = uCode >> 8; + handler = chan => { + if (chan === channel) { + this.subscriber.removeListener("subscribe", handler); + this.limiters[channel] = instance; + return resolve(); + } + }; - // Reset trie node. - nodeIdx = 0; seqStart = i+1; + this.subscriber.on("subscribe", handler); + return this.subscriber.subscribe(channel); + }); + })); } - this.nodeIdx = nodeIdx; - this.prevBuf = (seqStart >= 0) ? buf.slice(seqStart) : prevBuf.slice(seqStart + prevBufOffset); - return newBuf.slice(0, j).toString('ucs2'); -} + __removeLimiter__(instance) { + var _this2 = this; -DBCSDecoder.prototype.end = function() { - var ret = ''; + return this.Promise.all([instance.channel(), instance.channel_client()].map( + /*#__PURE__*/ + function () { + var _ref = _asyncToGenerator(function* (channel) { + if (!_this2.terminated) { + yield new _this2.Promise((resolve, reject) => { + return _this2.subscriber.unsubscribe(channel, function (err, chan) { + if (err != null) { + return reject(err); + } - // Try to parse all remaining chars. - while (this.prevBuf.length > 0) { - // Skip 1 character in the buffer. - ret += this.defaultCharUnicode; - var buf = this.prevBuf.slice(1); + if (chan === channel) { + return resolve(); + } + }); + }); + } - // Parse remaining as usual. - this.prevBuf = Buffer.alloc(0); - this.nodeIdx = 0; - if (buf.length > 0) - ret += this.write(buf); + return delete _this2.limiters[channel]; + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; + }())); } - this.nodeIdx = 0; - return ret; -} + __scriptArgs__(name, id, args, cb) { + var keys; + keys = Scripts.keys(name, id); + return [this.shas[name], keys.length].concat(keys, args, cb); + } -// Binary search for GB18030. Returns largest i such that table[i] <= val. -function findIdx(table, val) { - if (table[0] > val) - return -1; + __scriptFn__(name) { + return this.client.evalsha.bind(this.client); + } - var l = 0, r = table.length; - while (l < r-1) { // always table[l] <= val < table[r] - var mid = l + Math.floor((r-l+1)/2); - if (table[mid] <= val) - l = mid; - else - r = mid; + disconnect(flush = true) { + var i, k, len, ref; + ref = Object.keys(this.limiters); + + for (i = 0, len = ref.length; i < len; i++) { + k = ref[i]; + clearInterval(this.limiters[k]._store.heartbeat); + } + + this.limiters = {}; + this.terminated = true; + this.client.end(flush); + this.subscriber.end(flush); + return this.Promise.resolve(); } - return l; -} + } + + ; + RedisConnection.prototype.datastore = "redis"; + RedisConnection.prototype.defaults = { + Redis: null, + clientOptions: {}, + client: null, + Promise: Promise, + Events: null + }; + return RedisConnection; +}.call(void 0); +module.exports = RedisConnection; /***/ }), -/***/ 61587: +/***/ 35068: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// Description of supported double byte encodings and aliases. -// Tables are not require()-d until they are needed to speed up library load. -// require()-s are direct to support Browserify. +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } -module.exports = { - - // == Japanese/ShiftJIS ==================================================== - // All japanese encodings are based on JIS X set of standards: - // JIS X 0201 - Single-byte encoding of ASCII + ¥ + Kana chars at 0xA1-0xDF. - // JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes. - // Has several variations in 1978, 1983, 1990 and 1997. - // JIS X 0212 - Supplementary plane of 6067 chars in 94x94 plane. 1990. Effectively dead. - // JIS X 0213 - Extension and modern replacement of 0208 and 0212. Total chars: 11233. - // 2 planes, first is superset of 0208, second - revised 0212. - // Introduced in 2000, revised 2004. Some characters are in Unicode Plane 2 (0x2xxxx) +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } - // Byte encodings are: - // * Shift_JIS: Compatible with 0201, uses not defined chars in top half as lead bytes for double-byte - // encoding of 0208. Lead byte ranges: 0x81-0x9F, 0xE0-0xEF; Trail byte ranges: 0x40-0x7E, 0x80-0x9E, 0x9F-0xFC. - // Windows CP932 is a superset of Shift_JIS. Some companies added more chars, notably KDDI. - // * EUC-JP: Up to 3 bytes per character. Used mostly on *nixes. - // 0x00-0x7F - lower part of 0201 - // 0x8E, 0xA1-0xDF - upper part of 0201 - // (0xA1-0xFE)x2 - 0208 plane (94x94). - // 0x8F, (0xA1-0xFE)x2 - 0212 plane (94x94). - // * JIS X 208: 7-bit, direct encoding of 0208. Byte ranges: 0x21-0x7E (94 values). Uncommon. - // Used as-is in ISO2022 family. - // * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII, - // 0201-1976 Roman, 0208-1978, 0208-1983. - // * ISO2022-JP-1: Adds esc seq for 0212-1990. - // * ISO2022-JP-2: Adds esc seq for GB2313-1980, KSX1001-1992, ISO8859-1, ISO8859-7. - // * ISO2022-JP-3: Adds esc seq for 0201-1976 Kana set, 0213-2000 Planes 1, 2. - // * ISO2022-JP-2004: Adds 0213-2004 Plane 1. - // - // After JIS X 0213 appeared, Shift_JIS-2004, EUC-JISX0213 and ISO2022-JP-2004 followed, with just changing the planes. - // - // Overall, it seems that it's a mess :( http://www8.plala.or.jp/tkubota1/unicode-symbols-map2.html +function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } - 'shiftjis': { - type: '_dbcs', - table: function() { return __nccwpck_require__(94227) }, - encodeAdd: {'\u00a5': 0x5C, '\u203E': 0x7E}, - encodeSkipVals: [{from: 0xED40, to: 0xF940}], - }, - 'csshiftjis': 'shiftjis', - 'mskanji': 'shiftjis', - 'sjis': 'shiftjis', - 'windows31j': 'shiftjis', - 'ms31j': 'shiftjis', - 'xsjis': 'shiftjis', - 'windows932': 'shiftjis', - 'ms932': 'shiftjis', - '932': 'shiftjis', - 'cp932': 'shiftjis', +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } - 'eucjp': { - type: '_dbcs', - table: function() { return __nccwpck_require__(99594) }, - encodeAdd: {'\u00a5': 0x5C, '\u203E': 0x7E}, - }, +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } - // TODO: KDDI extension to Shift_JIS - // TODO: IBM CCSID 942 = CP932, but F0-F9 custom chars and other char changes. - // TODO: IBM CCSID 943 = Shift_JIS = CP932 with original Shift_JIS lower 128 chars. +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +var BottleneckError, IORedisConnection, RedisConnection, RedisDatastore, parser; +parser = __nccwpck_require__(90651); +BottleneckError = __nccwpck_require__(88185); +RedisConnection = __nccwpck_require__(28037); +IORedisConnection = __nccwpck_require__(41725); +RedisDatastore = class RedisDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.originalId = this.instance.id; + this.clientId = this.instance._randomIndex(); + parser.load(storeInstanceOptions, storeInstanceOptions, this); + this.clients = {}; + this.capacityPriorityCounters = {}; + this.sharedConnection = this.connection != null; - // == Chinese/GBK ========================================================== - // http://en.wikipedia.org/wiki/GBK - // We mostly implement W3C recommendation: https://www.w3.org/TR/encoding/#gbk-encoder + if (this.connection == null) { + this.connection = this.instance.datastore === "redis" ? new RedisConnection({ + Redis: this.Redis, + clientOptions: this.clientOptions, + Promise: this.Promise, + Events: this.instance.Events + }) : this.instance.datastore === "ioredis" ? new IORedisConnection({ + Redis: this.Redis, + clientOptions: this.clientOptions, + clusterNodes: this.clusterNodes, + Promise: this.Promise, + Events: this.instance.Events + }) : void 0; + } - // Oldest GB2312 (1981, ~7600 chars) is a subset of CP936 - 'gb2312': 'cp936', - 'gb231280': 'cp936', - 'gb23121980': 'cp936', - 'csgb2312': 'cp936', - 'csiso58gb231280': 'cp936', - 'euccn': 'cp936', + this.instance.connection = this.connection; + this.instance.datastore = this.connection.datastore; + this.ready = this.connection.ready.then(clients => { + this.clients = clients; + return this.runScript("init", this.prepareInitSettings(this.clearDatastore)); + }).then(() => { + return this.connection.__addLimiter__(this.instance); + }).then(() => { + return this.runScript("register_client", [this.instance.queued()]); + }).then(() => { + var base; - // Microsoft's CP936 is a subset and approximation of GBK. - 'windows936': 'cp936', - 'ms936': 'cp936', - '936': 'cp936', - 'cp936': { - type: '_dbcs', - table: function() { return __nccwpck_require__(51716) }, - }, + if (typeof (base = this.heartbeat = setInterval(() => { + return this.runScript("heartbeat", []).catch(e => { + return this.instance.Events.trigger("error", e); + }); + }, this.heartbeatInterval)).unref === "function") { + base.unref(); + } - // GBK (~22000 chars) is an extension of CP936 that added user-mapped chars and some other. - 'gbk': { - type: '_dbcs', - table: function() { return (__nccwpck_require__(51716).concat)(__nccwpck_require__(18174)) }, - }, - 'xgbk': 'gbk', - 'isoir58': 'gbk', + return this.clients; + }); + } - // GB18030 is an algorithmic extension of GBK. - // Main source: https://www.w3.org/TR/encoding/#gbk-encoder - // http://icu-project.org/docs/papers/gb18030.html - // http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml - // http://www.khngai.com/chinese/charmap/tblgbk.php?page=0 - 'gb18030': { - type: '_dbcs', - table: function() { return (__nccwpck_require__(51716).concat)(__nccwpck_require__(18174)) }, - gb18030: function() { return __nccwpck_require__(71565) }, - encodeSkipVals: [0x80], - encodeAdd: {'€': 0xA2E3}, - }, + __publish__(message) { + var _this = this; - 'chinese': 'gb18030', + return _asyncToGenerator(function* () { + var client; + var _ref = yield _this.ready; - // == Korean =============================================================== - // EUC-KR, KS_C_5601 and KS X 1001 are exactly the same. - 'windows949': 'cp949', - 'ms949': 'cp949', - '949': 'cp949', - 'cp949': { - type: '_dbcs', - table: function() { return __nccwpck_require__(95578) }, - }, + client = _ref.client; + return client.publish(_this.instance.channel(), `message:${message.toString()}`); + })(); + } - 'cseuckr': 'cp949', - 'csksc56011987': 'cp949', - 'euckr': 'cp949', - 'isoir149': 'cp949', - 'korean': 'cp949', - 'ksc56011987': 'cp949', - 'ksc56011989': 'cp949', - 'ksc5601': 'cp949', + onMessage(channel, message) { + var _this2 = this; + return _asyncToGenerator(function* () { + var capacity, counter, data, drained, e, newCapacity, pos, priorityClient, rawCapacity, type; - // == Big5/Taiwan/Hong Kong ================================================ - // There are lots of tables for Big5 and cp950. Please see the following links for history: - // http://moztw.org/docs/big5/ http://www.haible.de/bruno/charsets/conversion-tables/Big5.html - // Variations, in roughly number of defined chars: - // * Windows CP 950: Microsoft variant of Big5. Canonical: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT - // * Windows CP 951: Microsoft variant of Big5-HKSCS-2001. Seems to be never public. http://me.abelcheung.org/articles/research/what-is-cp951/ - // * Big5-2003 (Taiwan standard) almost superset of cp950. - // * Unicode-at-on (UAO) / Mozilla 1.8. Falling out of use on the Web. Not supported by other browsers. - // * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard. - // many unicode code points moved from PUA to Supplementary plane (U+2XXXX) over the years. - // Plus, it has 4 combining sequences. - // Seems that Mozilla refused to support it for 10 yrs. https://bugzilla.mozilla.org/show_bug.cgi?id=162431 https://bugzilla.mozilla.org/show_bug.cgi?id=310299 - // because big5-hkscs is the only encoding to include astral characters in non-algorithmic way. - // Implementations are not consistent within browsers; sometimes labeled as just big5. - // MS Internet Explorer switches from big5 to big5-hkscs when a patch applied. - // Great discussion & recap of what's going on https://bugzilla.mozilla.org/show_bug.cgi?id=912470#c31 - // In the encoder, it might make sense to support encoding old PUA mappings to Big5 bytes seq-s. - // Official spec: http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/terms/doc/2003cmp_2008.txt - // http://www.ogcio.gov.hk/tc/business/tech_promotion/ccli/terms/doc/hkscs-2008-big5-iso.txt - // - // Current understanding of how to deal with Big5(-HKSCS) is in the Encoding Standard, http://encoding.spec.whatwg.org/#big5-encoder - // Unicode mapping (http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT) is said to be wrong. + try { + pos = message.indexOf(":"); + var _ref2 = [message.slice(0, pos), message.slice(pos + 1)]; + type = _ref2[0]; + data = _ref2[1]; - 'windows950': 'cp950', - 'ms950': 'cp950', - '950': 'cp950', - 'cp950': { - type: '_dbcs', - table: function() { return __nccwpck_require__(29856) }, - }, + if (type === "capacity") { + return yield _this2.instance._drainAll(data.length > 0 ? ~~data : void 0); + } else if (type === "capacity-priority") { + var _data$split = data.split(":"); - // Big5 has many variations and is an extension of cp950. We use Encoding Standard's as a consensus. - 'big5': 'big5hkscs', - 'big5hkscs': { - type: '_dbcs', - table: function() { return (__nccwpck_require__(29856).concat)(__nccwpck_require__(31479)) }, - encodeSkipVals: [0xa2cc], - }, + var _data$split2 = _slicedToArray(_data$split, 3); - 'cnbig5': 'big5hkscs', - 'csbig5': 'big5hkscs', - 'xxbig5': 'big5hkscs', -}; + rawCapacity = _data$split2[0]; + priorityClient = _data$split2[1]; + counter = _data$split2[2]; + capacity = rawCapacity.length > 0 ? ~~rawCapacity : void 0; + if (priorityClient === _this2.clientId) { + drained = yield _this2.instance._drainAll(capacity); + newCapacity = capacity != null ? capacity - (drained || 0) : ""; + return yield _this2.clients.client.publish(_this2.instance.channel(), `capacity-priority:${newCapacity}::${counter}`); + } else if (priorityClient === "") { + clearTimeout(_this2.capacityPriorityCounters[counter]); + delete _this2.capacityPriorityCounters[counter]; + return _this2.instance._drainAll(capacity); + } else { + return _this2.capacityPriorityCounters[counter] = setTimeout( + /*#__PURE__*/ + _asyncToGenerator(function* () { + var e; -/***/ }), + try { + delete _this2.capacityPriorityCounters[counter]; + yield _this2.runScript("blacklist_client", [priorityClient]); + return yield _this2.instance._drainAll(capacity); + } catch (error) { + e = error; + return _this2.instance.Events.trigger("error", e); + } + }), 1000); + } + } else if (type === "message") { + return _this2.instance.Events.trigger("message", data); + } else if (type === "blocked") { + return yield _this2.instance._dropAllQueued(); + } + } catch (error) { + e = error; + return _this2.instance.Events.trigger("error", e); + } + })(); + } -/***/ 35760: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + __disconnect__(flush) { + clearInterval(this.heartbeat); -"use strict"; + if (this.sharedConnection) { + return this.connection.__removeLimiter__(this.instance); + } else { + return this.connection.disconnect(flush); + } + } + runScript(name, args) { + var _this3 = this; -// Update this array if you add/rename/remove files in this directory. -// We support Browserify by skipping automatic module discovery and requiring modules directly. -var modules = [ - __nccwpck_require__(77319), - __nccwpck_require__(53154), - __nccwpck_require__(50256), - __nccwpck_require__(74274), - __nccwpck_require__(83346), - __nccwpck_require__(24542), - __nccwpck_require__(80961), - __nccwpck_require__(61587), -]; + return _asyncToGenerator(function* () { + if (!(name === "init" || name === "register_client")) { + yield _this3.ready; + } -// Put all encoding/alias/codec definitions to single object and export it. -for (var i = 0; i < modules.length; i++) { - var module = modules[i]; - for (var enc in module) - if (Object.prototype.hasOwnProperty.call(module, enc)) - exports[enc] = module[enc]; -} + return new _this3.Promise((resolve, reject) => { + var all_args, arr; + all_args = [Date.now(), _this3.clientId].concat(args); + _this3.instance.Events.trigger("debug", `Calling Redis script: ${name}.lua`, all_args); -/***/ }), + arr = _this3.connection.__scriptArgs__(name, _this3.originalId, all_args, function (err, replies) { + if (err != null) { + return reject(err); + } -/***/ 77319: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return resolve(replies); + }); + return _this3.connection.__scriptFn__(name)(...arr); + }).catch(e => { + if (e.message === "SETTINGS_KEY_NOT_FOUND") { + if (name === "heartbeat") { + return _this3.Promise.resolve(); + } else { + return _this3.runScript("init", _this3.prepareInitSettings(false)).then(() => { + return _this3.runScript(name, args); + }); + } + } else if (e.message === "UNKNOWN_CLIENT") { + return _this3.runScript("register_client", [_this3.instance.queued()]).then(() => { + return _this3.runScript(name, args); + }); + } else { + return _this3.Promise.reject(e); + } + }); + })(); + } -"use strict"; + prepareArray(arr) { + var i, len, results, x; + results = []; -var Buffer = (__nccwpck_require__(70159).Buffer); + for (i = 0, len = arr.length; i < len; i++) { + x = arr[i]; + results.push(x != null ? x.toString() : ""); + } -// Export Node.js internal encodings. + return results; + } -module.exports = { - // Encodings - utf8: { type: "_internal", bomAware: true}, - cesu8: { type: "_internal", bomAware: true}, - unicode11utf8: "utf8", + prepareObject(obj) { + var arr, k, v; + arr = []; - ucs2: { type: "_internal", bomAware: true}, - utf16le: "ucs2", + for (k in obj) { + v = obj[k]; + arr.push(k, v != null ? v.toString() : ""); + } - binary: { type: "_internal" }, - base64: { type: "_internal" }, - hex: { type: "_internal" }, + return arr; + } - // Codec. - _internal: InternalCodec, -}; + prepareInitSettings(clear) { + var args; + args = this.prepareObject(Object.assign({}, this.storeOptions, { + id: this.originalId, + version: this.instance.version, + groupTimeout: this.timeout, + clientTimeout: this.clientTimeout + })); + args.unshift(clear ? 1 : 0, this.instance.version); + return args; + } -//------------------------------------------------------------------------------ + convertBool(b) { + return !!b; + } -function InternalCodec(codecOptions, iconv) { - this.enc = codecOptions.encodingName; - this.bomAware = codecOptions.bomAware; + __updateSettings__(options) { + var _this4 = this; - if (this.enc === "base64") - this.encoder = InternalEncoderBase64; - else if (this.enc === "cesu8") { - this.enc = "utf8"; // Use utf8 for decoding. - this.encoder = InternalEncoderCesu8; + return _asyncToGenerator(function* () { + yield _this4.runScript("update_settings", _this4.prepareObject(options)); + return parser.overwrite(options, options, _this4.storeOptions); + })(); + } - // Add decoder for versions of Node not supporting CESU-8 - if (Buffer.from('eda0bdedb2a9', 'hex').toString() !== '💩') { - this.decoder = InternalDecoderCesu8; - this.defaultCharUnicode = iconv.defaultCharUnicode; - } - } -} + __running__() { + return this.runScript("running", []); + } -InternalCodec.prototype.encoder = InternalEncoder; -InternalCodec.prototype.decoder = InternalDecoder; + __queued__() { + return this.runScript("queued", []); + } -//------------------------------------------------------------------------------ + __done__() { + return this.runScript("done", []); + } -// We use node.js internal decoder. Its signature is the same as ours. -var StringDecoder = (__nccwpck_require__(13193).StringDecoder); + __groupCheck__() { + var _this5 = this; -if (!StringDecoder.prototype.end) // Node v0.8 doesn't have this method. - StringDecoder.prototype.end = function() {}; + return _asyncToGenerator(function* () { + return _this5.convertBool((yield _this5.runScript("group_check", []))); + })(); + } + __incrementReservoir__(incr) { + return this.runScript("increment_reservoir", [incr]); + } -function InternalDecoder(options, codec) { - StringDecoder.call(this, codec.enc); -} + __currentReservoir__() { + return this.runScript("current_reservoir", []); + } -InternalDecoder.prototype = StringDecoder.prototype; + __check__(weight) { + var _this6 = this; + return _asyncToGenerator(function* () { + return _this6.convertBool((yield _this6.runScript("check", _this6.prepareArray([weight])))); + })(); + } -//------------------------------------------------------------------------------ -// Encoder is mostly trivial + __register__(index, weight, expiration) { + var _this7 = this; -function InternalEncoder(options, codec) { - this.enc = codec.enc; -} + return _asyncToGenerator(function* () { + var reservoir, success, wait; -InternalEncoder.prototype.write = function(str) { - return Buffer.from(str, this.enc); -} + var _ref4 = yield _this7.runScript("register", _this7.prepareArray([index, weight, expiration])); -InternalEncoder.prototype.end = function() { -} + var _ref5 = _slicedToArray(_ref4, 3); + success = _ref5[0]; + wait = _ref5[1]; + reservoir = _ref5[2]; + return { + success: _this7.convertBool(success), + wait, + reservoir + }; + })(); + } -//------------------------------------------------------------------------------ -// Except base64 encoder, which must keep its state. + __submit__(queueLength, weight) { + var _this8 = this; -function InternalEncoderBase64(options, codec) { - this.prevStr = ''; -} + return _asyncToGenerator(function* () { + var blocked, e, maxConcurrent, overweight, reachedHWM, strategy; -InternalEncoderBase64.prototype.write = function(str) { - str = this.prevStr + str; - var completeQuads = str.length - (str.length % 4); - this.prevStr = str.slice(completeQuads); - str = str.slice(0, completeQuads); + try { + var _ref6 = yield _this8.runScript("submit", _this8.prepareArray([queueLength, weight])); - return Buffer.from(str, "base64"); -} + var _ref7 = _slicedToArray(_ref6, 3); -InternalEncoderBase64.prototype.end = function() { - return Buffer.from(this.prevStr, "base64"); -} + reachedHWM = _ref7[0]; + blocked = _ref7[1]; + strategy = _ref7[2]; + return { + reachedHWM: _this8.convertBool(reachedHWM), + blocked: _this8.convertBool(blocked), + strategy + }; + } catch (error) { + e = error; + if (e.message.indexOf("OVERWEIGHT") === 0) { + var _e$message$split = e.message.split(":"); -//------------------------------------------------------------------------------ -// CESU-8 encoder is also special. + var _e$message$split2 = _slicedToArray(_e$message$split, 3); -function InternalEncoderCesu8(options, codec) { -} + overweight = _e$message$split2[0]; + weight = _e$message$split2[1]; + maxConcurrent = _e$message$split2[2]; + throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${maxConcurrent}`); + } else { + throw e; + } + } + })(); + } -InternalEncoderCesu8.prototype.write = function(str) { - var buf = Buffer.alloc(str.length * 3), bufIdx = 0; - for (var i = 0; i < str.length; i++) { - var charCode = str.charCodeAt(i); - // Naive implementation, but it works because CESU-8 is especially easy - // to convert from UTF-16 (which all JS strings are encoded in). - if (charCode < 0x80) - buf[bufIdx++] = charCode; - else if (charCode < 0x800) { - buf[bufIdx++] = 0xC0 + (charCode >>> 6); - buf[bufIdx++] = 0x80 + (charCode & 0x3f); - } - else { // charCode will always be < 0x10000 in javascript. - buf[bufIdx++] = 0xE0 + (charCode >>> 12); - buf[bufIdx++] = 0x80 + ((charCode >>> 6) & 0x3f); - buf[bufIdx++] = 0x80 + (charCode & 0x3f); - } + __free__(index, weight) { + var _this9 = this; + + return _asyncToGenerator(function* () { + var running; + running = yield _this9.runScript("free", _this9.prepareArray([index])); + return { + running + }; + })(); + } + +}; +module.exports = RedisDatastore; + +/***/ }), + +/***/ 65206: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +var headers, lua, templates; +lua = __nccwpck_require__(79583); +headers = { + refs: lua["refs.lua"], + validate_keys: lua["validate_keys.lua"], + validate_client: lua["validate_client.lua"], + refresh_expiration: lua["refresh_expiration.lua"], + process_tick: lua["process_tick.lua"], + conditions_check: lua["conditions_check.lua"], + get_time: lua["get_time.lua"] +}; + +exports.allKeys = function (id) { + return [ + /* + HASH + */ + `b_${id}_settings`, + /* + HASH + job index -> weight + */ + `b_${id}_job_weights`, + /* + ZSET + job index -> expiration + */ + `b_${id}_job_expirations`, + /* + HASH + job index -> client + */ + `b_${id}_job_clients`, + /* + ZSET + client -> sum running + */ + `b_${id}_client_running`, + /* + HASH + client -> num queued + */ + `b_${id}_client_num_queued`, + /* + ZSET + client -> last job registered + */ + `b_${id}_client_last_registered`, + /* + ZSET + client -> last seen + */ + `b_${id}_client_last_seen`]; +}; + +templates = { + init: { + keys: exports.allKeys, + headers: ["process_tick"], + refresh_expiration: true, + code: lua["init.lua"] + }, + group_check: { + keys: exports.allKeys, + headers: [], + refresh_expiration: false, + code: lua["group_check.lua"] + }, + register_client: { + keys: exports.allKeys, + headers: ["validate_keys"], + refresh_expiration: false, + code: lua["register_client.lua"] + }, + blacklist_client: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client"], + refresh_expiration: false, + code: lua["blacklist_client.lua"] + }, + heartbeat: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client", "process_tick"], + refresh_expiration: false, + code: lua["heartbeat.lua"] + }, + update_settings: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client", "process_tick"], + refresh_expiration: true, + code: lua["update_settings.lua"] + }, + running: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client", "process_tick"], + refresh_expiration: false, + code: lua["running.lua"] + }, + queued: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client"], + refresh_expiration: false, + code: lua["queued.lua"] + }, + done: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client", "process_tick"], + refresh_expiration: false, + code: lua["done.lua"] + }, + check: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client", "process_tick", "conditions_check"], + refresh_expiration: false, + code: lua["check.lua"] + }, + submit: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client", "process_tick", "conditions_check"], + refresh_expiration: true, + code: lua["submit.lua"] + }, + register: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client", "process_tick", "conditions_check"], + refresh_expiration: true, + code: lua["register.lua"] + }, + free: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client", "process_tick"], + refresh_expiration: true, + code: lua["free.lua"] + }, + current_reservoir: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client", "process_tick"], + refresh_expiration: false, + code: lua["current_reservoir.lua"] + }, + increment_reservoir: { + keys: exports.allKeys, + headers: ["validate_keys", "validate_client", "process_tick"], + refresh_expiration: true, + code: lua["increment_reservoir.lua"] + } +}; +exports.names = Object.keys(templates); + +exports.keys = function (name, id) { + return templates[name].keys(id); +}; + +exports.payload = function (name) { + var template; + template = templates[name]; + return Array.prototype.concat(headers.refs, template.headers.map(function (h) { + return headers[h]; + }), template.refresh_expiration ? headers.refresh_expiration : "", template.code).join("\n"); +}; + +/***/ }), + +/***/ 72878: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +var BottleneckError, States; +BottleneckError = __nccwpck_require__(88185); +States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function () { + return 0; + }); + } + + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + + if (current != null && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; } - return buf.slice(0, bufIdx); -} + } -InternalEncoderCesu8.prototype.end = function() { -} + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } -//------------------------------------------------------------------------------ -// CESU-8 decoder is not implemented in Node v4.0+ + remove(id) { + var current; + current = this._jobs[id]; -function InternalDecoderCesu8(options, codec) { - this.acc = 0; - this.contBytes = 0; - this.accBytes = 0; - this.defaultCharUnicode = codec.defaultCharUnicode; -} + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } -InternalDecoderCesu8.prototype.write = function(buf) { - var acc = this.acc, contBytes = this.contBytes, accBytes = this.accBytes, - res = ''; - for (var i = 0; i < buf.length; i++) { - var curByte = buf[i]; - if ((curByte & 0xC0) !== 0x80) { // Leading byte - if (contBytes > 0) { // Previous code is invalid - res += this.defaultCharUnicode; - contBytes = 0; - } + return current != null; + } - if (curByte < 0x80) { // Single-byte code - res += String.fromCharCode(curByte); - } else if (curByte < 0xE0) { // Two-byte code - acc = curByte & 0x1F; - contBytes = 1; accBytes = 1; - } else if (curByte < 0xF0) { // Three-byte code - acc = curByte & 0x0F; - contBytes = 2; accBytes = 1; - } else { // Four or more are not supported for CESU-8. - res += this.defaultCharUnicode; - } - } else { // Continuation byte - if (contBytes > 0) { // We're waiting for it. - acc = (acc << 6) | (curByte & 0x3f); - contBytes--; accBytes++; - if (contBytes === 0) { - // Check for overlong encoding, but support Modified UTF-8 (encoding NULL as C0 80) - if (accBytes === 2 && acc < 0x80 && acc > 0) - res += this.defaultCharUnicode; - else if (accBytes === 3 && acc < 0x800) - res += this.defaultCharUnicode; - else - // Actually add character. - res += String.fromCharCode(acc); - } - } else { // Unexpected continuation byte - res += this.defaultCharUnicode; - } + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } + + statusJobs(status) { + var k, pos, ref, results, v; + + if (status != null) { + pos = this.status.indexOf(status); + + if (pos < 0) { + throw new BottleneckError(`status must be one of ${this.status.join(', ')}`); + } + + ref = this._jobs; + results = []; + + for (k in ref) { + v = ref[k]; + + if (v === pos) { + results.push(k); } + } + + return results; + } else { + return Object.keys(this._jobs); } - this.acc = acc; this.contBytes = contBytes; this.accBytes = accBytes; - return res; -} + } -InternalDecoderCesu8.prototype.end = function() { - var res = 0; - if (this.contBytes > 0) - res += this.defaultCharUnicode; - return res; -} + statusCounts() { + return this.counts.reduce((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }, {}); + } +}; +module.exports = States; /***/ }), -/***/ 74274: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 33923: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -var Buffer = (__nccwpck_require__(70159).Buffer); -// Single-byte codec. Needs a 'chars' string parameter that contains 256 or 128 chars that -// correspond to encoded bytes (if 128 - then lower half is ASCII). +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } -exports._sbcs = SBCSCodec; -function SBCSCodec(codecOptions, iconv) { - if (!codecOptions) - throw new Error("SBCS codec is called without the data.") - - // Prepare char buffer for decoding. - if (!codecOptions.chars || (codecOptions.chars.length !== 128 && codecOptions.chars.length !== 256)) - throw new Error("Encoding '"+codecOptions.type+"' has incorrect 'chars' (must be of len 128 or 256)"); - - if (codecOptions.chars.length === 128) { - var asciiString = ""; - for (var i = 0; i < 128; i++) - asciiString += String.fromCharCode(i); - codecOptions.chars = asciiString + codecOptions.chars; - } +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } - this.decodeBuf = Buffer.from(codecOptions.chars, 'ucs2'); - - // Encoding buffer. - var encodeBuf = Buffer.alloc(65536, iconv.defaultCharSingleByte.charCodeAt(0)); +var DLList, Sync; +DLList = __nccwpck_require__(64792); +Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList(); + } - for (var i = 0; i < codecOptions.chars.length; i++) - encodeBuf[codecOptions.chars.charCodeAt(i)] = i; + isEmpty() { + return this._queue.length === 0; + } - this.encodeBuf = encodeBuf; -} + _tryToRun() { + var _this = this; -SBCSCodec.prototype.encoder = SBCSEncoder; -SBCSCodec.prototype.decoder = SBCSDecoder; + return _asyncToGenerator(function* () { + var args, cb, error, reject, resolve, returned, task; + if (_this._running < 1 && _this._queue.length > 0) { + _this._running++; -function SBCSEncoder(options, codec) { - this.encodeBuf = codec.encodeBuf; -} + var _this$_queue$shift = _this._queue.shift(); -SBCSEncoder.prototype.write = function(str) { - var buf = Buffer.alloc(str.length); - for (var i = 0; i < str.length; i++) - buf[i] = this.encodeBuf[str.charCodeAt(i)]; - - return buf; -} + task = _this$_queue$shift.task; + args = _this$_queue$shift.args; + resolve = _this$_queue$shift.resolve; + reject = _this$_queue$shift.reject; + cb = yield _asyncToGenerator(function* () { + try { + returned = yield task(...args); + return function () { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function () { + return reject(error); + }; + } + })(); + _this._running--; -SBCSEncoder.prototype.end = function() { -} + _this._tryToRun(); + return cb(); + } + })(); + } -function SBCSDecoder(options, codec) { - this.decodeBuf = codec.decodeBuf; -} + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function (_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); -SBCSDecoder.prototype.write = function(buf) { - // Strings are immutable in JS -> we use ucs2 buffer to speed up computations. - var decodeBuf = this.decodeBuf; - var newBuf = Buffer.alloc(buf.length*2); - var idx1 = 0, idx2 = 0; - for (var i = 0; i < buf.length; i++) { - idx1 = buf[i]*2; idx2 = i*2; - newBuf[idx2] = decodeBuf[idx1]; - newBuf[idx2+1] = decodeBuf[idx1+1]; - } - return newBuf.toString('ucs2'); -} + this._queue.push({ + task, + args, + resolve, + reject + }); -SBCSDecoder.prototype.end = function() { -} + this._tryToRun(); + + return promise; + } +}; +module.exports = Sync; /***/ }), -/***/ 24542: -/***/ ((module) => { +/***/ 1666: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// Generated data for sbcs codec. Don't edit manually. Regenerate using generation/gen-sbcs.js script. -module.exports = { - "437": "cp437", - "737": "cp737", - "775": "cp775", - "850": "cp850", - "852": "cp852", - "855": "cp855", - "856": "cp856", - "857": "cp857", - "858": "cp858", - "860": "cp860", - "861": "cp861", - "862": "cp862", - "863": "cp863", - "864": "cp864", - "865": "cp865", - "866": "cp866", - "869": "cp869", - "874": "windows874", - "922": "cp922", - "1046": "cp1046", - "1124": "cp1124", - "1125": "cp1125", - "1129": "cp1129", - "1133": "cp1133", - "1161": "cp1161", - "1162": "cp1162", - "1163": "cp1163", - "1250": "windows1250", - "1251": "windows1251", - "1252": "windows1252", - "1253": "windows1253", - "1254": "windows1254", - "1255": "windows1255", - "1256": "windows1256", - "1257": "windows1257", - "1258": "windows1258", - "28591": "iso88591", - "28592": "iso88592", - "28593": "iso88593", - "28594": "iso88594", - "28595": "iso88595", - "28596": "iso88596", - "28597": "iso88597", - "28598": "iso88598", - "28599": "iso88599", - "28600": "iso885910", - "28601": "iso885911", - "28603": "iso885913", - "28604": "iso885914", - "28605": "iso885915", - "28606": "iso885916", - "windows874": { - "type": "_sbcs", - "chars": "€����…�����������‘’“”•–—�������� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" - }, - "win874": "windows874", - "cp874": "windows874", - "windows1250": { - "type": "_sbcs", - "chars": "€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" - }, - "win1250": "windows1250", - "cp1250": "windows1250", - "windows1251": { - "type": "_sbcs", - "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" - }, - "win1251": "windows1251", - "cp1251": "windows1251", - "windows1252": { - "type": "_sbcs", - "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "win1252": "windows1252", - "cp1252": "windows1252", - "windows1253": { - "type": "_sbcs", - "chars": "€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" - }, - "win1253": "windows1253", - "cp1253": "windows1253", - "windows1254": { - "type": "_sbcs", - "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" - }, - "win1254": "windows1254", - "cp1254": "windows1254", - "windows1255": { - "type": "_sbcs", - "chars": "€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹֺֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" - }, - "win1255": "windows1255", - "cp1255": "windows1255", - "windows1256": { - "type": "_sbcs", - "chars": "€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œ‌‍ں ،¢£¤¥¦§¨©ھ«¬­®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûü‎‏ے" - }, - "win1256": "windows1256", - "cp1256": "windows1256", - "windows1257": { - "type": "_sbcs", - "chars": "€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙" - }, - "win1257": "windows1257", - "cp1257": "windows1257", - "windows1258": { - "type": "_sbcs", - "chars": "€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" - }, - "win1258": "windows1258", - "cp1258": "windows1258", - "iso88591": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "cp28591": "iso88591", - "iso88592": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ą˘Ł¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" - }, - "cp28592": "iso88592", - "iso88593": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ħ˘£¤�Ĥ§¨İŞĞĴ­�Ż°ħ²³´µĥ·¸ışğĵ½�żÀÁÂ�ÄĊĈÇÈÉÊËÌÍÎÏ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ĝùúûüŭŝ˙" - }, - "cp28593": "iso88593", - "iso88594": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĸŖ¤ĨĻ§¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙" - }, - "cp28594": "iso88594", - "iso88595": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ" - }, - "cp28595": "iso88595", - "iso88596": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ���¤�������،­�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـفقكلمنهوىيًٌٍَُِّْ�������������" - }, - "cp28596": "iso88596", - "iso88597": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ‘’£€₯¦§¨©ͺ«¬­�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" - }, - "cp28597": "iso88597", - "iso88598": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" - }, - "cp28598": "iso88598", - "iso88599": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" - }, - "cp28599": "iso88599", - "iso885910": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĒĢĪĨĶ§ĻĐŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ" - }, - "cp28600": "iso885910", - "iso885911": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" - }, - "cp28601": "iso885911", - "iso885913": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ”¢£¤„¦§Ø©Ŗ«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’" - }, - "cp28603": "iso885913", - "iso885914": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ" - }, - "cp28604": "iso885914", - "iso885915": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "cp28605": "iso885915", - "iso885916": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄąŁ€„Š§š©Ș«Ź­źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ" - }, - "cp28606": "iso885916", - "cp437": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm437": "cp437", - "csibm437": "cp437", - "cp737": { - "type": "_sbcs", - "chars": "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ " - }, - "ibm737": "cp737", - "csibm737": "cp737", - "cp775": { - "type": "_sbcs", - "chars": "ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£ØפĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’­±“¾¶§÷„°∙·¹³²■ " - }, - "ibm775": "cp775", - "csibm775": "cp775", - "cp850": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " - }, - "ibm850": "cp850", - "csibm850": "cp850", - "cp852": { - "type": "_sbcs", - "chars": "ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´­˝˛ˇ˘§÷¸°¨˙űŘř■ " - }, - "ibm852": "cp852", - "csibm852": "cp852", - "cp855": { - "type": "_sbcs", - "chars": "ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№­ыЫзЗшШэЭщЩчЧ§■ " - }, - "ibm855": "cp855", - "csibm855": "cp855", - "cp856": { - "type": "_sbcs", - "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת�£�×����������®¬½¼�«»░▒▓│┤���©╣║╗╝¢¥┐└┴┬├─┼��╚╔╩╦╠═╬¤���������┘┌█▄¦�▀������µ�������¯´­±‗¾¶§÷¸°¨·¹³²■ " - }, - "ibm856": "cp856", - "csibm856": "cp856", - "cp857": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ�ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´­±�¾¶§÷¸°¨·¹³²■ " - }, - "ibm857": "cp857", - "csibm857": "cp857", - "cp858": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " - }, - "ibm858": "cp858", - "csibm858": "cp858", - "cp860": { - "type": "_sbcs", - "chars": "ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm860": "cp860", - "csibm860": "cp860", - "cp861": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm861": "cp861", - "csibm861": "cp861", - "cp862": { - "type": "_sbcs", - "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm862": "cp862", - "csibm862": "cp862", - "cp863": { - "type": "_sbcs", - "chars": "ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm863": "cp863", - "csibm863": "cp863", - "cp864": { - "type": "_sbcs", - "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$٪&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~°·∙√▒─│┼┤┬├┴┐┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ­ﺂ£¤ﺄ��ﺎﺏﺕﺙ،ﺝﺡﺥ٠١٢٣٤٥٦٧٨٩ﻑ؛ﺱﺵﺹ؟¢ﺀﺁﺃﺅﻊﺋﺍﺑﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻁﻅﻋﻏ¦¬÷×ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎﻍﻡﹽّﻥﻩﻬﻰﻲﻐﻕﻵﻶﻝﻙﻱ■�" - }, - "ibm864": "cp864", - "csibm864": "cp864", - "cp865": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm865": "cp865", - "csibm865": "cp865", - "cp866": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ " - }, - "ibm866": "cp866", - "csibm866": "cp866", - "cp869": { - "type": "_sbcs", - "chars": "������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄­±υφχ§ψ΅°¨ωϋΰώ■ " - }, - "ibm869": "cp869", - "csibm869": "cp869", - "cp922": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®‾°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŠÑÒÓÔÕÖ×ØÙÚÛÜÝŽßàáâãäåæçèéêëìíîïšñòóôõö÷øùúûüýžÿ" - }, - "ibm922": "cp922", - "csibm922": "cp922", - "cp1046": { - "type": "_sbcs", - "chars": "ﺈ×÷ﹱˆ■│─┐┌└┘ﹹﹻﹽﹿﹷﺊﻰﻳﻲﻎﻏﻐﻶﻸﻺﻼ ¤ﺋﺑﺗﺛﺟﺣ،­ﺧﺳ٠١٢٣٤٥٦٧٨٩ﺷ؛ﺻﺿﻊ؟ﻋءآأؤإئابةتثجحخدذرزسشصضطﻇعغﻌﺂﺄﺎﻓـفقكلمنهوىيًٌٍَُِّْﻗﻛﻟﻵﻷﻹﻻﻣﻧﻬﻩ�" - }, - "ibm1046": "cp1046", - "csibm1046": "cp1046", - "cp1124": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂҐЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђґєѕіїјљњћќ§ўџ" - }, - "ibm1124": "cp1124", - "csibm1124": "cp1124", - "cp1125": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёҐґЄєІіЇї·√№¤■ " - }, - "ibm1125": "cp1125", - "csibm1125": "cp1125", - "cp1129": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" - }, - "ibm1129": "cp1129", - "csibm1129": "cp1129", - "cp1133": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ກຂຄງຈສຊຍດຕຖທນບປຜຝພຟມຢຣລວຫອຮ���ຯະາຳິີຶືຸູຼັົຽ���ເແໂໃໄ່້໊໋໌ໍໆ�ໜໝ₭����������������໐໑໒໓໔໕໖໗໘໙��¢¬¦�" - }, - "ibm1133": "cp1133", - "csibm1133": "cp1133", - "cp1161": { - "type": "_sbcs", - "chars": "��������������������������������่กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู้๊๋€฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛¢¬¦ " - }, - "ibm1161": "cp1161", - "csibm1161": "cp1161", - "cp1162": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" - }, - "ibm1162": "cp1162", - "csibm1162": "cp1162", - "cp1163": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" - }, - "ibm1163": "cp1163", - "csibm1163": "cp1163", - "maccroatian": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊�©⁄¤‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ" - }, - "maccyrillic": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°¢£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµ∂ЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" - }, - "macgreek": { - "type": "_sbcs", - "chars": "Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ�" - }, - "maciceland": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" - }, - "macroman": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" - }, - "macromania": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂŞ∞±≤≥¥µ∂∑∏π∫ªºΩăş¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›Ţţ‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" - }, - "macthai": { - "type": "_sbcs", - "chars": "«»…“”�•‘’� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู​–—฿เแโใไๅๆ็่้๊๋์ํ™๏๐๑๒๓๔๕๖๗๘๙®©����" - }, - "macturkish": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙ�ˆ˜¯˘˙˚¸˝˛ˇ" - }, - "macukraine": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" - }, - "koi8r": { - "type": "_sbcs", - "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" - }, - "koi8u": { - "type": "_sbcs", - "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґ╝╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪Ґ╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" - }, - "koi8ru": { - "type": "_sbcs", - "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґў╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪ҐЎ©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" - }, - "koi8t": { - "type": "_sbcs", - "chars": "қғ‚Ғ„…†‡�‰ҳ‹ҲҷҶ�Қ‘’“”•–—�™�›�����ӯӮё¤ӣ¦§���«¬­®�°±²Ё�Ӣ¶·�№�»���©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" - }, - "armscii8": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �և։)(»«—.՝,-֊…՜՛՞ԱաԲբԳգԴդԵեԶզԷէԸըԹթԺժԻիԼլԽխԾծԿկՀհՁձՂղՃճՄմՅյՆնՇշՈոՉչՊպՋջՌռՍսՎվՏտՐրՑցՒւՓփՔքՕօՖֆ՚�" - }, - "rk1048": { - "type": "_sbcs", - "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊҚҺЏђ‘’“”•–—�™љ›њқһџ ҰұӘ¤Ө¦§Ё©Ғ«¬­®Ү°±Ііөµ¶·ё№ғ»әҢңүАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" - }, - "tcvn": { - "type": "_sbcs", - "chars": "\u0000ÚỤ\u0003ỪỬỮ\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010ỨỰỲỶỸÝỴ\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÀẢÃÁẠẶẬÈẺẼÉẸỆÌỈĨÍỊÒỎÕÓỌỘỜỞỠỚỢÙỦŨ ĂÂÊÔƠƯĐăâêôơưđẶ̀̀̉̃́àảãáạẲằẳẵắẴẮẦẨẪẤỀặầẩẫấậèỂẻẽéẹềểễếệìỉỄẾỒĩíịòỔỏõóọồổỗốộờởỡớợùỖủũúụừửữứựỳỷỹýỵỐ" - }, - "georgianacademy": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰჱჲჳჴჵჶçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "georgianps": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზჱთიკლმნჲოპჟრსტჳუფქღყშჩცძწჭხჴჯჰჵæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "pt154": { - "type": "_sbcs", - "chars": "ҖҒӮғ„…ҶҮҲүҠӢҢҚҺҸҗ‘’“”•–—ҳҷҡӣңқһҹ ЎўЈӨҘҰ§Ё©Ә«¬ӯ®Ҝ°ұІіҙө¶·ё№ә»јҪҫҝАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" - }, - "viscii": { - "type": "_sbcs", - "chars": "\u0000\u0001Ẳ\u0003\u0004ẴẪ\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013Ỷ\u0015\u0016\u0017\u0018Ỹ\u001a\u001b\u001c\u001dỴ\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ẠẮẰẶẤẦẨẬẼẸẾỀỂỄỆỐỒỔỖỘỢỚỜỞỊỎỌỈỦŨỤỲÕắằặấầẩậẽẹếềểễệốồổỗỠƠộờởịỰỨỪỬơớƯÀÁÂÃẢĂẳẵÈÉÊẺÌÍĨỳĐứÒÓÔạỷừửÙÚỹỵÝỡưàáâãảăữẫèéêẻìíĩỉđựòóôõỏọụùúũủýợỮ" - }, - "iso646cn": { - "type": "_sbcs", - "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#¥%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}‾��������������������������������������������������������������������������������������������������������������������������������" - }, - "iso646jp": { - "type": "_sbcs", - "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[¥]^_`abcdefghijklmnopqrstuvwxyz{|}‾��������������������������������������������������������������������������������������������������������������������������������" - }, - "hproman8": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ÀÂÈÊËÎÏ´ˋˆ¨˜ÙÛ₤¯Ýý°ÇçÑñ¡¿¤£¥§ƒ¢âêôûáéóúàèòùäëöüÅîØÆåíøæÄìÖÜÉïßÔÁÃãÐðÍÌÓÒÕõŠšÚŸÿÞþ·µ¶¾—¼½ªº«■»±�" - }, - "macintosh": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" - }, - "ascii": { - "type": "_sbcs", - "chars": "��������������������������������������������������������������������������������������������������������������������������������" - }, - "tis620": { - "type": "_sbcs", - "chars": "���������������������������������กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" - } -} +module.exports = __nccwpck_require__(29263); /***/ }), -/***/ 83346: -/***/ ((module) => { +/***/ 90651: +/***/ ((__unused_webpack_module, exports) => { "use strict"; -// Manually added data to be used by sbcs codec in addition to generated one. +exports.load = function (received, defaults, onto = {}) { + var k, ref, v; -module.exports = { - // Not supported by iconv, not sure why. - "10029": "maccenteuro", - "maccenteuro": { - "type": "_sbcs", - "chars": "ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ" - }, + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } - "808": "cp808", - "ibm808": "cp808", - "cp808": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№€■ " - }, + return onto; +}; - "mik": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя└┴┬├─┼╣║╚╔╩╦╠═╬┐░▒▓│┤№§╗╝┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, +exports.overwrite = function (received, defaults, onto = {}) { + var k, v; - // Aliases of generated encodings. - "ascii8bit": "ascii", - "usascii": "ascii", - "ansix34": "ascii", - "ansix341968": "ascii", - "ansix341986": "ascii", - "csascii": "ascii", - "cp367": "ascii", - "ibm367": "ascii", - "isoir6": "ascii", - "iso646us": "ascii", - "iso646irv": "ascii", - "us": "ascii", + for (k in received) { + v = received[k]; - "latin1": "iso88591", - "latin2": "iso88592", - "latin3": "iso88593", - "latin4": "iso88594", - "latin5": "iso88599", - "latin6": "iso885910", - "latin7": "iso885913", - "latin8": "iso885914", - "latin9": "iso885915", - "latin10": "iso885916", + if (defaults[k] !== void 0) { + onto[k] = v; + } + } - "csisolatin1": "iso88591", - "csisolatin2": "iso88592", - "csisolatin3": "iso88593", - "csisolatin4": "iso88594", - "csisolatincyrillic": "iso88595", - "csisolatinarabic": "iso88596", - "csisolatingreek" : "iso88597", - "csisolatinhebrew": "iso88598", - "csisolatin5": "iso88599", - "csisolatin6": "iso885910", + return onto; +}; - "l1": "iso88591", - "l2": "iso88592", - "l3": "iso88593", - "l4": "iso88594", - "l5": "iso88599", - "l6": "iso885910", - "l7": "iso885913", - "l8": "iso885914", - "l9": "iso885915", - "l10": "iso885916", +/***/ }), - "isoir14": "iso646jp", - "isoir57": "iso646cn", - "isoir100": "iso88591", - "isoir101": "iso88592", - "isoir109": "iso88593", - "isoir110": "iso88594", - "isoir144": "iso88595", - "isoir127": "iso88596", - "isoir126": "iso88597", - "isoir138": "iso88598", - "isoir148": "iso88599", - "isoir157": "iso885910", - "isoir166": "tis620", - "isoir179": "iso885913", - "isoir199": "iso885914", - "isoir203": "iso885915", - "isoir226": "iso885916", +/***/ 80890: +/***/ (function(module) { - "cp819": "iso88591", - "ibm819": "iso88591", - - "cyrillic": "iso88595", - - "arabic": "iso88596", - "arabic8": "iso88596", - "ecma114": "iso88596", - "asmo708": "iso88596", +/** + * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. + * https://github.com/SGrondin/bottleneck + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; - "greek" : "iso88597", - "greek8" : "iso88597", - "ecma118" : "iso88597", - "elot928" : "iso88597", + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - "hebrew": "iso88598", - "hebrew8": "iso88598", + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } - "turkish": "iso88599", - "turkish8": "iso88599", + var load = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; - "thai": "iso885911", - "thai8": "iso885911", + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; - "celtic": "iso885914", - "celtic8": "iso885914", - "isoceltic": "iso885914", + var parser = { + load: load, + overwrite: overwrite + }; - "tis6200": "tis620", - "tis62025291": "tis620", - "tis62025330": "tis620", + var DLList; - "10000": "macroman", - "10006": "macgreek", - "10007": "maccyrillic", - "10079": "maciceland", - "10081": "macturkish", + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } - "cspc8codepage437": "cp437", - "cspc775baltic": "cp775", - "cspc850multilingual": "cp850", - "cspcp852": "cp852", - "cspc862latinhebrew": "cp862", - "cpgr": "cp869", + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } - "msee": "cp1250", - "mscyrl": "cp1251", - "msansi": "cp1252", - "msgreek": "cp1253", - "msturk": "cp1254", - "mshebr": "cp1255", - "msarab": "cp1256", - "winbaltrim": "cp1257", + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } - "cp20866": "koi8r", - "20866": "koi8r", - "ibm878": "koi8r", - "cskoi8r": "koi8r", + first() { + if (this._first != null) { + return this._first.value; + } + } - "cp21866": "koi8u", - "21866": "koi8u", - "ibm1168": "koi8u", + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } - "strk10482002": "rk1048", + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + (cb(node), node = this.shift()); + } + return void 0; + } - "tcvn5712": "tcvn", - "tcvn57121": "tcvn", + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } - "gb198880": "iso646cn", - "cn": "iso646cn", + }; - "csiso14jisc6220ro": "iso646jp", - "jisc62201969ro": "iso646jp", - "jp": "iso646jp", + var DLList_1 = DLList; - "cshproman8": "hproman8", - "r8": "hproman8", - "roman8": "hproman8", - "xroman8": "hproman8", - "ibm1051": "hproman8", + var Events; - "mac": "macintosh", - "csmacintosh": "macintosh", -}; + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({cb, status}); + return this.instance; + } + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } -/***/ }), + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async(listener) => { + var e, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return (await returned); + } else { + return returned; + } + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + }); + return ((await Promise.all(promises))).find(function(x) { + return x != null; + }); + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + } -/***/ 53154: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + }; -"use strict"; + var Events_1 = Events; -var Buffer = (__nccwpck_require__(70159).Buffer); + var DLList$1, Events$1, Queues; -// Note: UTF16-LE (or UCS2) codec is Node.js native. See encodings/internal.js + DLList$1 = DLList_1; -// == UTF16-BE codec. ========================================================== + Events$1 = Events_1; -exports.utf16be = Utf16BECodec; -function Utf16BECodec() { -} + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } -Utf16BECodec.prototype.encoder = Utf16BEEncoder; -Utf16BECodec.prototype.decoder = Utf16BEDecoder; -Utf16BECodec.prototype.bomAware = true; + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } -// -- Encoding + push(job) { + return this._lists[job.options.priority].push(job); + } -function Utf16BEEncoder() { -} + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } -Utf16BEEncoder.prototype.write = function(str) { - var buf = Buffer.from(str, 'ucs2'); - for (var i = 0; i < buf.length; i += 2) { - var tmp = buf[i]; buf[i] = buf[i+1]; buf[i+1] = tmp; - } - return buf; -} + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } -Utf16BEEncoder.prototype.end = function() { -} + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -// -- Decoding + }; -function Utf16BEDecoder() { - this.overflowByte = -1; -} + var Queues_1 = Queues; -Utf16BEDecoder.prototype.write = function(buf) { - if (buf.length == 0) - return ''; + var BottleneckError; - var buf2 = Buffer.alloc(buf.length + 1), - i = 0, j = 0; + BottleneckError = class BottleneckError extends Error {}; - if (this.overflowByte !== -1) { - buf2[0] = buf[0]; - buf2[1] = this.overflowByte; - i = 1; j = 2; - } + var BottleneckError_1 = BottleneckError; - for (; i < buf.length-1; i += 2, j+= 2) { - buf2[j] = buf[i+1]; - buf2[j+1] = buf[i]; - } + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; - this.overflowByte = (i == buf.length-1) ? buf[buf.length-1] : -1; + NUM_PRIORITIES = 10; - return buf2.slice(0, j).toString('ucs2'); -} + DEFAULT_PRIORITY = 5; -Utf16BEDecoder.prototype.end = function() { -} + parser$1 = parser; + BottleneckError$1 = BottleneckError_1; -// == UTF-16 codec ============================================================= -// Decoder chooses automatically from UTF-16LE and UTF-16BE using BOM and space-based heuristic. -// Defaults to UTF-16LE, as it's prevalent and default in Node. -// http://en.wikipedia.org/wiki/UTF-16 and http://encoding.spec.whatwg.org/#utf-16le -// Decoder default can be changed: iconv.decode(buf, 'utf16', {defaultEncoding: 'utf-16be'}); + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } -// Encoder uses UTF-16LE and prepends BOM (which can be overridden with addBOM: false). + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } -exports.utf16 = Utf16Codec; -function Utf16Codec(codecOptions, iconv) { - this.iconv = iconv; -} + _randomIndex() { + return Math.random().toString(36).slice(2); + } -Utf16Codec.prototype.encoder = Utf16Encoder; -Utf16Codec.prototype.decoder = Utf16Decoder; + doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); + return true; + } else { + return false; + } + } + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || (expected === "DONE" && status === null))) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } -// -- Encoding (pass-through) + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", {args: this.args, options: this.options}); + } -function Utf16Encoder(options, codec) { - options = options || {}; - if (options.addBOM === undefined) - options.addBOM = true; - this.encoder = codec.iconv.getEncoder('utf-16le', options); -} + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); + } -Utf16Encoder.prototype.write = function(str) { - return this.encoder.write(str); -} + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", {args: this.args, options: this.options}); + } -Utf16Encoder.prototype.end = function() { - return this.encoder.end(); -} + async doExecute(chained, clearGlobalState, run, free) { + var error, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + this.Events.trigger("executing", eventInfo); + try { + passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error = error1; + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + } + doExpire(clearGlobalState, run, free) { + var error, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } -// -- Decoding + async _onFailure(error, eventInfo, clearGlobalState, run, free) { + var retry, retryAfter; + if (clearGlobalState()) { + retry = (await this.Events.trigger("failed", error, eventInfo)); + if (retry != null) { + retryAfter = ~~retry; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error); + } + } + } -function Utf16Decoder(options, codec) { - this.decoder = null; - this.initialBytes = []; - this.initialBytesLen = 0; + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } - this.options = options || {}; - this.iconv = codec.iconv; -} + }; -Utf16Decoder.prototype.write = function(buf) { - if (!this.decoder) { - // Codec is not chosen yet. Accumulate initial bytes. - this.initialBytes.push(buf); - this.initialBytesLen += buf.length; - - if (this.initialBytesLen < 16) // We need more bytes to use space heuristic (see below) - return ''; + var Job_1 = Job; - // We have enough bytes -> detect endianness. - var buf = Buffer.concat(this.initialBytes), - encoding = detectEncoding(buf, this.options.defaultEncoding); - this.decoder = this.iconv.getDecoder(encoding, this.options); - this.initialBytes.length = this.initialBytesLen = 0; - } + var BottleneckError$2, LocalDatastore, parser$2; - return this.decoder.write(buf); -} + parser$2 = parser; -Utf16Decoder.prototype.end = function() { - if (!this.decoder) { - var buf = Buffer.concat(this.initialBytes), - encoding = detectEncoding(buf, this.options.defaultEncoding); - this.decoder = this.iconv.getDecoder(encoding, this.options); + BottleneckError$2 = BottleneckError_1; - var res = this.decoder.write(buf), - trail = this.decoder.end(); + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } - return trail ? (res + trail) : res; - } - return this.decoder.end(); -} + _startHeartbeat() { + var base; + if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { + return typeof (base = (this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } -function detectEncoding(buf, defaultEncoding) { - var enc = defaultEncoding || 'utf-16le'; + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } - if (buf.length >= 2) { - // Check BOM. - if (buf[0] == 0xFE && buf[1] == 0xFF) // UTF-16BE BOM - enc = 'utf-16be'; - else if (buf[0] == 0xFF && buf[1] == 0xFE) // UTF-16LE BOM - enc = 'utf-16le'; - else { - // No BOM found. Try to deduce encoding from initial content. - // Most of the time, the content has ASCII chars (U+00**), but the opposite (U+**00) is uncommon. - // So, we count ASCII as if it was LE or BE, and decide from that. - var asciiCharsLE = 0, asciiCharsBE = 0, // Counts of chars in both positions - _len = Math.min(buf.length - (buf.length % 2), 64); // Len is always even. + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } - for (var i = 0; i < _len; i += 2) { - if (buf[i] === 0 && buf[i+1] !== 0) asciiCharsBE++; - if (buf[i] !== 0 && buf[i+1] === 0) asciiCharsLE++; - } + yieldLoop(t = 0) { + return new this.Promise(function(resolve, reject) { + return setTimeout(resolve, t); + }); + } - if (asciiCharsBE > asciiCharsLE) - enc = 'utf-16be'; - else if (asciiCharsBE < asciiCharsLE) - enc = 'utf-16le'; - } - } + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; + } - return enc; -} + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } + async __running__() { + await this.yieldLoop(); + return this._running; + } + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } + async __done__() { + await this.yieldLoop(); + return this._done; + } -/***/ }), + async __groupCheck__(time) { + await this.yieldLoop(); + return (this._nextRequest + this.timeout) < time; + } -/***/ 50256: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + computeCapacity() { + var maxConcurrent, reservoir; + ({maxConcurrent, reservoir} = this.storeOptions); + if ((maxConcurrent != null) && (reservoir != null)) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } -"use strict"; + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return (capacity == null) || weight <= capacity; + } -var Buffer = (__nccwpck_require__(70159).Buffer); + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } -// UTF-7 codec, according to https://tools.ietf.org/html/rfc2152 -// See also below a UTF-7-IMAP codec, according to http://tools.ietf.org/html/rfc3501#section-5.1.3 + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } -exports.utf7 = Utf7Codec; -exports.unicode11utf7 = 'utf7'; // Alias UNICODE-1-1-UTF-7 -function Utf7Codec(codecOptions, iconv) { - this.iconv = iconv; -}; + isBlocked(now) { + return this._unblockTime >= now; + } -Utf7Codec.prototype.encoder = Utf7Encoder; -Utf7Codec.prototype.decoder = Utf7Decoder; -Utf7Codec.prototype.bomAware = true; + check(weight, now) { + return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; + } + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } -// -- Encoding + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } -var nonDirectChars = /[^A-Za-z0-9'\(\),-\.\/:\? \n\r\t]+/g; + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } -function Utf7Encoder(options, codec) { - this.iconv = codec.iconv; -} + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } -Utf7Encoder.prototype.write = function(str) { - // Naive implementation. - // Non-direct chars are encoded as "+-"; single "+" char is encoded as "+-". - return Buffer.from(str.replace(nonDirectChars, function(chunk) { - return "+" + (chunk === '+' ? '' : - this.iconv.encode(chunk, 'utf16-be').toString('base64').replace(/=+$/, '')) - + "-"; - }.bind(this))); -} + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } -Utf7Encoder.prototype.end = function() { -} + }; + var LocalDatastore_1 = LocalDatastore; -// -- Decoding + var BottleneckError$3, States; -function Utf7Decoder(options, codec) { - this.iconv = codec.iconv; - this.inBase64 = false; - this.base64Accum = ''; -} + BottleneckError$3 = BottleneckError_1; -var base64Regex = /[A-Za-z0-9\/+]/; -var base64Chars = []; -for (var i = 0; i < 256; i++) - base64Chars[i] = base64Regex.test(String.fromCharCode(i)); + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } -var plusChar = '+'.charCodeAt(0), - minusChar = '-'.charCodeAt(0), - andChar = '&'.charCodeAt(0); + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if ((current != null) && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } -Utf7Decoder.prototype.write = function(buf) { - var res = "", lastI = 0, - inBase64 = this.inBase64, - base64Accum = this.base64Accum; + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } - // The decoder is more involved as we must handle chunks in stream. + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } - for (var i = 0; i < buf.length; i++) { - if (!inBase64) { // We're in direct mode. - // Write direct chars until '+' - if (buf[i] == plusChar) { - res += this.iconv.decode(buf.slice(lastI, i), "ascii"); // Write direct chars. - lastI = i+1; - inBase64 = true; - } - } else { // We decode base64. - if (!base64Chars[buf[i]]) { // Base64 ended. - if (i == lastI && buf[i] == minusChar) {// "+-" -> "+" - res += "+"; - } else { - var b64str = base64Accum + buf.slice(lastI, i).toString(); - res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); - } + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } - if (buf[i] != minusChar) // Minus is absorbed after base64. - i--; + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } - lastI = i+1; - inBase64 = false; - base64Accum = ''; - } - } - } + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } - if (!inBase64) { - res += this.iconv.decode(buf.slice(lastI), "ascii"); // Write direct chars. - } else { - var b64str = base64Accum + buf.slice(lastI).toString(); + }; - var canBeDecoded = b64str.length - (b64str.length % 8); // Minimal chunk: 2 quads -> 2x3 bytes -> 3 chars. - base64Accum = b64str.slice(canBeDecoded); // The rest will be decoded in future. - b64str = b64str.slice(0, canBeDecoded); + var States_1 = States; - res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); - } + var DLList$2, Sync; - this.inBase64 = inBase64; - this.base64Accum = base64Accum; + DLList$2 = DLList_1; - return res; -} + Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList$2(); + } -Utf7Decoder.prototype.end = function() { - var res = ""; - if (this.inBase64 && this.base64Accum.length > 0) - res = this.iconv.decode(Buffer.from(this.base64Accum, 'base64'), "utf16-be"); + isEmpty() { + return this._queue.length === 0; + } - this.inBase64 = false; - this.base64Accum = ''; - return res; -} + async _tryToRun() { + var args, cb, error, reject, resolve, returned, task; + if ((this._running < 1) && this._queue.length > 0) { + this._running++; + ({task, args, resolve, reject} = this._queue.shift()); + cb = (await (async function() { + try { + returned = (await task(...args)); + return function() { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function() { + return reject(error); + }; + } + })()); + this._running--; + this._tryToRun(); + return cb(); + } + } + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + this._queue.push({task, args, resolve, reject}); + this._tryToRun(); + return promise; + } -// UTF-7-IMAP codec. -// RFC3501 Sec. 5.1.3 Modified UTF-7 (http://tools.ietf.org/html/rfc3501#section-5.1.3) -// Differences: -// * Base64 part is started by "&" instead of "+" -// * Direct characters are 0x20-0x7E, except "&" (0x26) -// * In Base64, "," is used instead of "/" -// * Base64 must not be used to represent direct characters. -// * No implicit shift back from Base64 (should always end with '-') -// * String must end in non-shifted position. -// * "-&" while in base64 is not allowed. + }; + var Sync_1 = Sync; -exports.utf7imap = Utf7IMAPCodec; -function Utf7IMAPCodec(codecOptions, iconv) { - this.iconv = iconv; -}; + var version = "2.19.5"; + var version$1 = { + version: version + }; -Utf7IMAPCodec.prototype.encoder = Utf7IMAPEncoder; -Utf7IMAPCodec.prototype.decoder = Utf7IMAPDecoder; -Utf7IMAPCodec.prototype.bomAware = true; + var version$2 = /*#__PURE__*/Object.freeze({ + version: version, + default: version$1 + }); + var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -// -- Encoding + var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -function Utf7IMAPEncoder(options, codec) { - this.iconv = codec.iconv; - this.inBase64 = false; - this.base64Accum = Buffer.alloc(6); - this.base64AccumIdx = 0; -} + var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -Utf7IMAPEncoder.prototype.write = function(str) { - var inBase64 = this.inBase64, - base64Accum = this.base64Accum, - base64AccumIdx = this.base64AccumIdx, - buf = Buffer.alloc(str.length*5 + 10), bufIdx = 0; + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; - for (var i = 0; i < str.length; i++) { - var uChar = str.charCodeAt(i); - if (0x20 <= uChar && uChar <= 0x7E) { // Direct character or '&'. - if (inBase64) { - if (base64AccumIdx > 0) { - bufIdx += buf.write(base64Accum.slice(0, base64AccumIdx).toString('base64').replace(/\//g, ',').replace(/=+$/, ''), bufIdx); - base64AccumIdx = 0; - } + parser$3 = parser; - buf[bufIdx++] = minusChar; // Write '-', then go to direct mode. - inBase64 = false; - } + Events$2 = Events_1; - if (!inBase64) { - buf[bufIdx++] = uChar; // Write direct character + RedisConnection$1 = require$$2; - if (uChar === andChar) // Ampersand -> '&-' - buf[bufIdx++] = minusChar; - } + IORedisConnection$1 = require$$3; - } else { // Non-direct character - if (!inBase64) { - buf[bufIdx++] = andChar; // Write '&', then go to base64 mode. - inBase64 = true; - } - if (inBase64) { - base64Accum[base64AccumIdx++] = uChar >> 8; - base64Accum[base64AccumIdx++] = uChar & 0xFF; + Scripts$1 = require$$4; - if (base64AccumIdx == base64Accum.length) { - bufIdx += buf.write(base64Accum.toString('base64').replace(/\//g, ','), bufIdx); - base64AccumIdx = 0; - } - } - } - } + Group = (function() { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } + } + } - this.inBase64 = inBase64; - this.base64AccumIdx = base64AccumIdx; + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } - return buf.slice(0, bufIdx); -} + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return (instance != null) || deleted > 0; + } -Utf7IMAPEncoder.prototype.end = function() { - var buf = Buffer.alloc(10), bufIdx = 0; - if (this.inBase64) { - if (this.base64AccumIdx > 0) { - bufIdx += buf.write(this.base64Accum.slice(0, this.base64AccumIdx).toString('base64').replace(/\//g, ',').replace(/=+$/, ''), bufIdx); - this.base64AccumIdx = 0; - } + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } - buf[bufIdx++] = minusChar; // Write '-', then go to direct mode. - this.inBase64 = false; - } + keys() { + return Object.keys(this.instances); + } - return buf.slice(0, bufIdx); -} + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = (this.interval = setInterval(async() => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if ((await v._store.__groupCheck__(time))) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; + } -// -- Decoding + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -function Utf7IMAPDecoder(options, codec) { - this.iconv = codec.iconv; - this.inBase64 = false; - this.base64Accum = ''; -} + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -var base64IMAPChars = base64Chars.slice(); -base64IMAPChars[','.charCodeAt(0)] = true; + } + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; -Utf7IMAPDecoder.prototype.write = function(buf) { - var res = "", lastI = 0, - inBase64 = this.inBase64, - base64Accum = this.base64Accum; + return Group; - // The decoder is more involved as we must handle chunks in stream. - // It is forgiving, closer to standard UTF-7 (for example, '-' is optional at the end). + }).call(commonjsGlobal); - for (var i = 0; i < buf.length; i++) { - if (!inBase64) { // We're in direct mode. - // Write direct chars until '&' - if (buf[i] == andChar) { - res += this.iconv.decode(buf.slice(lastI, i), "ascii"); // Write direct chars. - lastI = i+1; - inBase64 = true; - } - } else { // We decode base64. - if (!base64IMAPChars[buf[i]]) { // Base64 ended. - if (i == lastI && buf[i] == minusChar) { // "&-" -> "&" - res += "&"; - } else { - var b64str = base64Accum + buf.slice(lastI, i).toString().replace(/,/g, '/'); - res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); - } + var Group_1 = Group; - if (buf[i] != minusChar) // Minus may be absorbed after base64. - i--; + var Batcher, Events$3, parser$4; - lastI = i+1; - inBase64 = false; - base64Accum = ''; - } - } - } + parser$4 = parser; - if (!inBase64) { - res += this.iconv.decode(buf.slice(lastI), "ascii"); // Write direct chars. - } else { - var b64str = base64Accum + buf.slice(lastI).toString().replace(/,/g, '/'); + Events$3 = Events_1; - var canBeDecoded = b64str.length - (b64str.length % 8); // Minimal chunk: 2 quads -> 2x3 bytes -> 3 chars. - base64Accum = b64str.slice(canBeDecoded); // The rest will be decoded in future. - b64str = b64str.slice(0, canBeDecoded); + Batcher = (function() { + class Batcher { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } - res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); - } + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } - this.inBase64 = inBase64; - this.base64Accum = base64Accum; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } - return res; -} + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if ((this.maxTime != null) && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } -Utf7IMAPDecoder.prototype.end = function() { - var res = ""; - if (this.inBase64 && this.base64Accum.length > 0) - res = this.iconv.decode(Buffer.from(this.base64Accum, 'base64'), "utf16-be"); + } + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; - this.inBase64 = false; - this.base64Accum = ''; - return res; -} + return Batcher; + }).call(commonjsGlobal); + var Batcher_1 = Batcher; + var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -/***/ }), + var require$$8 = getCjsExportFromNamespace(version$2); -/***/ 26293: -/***/ ((__unused_webpack_module, exports) => { + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, + splice = [].splice; -"use strict"; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; -var BOMChar = '\uFEFF'; + parser$5 = parser; -exports.PrependBOM = PrependBOMWrapper -function PrependBOMWrapper(encoder, options) { - this.encoder = encoder; - this.addBOM = true; -} + Queues$1 = Queues_1; -PrependBOMWrapper.prototype.write = function(str) { - if (this.addBOM) { - str = BOMChar + str; - this.addBOM = false; - } + Job$1 = Job_1; - return this.encoder.write(str); -} + LocalDatastore$1 = LocalDatastore_1; -PrependBOMWrapper.prototype.end = function() { - return this.encoder.end(); -} + RedisDatastore$1 = require$$4$1; + Events$4 = Events_1; -//------------------------------------------------------------------------------ + States$1 = States_1; -exports.StripBOM = StripBOMWrapper; -function StripBOMWrapper(decoder, options) { - this.decoder = decoder; - this.pass = false; - this.options = options || {}; -} + Sync$1 = Sync_1; -StripBOMWrapper.prototype.write = function(buf) { - var res = this.decoder.write(buf); - if (this.pass || !res) - return res; + Bottleneck = (function() { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } - if (res[0] === BOMChar) { - res = res.slice(1); - if (typeof this.options.stripBOM === 'function') - this.options.stripBOM(); - } + _validateOptions(options, invalid) { + if (!((options != null) && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } - this.pass = true; - return res; -} + ready() { + return this._store.ready; + } -StripBOMWrapper.prototype.end = function() { - return this.decoder.end(); -} + clients() { + return this._store.clients; + } + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -/***/ }), + publish(message) { + return this._store.__publish__(message); + } -/***/ 32826: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } -"use strict"; + chain(_limiter) { + this._limiter = _limiter; + return this; + } -var Buffer = (__nccwpck_require__(20181).Buffer); -// Note: not polyfilled with safer-buffer on a purpose, as overrides Buffer + queued(priority) { + return this._queues.queued(priority); + } -// == Extend Node primitives to use iconv-lite ================================= + clusterQueued() { + return this._store.__queued__(); + } -module.exports = function (iconv) { - var original = undefined; // Place to keep original methods. + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } - // Node authors rewrote Buffer internals to make it compatible with - // Uint8Array and we cannot patch key functions since then. - // Note: this does use older Buffer API on a purpose - iconv.supportsNodeEncodingsExtension = !(Buffer.from || new Buffer(0) instanceof Uint8Array); + running() { + return this._store.__running__(); + } - iconv.extendNodeEncodings = function extendNodeEncodings() { - if (original) return; - original = {}; + done() { + return this._store.__done__(); + } - if (!iconv.supportsNodeEncodingsExtension) { - console.error("ACTION NEEDED: require('iconv-lite').extendNodeEncodings() is not supported in your version of Node"); - console.error("See more info at https://github.com/ashtuchkin/iconv-lite/wiki/Node-v4-compatibility"); - return; - } + jobStatus(id) { + return this._states.jobStatus(id); + } - var nodeNativeEncodings = { - 'hex': true, 'utf8': true, 'utf-8': true, 'ascii': true, 'binary': true, - 'base64': true, 'ucs2': true, 'ucs-2': true, 'utf16le': true, 'utf-16le': true, - }; + jobs(status) { + return this._states.statusJobs(status); + } - Buffer.isNativeEncoding = function(enc) { - return enc && nodeNativeEncodings[enc.toLowerCase()]; - } + counts() { + return this._states.statusCounts(); + } - // -- SlowBuffer ----------------------------------------------------------- - var SlowBuffer = (__nccwpck_require__(20181).SlowBuffer); + _randomIndex() { + return Math.random().toString(36).slice(2); + } - original.SlowBufferToString = SlowBuffer.prototype.toString; - SlowBuffer.prototype.toString = function(encoding, start, end) { - encoding = String(encoding || 'utf8').toLowerCase(); + check(weight = 1) { + return this._store.__check__(weight); + } - // Use native conversion when possible - if (Buffer.isNativeEncoding(encoding)) - return original.SlowBufferToString.call(this, encoding, start, end); + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } - // Otherwise, use our decoding method. - if (typeof start == 'undefined') start = 0; - if (typeof end == 'undefined') end = this.length; - return iconv.decode(this.slice(start, end), encoding); - } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({running} = (await this._store.__free__(index, options.weight))); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } - original.SlowBufferWrite = SlowBuffer.prototype.write; - SlowBuffer.prototype.write = function(string, offset, length, encoding) { - // Support both (string, offset, length, encoding) - // and the legacy (string, encoding, offset, length) - if (isFinite(offset)) { - if (!isFinite(length)) { - encoding = length; - length = undefined; - } - } else { // legacy - var swap = encoding; - encoding = offset; - offset = length; - length = swap; - } + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } - offset = +offset || 0; - var remaining = this.length - offset; - if (!length) { - length = remaining; - } else { - length = +length; - if (length > remaining) { - length = remaining; - } - } - encoding = String(encoding || 'utf8').toLowerCase(); + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({options, args} = next = queue.first()); + if ((capacity != null) && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } - // Use native conversion when possible - if (Buffer.isNativeEncoding(encoding)) - return original.SlowBufferWrite.call(this, string, offset, length, encoding); + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } - if (string.length > 0 && (length < 0 || offset < 0)) - throw new RangeError('attempt to write beyond buffer bounds'); + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({message}); + }); + } - // Otherwise, use our encoding method. - var buf = iconv.encode(string, encoding); - if (buf.length < length) length = buf.length; - buf.copy(this, offset, 0, length); - return length; - } + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return (counts[0] + counts[1] + counts[2] + counts[3]) === at; + }; + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } - // -- Buffer --------------------------------------------------------------- + async _addToQueue(job) { + var args, blocked, error, options, reachedHWM, shifted, strategy; + ({args, options} = job); + try { + ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); + } catch (error1) { + error = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); + job.doDrop({error}); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } - original.BufferIsEncoding = Buffer.isEncoding; - Buffer.isEncoding = function(encoding) { - return Buffer.isNativeEncoding(encoding) || iconv.encodingExists(encoding); - } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } - original.BufferByteLength = Buffer.byteLength; - Buffer.byteLength = SlowBuffer.byteLength = function(str, encoding) { - encoding = String(encoding || 'utf8').toLowerCase(); + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args) => { + return new this.Promise(function(resolve, reject) { + return fn(...args, function(...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function(args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; + } + }); + return this._receive(job); + } - // Use native conversion when possible - if (Buffer.isNativeEncoding(encoding)) - return original.BufferByteLength.call(this, str, encoding); + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } - // Slow, I know, but we don't have a better way yet. - return iconv.encode(str, encoding).length; - } + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } - original.BufferToString = Buffer.prototype.toString; - Buffer.prototype.toString = function(encoding, start, end) { - encoding = String(encoding || 'utf8').toLowerCase(); + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } - // Use native conversion when possible - if (Buffer.isNativeEncoding(encoding)) - return original.BufferToString.call(this, encoding, start, end); + currentReservoir() { + return this._store.__currentReservoir__(); + } - // Otherwise, use our decoding method. - if (typeof start == 'undefined') start = 0; - if (typeof end == 'undefined') end = this.length; - return iconv.decode(this.slice(start, end), encoding); - } + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } - original.BufferWrite = Buffer.prototype.write; - Buffer.prototype.write = function(string, offset, length, encoding) { - var _offset = offset, _length = length, _encoding = encoding; - // Support both (string, offset, length, encoding) - // and the legacy (string, encoding, offset, length) - if (isFinite(offset)) { - if (!isFinite(length)) { - encoding = length; - length = undefined; - } - } else { // legacy - var swap = encoding; - encoding = offset; - offset = length; - length = swap; - } + } + Bottleneck.default = Bottleneck; - encoding = String(encoding || 'utf8').toLowerCase(); + Bottleneck.Events = Events$4; - // Use native conversion when possible - if (Buffer.isNativeEncoding(encoding)) - return original.BufferWrite.call(this, string, _offset, _length, _encoding); + Bottleneck.version = Bottleneck.prototype.version = require$$8.version; - offset = +offset || 0; - var remaining = this.length - offset; - if (!length) { - length = remaining; - } else { - length = +length; - if (length > remaining) { - length = remaining; - } - } + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; - if (string.length > 0 && (length < 0 || offset < 0)) - throw new RangeError('attempt to write beyond buffer bounds'); + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; - // Otherwise, use our encoding method. - var buf = iconv.encode(string, encoding); - if (buf.length < length) length = buf.length; - buf.copy(this, offset, 0, length); - return length; + Bottleneck.Group = Bottleneck.prototype.Group = Group_1; - // TODO: Set _charsWritten. - } + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; - // -- Readable ------------------------------------------------------------- - if (iconv.supportsStreams) { - var Readable = (__nccwpck_require__(2203).Readable); + Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; - original.ReadableSetEncoding = Readable.prototype.setEncoding; - Readable.prototype.setEncoding = function setEncoding(enc, options) { - // Use our own decoder, it has the same interface. - // We cannot use original function as it doesn't handle BOM-s. - this._readableState.decoder = iconv.getDecoder(enc, options); - this._readableState.encoding = enc; - } + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; - Readable.prototype.collect = iconv._collect; - } - } + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; - // Remove iconv-lite Node primitive extensions. - iconv.undoExtendNodeEncodings = function undoExtendNodeEncodings() { - if (!iconv.supportsNodeEncodingsExtension) - return; - if (!original) - throw new Error("require('iconv-lite').undoExtendNodeEncodings(): Nothing to undo; extendNodeEncodings() is not called.") + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; - delete Buffer.isNativeEncoding; + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; - var SlowBuffer = (__nccwpck_require__(20181).SlowBuffer); + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; - SlowBuffer.prototype.toString = original.SlowBufferToString; - SlowBuffer.prototype.write = original.SlowBufferWrite; + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; - Buffer.isEncoding = original.BufferIsEncoding; - Buffer.byteLength = original.BufferByteLength; - Buffer.prototype.toString = original.BufferToString; - Buffer.prototype.write = original.BufferWrite; + return Bottleneck; - if (iconv.supportsStreams) { - var Readable = (__nccwpck_require__(2203).Readable); + }).call(commonjsGlobal); - Readable.prototype.setEncoding = original.ReadableSetEncoding; - delete Readable.prototype.collect; - } + var Bottleneck_1 = Bottleneck; - original = undefined; - } + var lib = Bottleneck_1; + + return lib; + +}))); + + +/***/ }), + +/***/ 71091: +/***/ ((module) => { + +module.exports = function btoa(str) { + return new Buffer(str).toString('base64') } /***/ }), -/***/ 81241: +/***/ 99905: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; +/*jshint node:true */ +var Buffer = (__nccwpck_require__(20181).Buffer); // browserify +var SlowBuffer = (__nccwpck_require__(20181).SlowBuffer); -// Some environments don't have global Buffer (e.g. React Native). -// Solution would be installing npm modules "buffer" and "stream" explicitly. -var Buffer = (__nccwpck_require__(70159).Buffer); - -var bomHandling = __nccwpck_require__(26293), - iconv = module.exports; - -// All codecs and aliases are kept here, keyed by encoding name/alias. -// They are lazy loaded in `iconv.getCodec` from `encodings/index.js`. -iconv.encodings = null; +module.exports = bufferEq; -// Characters emitted in case of error. -iconv.defaultCharUnicode = '�'; -iconv.defaultCharSingleByte = '?'; +function bufferEq(a, b) { -// Public API. -iconv.encode = function encode(str, encoding, options) { - str = "" + (str || ""); // Ensure string. + // shortcutting on type is necessary for correctness + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + return false; + } - var encoder = iconv.getEncoder(encoding, options); + // buffer sizes should be well-known information, so despite this + // shortcutting, it doesn't leak any information about the *contents* of the + // buffers. + if (a.length !== b.length) { + return false; + } - var res = encoder.write(str); - var trail = encoder.end(); - - return (trail && trail.length > 0) ? Buffer.concat([res, trail]) : res; + var c = 0; + for (var i = 0; i < a.length; i++) { + /*jshint bitwise:false */ + c |= a[i] ^ b[i]; // XOR + } + return c === 0; } -iconv.decode = function decode(buf, encoding, options) { - if (typeof buf === 'string') { - if (!iconv.skipDecodeWarning) { - console.error('Iconv-lite warning: decode()-ing strings is deprecated. Refer to https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding'); - iconv.skipDecodeWarning = true; - } +bufferEq.install = function() { + Buffer.prototype.equal = SlowBuffer.prototype.equal = function equal(that) { + return bufferEq(this, that); + }; +}; - buf = Buffer.from("" + (buf || ""), "binary"); // Ensure buffer. - } +var origBufEqual = Buffer.prototype.equal; +var origSlowBufEqual = SlowBuffer.prototype.equal; +bufferEq.restore = function() { + Buffer.prototype.equal = origBufEqual; + SlowBuffer.prototype.equal = origSlowBufEqual; +}; - var decoder = iconv.getDecoder(encoding, options); - var res = decoder.write(buf); - var trail = decoder.end(); +/***/ }), - return trail ? (res + trail) : res; -} +/***/ 89015: +/***/ ((module) => { -iconv.encodingExists = function encodingExists(enc) { - try { - iconv.getCodec(enc); - return true; - } catch (e) { - return false; - } -} +"use strict"; +/*! + * bytes + * Copyright(c) 2012-2014 TJ Holowaychuk + * Copyright(c) 2015 Jed Watson + * MIT Licensed + */ -// Legacy aliases to convert functions -iconv.toEncoding = iconv.encode; -iconv.fromEncoding = iconv.decode; -// Search for a codec in iconv.encodings. Cache codec data in iconv._codecDataCache. -iconv._codecDataCache = {}; -iconv.getCodec = function getCodec(encoding) { - if (!iconv.encodings) - iconv.encodings = __nccwpck_require__(35760); // Lazy load all encoding definitions. - - // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. - var enc = iconv._canonicalizeEncoding(encoding); - // Traverse iconv.encodings to find actual codec. - var codecOptions = {}; - while (true) { - var codec = iconv._codecDataCache[enc]; - if (codec) - return codec; +/** + * Module exports. + * @public + */ - var codecDef = iconv.encodings[enc]; +module.exports = bytes; +module.exports.format = format; +module.exports.parse = parse; - switch (typeof codecDef) { - case "string": // Direct alias to other encoding. - enc = codecDef; - break; +/** + * Module variables. + * @private + */ - case "object": // Alias with options. Can be layered. - for (var key in codecDef) - codecOptions[key] = codecDef[key]; +var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g; - if (!codecOptions.encodingName) - codecOptions.encodingName = enc; - - enc = codecDef.type; - break; +var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/; - case "function": // Codec itself. - if (!codecOptions.encodingName) - codecOptions.encodingName = enc; +var map = { + b: 1, + kb: 1 << 10, + mb: 1 << 20, + gb: 1 << 30, + tb: Math.pow(1024, 4), + pb: Math.pow(1024, 5), +}; - // The codec function must load all tables and return object with .encoder and .decoder methods. - // It'll be called only once (for each different options object). - codec = new codecDef(codecOptions, iconv); +var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i; - iconv._codecDataCache[codecOptions.encodingName] = codec; // Save it to be reused later. - return codec; +/** + * Convert the given value in bytes into a string or parse to string to an integer in bytes. + * + * @param {string|number} value + * @param {{ + * case: [string], + * decimalPlaces: [number] + * fixedDecimals: [boolean] + * thousandsSeparator: [string] + * unitSeparator: [string] + * }} [options] bytes options. + * + * @returns {string|number|null} + */ - default: - throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')"); - } - } -} +function bytes(value, options) { + if (typeof value === 'string') { + return parse(value); + } -iconv._canonicalizeEncoding = function(encoding) { - // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. - return (''+encoding).toLowerCase().replace(/:\d{4}$|[^0-9a-z]/g, ""); + if (typeof value === 'number') { + return format(value, options); + } + + return null; } -iconv.getEncoder = function getEncoder(encoding, options) { - var codec = iconv.getCodec(encoding), - encoder = new codec.encoder(options, codec); +/** + * Format the given value in bytes into a string. + * + * If the value is negative, it is kept as such. If it is a float, + * it is rounded. + * + * @param {number} value + * @param {object} [options] + * @param {number} [options.decimalPlaces=2] + * @param {number} [options.fixedDecimals=false] + * @param {string} [options.thousandsSeparator=] + * @param {string} [options.unit=] + * @param {string} [options.unitSeparator=] + * + * @returns {string|null} + * @public + */ - if (codec.bomAware && options && options.addBOM) - encoder = new bomHandling.PrependBOM(encoder, options); +function format(value, options) { + if (!Number.isFinite(value)) { + return null; + } - return encoder; -} + var mag = Math.abs(value); + var thousandsSeparator = (options && options.thousandsSeparator) || ''; + var unitSeparator = (options && options.unitSeparator) || ''; + var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2; + var fixedDecimals = Boolean(options && options.fixedDecimals); + var unit = (options && options.unit) || ''; -iconv.getDecoder = function getDecoder(encoding, options) { - var codec = iconv.getCodec(encoding), - decoder = new codec.decoder(options, codec); + if (!unit || !map[unit.toLowerCase()]) { + if (mag >= map.pb) { + unit = 'PB'; + } else if (mag >= map.tb) { + unit = 'TB'; + } else if (mag >= map.gb) { + unit = 'GB'; + } else if (mag >= map.mb) { + unit = 'MB'; + } else if (mag >= map.kb) { + unit = 'KB'; + } else { + unit = 'B'; + } + } - if (codec.bomAware && !(options && options.stripBOM === false)) - decoder = new bomHandling.StripBOM(decoder, options); + var val = value / map[unit.toLowerCase()]; + var str = val.toFixed(decimalPlaces); - return decoder; + if (!fixedDecimals) { + str = str.replace(formatDecimalsRegExp, '$1'); + } + + if (thousandsSeparator) { + str = str.split('.').map(function (s, i) { + return i === 0 + ? s.replace(formatThousandsRegExp, thousandsSeparator) + : s + }).join('.'); + } + + return str + unitSeparator + unit; } +/** + * Parse the string value into an integer in bytes. + * + * If no unit is given, it is assumed the value is in bytes. + * + * @param {number|string} val + * + * @returns {number|null} + * @public + */ -// Load extensions in Node. All of them are omitted in Browserify build via 'browser' field in package.json. -var nodeVer = typeof process !== 'undefined' && process.versions && process.versions.node; -if (nodeVer) { +function parse(val) { + if (typeof val === 'number' && !isNaN(val)) { + return val; + } - // Load streaming support in Node v0.10+ - var nodeVerArr = nodeVer.split(".").map(Number); - if (nodeVerArr[0] > 0 || nodeVerArr[1] >= 10) { - __nccwpck_require__(53064)(iconv); - } + if (typeof val !== 'string') { + return null; + } - // Load Node primitive extensions. - __nccwpck_require__(32826)(iconv); -} + // Test if the string passed is valid + var results = parseRegExp.exec(val); + var floatValue; + var unit = 'b'; -if (false) {} + if (!results) { + // Nothing could be extracted from the given string + floatValue = parseInt(val, 10); + unit = 'b' + } else { + // Retrieve the value and the unit + floatValue = parseFloat(results[1]); + unit = results[4].toLowerCase(); + } + + if (isNaN(floatValue)) { + return null; + } + + return Math.floor(map[unit] * floatValue); +} /***/ }), -/***/ 53064: +/***/ 76727: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -var Buffer = (__nccwpck_require__(20181).Buffer), - Transform = (__nccwpck_require__(2203).Transform); - - -// == Exports ================================================================== -module.exports = function(iconv) { - - // Additional Public API. - iconv.encodeStream = function encodeStream(encoding, options) { - return new IconvLiteEncoderStream(iconv.getEncoder(encoding, options), options); - } - - iconv.decodeStream = function decodeStream(encoding, options) { - return new IconvLiteDecoderStream(iconv.getDecoder(encoding, options), options); - } +var GetIntrinsic = __nccwpck_require__(36546); - iconv.supportsStreams = true; +var callBind = __nccwpck_require__(57211); +var $indexOf = callBind(GetIntrinsic('String.prototype.indexOf')); - // Not published yet. - iconv.IconvLiteEncoderStream = IconvLiteEncoderStream; - iconv.IconvLiteDecoderStream = IconvLiteDecoderStream; - iconv._collect = IconvLiteDecoderStream.prototype.collect; +module.exports = function callBoundIntrinsic(name, allowMissing) { + var intrinsic = GetIntrinsic(name, !!allowMissing); + if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) { + return callBind(intrinsic); + } + return intrinsic; }; -// == Encoder stream ======================================================= -function IconvLiteEncoderStream(conv, options) { - this.conv = conv; - options = options || {}; - options.decodeStrings = false; // We accept only strings, so we don't need to decode them. - Transform.call(this, options); -} - -IconvLiteEncoderStream.prototype = Object.create(Transform.prototype, { - constructor: { value: IconvLiteEncoderStream } -}); +/***/ }), -IconvLiteEncoderStream.prototype._transform = function(chunk, encoding, done) { - if (typeof chunk != 'string') - return done(new Error("Iconv encoding stream needs strings as its input.")); - try { - var res = this.conv.write(chunk); - if (res && res.length) this.push(res); - done(); - } - catch (e) { - done(e); - } -} +/***/ 57211: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -IconvLiteEncoderStream.prototype._flush = function(done) { - try { - var res = this.conv.end(); - if (res && res.length) this.push(res); - done(); - } - catch (e) { - done(e); - } -} +"use strict"; -IconvLiteEncoderStream.prototype.collect = function(cb) { - var chunks = []; - this.on('error', cb); - this.on('data', function(chunk) { chunks.push(chunk); }); - this.on('end', function() { - cb(null, Buffer.concat(chunks)); - }); - return this; -} +var bind = __nccwpck_require__(58115); +var GetIntrinsic = __nccwpck_require__(36546); +var setFunctionLength = __nccwpck_require__(80296); -// == Decoder stream ======================================================= -function IconvLiteDecoderStream(conv, options) { - this.conv = conv; - options = options || {}; - options.encoding = this.encoding = 'utf8'; // We output strings. - Transform.call(this, options); -} +var $TypeError = __nccwpck_require__(78279); +var $apply = GetIntrinsic('%Function.prototype.apply%'); +var $call = GetIntrinsic('%Function.prototype.call%'); +var $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply); -IconvLiteDecoderStream.prototype = Object.create(Transform.prototype, { - constructor: { value: IconvLiteDecoderStream } -}); +var $defineProperty = __nccwpck_require__(21410); +var $max = GetIntrinsic('%Math.max%'); -IconvLiteDecoderStream.prototype._transform = function(chunk, encoding, done) { - if (!Buffer.isBuffer(chunk)) - return done(new Error("Iconv decoding stream needs buffers as its input.")); - try { - var res = this.conv.write(chunk); - if (res && res.length) this.push(res, this.encoding); - done(); - } - catch (e) { - done(e); - } -} +module.exports = function callBind(originalFunction) { + if (typeof originalFunction !== 'function') { + throw new $TypeError('a function is required'); + } + var func = $reflectApply(bind, $call, arguments); + return setFunctionLength( + func, + 1 + $max(0, originalFunction.length - (arguments.length - 1)), + true + ); +}; -IconvLiteDecoderStream.prototype._flush = function(done) { - try { - var res = this.conv.end(); - if (res && res.length) this.push(res, this.encoding); - done(); - } - catch (e) { - done(e); - } -} +var applyBind = function applyBind() { + return $reflectApply(bind, $apply, arguments); +}; -IconvLiteDecoderStream.prototype.collect = function(cb) { - var res = ''; - this.on('error', cb); - this.on('data', function(chunk) { res += chunk; }); - this.on('end', function() { - cb(null, res); - }); - return this; +if ($defineProperty) { + $defineProperty(module.exports, 'apply', { value: applyBind }); +} else { + module.exports.apply = applyBind; } - /***/ }), -/***/ 40865: -/***/ ((module) => { +/***/ 71649: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; +const os = __nccwpck_require__(70857); -module.exports = (string, count = 1, options) => { - options = { - indent: ' ', - includeEmptyLines: false, - ...options - }; +const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; +const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; +const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir(); - if (typeof string !== 'string') { - throw new TypeError( - `Expected \`input\` to be a \`string\`, got \`${typeof string}\`` - ); - } +module.exports = (stack, options) => { + options = Object.assign({pretty: false}, options); - if (typeof count !== 'number') { - throw new TypeError( - `Expected \`count\` to be a \`number\`, got \`${typeof count}\`` - ); - } + return stack.replace(/\\/g, '/') + .split('\n') + .filter(line => { + const pathMatches = line.match(extractPathRegex); + if (pathMatches === null || !pathMatches[1]) { + return true; + } - if (typeof options.indent !== 'string') { - throw new TypeError( - `Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\`` - ); - } + const match = pathMatches[1]; - if (count === 0) { - return string; - } + // Electron + if ( + match.includes('.app/Contents/Resources/electron.asar') || + match.includes('.app/Contents/Resources/default_app.asar') + ) { + return false; + } - const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm; + return !pathRegex.test(match); + }) + .filter(line => line.trim() !== '') + .map(line => { + if (options.pretty) { + return line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~'))); + } - return string.replace(regex, options.indent.repeat(count)); + return line; + }) + .join('\n'); }; /***/ }), -/***/ 34383: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -try { - var util = __nccwpck_require__(39023); - /* istanbul ignore next */ - if (typeof util.inherits !== 'function') throw ''; - module.exports = util.inherits; -} catch (e) { - /* istanbul ignore next */ - module.exports = __nccwpck_require__(18580); -} - - -/***/ }), - -/***/ 18580: +/***/ 10491: /***/ ((module) => { -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }) - } - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } - } -} - - -/***/ }), - -/***/ 71773: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -const commands_1 = __nccwpck_require__(16297); -const calculateSlot = __nccwpck_require__(10491); -const standard_as_callback_1 = __nccwpck_require__(34167); -const utils_1 = __nccwpck_require__(38506); -/** - * Command instance - * - * It's rare that you need to create a Command instance yourself. +/* + * Copyright 2001-2010 Georges Menie (www.menie.org) + * Copyright 2010 Salvatore Sanfilippo (adapted to Redis coding style) + * Copyright 2015 Zihua Li (http://zihua.li) (ported to JavaScript) + * Copyright 2016 Mike Diarmid (http://github.com/salakar) (re-write for performance, ~700% perf inc) + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * ```js - * var infoCommand = new Command('info', null, function (err, result) { - * console.log('result', result); - * }); + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * redis.sendCommand(infoCommand); + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* CRC16 implementation according to CCITT standards. * - * // When no callback provided, Command instance will have a `promise` property, - * // which will resolve/reject with the result of the command. - * var getCommand = new Command('get', ['foo']); - * getCommand.promise.then(function (result) { - * console.log('result', result); - * }); - * ``` + * Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the + * following parameters: + * + * Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN" + * Width : 16 bit + * Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1) + * Initialization : 0000 + * Reflect Input byte : False + * Reflect Output CRC : False + * Xor constant to output CRC : 0000 + * Output for "123456789" : 31C3 */ -class Command { - /** - * Creates an instance of Command. - * @param name Command name - * @param args An array of command arguments - * @param options - * @param callback The callback that handles the response. - * If omit, the response will be handled via Promise - */ - constructor(name, args = [], options = {}, callback) { - this.name = name; - this.inTransaction = false; - this.isResolved = false; - this.transformed = false; - this.replyEncoding = options.replyEncoding; - this.errorStack = options.errorStack; - this.args = args.flat(); - this.callback = callback; - this.initPromise(); - if (options.keyPrefix) { - // @ts-expect-error - const isBufferKeyPrefix = options.keyPrefix instanceof Buffer; - // @ts-expect-error - let keyPrefixBuffer = isBufferKeyPrefix - ? options.keyPrefix - : null; - this._iterateKeys((key) => { - if (key instanceof Buffer) { - if (keyPrefixBuffer === null) { - keyPrefixBuffer = Buffer.from(options.keyPrefix); - } - return Buffer.concat([keyPrefixBuffer, key]); - } - else if (isBufferKeyPrefix) { - // @ts-expect-error - return Buffer.concat([options.keyPrefix, Buffer.from(String(key))]); - } - return options.keyPrefix + key; - }); - } - if (options.readOnly) { - this.isReadOnly = true; - } - } - /** - * Check whether the command has the flag - */ - static checkFlag(flagName, commandName) { - return !!this.getFlagMap()[flagName][commandName]; - } - static setArgumentTransformer(name, func) { - this._transformer.argument[name] = func; - } - static setReplyTransformer(name, func) { - this._transformer.reply[name] = func; - } - static getFlagMap() { - if (!this.flagMap) { - this.flagMap = Object.keys(Command.FLAGS).reduce((map, flagName) => { - map[flagName] = {}; - Command.FLAGS[flagName].forEach((commandName) => { - map[flagName][commandName] = true; - }); - return map; - }, {}); - } - return this.flagMap; - } - getSlot() { - if (typeof this.slot === "undefined") { - const key = this.getKeys()[0]; - this.slot = key == null ? null : calculateSlot(key); - } - return this.slot; - } - getKeys() { - return this._iterateKeys(); - } - /** - * Convert command to writable buffer or string - */ - toWritable(_socket) { - let result; - const commandStr = "*" + - (this.args.length + 1) + - "\r\n$" + - Buffer.byteLength(this.name) + - "\r\n" + - this.name + - "\r\n"; - if (this.bufferMode) { - const buffers = new MixedBuffers(); - buffers.push(commandStr); - for (let i = 0; i < this.args.length; ++i) { - const arg = this.args[i]; - if (arg instanceof Buffer) { - if (arg.length === 0) { - buffers.push("$0\r\n\r\n"); - } - else { - buffers.push("$" + arg.length + "\r\n"); - buffers.push(arg); - buffers.push("\r\n"); - } - } - else { - buffers.push("$" + - Buffer.byteLength(arg) + - "\r\n" + - arg + - "\r\n"); - } - } - result = buffers.toBuffer(); - } - else { - result = commandStr; - for (let i = 0; i < this.args.length; ++i) { - const arg = this.args[i]; - result += - "$" + - Buffer.byteLength(arg) + - "\r\n" + - arg + - "\r\n"; - } - } - return result; - } - stringifyArguments() { - for (let i = 0; i < this.args.length; ++i) { - const arg = this.args[i]; - if (typeof arg === "string") { - // buffers and strings don't need any transformation - } - else if (arg instanceof Buffer) { - this.bufferMode = true; - } - else { - this.args[i] = (0, utils_1.toArg)(arg); - } - } - } - /** - * Convert buffer/buffer[] to string/string[], - * and apply reply transformer. - */ - transformReply(result) { - if (this.replyEncoding) { - result = (0, utils_1.convertBufferToString)(result, this.replyEncoding); - } - const transformer = Command._transformer.reply[this.name]; - if (transformer) { - result = transformer(result); - } - return result; - } - /** - * Set the wait time before terminating the attempt to execute a command - * and generating an error. - */ - setTimeout(ms) { - if (!this._commandTimeoutTimer) { - this._commandTimeoutTimer = setTimeout(() => { - if (!this.isResolved) { - this.reject(new Error("Command timed out")); - } - }, ms); - } - } - initPromise() { - const promise = new Promise((resolve, reject) => { - if (!this.transformed) { - this.transformed = true; - const transformer = Command._transformer.argument[this.name]; - if (transformer) { - this.args = transformer(this.args); - } - this.stringifyArguments(); - } - this.resolve = this._convertValue(resolve); - if (this.errorStack) { - this.reject = (err) => { - reject((0, utils_1.optimizeErrorStack)(err, this.errorStack.stack, __dirname)); - }; - } - else { - this.reject = reject; - } - }); - this.promise = (0, standard_as_callback_1.default)(promise, this.callback); - } - /** - * Iterate through the command arguments that are considered keys. - */ - _iterateKeys(transform = (key) => key) { - if (typeof this.keys === "undefined") { - this.keys = []; - if ((0, commands_1.exists)(this.name)) { - // @ts-expect-error - const keyIndexes = (0, commands_1.getKeyIndexes)(this.name, this.args); - for (const index of keyIndexes) { - this.args[index] = transform(this.args[index]); - this.keys.push(this.args[index]); - } - } - } - return this.keys; - } - /** - * Convert the value from buffer to the target encoding. - */ - _convertValue(resolve) { - return (value) => { - try { - const existingTimer = this._commandTimeoutTimer; - if (existingTimer) { - clearTimeout(existingTimer); - delete this._commandTimeoutTimer; - } - resolve(this.transformReply(value)); - this.isResolved = true; - } - catch (err) { - this.reject(err); - } - return this.promise; - }; + +var lookup = [ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +]; + +/** + * Convert a string to a UTF8 array - faster than via buffer + * @param str + * @returns {Array} + */ +var toUTF8Array = function toUTF8Array(str) { + var char; + var i = 0; + var p = 0; + var utf8 = []; + var len = str.length; + + for (; i < len; i++) { + char = str.charCodeAt(i); + if (char < 128) { + utf8[p++] = char; + } else if (char < 2048) { + utf8[p++] = (char >> 6) | 192; + utf8[p++] = (char & 63) | 128; + } else if ( + ((char & 0xFC00) === 0xD800) && (i + 1) < str.length && + ((str.charCodeAt(i + 1) & 0xFC00) === 0xDC00)) { + char = 0x10000 + ((char & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF); + utf8[p++] = (char >> 18) | 240; + utf8[p++] = ((char >> 12) & 63) | 128; + utf8[p++] = ((char >> 6) & 63) | 128; + utf8[p++] = (char & 63) | 128; + } else { + utf8[p++] = (char >> 12) | 224; + utf8[p++] = ((char >> 6) & 63) | 128; + utf8[p++] = (char & 63) | 128; } -} -exports["default"] = Command; -Command.FLAGS = { - VALID_IN_SUBSCRIBER_MODE: [ - "subscribe", - "psubscribe", - "unsubscribe", - "punsubscribe", - "ssubscribe", - "sunsubscribe", - "ping", - "quit", - ], - VALID_IN_MONITOR_MODE: ["monitor", "auth"], - ENTER_SUBSCRIBER_MODE: ["subscribe", "psubscribe", "ssubscribe"], - EXIT_SUBSCRIBER_MODE: ["unsubscribe", "punsubscribe", "sunsubscribe"], - WILL_DISCONNECT: ["quit"], -}; -Command._transformer = { - argument: {}, - reply: {}, + } + + return utf8; }; -const msetArgumentTransformer = function (args) { - if (args.length === 1) { - if (args[0] instanceof Map) { - return (0, utils_1.convertMapToArray)(args[0]); - } - if (typeof args[0] === "object" && args[0] !== null) { - return (0, utils_1.convertObjectToArray)(args[0]); - } + +/** + * Convert a string into a redis slot hash. + * @param str + * @returns {number} + */ +var generate = module.exports = function generate(str) { + var char; + var i = 0; + var start = -1; + var result = 0; + var resultHash = 0; + var utf8 = typeof str === 'string' ? toUTF8Array(str) : str; + var len = utf8.length; + + while (i < len) { + char = utf8[i++]; + if (start === -1) { + if (char === 0x7B) { + start = i; + } + } else if (char !== 0x7D) { + resultHash = lookup[(char ^ (resultHash >> 8)) & 0xFF] ^ (resultHash << 8); + } else if (i - 1 !== start) { + return resultHash & 0x3FFF; } - return args; + + result = lookup[(char ^ (result >> 8)) & 0xFF] ^ (result << 8); + } + + return result & 0x3FFF; }; -const hsetArgumentTransformer = function (args) { - if (args.length === 2) { - if (args[1] instanceof Map) { - return [args[0]].concat((0, utils_1.convertMapToArray)(args[1])); - } - if (typeof args[1] === "object" && args[1] !== null) { - return [args[0]].concat((0, utils_1.convertObjectToArray)(args[1])); - } - } - return args; + +/** + * Convert an array of multiple strings into a redis slot hash. + * Returns -1 if one of the keys is not for the same slot as the others + * @param keys + * @returns {number} + */ +module.exports.generateMulti = function generateMulti(keys) { + var i = 1; + var len = keys.length; + var base = generate(keys[0]); + + while (i < len) { + if (generate(keys[i++]) !== base) return -1; + } + + return base; }; -Command.setArgumentTransformer("mset", msetArgumentTransformer); -Command.setArgumentTransformer("msetnx", msetArgumentTransformer); -Command.setArgumentTransformer("hset", hsetArgumentTransformer); -Command.setArgumentTransformer("hmset", hsetArgumentTransformer); -Command.setReplyTransformer("hgetall", function (result) { - if (Array.isArray(result)) { - const obj = {}; - for (let i = 0; i < result.length; i += 2) { - const key = result[i]; - const value = result[i + 1]; - if (key in obj) { - // can only be truthy if the property is special somehow, like '__proto__' or 'constructor' - // https://github.com/luin/ioredis/issues/1267 - Object.defineProperty(obj, key, { - value, - configurable: true, - enumerable: true, - writable: true, - }); - } - else { - obj[key] = value; - } - } - return obj; - } - return result; -}); -class MixedBuffers { - constructor() { - this.length = 0; - this.items = []; - } - push(x) { - this.length += Buffer.byteLength(x); - this.items.push(x); - } - toBuffer() { - const result = Buffer.allocUnsafe(this.length); - let offset = 0; - for (const item of this.items) { - const length = Buffer.byteLength(item); - Buffer.isBuffer(item) - ? item.copy(result, offset) - : result.write(item, offset, length); - offset += length; - } - return result; - } -} /***/ }), -/***/ 17768: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 45942: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; +/*! + * content-disposition + * Copyright(c) 2014-2017 Douglas Christopher Wilson + * MIT Licensed + */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -const Command_1 = __nccwpck_require__(71773); -const utils_1 = __nccwpck_require__(38506); -const RedisParser = __nccwpck_require__(66752); -const SubscriptionSet_1 = __nccwpck_require__(44563); -const debug = (0, utils_1.Debug)("dataHandler"); -class DataHandler { - constructor(redis, parserOptions) { - this.redis = redis; - const parser = new RedisParser({ - stringNumbers: parserOptions.stringNumbers, - returnBuffers: true, - returnError: (err) => { - this.returnError(err); - }, - returnFatalError: (err) => { - this.returnFatalError(err); - }, - returnReply: (reply) => { - this.returnReply(reply); - }, - }); - redis.stream.on("data", (data) => { - parser.execute(data); - }); - } - returnFatalError(err) { - err.message += ". Please report this."; - this.redis.recoverFromFatalError(err, err, { offlineQueue: false }); - } - returnError(err) { - const item = this.shiftCommand(err); - if (!item) { - return; - } - err.command = { + + +/** + * Module exports. + * @public + */ + +module.exports = contentDisposition +module.exports.parse = parse + +/** + * Module dependencies. + * @private + */ + +var basename = (__nccwpck_require__(16928).basename) +var Buffer = (__nccwpck_require__(26843).Buffer) + +/** + * RegExp to match non attr-char, *after* encodeURIComponent (i.e. not including "%") + * @private + */ + +var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g // eslint-disable-line no-control-regex + +/** + * RegExp to match percent encoding escape. + * @private + */ + +var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/ +var HEX_ESCAPE_REPLACE_REGEXP = /%([0-9A-Fa-f]{2})/g + +/** + * RegExp to match non-latin1 characters. + * @private + */ + +var NON_LATIN1_REGEXP = /[^\x20-\x7e\xa0-\xff]/g + +/** + * RegExp to match quoted-pair in RFC 2616 + * + * quoted-pair = "\" CHAR + * CHAR = + * @private + */ + +var QESC_REGEXP = /\\([\u0000-\u007f])/g // eslint-disable-line no-control-regex + +/** + * RegExp to match chars that must be quoted-pair in RFC 2616 + * @private + */ + +var QUOTE_REGEXP = /([\\"])/g + +/** + * RegExp for various RFC 2616 grammar + * + * parameter = token "=" ( token | quoted-string ) + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + * quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) + * qdtext = > + * quoted-pair = "\" CHAR + * CHAR = + * TEXT = + * LWS = [CRLF] 1*( SP | HT ) + * CRLF = CR LF + * CR = + * LF = + * SP = + * HT = + * CTL = + * OCTET = + * @private + */ + +var PARAM_REGEXP = /;[\x09\x20]*([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*=[\x09\x20]*("(?:[\x20!\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*/g // eslint-disable-line no-control-regex +var TEXT_REGEXP = /^[\x20-\x7e\x80-\xff]+$/ +var TOKEN_REGEXP = /^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/ + +/** + * RegExp for various RFC 5987 grammar + * + * ext-value = charset "'" [ language ] "'" value-chars + * charset = "UTF-8" / "ISO-8859-1" / mime-charset + * mime-charset = 1*mime-charsetc + * mime-charsetc = ALPHA / DIGIT + * / "!" / "#" / "$" / "%" / "&" + * / "+" / "-" / "^" / "_" / "`" + * / "{" / "}" / "~" + * language = ( 2*3ALPHA [ extlang ] ) + * / 4ALPHA + * / 5*8ALPHA + * extlang = *3( "-" 3ALPHA ) + * value-chars = *( pct-encoded / attr-char ) + * pct-encoded = "%" HEXDIG HEXDIG + * attr-char = ALPHA / DIGIT + * / "!" / "#" / "$" / "&" / "+" / "-" / "." + * / "^" / "_" / "`" / "|" / "~" + * @private + */ + +var EXT_VALUE_REGEXP = /^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+.^_`|~-])+)$/ + +/** + * RegExp for various RFC 6266 grammar + * + * disposition-type = "inline" | "attachment" | disp-ext-type + * disp-ext-type = token + * disposition-parm = filename-parm | disp-ext-parm + * filename-parm = "filename" "=" value + * | "filename*" "=" ext-value + * disp-ext-parm = token "=" value + * | ext-token "=" ext-value + * ext-token = + * @private + */ + +var DISPOSITION_TYPE_REGEXP = /^([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*(?:$|;)/ // eslint-disable-line no-control-regex + +/** + * Create an attachment Content-Disposition header. + * + * @param {string} [filename] + * @param {object} [options] + * @param {string} [options.type=attachment] + * @param {string|boolean} [options.fallback=true] + * @return {string} + * @public + */ + +function contentDisposition (filename, options) { + var opts = options || {} + + // get type + var type = opts.type || 'attachment' + + // get parameters + var params = createparams(filename, opts.fallback) + + // format into string + return format(new ContentDisposition(type, params)) +} + +/** + * Create parameters object from filename and fallback. + * + * @param {string} [filename] + * @param {string|boolean} [fallback=true] + * @return {object} + * @private + */ + +function createparams (filename, fallback) { + if (filename === undefined) { + return + } + + var params = {} + + if (typeof filename !== 'string') { + throw new TypeError('filename must be a string') + } + + // fallback defaults to true + if (fallback === undefined) { + fallback = true + } + + if (typeof fallback !== 'string' && typeof fallback !== 'boolean') { + throw new TypeError('fallback must be a string or boolean') + } + + if (typeof fallback === 'string' && NON_LATIN1_REGEXP.test(fallback)) { + throw new TypeError('fallback must be ISO-8859-1 string') + } + + // restrict to file base name + var name = basename(filename) + + // determine if name is suitable for quoted string + var isQuotedString = TEXT_REGEXP.test(name) + + // generate fallback name + var fallbackName = typeof fallback !== 'string' + ? fallback && getlatin1(name) + : basename(fallback) + var hasFallback = typeof fallbackName === 'string' && fallbackName !== name + + // set extended filename parameter + if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) { + params['filename*'] = name + } + + // set filename parameter + if (isQuotedString || hasFallback) { + params.filename = hasFallback + ? fallbackName + : name + } + + return params +} + +/** + * Format object to Content-Disposition header. + * + * @param {object} obj + * @param {string} obj.type + * @param {object} [obj.parameters] + * @return {string} + * @private + */ + +function format (obj) { + var parameters = obj.parameters + var type = obj.type + + if (!type || typeof type !== 'string' || !TOKEN_REGEXP.test(type)) { + throw new TypeError('invalid type') + } + + // start with normalized type + var string = String(type).toLowerCase() + + // append parameters + if (parameters && typeof parameters === 'object') { + var param + var params = Object.keys(parameters).sort() + + for (var i = 0; i < params.length; i++) { + param = params[i] + + var val = param.substr(-1) === '*' + ? ustring(parameters[param]) + : qstring(parameters[param]) + + string += '; ' + param + '=' + val + } + } + + return string +} + +/** + * Decode a RFC 5987 field value (gracefully). + * + * @param {string} str + * @return {string} + * @private + */ + +function decodefield (str) { + var match = EXT_VALUE_REGEXP.exec(str) + + if (!match) { + throw new TypeError('invalid extended field value') + } + + var charset = match[1].toLowerCase() + var encoded = match[2] + var value + + // to binary string + var binary = encoded.replace(HEX_ESCAPE_REPLACE_REGEXP, pdecode) + + switch (charset) { + case 'iso-8859-1': + value = getlatin1(binary) + break + case 'utf-8': + value = Buffer.from(binary, 'binary').toString('utf8') + break + default: + throw new TypeError('unsupported charset in extended field') + } + + return value +} + +/** + * Get ISO-8859-1 version of string. + * + * @param {string} val + * @return {string} + * @private + */ + +function getlatin1 (val) { + // simple Unicode -> ISO-8859-1 transformation + return String(val).replace(NON_LATIN1_REGEXP, '?') +} + +/** + * Parse Content-Disposition header string. + * + * @param {string} string + * @return {object} + * @public + */ + +function parse (string) { + if (!string || typeof string !== 'string') { + throw new TypeError('argument string is required') + } + + var match = DISPOSITION_TYPE_REGEXP.exec(string) + + if (!match) { + throw new TypeError('invalid type format') + } + + // normalize type + var index = match[0].length + var type = match[1].toLowerCase() + + var key + var names = [] + var params = {} + var value + + // calculate index to start at + index = PARAM_REGEXP.lastIndex = match[0].substr(-1) === ';' + ? index - 1 + : index + + // match parameters + while ((match = PARAM_REGEXP.exec(string))) { + if (match.index !== index) { + throw new TypeError('invalid parameter format') + } + + index += match[0].length + key = match[1].toLowerCase() + value = match[2] + + if (names.indexOf(key) !== -1) { + throw new TypeError('invalid duplicate parameter') + } + + names.push(key) + + if (key.indexOf('*') + 1 === key.length) { + // decode extended value + key = key.slice(0, -1) + value = decodefield(value) + + // overwrite existing value + params[key] = value + continue + } + + if (typeof params[key] === 'string') { + continue + } + + if (value[0] === '"') { + // remove quotes and escapes + value = value + .substr(1, value.length - 2) + .replace(QESC_REGEXP, '$1') + } + + params[key] = value + } + + if (index !== -1 && index !== string.length) { + throw new TypeError('invalid parameter format') + } + + return new ContentDisposition(type, params) +} + +/** + * Percent decode a single character. + * + * @param {string} str + * @param {string} hex + * @return {string} + * @private + */ + +function pdecode (str, hex) { + return String.fromCharCode(parseInt(hex, 16)) +} + +/** + * Percent encode a single character. + * + * @param {string} char + * @return {string} + * @private + */ + +function pencode (char) { + return '%' + String(char) + .charCodeAt(0) + .toString(16) + .toUpperCase() +} + +/** + * Quote a string for HTTP. + * + * @param {string} val + * @return {string} + * @private + */ + +function qstring (val) { + var str = String(val) + + return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"' +} + +/** + * Encode a Unicode string for HTTP (RFC 5987). + * + * @param {string} val + * @return {string} + * @private + */ + +function ustring (val) { + var str = String(val) + + // percent encode as UTF-8 + var encoded = encodeURIComponent(str) + .replace(ENCODE_URL_ATTR_CHAR_REGEXP, pencode) + + return 'UTF-8\'\'' + encoded +} + +/** + * Class for parsed Content-Disposition header for v8 optimization + * + * @public + * @param {string} type + * @param {object} parameters + * @constructor + */ + +function ContentDisposition (type, parameters) { + this.type = type + this.parameters = parameters +} + + +/***/ }), + +/***/ 22541: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; +/*! + * content-type + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + + + +/** + * RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1 + * + * parameter = token "=" ( token / quoted-string ) + * token = 1*tchar + * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" + * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" + * / DIGIT / ALPHA + * ; any VCHAR, except delimiters + * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE + * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text + * obs-text = %x80-FF + * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + */ +var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g // eslint-disable-line no-control-regex +var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/ // eslint-disable-line no-control-regex +var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/ + +/** + * RegExp to match quoted-pair in RFC 7230 sec 3.2.6 + * + * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + * obs-text = %x80-FF + */ +var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g // eslint-disable-line no-control-regex + +/** + * RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6 + */ +var QUOTE_REGEXP = /([\\"])/g + +/** + * RegExp to match type in RFC 7231 sec 3.1.1.1 + * + * media-type = type "/" subtype + * type = token + * subtype = token + */ +var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/ + +/** + * Module exports. + * @public + */ + +exports.format = format +exports.parse = parse + +/** + * Format object to media type. + * + * @param {object} obj + * @return {string} + * @public + */ + +function format (obj) { + if (!obj || typeof obj !== 'object') { + throw new TypeError('argument obj is required') + } + + var parameters = obj.parameters + var type = obj.type + + if (!type || !TYPE_REGEXP.test(type)) { + throw new TypeError('invalid type') + } + + var string = type + + // append parameters + if (parameters && typeof parameters === 'object') { + var param + var params = Object.keys(parameters).sort() + + for (var i = 0; i < params.length; i++) { + param = params[i] + + if (!TOKEN_REGEXP.test(param)) { + throw new TypeError('invalid parameter name') + } + + string += '; ' + param + '=' + qstring(parameters[param]) + } + } + + return string +} + +/** + * Parse media type to object. + * + * @param {string|object} string + * @return {Object} + * @public + */ + +function parse (string) { + if (!string) { + throw new TypeError('argument string is required') + } + + // support req/res-like objects as argument + var header = typeof string === 'object' + ? getcontenttype(string) + : string + + if (typeof header !== 'string') { + throw new TypeError('argument string is required to be a string') + } + + var index = header.indexOf(';') + var type = index !== -1 + ? header.slice(0, index).trim() + : header.trim() + + if (!TYPE_REGEXP.test(type)) { + throw new TypeError('invalid media type') + } + + var obj = new ContentType(type.toLowerCase()) + + // parse parameters + if (index !== -1) { + var key + var match + var value + + PARAM_REGEXP.lastIndex = index + + while ((match = PARAM_REGEXP.exec(header))) { + if (match.index !== index) { + throw new TypeError('invalid parameter format') + } + + index += match[0].length + key = match[1].toLowerCase() + value = match[2] + + if (value.charCodeAt(0) === 0x22 /* " */) { + // remove quotes + value = value.slice(1, -1) + + // remove escapes + if (value.indexOf('\\') !== -1) { + value = value.replace(QESC_REGEXP, '$1') + } + } + + obj.parameters[key] = value + } + + if (index !== header.length) { + throw new TypeError('invalid parameter format') + } + } + + return obj +} + +/** + * Get content-type from req/res objects. + * + * @param {object} + * @return {Object} + * @private + */ + +function getcontenttype (obj) { + var header + + if (typeof obj.getHeader === 'function') { + // res-like + header = obj.getHeader('content-type') + } else if (typeof obj.headers === 'object') { + // req-like + header = obj.headers && obj.headers['content-type'] + } + + if (typeof header !== 'string') { + throw new TypeError('content-type header is missing from object') + } + + return header +} + +/** + * Quote a string if necessary. + * + * @param {string} val + * @return {string} + * @private + */ + +function qstring (val) { + var str = String(val) + + // no need to quote tokens + if (TOKEN_REGEXP.test(str)) { + return str + } + + if (str.length > 0 && !TEXT_REGEXP.test(str)) { + throw new TypeError('invalid parameter value') + } + + return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"' +} + +/** + * Class to represent a content type. + * @private + */ +function ContentType (type) { + this.parameters = Object.create(null) + this.type = type +} + + +/***/ }), + +/***/ 93628: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +/** + * Module dependencies. + */ + +var crypto = __nccwpck_require__(76982); + +/** + * Sign the given `val` with `secret`. + * + * @param {String} val + * @param {String} secret + * @return {String} + * @api private + */ + +exports.sign = function(val, secret){ + if ('string' != typeof val) throw new TypeError("Cookie value must be provided as a string."); + if ('string' != typeof secret) throw new TypeError("Secret string must be provided."); + return val + '.' + crypto + .createHmac('sha256', secret) + .update(val) + .digest('base64') + .replace(/\=+$/, ''); +}; + +/** + * Unsign and decode the given `val` with `secret`, + * returning `false` if the signature is invalid. + * + * @param {String} val + * @param {String} secret + * @return {String|Boolean} + * @api private + */ + +exports.unsign = function(val, secret){ + if ('string' != typeof val) throw new TypeError("Signed cookie string must be provided."); + if ('string' != typeof secret) throw new TypeError("Secret string must be provided."); + var str = val.slice(0, val.lastIndexOf('.')) + , mac = exports.sign(str, secret); + + return sha1(mac) == sha1(val) ? str : false; +}; + +/** + * Private + */ + +function sha1(str){ + return crypto.createHash('sha1').update(str).digest('hex'); +} + + +/***/ }), + +/***/ 22975: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; +/*! + * cookie + * Copyright(c) 2012-2014 Roman Shtylman + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + + + +/** + * Module exports. + * @public + */ + +exports.parse = parse; +exports.serialize = serialize; + +/** + * Module variables. + * @private + */ + +var __toString = Object.prototype.toString + +/** + * RegExp to match cookie-name in RFC 6265 sec 4.1.1 + * This refers out to the obsoleted definition of token in RFC 2616 sec 2.2 + * which has been replaced by the token definition in RFC 7230 appendix B. + * + * cookie-name = token + * token = 1*tchar + * tchar = "!" / "#" / "$" / "%" / "&" / "'" / + * "*" / "+" / "-" / "." / "^" / "_" / + * "`" / "|" / "~" / DIGIT / ALPHA + */ + +var cookieNameRegExp = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/; + +/** + * RegExp to match cookie-value in RFC 6265 sec 4.1.1 + * + * cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) + * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + * ; US-ASCII characters excluding CTLs, + * ; whitespace DQUOTE, comma, semicolon, + * ; and backslash + */ + +var cookieValueRegExp = /^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/; + +/** + * RegExp to match domain-value in RFC 6265 sec 4.1.1 + * + * domain-value = + * ; defined in [RFC1034], Section 3.5, as + * ; enhanced by [RFC1123], Section 2.1 + * =