PageSourceSearch

https://mail.cop.es/-.._._.--.._1781955014/webmail/bundle.js?26062009

js cop.es collected 2026-10-02 05:50:09 UTC 1,692,216 bytes, 50,077 lines download raw bytes

1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2"use strict";
3var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'identifier\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\' data-ad-format="\'+T.e(c,v,\'format\')+\'" \'',3:'\' \'+T.e(c,v,\'key\')+\':\'+T.e(c,v,\'value\')+\';\''};module.exports=function(c){var c={c:c,p:0};return'<ins '+T.u(c,v,'hook')+' class=" adsbygoogle o-ad__ins '+T.s(s,c,v,'identifier', s[0])+' '+T.s(s,c,v,'class_name', s[1])+'" data-ad-client="'+T.e(c,v,'client_id')+'" data-ad-slot="'+T.e(c,v,'slot_id')+'" '+T.s(s,c,v,'format', s[2])+' style="'+T.s(s,c,v,'style', s[3])+' "></ins> '}
4},{"icebrace-runtime":"icebrace-runtime"}],2:[function(require,module,exports){
5"use strict";
6var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\' <div class="\'+T.s(s,c,v,\'class_name\', s[0])+\'" style="background-image: url(\\\'\'+T.e(c,v,\'src\')+\'\\\')"></div> \'',2:'\'\'+T.c(\'_name\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div class="o-ad" '+T.u(c,v,'hook')+'> '+T.s(s,c,v,'image', s[1])+''+T.s(s,c,v,'component', s[2])+'</div> '}
7},{"icebrace-runtime":"icebrace-runtime"}],3:[function(require,module,exports){
8"use strict";
9var T=require("icebrace-runtime"),v,s={0:'\' o-addon--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',3:'\'\'+T.e(c,v,\'text\')+\'\''};module.exports=function(c){var c={c:c,p:0};return'<a class=" o-addon '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' "'+T.u(c,v,'hook')+' tabIndex="-1">'+T.s(s,c,v,'icon', s[2])+''+T.s(s,c,v,'text', s[3])+'</a> '}
10},{"icebrace-runtime":"icebrace-runtime"}],4:[function(require,module,exports){
11"use strict";
12var T=require("icebrace-runtime"),v,s={0:'\' o-avatar--image \'',1:'\' o-avatar--letter \'',2:'\'\'+T.e(c,v,\'.\')+\'\'',3:'\' o-avatar--\'+T.e(c,v,\'.\')+\' \'',4:'\' style="background-image: url(\\\'\'+T.e(c,v,\'image\')+\'\\\')" \'',5:'\' data-\'+T.e(c,v,\'tag\')+\'="\'+T.e(c,v,\'value\')+\'" \'',6:'\' \'+T.s(s,c,v,\'data\', s[5])+\' \'',7:'\'\'+T.e(c,v,\'letter\')+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div class=" o-avatar '+T.s(s,c,v,'image', s[0])+' '+T.i(s,c,v,'image', s[1])+' '+T.s(s,c,v,'class_name', s[2])+' '+T.s(s,c,v,'mod', s[3])+' " '+T.s(s,c,v,'image', s[4])+' '+T.i(s,c,v,'image', s[6])+'>'+T.i(s,c,v,'image', s[7])+'</div> '}
13},{"icebrace-runtime":"icebrace-runtime"}],5:[function(require,module,exports){
14"use strict";
15var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',2:'\' <label class="o-dropdown__text">\'+T.e(c,v,\'code\')+\'</label> \''};module.exports=function(c){var c={c:c,p:0};return'<div class="o-dropdown'+T.s(s,c,v,'class_name', s[0])+'" '+T.u(c,v,'hook')+'> '+T.s(s,c,v,'icon', s[1])+''+T.s(s,c,v,'code', s[2])+'</div> '}
16},{"icebrace-runtime":"icebrace-runtime"}],6:[function(require,module,exports){
17"use strict";
18var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\' name="\'+T.e(c,v,\'name\')+\'"\'',2:'\' type="button"\'',3:'\' type="\'+T.e(c,v,\'type\')+\'"\'',4:'\' value="\'+T.e(c,v,\'value\')+\'"\'',5:'\' disabled="\'+T.e(c,v,\'disabled\')+\'"\'',6:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',7:'\'<span>\'+T.e(c,v,\'text\')+\'</span>\''};module.exports=function(c){var c={c:c,p:0};return'<button '+T.u(c,v,'hook')+' '+T.s(s,c,v,'class_name', s[0])+' '+T.s(s,c,v,'name', s[1])+' '+T.i(s,c,v,'type', s[2])+' '+T.s(s,c,v,'type', s[3])+' '+T.s(s,c,v,'value', s[4])+' '+T.s(s,c,v,'disabled', s[5])+' >'+T.s(s,c,v,'icon', s[6])+''+T.s(s,c,v,'text', s[7])+'</button> '}
19},{"icebrace-runtime":"icebrace-runtime"}],7:[function(require,module,exports){
20"use strict";
21var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\'\'',1:'\' type="\'+T.e(c,v,\'type\')+\'"\'',2:'\' accept="\'+T.e(c,v,\'accept\')+\'"\'',3:'\' name="\'+T.e(c,v,\'name\')+\'"\'',4:'\' value="\'+T.e(c,v,\'value\')+\'"\'',5:'\' placeholder="\'+T.e(c,v,\'placeholder\')+\'"\'',6:'\' autocomplete="\'+T.e(c,v,\'autocomplete\')+\'"\'',7:'\' max="\'+T.e(c,v,\'max\')+\'"\'',8:'\' min="\'+T.e(c,v,\'min\')+\'"\'',9:'\' size="\'+T.e(c,v,\'size\')+\'"\'',10:'\' maxlength="\'+T.e(c,v,\'maxlength\')+\'"\'',11:'\' minlength="\'+T.e(c,v,\'minlength\')+\'"\'',12:'\' multiple="\'+T.e(c,v,\'multiple\')+\'"\'',13:'\' readonly="readonly"\'',14:'\' checked="checked"\'',15:'\' disabled="disabled"\'',16:'\' required\''};module.exports=function(c){var c={c:c,p:0};return'<input class="'+T.s(s,c,v,'class_name', s[0])+'" '+T.s(s,c,v,'type', s[1])+' '+T.s(s,c,v,'accept', s[2])+' '+T.s(s,c,v,'name', s[3])+' '+T.s(s,c,v,'value', s[4])+' '+T.s(s,c,v,'placeholder', s[5])+' '+T.s(s,c,v,'autocomplete', s[6])+' '+T.s(s,c,v,'max', s[7])+' '+T.s(s,c,v,'min', s[8])+' '+T.s(s,c,v,'size', s[9])+' '+T.s(s,c,v,'maxlength', s[10])+' '+T.s(s,c,v,'minlength', s[11])+' '+T.s(s,c,v,'multiple', s[12])+' '+T.s(s,c,v,'readonly', s[13])+' '+T.s(s,c,v,'checked', s[14])+' '+T.s(s,c,v,'disabled', s[15])+' '+T.s(s,c,v,'required', s[16])+' '+T.u(c,v,'hook')+' > '}
22},{"icebrace-runtime":"icebrace-runtime"}],8:[function(require,module,exports){
23"use strict";
24var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\' name="\'+T.e(c,v,\'name\')+\'"\'',2:'\' size="\'+T.e(c,v,\'size\')+\'"\'',3:'\' disabled="disabled"\'',4:'\' readonly="readonly"\'',5:'\' multiple="true"\'',6:'\'\'+T.e(c,v,\'value\')+\'\'',7:'\' label="\'+T.e(c,v,\'label\')+\'"\'',8:'\' selected="selected"\'',9:'\' hidden="hidden"\'',10:'\' disabled="disabled"\'',11:'\' <option value="\'+T.s(s,c,v,\'value\', s[6])+\'" \'+T.s(s,c,v,\'label\', s[7])+\' \'+T.s(s,c,v,\'selected\', s[8])+\' \'+T.s(s,c,v,\'hidden\', s[9])+\' \'+T.s(s,c,v,\'disabled\', s[10])+\' >\'+T.e(c,v,\'text\')+\'</option> \''};module.exports=function(c){var c={c:c,p:0};return'<select '+T.u(c,v,'hook')+' class="'+T.s(s,c,v,'class_name', s[0])+'" '+T.s(s,c,v,'name', s[1])+' '+T.s(s,c,v,'size', s[2])+' '+T.s(s,c,v,'disabled', s[3])+' '+T.s(s,c,v,'readonly', s[4])+' '+T.s(s,c,v,'multiple', s[5])+'> '+T.s(s,c,v,'options', s[11])+'</select> '}
25},{"icebrace-runtime":"icebrace-runtime"}],9:[function(require,module,exports){
26"use strict";
27var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\' name="\'+T.e(c,v,\'name\')+\'"\'',2:'\' placeholder="\'+T.e(c,v,\'placeholder\')+\'"\'',3:'\' cols="\'+T.e(c,v,\'cols\')+\'"\'',4:'\' rows="\'+T.e(c,v,\'rows\')+\'"\'',5:'\' disabled="disabled"\'',6:'\' readonly="readonly"\'',7:'\' maxlength="\'+T.e(c,v,\'maxlength\')+\'"\'',8:'\' minlength="\'+T.e(c,v,\'minlength\')+\'"\'',9:'\' autocomplete="\'+T.e(c,v,\'autocomplete\')+\'"\'',10:'\' required\'',11:'\'\'+T.e(c,v,\'text\')+\'\''};module.exports=function(c){var c={c:c,p:0};return'<textarea class="'+T.s(s,c,v,'class_name', s[0])+'" '+T.s(s,c,v,'name', s[1])+' '+T.s(s,c,v,'placeholder', s[2])+' '+T.s(s,c,v,'cols', s[3])+' '+T.s(s,c,v,'rows', s[4])+' '+T.s(s,c,v,'disabled', s[5])+' '+T.s(s,c,v,'readonly', s[6])+' '+T.s(s,c,v,'maxlength', s[7])+' '+T.s(s,c,v,'minlength', s[8])+' '+T.s(s,c,v,'autocomplete', s[9])+' '+T.s(s,c,v,'required', s[10])+' '+T.u(c,v,'hook')+' >'+T.s(s,c,v,'text', s[11])+'</textarea> '}
28},{"icebrace-runtime":"icebrace-runtime"}],10:[function(require,module,exports){
29"use strict";
30var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \''};module.exports=function(c){var c={c:c,p:0};return'<svg '+T.u(c,v,'hook')+' class=" o-icon '+T.s(s,c,v,'class_name', s[0])+' "><use xlink:href="./images/icons/icons.svg?2#'+T.e(c,v,'icon')+'"></use></svg> '}
31},{"icebrace-runtime":"icebrace-runtime"}],11:[function(require,module,exports){
32"use strict";
33var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \''};module.exports=function(c){var c={c:c,p:0};return'<img class="'+T.s(s,c,v,'class_name', s[0])+'" src="'+T.e(c,v,'src')+'"> '}
34},{"icebrace-runtime":"icebrace-runtime"}],12:[function(require,module,exports){
35"use strict";
36var T=require("icebrace-runtime"),v,s={0:'\' o-info--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.u(c,v,\'text\')+\'\'',3:'\'\'+T.c(\'atoms-link\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<p class=" o-info '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' " '+T.u(c,v,'hook')+'>'+T.s(s,c,v,'text', s[2])+' '+T.s(s,c,v,'link', s[3])+'</p> '}
37},{"icebrace-runtime":"icebrace-runtime"}],13:[function(require,module,exports){
38"use strict";
39var T=require("icebrace-runtime"),v,s={0:'\' \'+T.u(c,v,\'hook\')+\'\'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.e(c,v,\'text\')+\'\'',3:'\' - \'+T.e(c,v,\'error\')+\'\''};module.exports=function(c){var c={c:c,p:0};return'<span'+T.s(s,c,v,'hook', s[0])+' class=" o-label '+T.s(s,c,v,'class_name', s[1])+' ">'+T.s(s,c,v,'text', s[2])+''+T.s(s,c,v,'error', s[3])+'</span> '}
40},{"icebrace-runtime":"icebrace-runtime"}],14:[function(require,module,exports){
41"use strict";
42var T=require("icebrace-runtime"),v,s={0:'\' o-link--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',3:'\'\'+T.e(c,v,\'text\')+\'\''};module.exports=function(c){var c={c:c,p:0};return'<a class=" o-link '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' " '+T.u(c,v,'hook')+'>'+T.s(s,c,v,'icon', s[2])+''+T.s(s,c,v,'text', s[3])+'</a> '}
43},{"icebrace-runtime":"icebrace-runtime"}],15:[function(require,module,exports){
44"use strict";
45var T=require("icebrace-runtime"),v,s={0:'\' o-loader--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \''};module.exports=function(c){var c={c:c,p:0};return'<div class=" o-loader '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' "></div> '}
46},{"icebrace-runtime":"icebrace-runtime"}],16:[function(require,module,exports){
47"use strict";
48var T=require("icebrace-runtime"),v,s={0:'\' o-section--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'_name\', c.c
48)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<section class=" o-section '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' " '+T.u(c,v,'hook')+'> '+T.s(s,c,v,'component', s[2])+'</section> '}
49},{"icebrace-runtime":"icebrace-runtime"}],17:[function(require,module,exports){
50"use strict";
51var T=require("icebrace-runtime"),v,s={};module.exports=function(c){var c={c:c,p:0};return'<span class="o-form__element" '+T.u(c,v,'hook')+'>'+T.e(c,v,'value')+'</span>'}
52},{"icebrace-runtime":"icebrace-runtime"}],18:[function(require,module,exports){
53"use strict";
54var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\'\'+T.c(\'atoms-avatar\', c.c)+\'\'',2:'\'<p class="o-switch__name">\'+T.e(c,v,\'name\')+\'</p>\'',3:'\'<p class="o-switch__email">\'+T.e(c,v,\'email\')+\'</p>\'',4:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',5:'\'\'+T.c(\'atoms-link\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div class=" o-switch '+T.s(s,c,v,'class_name', s[0])+' " '+T.u(c,v,'hook')+' tabindex="0"> '+T.s(s,c,v,'avatar', s[1])+' <div class="o-switch__text"> '+T.s(s,c,v,'name', s[2])+' '+T.s(s,c,v,'email', s[3])+' </div> '+T.s(s,c,v,'icon', s[4])+''+T.s(s,c,v,'link', s[5])+'</div> '}
55},{"icebrace-runtime":"icebrace-runtime"}],19:[function(require,module,exports){
56"use strict";
57var T=require("icebrace-runtime"),v,s={0:'\' data-color="\'+T.e(c,v,\'color\')+\'" \'',1:'\' o-tag--\'+T.e(c,v,\'.\')+\' \'',2:'\' \'+T.e(c,v,\'.\')+\' \'',3:'\'\'+T.e(c,v,\'text\')+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div '+T.s(s,c,v,'color', s[0])+' class=" o-tag '+T.s(s,c,v,'mod', s[1])+' '+T.s(s,c,v,'class_name', s[2])+' "> '+T.s(s,c,v,'text', s[3])+' <div class="o-tag__close" '+T.u(c,v,'hook')+'><svg class="o-tag__close-icon"><use xlink:href="./images/icons/icons.svg#xmark"></use></svg></div></div> '}
58},{"icebrace-runtime":"icebrace-runtime"}],20:[function(require,module,exports){
59"use strict";
60var T=require("icebrace-runtime"),v,s={};module.exports=function(c){var c={c:c,p:0};return'<i class="o-form__tooltip" '+T.u(c,v,'hook')+'>?</i> '}
61},{"icebrace-runtime":"icebrace-runtime"}],21:[function(require,module,exports){
62"use strict";
63var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',2:'\' controls\'',3:'\' type="\'+T.e(c,v,\'type\')+\'"\'',4:'\'<source src="\'+T.e(c,v,\'src\')+\'"\'+T.s(s,c,v,\'type\', s[3])+\'>\''};module.exports=function(c){var c={c:c,p:0};return'<div '+T.u(c,v,'hook')+' class=" o-video '+T.s(s,c,v,'class_name', s[0])+' "> '+T.s(s,c,v,'icon', s[1])+' <video '+T.u(c,v,'video-hook')+' '+T.s(s,c,v,'controls', s[2])+'> '+T.s(s,c,v,'source', s[4])+' </video></div> '}
64},{"icebrace-runtime":"icebrace-runtime"}],22:[function(require,module,exports){
65"use strict";
66var T=require("icebrace-runtime"),v,s={0:'\' o-well--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\' \'+T.e(c,v,\'.\')+\' \'',3:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',4:'\'<p class="o-well__text u-bold">\'+T.e(c,v,\'title\')+\'</p>\'',5:'\'<p class="o-well__text">\'+T.u(c,v,\'.\')+\'</p>\''};module.exports=function(c){var c={c:c,p:0};return'<div data-hook="well" class=" o-well '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' '+T.s(s,c,v,'wrapper-class', s[2])+' "> '+T.s(s,c,v,'icon', s[3])+' <div class="o-well__content"> '+T.s(s,c,v,'title', s[4])+' '+T.s(s,c,v,'text', s[5])+' </div></div> '}
67},{"icebrace-runtime":"icebrace-runtime"}],23:[function(require,module,exports){
68"use strict";
69var T=require("icebrace-runtime"),v,s={0:'\' <!--[if lte IE 11]><meta http-equiv="refresh" content="0;url=\'+T.e(c,v,\'url\')+\'"><![endif]--> \'',1:'\' <noscript><meta http-equiv="refresh" content="0;url=\'+T.e(c,v,\'url\')+\'"></noscript> \'',2:'\'<meta charset="\'+T.e(c,v,\'charset\')+\'">\'',3:'\'<meta http-equiv="X-UA-Compatible" content="\'+T.e(c,v,\'X-UA-Compatible\')+\'" />\'',4:'\'<meta name="viewport" content="\'+T.e(c,v,\'viewport\')+\'" />\'',5:'\'<meta name="google" value="notranslate" />\'',6:'\' <meta name="version" content="\'+T.e(c,v,\'version\')+\'"> \'',7:'\'\'+T.e(c,v,\'name\')+\'="\'+T.e(c,v,\'value\')+\'"\'',8:'\' <meta \'+T.s(s,c,v,\'attributes\', s[7])+\'> \'',9:'\'?version=\'+T.e(c,v,\'version\')+\'\'',10:'\' <link type="text/css" href="\'+T.e(c,v,\'.\')+\'\'+T.s(s,c,v,\'version\', s[9])+\'" rel="stylesheet"> \'',11:'\'?version=\'+T.e(c,v,\'version\')+\'\'',12:'\' <script src="\'+T.e(c,v,\'.\')+\'\'+T.s(s,c,v,\'version\', s[11])+\'"></script> \'',13:'\'?version=\'+T.e(c,v,\'version\')+\'\''};module.exports=function(c){var c={c:c,p:0};return'<head><title>'+T.e(c,v,'title')+'</title> {optional base}<base href="{base}"/>{/optional} <link rel="icon" href="./favicon-32.png" sizes="32x32"><link rel="icon" href="./favicon-192.png" sizes="192x192"><link rel="icon" href="{self}{favicon32}" sizes="32x32"><link rel="icon" href="{self}{favicon128}" sizes="128x128"><link rel="icon" href="{self}{favicon180}" sizes="180x180"><link rel="icon" href="{self}{favicon192}" sizes="192x192"><meta id="theme-colors"> '+T.s(s,c,v,'backward-compatibility-redirect', s[0])+''+T.s(s,c,v,'noscript-redirect', s[1])+' '+T.s(s,c,v,'charset', s[2])+' '+T.s(s,c,v,'X-UA-Compatible', s[3])+' '+T.s(s,c,v,'viewport', s[4])+' '+T.s(s,c,v,'google-notranslate', s[5])+' <!-- Turn on IE cleartype --><meta http-equiv="cleartype" content="on"> '+T.s(s,c,v,'version', s[6])+' '+T.s(s,c,v,'custom-meta', s[8])+' '+T.s(s,c,v,'css-files', s[10])+' <script> try { {SentryConfig} } catch (e) {} </script> '+T.s(s,c,v,'script-files', s[12])+' <script> try {window.custom_script} catch (e) {} </script><link type="text/css" href="css/custom.css'+T.s(s,c,v,'version', s[13])+'" rel="stylesheet"></head> '}
70},{"icebrace-runtime":"icebrace-runtime"}],24:[function(require,module,exports){
71"use strict";
72var T=require("icebrace-runtime"),v,s={0:'\'\'+T.c(\'meta-head\', c.c)+\'\'',1:'\'\'+T.c(\'atoms-loader\', c.c)+\'\'',2:'\'.min\'',3:'\'.min\''};module.exports=function(c){var c={c:c,p:0};return'<!DOCTYPE html><html> '+T.s(s,c,v,'head', s[0])+' <body><div class="l-loading" id="content"> '+T.s(s,c,v,'loader', s[1])+' </div><script src="framework'+T.s(s,c,v,'min', s[2])+'.js?'+T.e(c,v,'fw_version')+'"></script>
72<script src="bundle'+T.s(s,c,v,'min', s[3])+'.js?'+T.e(c,v,'version')+'"></script></body></html> '}
73},{"icebrace-runtime":"icebrace-runtime"}],25:[function(require,module,exports){
74"use strict";
75var T=require("icebrace-runtime"),v,s={0:'\' o-button--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'atoms-element-button\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div class=" o-button o-form__object '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' "> '+T.s(s,c,v,'button', s[2])+'</div> '}
76},{"icebrace-runtime":"icebrace-runtime"}],26:[function(require,module,exports){
77"use strict";
78var T=require("icebrace-runtime"),v,s={0:'\'\'+T.c(\'atoms-addon\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div class="l-captcha o-form__object"><div class="o-form__element"><div class="o-captcha" '+T.u(c,v,'hook')+'>'+T.c('atoms-loader', c.c)+'</div></div> '+T.s(s,c,v,'addon', s[0])+'</div> '}
79},{"icebrace-runtime":"icebrace-runtime"}],27:[function(require,module,exports){
80"use strict";
81var T=require("icebrace-runtime"),v,s={0:'\' o-checkbox--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'atoms-element-input\', c.c)+\'\'',3:'\'\'+T.e(c,v,\'label\')+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div class=" o-checkbox o-checkbox--default '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' "> '+T.s(s,c,v,'input', s[2])+' <i class="o-checkbox__icon"></i><label class="o-checkbox__label">'+T.s(s,c,v,'label', s[3])+'</label></div> '}
82},{"icebrace-runtime":"icebrace-runtime"}],28:[function(require,module,exports){
83"use strict";
84var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\' o-form__object--\'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'atoms-element-input\', c.c)+\'\'',3:'\'\'+T.c(\'atoms-label\', c.c)+\'\'',4:'\'\'+T.c(\'atoms-addon\', c.c)+\'\'',5:'\'\'+T.c(\'atoms-tooltip\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<label class=" o-input o-form__object molecules-input '+T.s(s,c,v,'class_name', s[0])+' '+T.s(s,c,v,'mod', s[1])+' " '+T.u(c,v,'hook')+'> '+T.s(s,c,v,'input', s[2])+''+T.s(s,c,v,'label', s[3])+''+T.s(s,c,v,'addon', s[4])+''+T.s(s,c,v,'tooltip', s[5])+'</label> '}
85},{"icebrace-runtime":"icebrace-runtime"}],29:[function(require,module,exports){
86"use strict";
87var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \''};module.exports=function(c){var c={c:c,p:0};return'<li tabindex="0" class=" o-language-picker__item '+T.s(s,c,v,'class_name', s[0])+' " '+T.u(c,v,'# hook')+''+T.u(c,v,'hook')+''+T.u(c,v,'/ hook')+'>'+T.e(c,v,'text')+'</li> '}
88},{"icebrace-runtime":"icebrace-runtime"}],30:[function(require,module,exports){
89"use strict";
90var T=require("icebrace-runtime"),v,s={0:'\' o-language-picker--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'molecules-language-picker-item\', c.c)+\'\'',3:'\' <ul class="o-language-picker__column"> \'+T.s(s,c,v,\'item\', s[2])+\' </ul> \''};module.exports=function(c){var c={c:c,p:0};return'<div class=" o-language-picker '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' "> '+T.s(s,c,v,'column', s[3])+'</div> '}
91},{"icebrace-runtime":"icebrace-runtime"}],31:[function(require,module,exports){
92"use strict";
93var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\'\'+T.c(\'atoms-element-select\', c.c)+\'\'',2:'\'\'+T.c(\'atoms-label\', c.c)+\'\'',3:'\'\'+T.c(\'atoms-tooltip\', c.c)+\'\'',4:'\'\'+T.c(\'atoms-icons\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<label class=" o-select o-form__object '+T.s(s,c,v,'class_name', s[0])+' "> '+T.s(s,c,v,'select', s[1])+''+T.s(s,c,v,'label', s[2])+''+T.s(s,c,v,'tooltip', s[3])+''+T.s(s,c,v,'icon', s[4])+'</label> '}
94},{"icebrace-runtime":"icebrace-runtime"}],32:[function(require,module,exports){
95"use strict";
96var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\' o-form__object--\'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'atoms-static\', c.c)+\'\'',3:'\'\'+T.c(\'atoms-label\', c.c)+\'\'',4:'\'\'+T.c(\'atoms-addon\', c.c)+\'\'',5:'\'\'+T.c(\'atoms-tooltip\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<label class=" o-static o-form__object '+T.s(s,c,v,'class_name', s[0])+' '+T.s(s,c,v,'mod', s[1])+' " '+T.u(c,v,'hook')+'> '+T.s(s,c,v,'static', s[2])+''+T.s(s,c,v,'label', s[3])+''+T.s(s,c,v,'addon', s[4])+''+T.s(s,c,v,'tooltip', s[5])+'</label> '}
97},{"icebrace-runtime":"icebrace-runtime"}],33:[function(require,module,exports){
98"use strict";
99var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\' o-form__object--\'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'atoms-tag\', c.c
99)+\'\'',3:'\'\'+T.c(\'atoms-element-textarea\', c.c)+\'\'',4:'\'\'+T.c(\'atoms-label\', c.c)+\'\'',5:'\'\'+T.c(\'atoms-addon\', c.c)+\'\'',6:'\'\'+T.c(\'atoms-tooltip\', c.c)+\'\'',7:'\'\'+T.c(\'atoms-icons\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<label class=" o-textarea o-form__object '+T.s(s,c,v,'class_name', s[0])+' '+T.s(s,c,v,'mod', s[1])+' " '+T.u(c,v,'hook')+'> '+T.s(s,c,v,'tag', s[2])+''+T.s(s,c,v,'textarea', s[3])+''+T.s(s,c,v,'label', s[4])+''+T.s(s,c,v,'addon', s[5])+''+T.s(s,c,v,'tooltip', s[6])+''+T.s(s,c,v,'icon', s[7])+'</label> '}
100},{"icebrace-runtime":"icebrace-runtime"}],34:[function(require,module,exports){
101"use strict";
102var T=require("icebrace-runtime"),v,s={0:'\'\'+T.c(\'_name\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div style=" border-bottom: 1px solid black; height: 40px; width: 100%; /* position: absolute; */ top: 0; background: #fff; z-index: 1;"> '+T.s(s,c,v,'components', s[0])+'</div> '}
103},{"icebrace-runtime":"icebrace-runtime"}],35:[function(require,module,exports){
104"use strict";
105var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\' o-bar__section--\'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',3:'\'\'+T.s(s,c,v,\'logo\', s[2])+\' <p class="o-external__copy o-info">\'+T.e(c,v,\'copyright\')+\' &copy;&nbsp;<time datetime="\'+T.e(c,v,\'current_year\')+\'">\'+T.e(c,v,\'current_year\')+\'</time></p> \'',4:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',5:'\' <a class="o-external__social" title="\'+T.e(c,v,\'href\')+\'" href="\'+T.e(c,v,\'href\')+\'" rel="noopener" target="_blank"> \'+T.s(s,c,v,\'icon\', s[4])+\' </a> \'',6:'\' <p class="o-info" title="\'+T.e(c,v,\'version\')+\'">\'+T.u(c,v,\'text\')+\'</p> \'',7:'\'\'+T.s(s,c,v,\'copyright\', s[3])+\' \'+T.s(s,c,v,\'social\', s[5])+\' \'+T.s(s,c,v,\'find-out-more\', s[6])+\'\'',8:'\' <section class=" o-bar__section \'+T.s(s,c,v,\'mod\', s[1])+\' "> \'+T.s(s,c,v,\'footer\', s[7])+\' </section> \''};module.exports=function(c){var c={c:c,p:0};return'<div class=" o-bar '+T.s(s,c,v,'class_name', s[0])+' "> '+T.s(s,c,v,'section', s[8])+' </div> '}
106},{"icebrace-runtime":"icebrace-runtime"}],36:[function(require,module,exports){
107"use strict";
108var T=require("icebrace-runtime"),v,s={0:'\' o-header--\'+T.e(c,v,\'.\')+\' \'',1:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',2:'\'\'+T.c(\'atoms-avatar\', c.c)+\'\'',3:'\'\'+T.c(\'atoms-image\', c.c)+\'\'',4:'\'\'+T.c(\'atoms-icons\', c.c)+\'\'',5:'\'\'+T.s(s,c,v,\'icon\', s[4])+\'\'',6:'\'\'+T.s(s,c,v,\'logo\', s[3])+\'\'+T.i(s,c,v,\'logo\', s[5])+\'\'',7:'\'\'+T.s(s,c,v,\'avatar\', s[2])+\'\'+T.i(s,c,v,\'avatar\', s[6])+\'\'',8:'\' \'+T.e(c,v,\'.\')+\' \'',9:'\' <h2 class=" o-header__title o-heading o-heading--beta \'+T.s(s,c,v,\'class_name\', s[8])+\' " \'+T.u(c,v,\'hook\')+\'>\'+T.e(c,v,\'.\')+\'</h2> \'',10:'\'\'+T.c(\'atoms-info\', c.c)+\'\'',11:'\'\'+T.c(\'atoms-info\', c.c)+\'\'',12:'\'\'+T.c(\'atoms-well\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div class=" o-header '+T.s(s,c,v,'mod', s[0])+' "><main class="o-header__main"><div class="o-header__content"> '+T.s(s,c,v,'card-icon', s[1])+''+T.i(s,c,v,'card-icon', s[7])+' '+T.s(s,c,v,'heading', s[9])+' '+T.s(s,c,v,'subtitle', s[10])+''+T.s(s,c,v,'subsubtitle', s[11])+' </div> '+T.s(s,c,v,'well', s[12])+' </main></div> '}
109},{"icebrace-runtime":"icebrace-runtime"}],37:[function(require,module,exports){
110"use strict";
111var T=require("icebrace-runtime"),v,s={0:'\' o-card__section--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'_name\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<section class=" o-card__section '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' " '+T.u(c,v,'hook')+'> '+T.s(s,c,v,'component', s[2])+'</section> '}
112},{"icebrace-runtime":"icebrace-runtime"}],38:[function(require,module,exports){
113"use strict";
114var T=require("icebrace-runtime"),v,s={0:'\' \'+T.e(c,v,\'.\')+\' \'',1:'\'\'+T.c(\'molecules-window-header\', c.c)+\'\'',2:'\'\'+T.c(\'_name\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div class=" o-window '+T.s(s,c,v,'class_name', s[0])+' "> '+T.s(s,c,v,'header', s[1])+' <div class="o-window__main"> '+T.s(s,c,v,'components', s[2])+' </div></div> '}
115},{"icebrace-runtime":"icebrace-runtime"}],39:[function(require,module,exports){
116"use strict";
117var T=require("icebrace-runtime"),v,s={0:'\' is-ie \'',1:'\'\'+T.e(c,v,\'background-size\')+\'\'',2:'\'background-color: \'+T.e(c,v,\'background-color\')+\';\'',3:'\'background-image: url(\\\'\'+T.e(c,v,\'background-image\')+\'\\\');\'',4:'\'\'+T.c(\'atoms-ad\', c.c)+\'\'',5:'\'\'+T.c(\'templates-card\', c.c)+\'\'',6:'\'\'+T.c(\'organisms-bar\', c.c
117)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<div class="o-external t-'+T.e(c,v,'theme')+' '+T.s(s,c,v,'ie', s[0])+''+T.s(s,c,v,'background-size', s[1])+'" style=" '+T.s(s,c,v,'background-color', s[2])+' '+T.s(s,c,v,'background-image', s[3])+' " ><main class="o-external__main"> '+T.s(s,c,v,'ad', s[4])+''+T.s(s,c,v,'card', s[5])+' </main> '+T.s(s,c,v,'bar', s[6])+'</div> '}
118},{"icebrace-runtime":"icebrace-runtime"}],40:[function(require,module,exports){
119"use strict";
120var T=require("icebrace-runtime"),v,s={0:'\' o-card--\'+T.e(c,v,\'.\')+\' \'',1:'\' \'+T.e(c,v,\'.\')+\' \'',2:'\'\'+T.c(\'_name\', c.c)+\'\'',3:'\'\'+T.c(\'organisms-card-section\', c.c)+\'\''};module.exports=function(c){var c={c:c,p:0};return'<form class=" o-card c-card '+T.s(s,c,v,'mod', s[0])+' '+T.s(s,c,v,'class_name', s[1])+' " '+T.u(c,v,'hook')+' method="POST"><div class="o-card__main"> '+T.s(s,c,v,'component', s[2])+' <div class="o-card__content" data-hook="content"> '+T.s(s,c,v,'content', s[3])+' </div></div></form> '}
121},{"icebrace-runtime":"icebrace-runtime"}],41:[function(require,module,exports){
122"use strict";
123require('./middleware/middleware')(
124	polyfills,
125	require('./middleware/i18n'),
126	require('./middleware/setLogLevel'),
127	require('./middleware/initEnvironment'),
128	require('./middleware/loadConfig'),
129	require('./middleware/initDebugger'),
130	setupApp,
131	legacyURL,
132	getServerProperties,
133	getWebmailResources,
134	changeLanguage,
135	startApp
136);
137
138/**
139 * @param {Object} data 
140 * @param {Function} next 
141 * @returns {undefined}
142 */
143function polyfills(data, next) {
144	require('classlist-polyfill');
145	require('svg4everybody')();
146	require('match-media');
147	require('es6-object-assign/auto');
148	SVGElement.prototype.contains = SVGElement.prototype.contains || HTMLDivElement.prototype.contains;
149
150	Element.prototype.matches = Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
151
152	Element.prototype.closest = Element.prototype.closest || function (s) {
153		var el = this;
154
155		do {
156			if (el.matches(s)) {
157				return el;
158			}
159			el = el.parentElement || el.parentNode;
160		} while (el !== null && el.nodeType === 1);
161		return null;
162	};
163
164	next();
165}
166
167/**
168 * 
169 * @param {Object} data 
170 * @param {Function} next 
171 * @returns {undefined}
172 */
173function legacyURL(data, next) {
174	var BaseModel = require('BaseModel');
175	BaseModel.static('LegacyURL').redirect() || next();
176}
177
178/**
179 * 
180 * @param {Object} data 
181 * @param {Function} next 
182 * @returns {undefined}
183 */
184function setupApp(data, next) {
185	var disabled;
186	var Hash = require('@icewarp/hash');
187	var BaseModel = require('BaseModel');
188	var BaseController = require('BaseController');
189	var OldCommunication = require('@icewarp/old-communication');
190	require('./communication-xml.js');
191
192	/**
193	 * Create new connection to get new request ID
194	 * @returns {OldCommunication}
195	 */
196	BaseModel.prototype.createNewConnection = function() {
197		return new OldCommunication(OldCommunication.XHR, Date.now(), {
198			host: (BaseModel.instance('Config').getData('config').icewarpapiUrl || ('//' + location.host + '/icewarpapi')) + '/',
199			xmlns: 'admin:iq:rpc'
200		});
201	};
202
203	/**
204	 * Call communication command on model
205	 * @param {String} command
206	 * @param {Object} args
207	 * @param {Object} callback
208	 * @returns {unresolved} response
209	 */
210	BaseModel.prototype.callCommunication = function (command, args, callback) {
211		return this.com[command].call(this, args, callback);
212	};
213
214	BaseController.prototype.disable = function () {
215		if (!this.DOMElement) {
216			return this;
217		}
218		this.DOMElement.classList.add('is-loading');
219		(disabled = this.DOMElement.querySelector(':focus')) && disabled.blur();
220		return this;
221	};
222
223	BaseController.prototype.enable = function () {
224		if (!this.DOMElement) {
225			return this;
226		}
227		this.DOMElement.classList.remove('is-loading');
228		!document.querySelector(':focus') && disabled && disabled.focus();
229		return this;
230	};
231
232	// set hashchange listener
233	Hash.update(async function (site, parts, previous_site, previous_parts) {
234		var old_controller;
235		var Template = require('icebrace-runtime');
236		var name = Template.t(site) ? site : Template.t('sites-' + site) ? 'sites-' + site : false;
237		var content = document.getElementById('content');
238		if (name) {
239			return new(BaseController.static(name))().execute().then(function (controller) {
240				controller.render(content);
241			});
242		}
243		old_controller = BaseController.prototype.getInstanceByElement(content);
244		if (!await ((old_controller || {})['onHashChange'] || function () {}).call(old_controller, site, parts, previous_site, previous_parts)) {
245			new(BaseController.static('sites-login'))().execute().then(function (controller) {
246				controller.render(content);
247			});
248		}
249	});
250
251	next();
252}
253
254/**
255 * 
256 * @param {Object} data 
257 * @param {Function} next 
258 * @returns {undefined}
259 */
260function getServerProperties(data, next) {
261	var BaseModel = require('BaseModel');
262	var Server = BaseModel.instance('Server');
263	Server.callCommunication('getServerProperties', {
264		serverpropertylist: ['c_webmail_url', 'c_accounts_policies_login_loginsettings', 'c_niceversion', 'c_version']
265	}, {
266		success: next,
267		error: error
268	});
269}
270
271/**
272 * 
273 * @param {Object} data 
274 * @param {Function} next 
275 * @returns {undefined}
276 */
277function getWebmailResources(data, next) {
278	var BaseModel = require('BaseModel');
279	var WebClient = BaseModel.instance('WebClient');
280	WebClient.callCommunication('getWebmailResources', {
281		properties: ['layout_settings', 'restrictions', 'custom_login_fields', 'reset_settings', 'languages', 'signup_domains', 'password_policy', 'banner_options'],
282		selector: document.location.hostname,
283		level: 1
284	}, {
285		success: next,
286		error: error
287	});
288}
289
290/**
291 * 
292 * @param {Object} data 
293 * @param {Function} next 
294 * @returns {undefined}
295 */
296function changeLanguage(data, next) {
297	var BaseModel = require('BaseModel');
298	var WebClient = BaseModel.instance('WebClient');
299	BaseModel.instance('Login').changeLanguage(WebClient.getData('layout_settings').getDefaultLanguageCode(), {
300		success: next,
301		error: next
302	});
303}
304
305/**
306 * 
307 * @param {Object} data 
308 * @param {Function} next 
309 * @returns {undefined}
310 */
311function startApp() {
312	var Hash = require('@icewarp/hash');
313	var chosen_users;
314	var BaseModel = require('BaseModel');
315	var BaseController = require('BaseController');
316	var WebClient = BaseModel.instance('WebClient');
317	var Login = BaseModel.instance('Login');
318	var Sentry = require('@sentry/browser');
319
320	if (window.SentryEnabled) {
321		Sentry.init({
322			dsn: window.SentryLoginDSN || 'https://[email protected]/3',
323			environment: window.SentryEnvironment || 'production',
324			release: BaseModel.instance('Server').getData('c_version'),
325			sampleRate: 1.0,
326			maxBreadcrumbs: 100,
327			autoSessionTracking: true
328		});
329	}
330
331	if (BaseModel.instance('Config').getData('config').application === 'webclient' && WebClient.getData('restrictions').getValue('sso_only')) {
332		if (Hash.getParts().eid) {
333			BaseController.new('sites-login', {
334				site: 'unavailable',
335				data: {
336					title: __('error.' + Hash.getParts().eid),
337					retry_link: './'
338				}
339			}).execute().then(function (controller) {
340				var content = document.getElementById('content');
341				controller.render(content);
342			});
343		} else {
344			location.href = './sso';
345		}
346		return;
347	}
348
349	if (Hash.getParts().auth_id) {
350		document.title = __('title.oauth');
351	} else {
352		document.title = WebClient.getData('layout_settings').getValue('title');
353	}
354
355	chosen_users = Hash.getParts().username ? [Hash.getParts().username] : Login.getUsers();
356	chosen_users[0] && Login.setData('chosen_account', chosen_users[0]);
357
358	Hash.update();
359}
360
361/**
362 * @returns {undefined}
363 */
364function error() {
365	var BaseModel = require('BaseModel');
366	var WebClient = BaseModel.instance('WebClient');
367	BaseModel.instance('Login').changeLanguage(WebClient.getData('layout_settings').getDefaultLanguageCode(), {
368		success: function () {
369			var BaseController = require('BaseController');
370			BaseController.new('sites-login').execute({
371				site: 'unavailable'
372			}).then(function (controller) {
373				var content = document.getElementById('content');
374				controller.render(content);
375			});
376		}
377	});
378}
379
380},{"./communication-xml.js":42,"./middleware/i18n":133,"./middleware/initDebugger":134,"./middleware/initEnvironment":135,"./middleware/loadConfig":136,"./middleware/middleware":137,"./middleware/setLogLevel":138,"@icewarp/hash":160,"@icewarp/old-communication":168,"@sentry/browser":223,"BaseController":"BaseController","BaseModel":"BaseModel","classlist-polyfill":356,"es6-object-assign/auto":358,"icebrace-runtime":"icebrace-runtime","match-media":363,"svg4everybody":367}],42:[function(require,module,exports){
381"use strict";
382var BaseModel = require('BaseModel');
383var Login = BaseModel.static('Login');
384Login.prototype.com= new (require('./communication/xml/Login/LoginPrototype.js'))();
385var WebClient = BaseModel.static('WebClient');
386WebClient.prototype.com= new (require('./communication/xml/WebClient/WebClientPrototype.js'))();
387var Server = BaseModel.static('Server');
388Server.prototype.com= new (require('./communication/xml/Server/ServerPrototype.js'))();
389var OAuth = BaseModel.static('OAuth');
390OAuth.prototype.com= new (require('./communication/xml/OAuth/OAuthPrototype.js'))();
391
392},{"./communication/xml/Login/LoginPrototype.js":43,"./communication/xml/OAuth/OAuthPrototype.js":44,"./communication/xml/Server/ServerPrototype.js":45,"./communication/xml/WebClient/WebClientPrototype.js":46,"BaseModel":"BaseModel"}],43:[function(require,module,exports){
393"use strict";
394// var OldCommunication = require('@icewarp/old-communication');
395var rsa = require('@icewarp/rsa');
396var Callback = require('Callback');
397var xhr_connection = require('@icewarp/xhr-connection');
398
399/**
400 * @param {String} password 
401 * @returns {String}
402 */
403function authPlain(password) {
404	return password;
405}
406
407/**
408 * @param {String} hash 
409 * @param {String} timestamp 
410 * @returns {String}
411 */
412function authRSA(hash, timestamp) {
413	return hash ? function (password) {
414		var RSA = new rsa();
415		RSA.setPublic(hash, '10001');
416		return RSA.encrypt('p=' + encodeURIComponent(password).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+') + '&t=' + timestamp);
417	} : authPlain;
418}
419
420/**
421 * Communication for Login model
422 * @class LoginPrototype
423 */
424function LoginPrototype() {}
425
426LoginPrototype.prototype.usernameAvailable = function (params, callback) {
427	var data = {
428		commandname: 'usernameavailable',
429		commandparams: {
430			username: params.username,
431			domain: params.domain,
432			session: params.session
433		}
434	};
435
436	this.createNewConnection().send(data, {
437		success: callback.success,
438		error: callback.error,
439		context: callback.context
440	});
441};
442
443LoginPrototype.prototype.getVerification = function (params, callback) {
444	var data = {
445		commandname: 'sendsignupverification',
446		commandparams: params
447	};
448	this.createNewConnection().send(data, {
449		success: function (auth) {
450			return Callback(Callback.SUCCESS, callback, auth);
451		},
452		error: callback.error,
453		context: callback.context
454	});
455};
456
457LoginPrototype.prototype.getAuthChallenge = function (callback) {
458	var data;
459	if (!this.getData('useRSA')) {
460		return Callback(Callback.SUCCESS, callback, authPlain);
461	}
462	data = {
463		commandname: 'getauthchallenge',
464		commandparams: {
465			authtype: +this.getData('useRSA')
466		}
467	};
468	this.createNewConnection().send(data, {
469		success: function (auth) {
470			var rsa;
471			try {
472				rsa = authRSA(auth.hashid, auth.timestamp);
473				return Callback(Callback.SUCCESS, callback, rsa);
474			} catch(error) {
475				return Callback(Callback.ERROR, callback, error);
476			}
477		},
478		error: callback.error,
479		context: callback.context
480	});
481};
482
483LoginPrototype.prototype.logoutTeamChatOnly = function (data, callback) {
484	var XHRConnection = new xhr_connection({
485		host: data.notifyuri + '?token=' + data.token + '&action=logout',
486		listeners: {
487			onmessage: {
488				func: callback.success,
489				context: callback.context
490			},
491			onerror: {
492				func: callback.error,
493				context: callback.context
494			}
495		}
496	});
497	XHRConnection.send('', Date.now());
498};
499
500LoginPrototype.prototype.teamchatError = function (data) {
501	var XHRConnection = new xhr_connection({
502		host: data.notifyuri + '?eid=' + data.eid
503	});
504	XHRConnection.send('', Date.now());
505};
506
507LoginPrototype.prototype.isGuestDomain = function (domain, callback) {
508	var data = {
509		commandname: 'isguestdomain',
510		commandparams: {
511			domainstr: domain
512		}
513	};
514
515	if (callback.context) {
516		callback.context.DOMShadowElement = callback.context.DOMElement || true;
517	}
518
519	if (!domain) {
520		return Callback(Callback.SUCCESS, callback, false);
521	}
522
523	this.createNewConnection().send(data, {
524		success: function (response) {
525			Callback(Callback.SUCCESS, callback, response);
526		},
527		error: function () {
528			Callback(Callback.SUCCESS, callback, false);
529		},
530		context: callback.context
531	});
532};
533
534module.exports = LoginPrototype;
535
536},{"@icewarp/rsa":174,"@icewarp/xhr-connection":181,"Callback":"Callback"}],44:[function(require,module,exports){
537"use strict";
538var Callback = require('Callback');
539var OldCommunication = require('@icewarp/old-communication');
540
541/**
542 *
543 * @description Resolves Admin API props to reasonable format
544 * @param {Object} value
545 * @returns {*}
546 */
547function resolveAPIItemValue(value) {
548	switch (value.classname) {
549		case 'TAccountName':
550			return [value.name, value.surname].filter(Boolean);
551		case 'TPropertyString':
552			return value.val;
553		case 'TPropertyNoValue':
554			return null;
555		case 'TAccountImage':
556			return {
557				data: value.base64data,
558				mime: value.contenttype,
559				url:
560					'data:' +
561					value.contenttype +
562					';base64,' +
563					encodeURIComponent(value.base64data)
564			};
565		default:
566			return false;
567	}
568}
569
570/**
571 * Communication for OAuth model
572 * @class OAuthPrototype
573 */
574function OAuthPrototype() {}
575
576OAuthPrototype.prototype.login = function (args, callback) {
577	var data = {
578		commandname: 'authenticate',
579		commandparams: {
580			authtype: +args.authtype,
581			email: args.user
582		}
583	};
584	data.commandparams[args.authtype ? 'digest' : 'password'] = args.password;
585
586	this.createNewConnection().send(data, {
587		success: function (result, attributes) {
588			Callback('success', callback, attributes._attributes.sid);
589		},
590		error: function (error) {
591			Callback('error', callback, error);
592		},
593		context: this
594	});
595};
596
597OAuthPrototype.prototype.GetOauthClientInfo = function (params, callback) {
598	var data = {
599		commandname: 'getoauthclientinfo',
600		commandparams: {
601			clientid: params.clientid
602		}
603	};
604	OldCommunication.getConnection('admin-auth').send(data, callback);
605};
606
607OAuthPrototype.prototype.GetSessionInfo = function (params, callback) {
608	var data = {
609		commandname: 'getsessioninfo'
610	};
611	return OldCommunication.getConnection('admin-auth').send(data, callback);
612};
613
614OAuthPrototype.prototype.GetOauthAuthorizationRequest = function (
615	params,
616	callback
617) {
618	var data = {
619		commandname: 'getoauthauthorizationrequest',
620		commandparams: {
621			requestid: params.requestid
622		}
623	};
624	OldCommunication.getConnection('admin-auth').send(data, callback);
625};
626OAuthPrototype.prototype.OauthAuthorizationExists = function (
627	params,
628	callback
629) {
630	var data = {
631		commandname: 'OauthAuthorizationExists',
632		commandparams: {
633			requestid: params.requestid
634		}
635	};
636	OldCommunication.getConnection('admin-auth').send(data, callback);
637};
638
639OAuthPrototype.prototype.GrantOauthAuthorization = function (params, callback) {
640	var data = {
641		commandname: 'grantoauthauthorization',
642		commandparams: {
643			requestid: params.requestid,
644			description: params.description
645		}
646	};
647	OldCommunication.getConnection('admin-auth').send(data, callback);
648};
649
650OAuthPrototype.prototype.getAccountDetail = function (args, callback) {
651	var data = {
652		commandname: 'GetAccountProperties',
653		commandparams: {
654			accountemail: args.email,
655			accountpropertyset: 1
656		}
657	};
658	OldCommunication.getConnection('admin-auth').send(data, {
659		success: function (data) {
660			var admin = {
661				A_Name: [args.email]
662			};
663			data.item.forEach(function (item) {
664				var value = resolveAPIItemValue(item.propertyval);
665				if (!value) {
666					return;
667				}
668				admin[item.apiproperty.propname] = value;
669			});
670			callback.success.call(callback.context, admin);
671		},
672		error: function (error) {
673			Callback('error', callback, error);
674		},
675		context: this
676	});
677};
678
679module.exports = OAuthPrototype;
680
681},{"@icewarp/old-communication":168,"Callback":"Callback"}],45:[function(require,module,exports){
682"use strict";
683var Callback = require('Callback');
684// var OldCommunication = require('@icewarp/old-communication');
685
686/**
687 * Communication for Server model
688 * @class ServerPrototype
689 */
690function ServerPrototype() {}
691
692ServerPrototype.prototype.getServerProperties = function (args, callback) {
693	var data = {
694		commandname: 'getserverproperties',
695		commandparams: {
696			serverpropertylist: args.serverpropertylist.map(function (property) {
697				return {
698					item: {
699						propname: property
700					}
701				};
702			})
703		}
704	};
705	this.createNewConnection().send(data, {
706		success: function (response_json) {
707			var items = Array.isArray(response_json.item) ? response_json.item : [response_json.item];
708			items.forEach(function (item) {
709				this.setData(item.apiproperty.propname, item.propertyval.val);
710			}, this);
711			Callback('success', callback, arguments);
712		},
713		error: function () {
714			Callback('error', callback, arguments);
715		},
716		context: this
717	});
718};
719
720module.exports = ServerPrototype;
721
722},{"Callback":"Callback"}],46:[function(require,module,exports){
723"use strict";
724// var OldCommunication = require('@icewarp/old-communication');
725var BaseModel = require('BaseModel');
726var Callback = require('Callback');
727
728/**
729 * Communication for WebClient model
730 * @class WebClientPrototype
731 */
732function WebClientPrototype() {}
733
734// sign-in-password
735WebClientPrototype.prototype.authenticate = function (args, callback) {
736	var authtype = +BaseModel.instance('Login').getData('useRSA');
737	var data = {
738		commandname: 'authenticate',
739		commandparams: {
740			email: args.email,
741			authtype: authtype,
742			persistentlogin: args.persistentlogin
743		}
744	};
745
746	data.commandparams[authtype ? 'digest' : 'password'] = args.password;
747
748	this.createNewConnection().send(data, callback);
749};
750
751WebClientPrototype.prototype.sendGatewayAuthentication = function (args, callback) {
752	var data = {
753		commandname: 'sendgatewayauthentication',
754		commandparams: {
755			email: args.email,
756			captcharequest: {
757				uid: args.captcharequest.uid,
758				value: args.captcharequest.value
759			}
760		}
761	};
762	this.createNewConnection().send(data, callback);
763};
764
765WebClientPrototype.prototype.getAuthToken = function (args, callback) {
766	var authtype = +BaseModel.instance('Login').getData('useRSA');
767	var data = {
768		commandname: 'getauthtoken',
769		commandparams: {
770			email: args.email,
771			authtype: authtype,
772			persistentlogin: args.persistentlogin
773		}
774	};
775
776	data.commandparams[authtype ? 'digest' : 'password'] = args.password;
777	args.totpcode && (data.commandparams.totpcode = args.totpcode);
778
779	this.createNewConnection().send(data, callback);
780};
781
782WebClientPrototype.prototype.confirmPersonality = function (args, callback) {
783	var data = {
784		commandname: 'confirmpersonality',
785		commandparams: {
786			email: args.email,
787			user: args.user,
788			hash: args.hash
789		}
790	};
791	this.createNewConnection().send(data, callback);
792};
793
794// create-account -> set-password
795WebClientPrototype.prototype.signupAccount = function (args, callback) {
796	this.createNewConnection().send({
797		commandname: 'signupaccount',
798		commandparams: args
799	}, callback);
800};
801
802// forgot-password
803WebClientPrototype.prototype.resetPasswordEmail = function (args, callback) {
804	var data = {
805		commandname: 'resetpasswordemail',
806		commandparams: {
807			email: args.email,
808			langid: BaseModel.instance('WebClient').getData('layout_settings').getUserLanguageCode(),
809			captcharequest: {
810				uid: args.captcharequest.uid,
811				value: args.captcharequest.value
812			}
813		}
814	};
815	this.createNewConnection().send(data, callback);
816};
817
818// reset-password
819WebClientPrototype.prototype.resetPassword = function (args, callback) {
820	var Hash = require('@icewarp/hash');
821	var data = {
822		commandname: 'resetpassword',
823		commandparams: {
824			email: args.user || Hash.getParts().user,
825			newpassword: args.newpassword,
826			resethash: args.resethash || Hash.getParts().hash,
827			authtype: +BaseModel.instance('Login').getData('useRSA')
828		}
829	};
830	this.createNewConnection().send(data, callback);
831};
832
833// change-password
834WebClientPrototype.prototype.changePassword = function (args, callback) {
835	var data = {
836		commandname: 'changepassword',
837		commandparams: {
838			email: args.email,
839			oldpassword: args.oldpassword,
840			newpassword: args.newpassword,
841			authtype: +BaseModel.instance('Login').getData('useRSA')
842		}
843	};
844	this.createNewConnection().send(data, callback);
845};
846
847WebClientPrototype.prototype.getCaptcha = function (callback) {
848	this.createNewConnection().send({
849		commandname: 'getcaptcha'
850	}, callback);
851};
852
853// contact-admin
854WebClientPrototype.prototype.contactAdministrator = function (args, callback) {
855	var data = {
856		commandname: 'contactadministrator',
857		commandparams: {
858			email: args.email,
859			data: args.data,
860			host: location.hostname,
861			captcharequest: {
862				uid: args.captcha.uid,
863				value: args.captcha.value
864			}
865		}
866	};
867	this.createNewConnection().send(data, callback);
868};
869
870//tc-join
871WebClientPrototype.prototype.guestConfirm = function (args, callback) {
872	var data = {
873		commandname: 'guestconfirm',
874		commandparams: {
875			email: args.email,
876			password: args.password,
877			fullname: args.fullname,
878			sender: args.sender,
879			hash: args.hash,
880			authtype: +BaseModel.instance('Login').getData('useRSA')
881		}
882	};
883	this.createNewConnection().send(data, callback);
884};
885
886WebClientPrototype.prototype.guestVerify = function (args, callback) {
887	var data = {
888		commandname: 'guestverify',
889		commandparams: {
890			email: args.email,
891			hash: args.hash
892		}
893	};
894	this.createNewConnection().send(data, callback);
895};
896
897// app start
898WebClientPrototype.prototype.getWebmailResources = function (args, callback) {
899	var data = {
900		commandname: 'getwebmailresources',
901		commandparams: {
902			resources: args.properties.map(function (prop) {
903				return {
904					item: {
905						name: prop
906					}
907				};
908			}),
909			selector: args.selector,
910			level: args.level
911		}
912	};
913	this.createNewConnection().send(data, {
914		success: function (response_json) {
915			BaseModel.instance('WebClient').initialize(response_json);
916			Callback('success', callback, response_json);
917		},
918		error: function () {
919			Callback('error', callback, arguments);
920		},
921		context: this
922	});
923};
924
925module.exports = WebClientPrototype;
926
927},{"@icewarp/hash":160,"BaseModel":"BaseModel","Callback":"Callback"}],47:[function(require,module,exports){
928"use strict";
929var BaseController = require('BaseController');
930var AtomsAdAdsense = BaseController.create('AtomsAdAdsense');
931
932AtomsAdAdsense.prototype.afterRender = function () {
933	var script;
934	(window.adsbygoogle = window.adsbygoogle || []).push({});
935	if (!document.getElementById('adsbygoogle')) {
936		script = document.createElement('script');
937		script.setAttribute('id', 'adsbygoogle');
938		script.setAttribute('async', true);
939		script.setAttribute('src', '//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js');
940		document.head.appendChild(script);
941	}
942};
943
944module.exports = AtomsAdAdsense;
945
946},{"BaseController":"BaseController"}],48:[function(require,module,exports){
947"use strict";
948var BaseModel = require('BaseModel');
949var BaseController = require('BaseController');
950var AtomsAd = BaseController.create('AtomsAd');
951
952AtomsAd.prototype.afterRender = function () {
953	if (!this.view_data.component && !this.view_data.image) {
954		this.remove();
955	}
956};
957
958AtomsAd.prototype.helper = function () {
959	var Restrictions = BaseModel.instance('WebClient').getData('restrictions');
960	var BannerOptions = BaseModel.instance('WebClient').getData('banner_options');
961
962	if (!this.data || !this.data.position) {
963		return {};
964	}
965
966	switch (BannerOptions.getValue(this.data.position + '_type')) {
967		case 'url':
968			if (!BannerOptions.getValue(this.data.position + '_url')) {
969				return {};
970			}
971			return {
972				image: {
973					src: BannerOptions.getValue(this.data.position + '_url'),
974					class_name: ['o-ad__img']
975				}
976			};
977		case 'code':
978			if (Restrictions.getValue('enable_adsense') !== 1 || !BannerOptions.getValue('customer_id') || !BannerOptions.getValue(this.data.position + '_code')) {
979				return {};
980			}
981			return {
982				component: BaseController.new('atoms-ad-adsense', {
983					slot_id: BannerOptions.getValue(this.data.position + '_code'),
984					client_id: BannerOptions.getValue('customer_id').trim(),
985					identifier: this.data.identifier,
986					style: this.data.style,
987					format: this.data.format || 'auto'
988				})
989			};
990	}
991	return {};
992};
993
994module.exports = AtomsAd;
995
996},{"BaseController":"BaseController","BaseModel":"BaseModel"}],49:[function(require,module,exports){
997"use strict";
998var BaseController = require('BaseController');
999var AtomsAddon = BaseController.create('AtomsAddon');
1000
1001AtomsAddon.prototype.helper = function () {
1002	return {
1003		class_name: this.data.class_name,
1004		mod: this.data.mod,
1005		text: this.data.text,
1006		icon: this.data.icon,
1007		hook: this.data.hook
1008	};
1009};
1010
1011module.exports = AtomsAddon;
1012
1013},{"BaseController":"BaseController"}],50:[function(require,module,exports){
1014"use strict";
1015var BaseController = require('BaseController');
1016var AtomsAddon = require('./addon');
1017var AtomsAddon_Show = BaseController.create('AtomsAddon_Show', AtomsAddon);
1018
1019AtomsAddon_Show.prototype.helper = function () {
1020	this.data.icon = BaseController.new('atoms-icons', {
1021		icon: 'eye'
1022	});
1023	this.data.mod = ['ico', 'floating'];
1024	this.data.hook = this.createHook('show-password');
1025	return AtomsAddon.prototype.helper.call(this);
1026};
1027
1028module.exports = AtomsAddon_Show;
1029
1030},{"./addon":49,"BaseController":"BaseController"}],51:[function(require,module,exports){
1031"use strict";
1032var BaseModel = require('BaseModel');
1033var BaseController = require('BaseController');
1034var AtomsAvatar = BaseController.create('AtomsAvatar');
1035
1036AtomsAvatar.prototype.helper = function () {
1037	return this.data['email'] ? {
1038		image: this.data['avatar_token'] ? BaseModel.instance('Server').getAvatar({email: this.data['email'], avatarhash: this.data['avatar_token']}) : false,
1039		letter: !this.data['avatar_token'] ? (this.data['name'] || this.data['email'] || '').substr(0, 1) : false,
1040		class_name: this.data.class_name,
1041		mod: this.data['mod'],
1042		data: [
1043			{
1044				tag: 'color',
1045				value: this.data['color']
1046			}
1047		]
1048	} : {};
1049};
1050
1051module.exports = AtomsAvatar;
1052
1053},{"BaseController":"BaseController","BaseModel":"BaseModel"}],52:[function(require,module,exports){
1054"use strict";
1055var BaseController = require('BaseController');
1056var AtomsDropdown = BaseController.create('AtomsDropdown');
1057
1058AtomsDropdown.prototype.helper = function () {
1059	return {
1060		class_name: this.data.class_name,
1061		icon: this.data.icon,
1062		hook: this.data.hook,
1063		code: this.data.code
1064	};
1065};
1066
1067module.exports = AtomsDropdown;
1068
1069},{"BaseController":"BaseController"}],53:[function(require,module,exports){
1070"use strict";
1071var BaseController = require('BaseController');
1072var AtomsElementButton = BaseController.create('AtomsElementButton');
1073
1074AtomsElementButton.prototype.helper = function () {
1075	return {
1076		class_name: this.data.class_name,
1077		name: this.data.name || 'button',
1078		text: this.data.text,
1079		hook: this.data.hook,
1080		disabled: this.data.disabled ? 'disabled' : false,
1081		icon: this.data.icon
1082	};
1083};
1084
1085module.exports = AtomsElementButton;
1086
1087},{"BaseController":"BaseController"}],54:[function(require,module,exports){
1088"use strict";
1089var BaseController = require('BaseController');
1090var AtomsElementInput = BaseController.create('AtomsElementInput');
1091
1092AtomsElementInput.prototype.focus = function () {
1093	this.DOMElement.focus();
1094};
1095
1096AtomsElementInput.prototype.helper = function () {
1097	return {
1098		class_name: this.data.class_name,
1099		type: this.data.type || 'text',
1100		accept: this.data.accept,
1101		name: this.data.name || 'input',
1102		value: this.data.value,
1103		placeholder: this.data.placeholder,
1104		autocomplete: this.data.autocomplete,
1105		max: this.data.max,
1106		min: this.data.min,
1107		size: this.data.size,
1108		maxlength: this.data.maxlength,
1109		minlength: this.data.minlength,
1110		multiple: this.data.multiple,
1111		readonly: this.data.readonly,
1112		checked: this.data.checked,
1113		disabled: this.data.disabled,
1114		required: this.data.required,
1115		hook: this.data.hook,
1116		maxDate: this.data.maxDate
1117	};
1118};
1119
1120module.exports = AtomsElementInput;
1121
1122},{"BaseController":"BaseController"}],55:[function(require,module,exports){
1123"use strict";
1124var Library = require('Library');
1125var BaseController = require('BaseController');
1126var AtomsElementInput = require('./element-input.js');
1127var AtomsElementInput_Date = BaseController.create('AtomsElementInput_Date_Date', AtomsElementInput);
1128
1129AtomsElementInput_Date.prototype.afterRender = function () {
1130	if (this.DOMElement.type === 'date') {
1131		return;
1132	}
1133	Library.get('pikaday', {
1134		success: function (Pikaday) {
1135			new Pikaday({
1136				field: this.DOMElement,
1137				maxDate: this.data.maxDate,
1138				onSelect: function (date) {
1139					this.date = date;
1140				}.bind(this),
1141				yearRange: [1900, new Date().getFullYear()],
1142				i18n: {
1143					previousMonth: __('calendar.previous_month'),
1144					nextMonth: __('calendar.next_month'),
1145					months: ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'].map(function (month) {
1146						return __('calendar.month.' + month);
1147					}),
1148					weekdays: ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'].map(function (day) {
1149						return __('calendar.day.' + day);
1150					}),
1151					weekdaysShort: ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'].map(function (day) {
1152						return __('calendar.day_short.' + day);
1153					})
1154				}
1155			});
1156		},
1157		error: function () {},
1158		context: this
1159	}, false, window);
1160};
1161
1162module.exports = AtomsElementInput_Date;
1163
1164},{"./element-input.js":54,"BaseController":"BaseController","Library":"Library"}],56:[function(require,module,exports){
1165"use strict";
1166var BaseController = require('BaseController');
1167var AtomsElementSelect = BaseController.create('AtomsElementSelect');
1168
1169AtomsElementSelect.prototype.focus = function () {
1170	this.DOMElement.focus();
1171};
1172
1173AtomsElementSelect.prototype.helper = function () {
1174	return {
1175		class_name: this.data.class_name,
1176		label: this.data.label,
1177		name: this.data.name || 'select',
1178		hook: this.data.hook,
1179		readonly: this.data.readonly,
1180		size: this.data.size,
1181		options: (this.data.options || []).map(function(option) {
1182			option.text = option.text === void 0 || option.text === false ? option.value : option.text;
1183			return option;
1184		})
1185	};
1186};
1187
1188module.exports = AtomsElementSelect;
1189
1190},{"BaseController":"BaseController"}],57:[function(require,module,exports){
1191"use strict";
1192var BaseController = require('BaseController');
1193var AtomsElementTextarea = BaseController.create('AtomsElementTextarea');
1194
1195AtomsElementTextarea.prototype.focus = function () {
1196	this.DOMElement.focus();
1197};
1198
1199AtomsElementTextarea.prototype.helper = function () {
1200	return {
1201		rows: this.data.rows || 3,
1202		class_name: this.data.class_name,
1203		placeholder: this.data.placeholder,
1204		name: this.data.name,
1205		autocomplete: this.data.autocomplete || 'off',
1206		required: this.data.required,
1207		text: this.data.text,
1208		hook: this.data.hook
1209	};
1210};
1211
1212module.exports = AtomsElementTextarea;
1213
1214},{"BaseController":"BaseController"}],58:[function(require,module,exports){
1215"use strict";
1216var BaseController = require('BaseController');
1217var AtomsInfo = BaseController.create('AtomsInfo');
1218
1219AtomsInfo.prototype.helper = function () {
1220	return {
1221		text: this.data.text,
1222		class_name: this.data.class_name || ['u-align-center'],
1223		link: this.data.link
1224	};
1225};
1226
1227module.exports = AtomsInfo;
1228
1229},{"BaseController":"BaseController"}],59:[function(require,module,exports){
1230"use strict";
1231var BaseController = require('BaseController');
1232var AtomsInfo_HaveAccount = BaseController.create('AtomsInfo_HaveAccount');
1233
1234AtomsInfo_HaveAccount.prototype.helper = function () {
1235	return {
1236		text: __('generic.have-account'),
1237		class_name: ['u-align-center'],
1238		link: BaseController.new('atoms-link~choose-account')
1239	};
1240};
1241
1242module.exports = AtomsInfo_HaveAccount;
1243
1244},{"BaseController":"BaseController"}],60:[function(require,module,exports){
1245"use strict";
1246var BaseController = require('BaseController');
1247var AtomsInfo_ContactAdmin = BaseController.create('AtomsInfo_ContactAdmin');
1248
1249AtomsInfo_ContactAdmin.prototype.helper = function () {
1250	return {
1251		text: __('contact-admin.having-problems'),
1252		class_name: ['u-align-center'],
1253		link: BaseController.new('atoms-link~contact-admin')
1254	};
1255};
1256
1257module.exports = AtomsInfo_ContactAdmin;
1258
1259},{"BaseController":"BaseController"}],61:[function(require,module,exports){
1260"use strict";
1261var BaseController = require('BaseController');
1262var AtomsInfo_DontHaveAccount = BaseController.create('AtomsInfo_DontHaveAccount');
1263
1264AtomsInfo_DontHaveAccount.prototype.helper = function () {
1265	return {
1266		text: __('generic.dont-have-account'),
1267		class_name: ['u-align-center'],
1268		link: BaseController.new('atoms-link~create-acc')
1269	};
1270};
1271
1272module.exports = AtomsInfo_DontHaveAccount;
1273
1274},{"BaseController":"BaseController"}],62:[function(require,module,exports){
1275"use strict";
1276var BaseController = require('BaseController');
1277var AtomsInfo_HaveAccount = BaseController.create('AtomsInfo_HaveAccount');
1278
1279AtomsInfo_HaveAccount.prototype.helper = function () {
1280	return {
1281		text: __('generic.have-account'),
1282		class_name: ['u-align-center'],
1283		link: BaseController.new('atoms-link~sign-in')
1284	};
1285};
1286
1287module.exports = AtomsInfo_HaveAccount;
1288
1289},{"BaseController":"BaseController"}],63:[function(require,module,exports){
1290"use strict";
1291var BaseModel = require('BaseModel');
1292var BaseController = require('BaseController');
1293var AtomsInfo_NotYou = BaseController.create('AtomsInfo_NotYou');
1294var Login = BaseModel.instance('Login');
1295
1296AtomsInfo_NotYou.prototype.helper = function () {
1297	return {
1298		text: __('generic.not-you'),
1299		class_name: ['u-align-center'],
1300		link: BaseController.new('atoms-link~' + (Login.getUsers().length ? 'choose-account' : 'check-account'))
1301	};
1302};
1303
1304module.exports = AtomsInfo_NotYou;
1305
1306},{"BaseController":"BaseController","BaseModel":"BaseModel"}],64:[function(require,module,exports){
1307"use strict";
1308var BaseController = require('BaseController');
1309var AtomsInfo_SignWithAnotherAcc = BaseController.create('AtomsInfo_SignWithAnotherAcc');
1310
1311AtomsInfo_SignWithAnotherAcc.prototype.helper = function () {
1312	return {
1313		// text: __('generic.dont-have-account'),
1314		class_name: ['u-align-center'],
1315		link: BaseController.new('atoms-link~sign-with-another-acc')
1316	};
1317};
1318
1319module.exports = AtomsInfo_SignWithAnotherAcc;
1320
1321},{"BaseController":"BaseController"}],65:[function(require,module,exports){
1322"use strict";
1323var BaseController = require('BaseController');
1324var AtomsLabel = BaseController.create('AtomsLabel');
1325
1326AtomsLabel.prototype.addListeners = function () {
1327	this.addGlobalListener('validation-error', this.handleValidation);
1328	this.addGlobalListener('validation-success', this.handleValidation);
1329};
1330
1331AtomsLabel.prototype.handleValidation = function (data) {
1332	if (this.getParent(data.controller._name) === data.controller) {
1333		this.data.error = data.message;
1334		this.rerender();
1335	}
1336};
1337
1338AtomsLabel.prototype.helper = function () {
1339	return {
1340		hook: this.data.hook,
1341		text: this.data.text,
1342		class_name: this.data.class_name,
1343		error: this.data.error
1344	};
1345};
1346
1347module.exports = AtomsLabel;
1348
1349},{"BaseController":"BaseController"}],66:[function(require,module,exports){
1350"use strict";
1351var BaseController = require('BaseController');
1352var AtomsLink_Back = BaseController.create('AtomsLink_Back');
1353
1354AtomsLink_Back.prototype.helper = function () {
1355	return {
1356		text: __('generic.back'),
1357		class_name: ['u-float-left'].concat(this.data.class_name ? this.data.class_name : []),
1358		hook: this.createHook('back'),
1359		icon: BaseController.new('atoms-icons', {
1360			icon: 'back'
1361		})
1362	};
1363};
1364
1365module.exports = AtomsLink_Back;
1366
1367},{"BaseController":"BaseController"}],67:[function(require,module,exports){
1368"use strict";
1369var BaseController = require('BaseController');
1370var AtomsLink_CheckAccount = BaseController.create('AtomsLink_CheckAccount');
1371
1372AtomsLink_CheckAccount.prototype.helper = function () {
1373	return {
1374		text: __('generic.check-account'),
1375		hook: this.createHook('back-to-email'),
1376		mod: ['switch']
1377	};
1378};
1379
1380module.exports = AtomsLink_CheckAccount;
1381
1382},{"BaseController":"BaseController"}],68:[function(require,module,exports){
1383"use strict";
1384var BaseController = require('BaseController');
1385var AtomsLink_CheckAccount = BaseController.create('AtomsLink_CheckAccount');
1386
1387AtomsLink_CheckAccount.prototype.helper = function () {
1388	return {
1389		text: __('generic.choose-different-account'),
1390		hook: this.createHook('choose-account'),
1391		mod: ['switch']
1392	};
1393};
1394
1395module.exports = AtomsLink_CheckAccount;
1396
1397},{"BaseController":"BaseController"}],69:[function(require,module,exports){
1398"use strict";
1399var BaseController = require('BaseController');
1400var AtomsLink_ContactAdmin = BaseController.create('AtomsLink_ContactAdmin');
1401
1402AtomsLink_ContactAdmin.prototype.helper = function () {
1403	return {
1404		text: __('generic.contact-admin'),
1405		class_name: this.data.class_name,
1406		hook: this.createHook('contact-admin'),
1407		mod: ['switch']
1408	};
1409};
1410
1411module.exports = AtomsLink_ContactAdmin;
1412
1413},{"BaseController":"BaseController"}],70:[function(require,module,exports){
1414"use strict";
1415var BaseController = require('BaseController');
1416var AtomsLink_CreateAcc = BaseController.create('AtomsLink_CreateAcc');
1417
1418AtomsLink_CreateAcc.prototype.helper = function () {
1419	return {
1420		text: __('generic.create-acc'),
1421		hook: this.createHook('create-acc'),
1422		mod: ['switch']
1423	};
1424};
1425
1426module.exports = AtomsLink_CreateAcc;
1427
1428},{"BaseController":"BaseController"}],71:[function(require,module,exports){
1429"use strict";
1430var BaseController = require('BaseController');
1431var AtomsLink_RemoveFromList = BaseController.create('AtomsLink_RemoveFromList');
1432
1433AtomsLink_RemoveFromList.prototype.helper = function () {
1434	return {
1435		text: __('choose-account.remove'),
1436		// class_name: ['u-float-left'],
1437		hook: this.createHook('remove-from-list')
1438	};
1439};
1440
1441module.exports = AtomsLink_RemoveFromList;
1442
1443},{"BaseController":"BaseController"}],72:[function(require,module,exports){
1444"use strict";
1445var BaseController = require('BaseController');
1446var AtomsLink_Retry = BaseController.create('AtomsLink_Retry');
1447
1448AtomsLink_Retry.prototype.addListeners = function () {
1449	this.addDOMListener('', 'click', this.retry);
1450};
1451
1452AtomsLink_Retry.prototype.retry = function (event) {
1453	event.preventDefault();
1454	if (this.data.link) {
1455		document.location = this.data.link;
1456	} else {
1457		document.location.reload();
1458	}
1459};
1460
1461AtomsLink_Retry.prototype.helper = function () {
1462	return {
1463		link: this.data.link,
1464		text: __('generic.retry'),
1465		class_name: ['u-float-center']
1466	};
1467};
1468
1469module.exports = AtomsLink_Retry;
1470
1471},{"BaseController":"BaseController"}],73:[function(require,module,exports){
1472"use strict";
1473var BaseController = require('BaseController');
1474var AtomsLink_SignIn = BaseController.create('AtomsLink_SignIn');
1475
1476AtomsLink_SignIn.prototype.helper = function () {
1477	return {
1478		text: __('generic.sign-in'),
1479		hook: this.createHook('sign-in'),
1480		mod: ['switch']
1481	};
1482};
1483
1484module.exports = AtomsLink_SignIn;
1485
1486},{"BaseController":"BaseController"}],74:[function(require,module,exports){
1487"use strict";
1488var BaseController = require('BaseController');
1489var AtomsLink_SignWithAnotherAcc = BaseController.create('AtomsLink_SignWithAnotherAcc');
1490
1491AtomsLink_SignWithAnotherAcc.prototype.helper = function () {
1492	return {
1493		text: __('generic.sign-with-another-acc'),
1494		class_name: ['u-align-center'],
1495		hook: this.createHook('sign-with-another-acc'),
1496		mod: ['switch']
1497	};
1498};
1499
1500module.exports = AtomsLink_SignWithAnotherAcc;
1501
1502},{"BaseController":"BaseController"}],75:[function(require,module,exports){
1503"use strict";
1504var BaseController = require('BaseController');
1505var AtomsLink_WhatIsTeamchat = BaseController.create('AtomsLink_WhatIsTeamchat');
1506
1507AtomsLink_WhatIsTeamchat.prototype.helper = function () {
1508	return {
1509		text: __('tc-join.what-is-teamchat'),
1510		hook: this.createHook('what-is-teamchat'),
1511		mod: ['switch']
1512	};
1513};
1514
1515module.exports = AtomsLink_WhatIsTeamchat;
1516
1517},{"BaseController":"BaseController"}],76:[function(require,module,exports){
1518"use strict";
1519var BaseController = require('BaseController');
1520var AtomsSwitch = BaseController.create('AtomsSwitch');
1521
1522AtomsSwitch.prototype.helper = function () {
1523	return {
1524		avatar: BaseController.new('atoms-avatar', Object.assign({}, this.data, {
1525			class_name: ['o-switch__avatar']
1526		})),
1527		name: this.data['name'] || this.data['email'],
1528		email: this.data['email'],
1529		class_name: this.data.class_name,
1530		hook: this.createHook('switch'),
1531		icon: [
1532			// BaseController.new('atoms-icons', {
1533			// 	icon: 'arrow', 
1534			// 	class_name: ['o-switch__ui', 'o-switch__arrow']
1535			// }),
1536			BaseController.new('atoms-icons', {
1537				icon: 'xmark',
1538				class_name: ['o-switch__ui', 'o-switch__xmark']
1539			})
1540		],
1541		link: {
1542			text: 'Undo',
1543			class_name: ['o-switch__ui', 'o-switch__addon'],
1544			hook: this.createHook('remove-from-list-undo')
1545		}
1546	};
1547};
1548
1549module.exports = AtomsSwitch;
1550
1551},{"BaseController":"BaseController"}],77:[function(require,module,exports){
1552"use strict";
1553var BaseController = require('BaseController');
1554var AtomsWell = require('BaseController').create('AtomsWell');
1555
1556AtomsWell.prototype.helper = function () {
1557	switch (this.data.type) {
1558		case 'success':
1559			this.data.mod = ['success'];
1560			this.data.icon = BaseController.new('atoms-icons', {
1561				icon: 'success',
1562				class_name: 'o-well__icon'
1563			});
1564			break;
1565		case 'error':
1566			this.data.mod = ['error'];
1567			this.data.icon = BaseController.new('atoms-icons', {
1568				icon: 'error',
1569				class_name: 'o-well__icon'
1570			});
1571			break;
1572		case 'primary':
1573		default:
1574			this.data.mod = ['secondary'];
1575			this.data.icon = BaseController.new('atoms-icons', {
1576				icon: 'information',
1577				class_name: 'o-well__icon'
1578			});
1579	}
1580	return this.data;
1581};
1582
1583module.exports = AtomsWell;
1584
1585},{"BaseController":"BaseController"}],78:[function(require,module,exports){
1586"use strict";
1587var BaseController = require('BaseController');
1588var Validatable = require('./validatable');
1589
1590var Form = BaseController.create('Form');
1591
1592Form.prototype.onCreate = function () {
1593	this.inputs = {};
1594};
1595
1596/**
1597 * Find all validatable children and validate them.
1598 * @param {Function} callback
1599 * @returns {boolean}
1600 */
1601Form.prototype.validate = function (callback) {
1602	var inputs = this.getChildrenByClass(Validatable),
1603		isValid = true;
1604
1605	this.disable();
1606
1607	/**
1608	 * @returns {Boolean}
1609	 */
1610	function validate() {
1611		var input = inputs.shift();
1612		if (input) {
1613			input.validate(false, function (valid) {
1614				isValid = isValid && valid;
1615				validate.call(this);
1616			}.bind(this));
1617		} else {
1618			if (!isValid) {
1619				this.hasError();
1620				callback && callback(false);
1621			} else {
1622				callback && callback(true);
1623			}
1624		}
1625	}
1626
1627	validate.call(this);
1628};
1629
1630Form.prototype.saveInputs = function () {
1631	this.selectAll('input').concat(this.selectAll('textarea')).forEach(function (input) {
1632		var value = input.value;
1633		if (input.type === 'checkbox') {
1634			value = input.checked;
1635		}
1636		this.inputs[input.getAttribute('name')] = value;
1637	}, this);
1638};
1639
1640Form.prototype.loadInputs = function () {
1641	this.selectAll('input').concat(this.selectAll('textarea')).forEach(function (input) {
1642		var value =  this.inputs[input.getAttribute('name')];
1643		if (!value) {
1644			return;
1645		}
1646		input.focus();
1647		if (input.type === 'checkbox') {
1648			input.checked = value;
1649		} else {
1650			input.value = value;
1651		}
1652		input.blur();
1653	}, this);
1654};
1655
1656module.exports = Form;
1657
1658},{"./validatable":127,"BaseController":"BaseController"}],79:[function(require,module,exports){
1659"use strict";
1660var BaseController = require('BaseController');
1661var MoleculesButton = BaseController.create('MoleculesButton');
1662
1663MoleculesButton.prototype.helper = function () {
1664	return {
1665		mod: this.data['mod'],
1666		class_name: this.data.class_name,
1667		button: BaseController.new('atoms-element-button', this.data.button)
1668	};
1669};
1670
1671module.exports = MoleculesButton;
1672
1673},{"BaseController":"BaseController"}],80:[function(require,module,exports){
1674"use strict";
1675var BaseModel = require('BaseModel');
1676var BaseController = require('BaseController');
1677var MoleculesCaptcha = BaseController.create('MoleculesCaptcha');
1678
1679MoleculesCaptcha.prototype.addListeners = function () {
1680	this.addHookListener('generate-captcha', 'click', this.rerender);
1681};
1682
1683MoleculesCaptcha.prototype.afterRender = function () {
1684	this.regenerate();
1685};
1686
1687MoleculesCaptcha.prototype.regenerate = function () {
1688	BaseModel.instance('WebClient').getCaptcha({
1689		success: function (response) {
1690			var parent, style;
1691			this.uid = response.uid;
1692			parent = this.hook('captcha_html');
1693			while (parent.firstChild) {
1694				parent.removeChild(parent.firstChild);
1695			}
1696			parent.insertAdjacentHTML('afterbegin', response.html);
1697			style = document.createElement('style');
1698			style.insertAdjacentHTML('afterbegin', response.style);
1699			this.hook('captcha_html').appendChild(style);
1700		},
1701		error: function () {
1702			console.error(arguments);
1703		},
1704		context: this
1705	});
1706};
1707
1708MoleculesCaptcha.prototype.helper = function () {
1709	var data = this.data || {};
1710
1711	data.addon = BaseController.new('atoms-addon', {
1712		text: __('generic.captcha-generate'),
1713		mod: ['top'],
1714		hook: this.createHook('generate-captcha')
1715	});
1716
1717	data.hook = this.createHook('captcha_html');
1718	return data;
1719};
1720
1721module.exports = MoleculesCaptcha;
1722
1723},{"BaseController":"BaseController","BaseModel":"BaseModel"}],81:[function(require,module,exports){
1724"use strict";
1725var BaseController = require('BaseController');
1726var MoleculesCheckbox = BaseController.create('MoleculesCheckbox');
1727
1728MoleculesCheckbox.prototype.onCreate = function () {
1729	this.input = BaseController.new('atoms-element-input', this.data.input);
1730};
1731
1732MoleculesCheckbox.prototype.addListeners = function() {
1733	this.addDOMListener('input', 'change', this.onChange);
1734};
1735
1736MoleculesCheckbox.prototype.onChange = function () {
1737	this.DOMElement.classList.toggle('checked', this.input.checked);
1738};
1739
1740MoleculesCheckbox.prototype.helper = function () {
1741
1742	this.data.input.type = this.data.input.type || 'checkbox';
1743	this.data.input.class_name = this.data.input.class_name || ['o-checkbox__element'];
1744	this.data.input.name = this.data.input.name;
1745	return {
1746		class_name: this.data.class_name,
1747		input: this.input,
1748		label: this.data.label
1749	};
1750};
1751
1752module.exports = MoleculesCheckbox;
1753
1754},{"BaseController":"BaseController"}],82:[function(require,module,exports){
1755"use strict";
1756var BaseController = require('BaseController');
1757var MoleculesInput = BaseController.create('MoleculesInput');
1758
1759MoleculesInput.prototype.addListeners = function () {
1760	this.addDOMListener('input', 'input keyup blur change', this.checkEmptiness);
1761	if (this.data.input.type === 'password') {
1762		this.addDOMListener('input', 'keyup', this.capsLockCheck);
1763	}
1764	this.addDOMListener('input', 'keyup', this.keyup);
1765};
1766
1767MoleculesInput.prototype.afterRender = function () {
1768	this.checkEmptiness({target: this.select('input')});
1769};
1770
1771MoleculesInput.prototype.capsLockCheck = function (event) {
1772	if (event.getModifierState) {
1773		this.input.DOMElement.setCustomValidity(event.getModifierState('CapsLock') ? __('error.capslock') : '');
1774		this.input.DOMElement.reportValidity();
1775	}
1776};
1777
1778MoleculesInput.prototype.keyup = function (event) {
1779	~[10, 13].indexOf(event.which || event.keyCode) && (event.form = this.DOMElement.closest('form')) && this.getInstanceByElement(event.form).submitForm(event);
1780};
1781
1782MoleculesInput.prototype.checkEmptiness = function (event) {
1783	this.DOMElement.classList[event.target.value ? 'remove' : 'add']('is-empty');
1784	this.data.input.value = event.target.value;
1785};
1786
1787MoleculesInput.prototype.focus = function () {
1788	this.input.focus();
1789};
1790
1791MoleculesInput.prototype.helper = function () {
1792	var label;
1793
1794	this.data.input.class_name = ['o-form__element'];
1795	if (this.data.input.type === 'date') {
1796		this.input = BaseController.new('atoms-element-input~date', this.data.input);
1797	} else {
1798		this.input = BaseController.new('atoms-element-input', this.data.input);
1799	}
1800
1801	if (this.data.label) {
1802		this.data.label.class_name = ['o-form__label', 'o-form__label--main', 'o-form__label--floating'];
1803		label = BaseController.new('atoms-label', this.data.label);
1804	}
1805
1806	return {
1807		class_name: this.data.class_name,
1808		input: this.input,
1809		label: label,
1810		addon: this.data.addon,
1811		tooltip: this.data.tooltip,
1812		mod: this.data.mod,
1813		tag: this.data.tag,
1814		hook: this.data.hook,
1815		icon: this.data.icon,
1816		value: this.data.value
1817	};
1818};
1819
1820module.exports = MoleculesInput;
1821
1822},{"BaseController":"BaseController"}],83:[function(require,module,exports){
1823"use strict";
1824var BaseModel = require('BaseModel');
1825var BaseController = require('BaseController');
1826var MoleculesInput_Password = require('./input~password.js');
1827var MoleculesInput_PasswordWithPolicy = BaseController.create('MoleculesInput_PasswordWithPolicy', MoleculesInput_Password);
1828
1829MoleculesInput_PasswordWithPolicy.prototype.addListeners = function () {
1830	MoleculesInput_Password.prototype.addListeners.call(this);
1831};
1832
1833MoleculesInput_PasswordWithPolicy.prototype.helper = function () {
1834	var Login = BaseModel.instance('Login');
1835	var password_policy = BaseModel.instance('WebClient').getData('password_policy') || {};
1836
1837	var alias_rule = password_policy.getValue('user_alias') && {
1838		name: 'not_contains',
1839		counterpart_value: Login.getData('create_account').username || Login.getData('chosen_account').username,
1840		parent_hook: 'form',
1841		counterpart_hook: 'username',
1842		message: __('validation.user_alias')
1843	};
1844
1845	var policies = password_policy.getWorkingDataKeys().filter(function(policy) {
1846		return policy !== 'user_alias';
1847	});
1848
1849	this.data.rules = [
1850		{
1851			name: 'empty',
1852			message: __('validation.empty')
1853		},
1854		alias_rule
1855	].concat(policies.map(function (key) {
1856		return password_policy.getValue(key) && {
1857			name: key,
1858			data: password_policy.getValue(key),
1859			message: __('validation.' + key, password_policy.getValue(key))
1860		};
1861	})).filter(Boolean);
1862
1863	this.data.addon = Array.isArray(this.data.addon) ? this.data.addon : [this.data.addon];
1864	if (policies.length) {
1865		if (!this.data.addon.some(function(addon) {
1866			return addon.data.class_name === 'policy';
1867		})) {
1868			this.data.addon.push(BaseController.new('atoms-addon', {
1869				hook: this.createHook('tooltip'),
1870				class_name: 'policy',
1871				text: __('generic.password-policy')
1872			}));
1873		}
1874		this.data.tooltip_well = this.data.tooltip_well === void 0 ? {
1875			title: __('generic.password-policy'),
1876			text: policies.map(function (key) {
1877				return password_policy.getValue(key) && __('validation.' + key, password_policy.getValue(key));
1878			}).filter(Boolean),
1879			type: 'primary',
1880			pinned: this.data.tooltip_well_pinned
1881		} : this.data.tooltip_well;
1882	}
1883
1884	return MoleculesInput_Password.prototype.helper.call(this);
1885};
1886
1887module.exports = MoleculesInput_PasswordWithPolicy;
1888
1889},{"./input~password.js":84,"BaseController":"BaseController","BaseModel":"BaseModel"}],84:[function(require,module,exports){
1890"use strict";
1891var BaseController = require('BaseController');
1892var MoleculesInput_Validatable = require('./input~validatable.js');
1893var MoleculesInput_Password = BaseController.create('MoleculesInput_Password', MoleculesInput_Validatable);
1894
1895MoleculesInput_Password.prototype.onCreate = function () {
1896	this.show = false;
1897	this.data.input.type = 'password';
1898	this.data.input.class_name = ['o-form__element--password'];
1899};
1900
1901MoleculesInput_Password.prototype.addListeners = function () {
1902	MoleculesInput_Validatable.prototype.addListeners.call(this);
1903	this.addDelegatedHookListener('show-password', 'click', this.showPassword);
1904};
1905
1906MoleculesInput_Password.prototype.showPassword = function () {
1907	var icon = (this.data.addon[0] || this.data.addon).data.icon;
1908	this.select('input').setAttribute('type', this.show ? 'password' : 'text');
1909	icon.data.icon = this.show ? 'eye' : 'eye-crossed';
1910	this.show = !this.show;
1911	icon.rerender();
1912};
1913
1914module.exports = MoleculesInput_Password;
1915
1916},{"./input~validatable.js":86,"BaseController":"BaseController"}],85:[function(require,module,exports){
1917"use strict";
1918var BaseModel = require('BaseModel');
1919var BaseController = require('BaseController');
1920var MoleculesInput = require('./input');
1921var MoleculesInput_Search = BaseController.create('MoleculesInput_Search', MoleculesInput);
1922
1923MoleculesInput_Search.prototype.addListeners = function () {
1924	MoleculesInput.prototype.addListeners.call(this);
1925
1926	this.addDOMListener('input', 'submit', this.search);
1927	this.addDOMListener('input', 'keydown', this.keyup);
1928};
1929
1930MoleculesInput_Search.prototype.keyup = function (event) {
1931	((event.which || event.keyCode) === 13) && this.search(event);
1932};
1933
1934MoleculesInput_Search.prototype.search = function (event) {
1935	var WebClient = BaseModel.instance('WebClient');
1936	var url = WebClient.getData('layout_settings').getValue('search_phrase').replace(/%%query%%/g, event.target.value);
1937	var search = window.open(url);
1938	if (!search) {
1939		window.location = url;
1940		return;
1941	}
1942	search.focus();
1943	event.target.value = '';
1944	event.target.blur();
1945
1946	event.preventDefault();
1947	event.stopPropagation();
1948	event.stopImmediatePropagation();
1949};
1950
1951module.exports = MoleculesInput_Search;
1952
1953},{"./input":82,"BaseController":"BaseController","BaseModel":"BaseModel"}],86:[function(require,module,exports){
1954"use strict";
1955var BaseController = require('BaseController');
1956var MoleculesInput = require('./input');
1957var Validatable = require('../../validatable');
1958var MoleculesInput_Validatable = BaseController.create('MoleculesInput_Validatable', MoleculesInput, Validatable);
1959
1960MoleculesInput_Validatable.prototype.addListeners = function () {
1961	Validatable.prototype.addListeners.call(this);
1962	MoleculesInput.prototype.addListeners.call(this);
1963
1964	this.addDOMListener('input', 'change', this.validate);
1965};
1966
1967MoleculesInput_Validatable.prototype.helper = function () {
1968	this.data.tooltip && (this.data.tooltip.hook = this.createHook('tooltip'));
1969	return MoleculesInput.prototype.helper.call(this);
1970};
1971
1972module.exports = MoleculesInput_Validatable;
1973
1974},{"../../validatable":127,"./input":82,"BaseController":"BaseController"}],87:[function(require,module,exports){
1975"use strict";
1976var BaseModel = require('BaseModel');
1977var BaseController = require('BaseController');
1978var Window = require('../../window.js');
1979var MoleculesLanguagePicker = BaseController.create('MoleculesLanguagePicker', Window);
1980
1981MoleculesLanguagePicker.prototype.onCreate = function () {
1982	Window.prototype.onCreate.apply(this, arguments);
1983	this.setup({
1984		move_selector: false,
1985		draggable_border: false
1986	});
1987};
1988
1989MoleculesLanguagePicker.prototype.afterRender = function () {
1990	Window.prototype.afterRender.apply(this, arguments);
1991	this.DOMElement.classList.add('c-card');
1992};
1993
1994MoleculesLanguagePicker.prototype.addListeners = function () {
1995	Window.prototype.addListeners.apply(this, arguments);
1996	this.addPartialListener('molecules-language-picker-item', 'click', this.changeLanguage);
1997	this.addClickOutsideListener(this.DOMShadowElement, this.onClickOutside);
1998};
1999
2000MoleculesLanguagePicker.prototype.onClickOutside = function () {
2001	this.invoker.removeChooseLanguage();
2002};
2003
2004MoleculesLanguagePicker.prototype.changeLanguage = function (event) {
2005	var controller = this.getInstanceByElement(event.target);
2006	var code = controller.data.model.getValue('code');
2007	var codes = BaseModel.static('language').codes;
2008	this.disable();
2009
2010	BaseModel.instance('Login').changeLanguage(codes[code] || code, {
2011		success: function () {
2012			var site = this.getParent('sites');
2013			site.style && document.head.appendChild(site.style);
2014			this.invoker.removeChooseLanguage.call(this.invoker);
2015			site.getChildren('organisms-bar').forEach(function (bar) {
2016				bar.rerender();
2017			});
2018			site.getChildren('templates-card').forEach(function (card) {
2019				card.saveInputs();
2020				card.rerender().then(function() {
2021					card.loadInputs();
2022					card.enable();
2023				});
2024			});
2025		},
2026		error: function (error) {
2027			var site = this.getParent('sites');
2028			this.enable();
2029			this.trigger('error-message-show', {
2030				title: __('generic.error'),
2031				text: error || __('error.language-not-found'),
2032				type: 'error'
2033			});
2034			this.invoker.removeChooseLanguage.call(this.invoker);
2035			site.getChildren('templates-card').forEach(function (card) {
2036				card.enable();
2037			});
2038		},
2039		context: this
2040	});
2041
2042};
2043
2044MoleculesLanguagePicker.prototype.helper = function () {
2045	var WebClient = BaseModel.instance('WebClient');
2046	var languages = WebClient.getData('languages');
2047	var columns = Math.ceil(languages.length / 13);
2048	var rows = Math.ceil(languages.length / columns);
2049	var column = [];
2050
2051	languages.sort(function (a, b) {
2052		var _a = a.getValue('code'), _b = b.getValue('code');
2053		if (_a === 'en') {
2054			return -1;
2055		} else if (_b === 'en') {
2056			return 1;
2057		}
2058		return _a < _b ? -1 : _b < _a;
2059	}).map(function (language) {
2060		var code = language.getValue('code');
2061		return BaseController.new('molecules-language-picker-item', {
2062			text: __('languages.' + code, { useDefaultDictionary: true }),
2063			class_name: WebClient.getData('layout_settings').getUserLanguage().getValue('code') === code ? ['is-active'] : false,
2064			hook: this.createHook('language'),
2065			model: language
2066		});
2067	}, this).forEach(function (language, i) {
2068		var index = Math.floor(i / rows);
2069		column[index] = column[index] || {item: []};
2070		column[index].item.push(language);
2071	});
2072	return {
2073		column: column
2074	};
2075};
2076
2077module.exports = MoleculesLanguagePicker;
2078
2079},{"../../window.js":128,"BaseController":"BaseController","BaseModel":"BaseModel"}],88:[function(require,module,exports){
2080"use strict";
2081var BaseController = require('BaseController');
2082var MoleculesSelect = BaseController.create('MoleculesSelect');
2083
2084MoleculesSelect.prototype.addListeners = function () {
2085	this.addDOMListener('select', 'change', this.checkEmptiness);
2086};
2087
2088MoleculesSelect.prototype.afterRender = function () {
2089	this.checkEmptiness({target: this.select('select')});
2090};
2091
2092MoleculesSelect.prototype.checkEmptiness = function (event) {
2093	this.DOMElement.classList[event.target.value ? 'remove' : 'add']('is-empty');
2094	this.data.select.value = event.target.value;
2095};
2096
2097MoleculesSelect.prototype.focus = function () {
2098	this.input.focus();
2099};
2100
2101MoleculesSelect.prototype.helper = function () {
2102	var select, label;
2103	this.data.select = this.data.select || {};
2104	this.data.select.class_name = this.data.select.class_name || [];
2105	this.data.select.class_name.push('o-form__element');
2106	select = BaseController.new('atoms-element-select', this.data.select);
2107
2108	if (this.data.label) {
2109		this.data.label.class_name = this.data.label.class_name || [];
2110		this.data.label.class_name.push('o-form__label', 'o-form__label--main', 'o-form__label--floating');
2111		label = BaseController.new('atoms-label', this.data.label);
2112	}
2113	
2114	return {
2115		class_name: this.data.class_name,
2116		select: select,
2117		label: label,
2118		icon: BaseController.new('atoms-icons', {
2119			icon: 'arrow',
2120			class_name: ['o-select__arrow']
2121		})
2122	};
2123};
2124
2125module.exports = MoleculesSelect;
2126
2127},{"BaseController":"BaseController"}],89:[function(require,module,exports){
2128"use strict";
2129var BaseController = require('BaseController');
2130var MoleculesSelect = require('./select');
2131var Validatable = require('../../validatable');
2132var MoleculesSelect_Validatable = BaseController.create('MoleculesSelect_Validatable', MoleculesSelect, Validatable);
2133
2134MoleculesSelect_Validatable.prototype.addListeners = function () {
2135	Validatable.prototype.addListeners.call(this);
2136	MoleculesSelect.prototype.addListeners.call(this);
2137
2138	this.addDOMListener('select', 'change', this.validate);
2139};
2140
2141MoleculesSelect_Validatable.prototype.helper = function () {
2142	this.data.tooltip && (this.data.tooltip.hook = this.createHook('tooltip'));
2143	return MoleculesSelect.prototype.helper.call(this);
2144};
2145
2146module.exports = MoleculesSelect_Validatable;
2147
2148},{"../../validatable":127,"./select":88,"BaseController":"BaseController"}],90:[function(require,module,exports){
2149"use strict";
2150var BaseController = require('BaseController');
2151var MoleculesStatic = BaseController.create('MoleculesStatic');
2152
2153MoleculesStatic.prototype.helper = function () {
2154	if (this.data.label) {
2155		this.data.label.class_name = this.data.label.class_name || [];
2156		this.data.label.class_name.push('o-form__label', 'o-form__label--main', 'o-form__label--floating');
2157		this.data.label = BaseController.new('atoms-label', this.data.label);
2158	}
2159
2160	return this.data;
2161};
2162
2163module.exports = MoleculesStatic;
2164
2165},{"BaseController":"BaseController"}],91:[function(require,module,exports){
2166"use strict";
2167var BaseController = require('BaseController');
2168var MoleculesTextarea = BaseController.create('MoleculesTextarea');
2169
2170MoleculesTextarea.prototype.addListeners = function () {
2171	this.addDOMListener('textarea', 'input keyup blur', this.checkEmptiness);
2172};
2173
2174MoleculesTextarea.prototype.afterRender = function () {
2175	this.checkEmptiness({target: this.select('textarea')});
2176};
2177
2178MoleculesTextarea.prototype.checkEmptiness = function (event) {
2179	this.DOMElement.classList[event.target.value ? 'remove' : 'add']('is-empty');
2180	this.data.textarea.text = event.target.value;
2181};
2182
2183MoleculesTextarea.prototype.focus = function () {
2184	this.input.focus();
2185};
2186
2187MoleculesTextarea.prototype.helper = function () {
2188	var textarea, label;
2189	this.data.textarea = this.data.textarea || {};
2190	this.data.textarea.class_name = this.data.textarea.class_name || [];
2191	this.data.textarea.class_name.push('o-form__element');
2192	textarea = BaseController.new('atoms-element-textarea', this.data.textarea);
2193
2194	if (this.data.label) {
2195		this.data.label.class_name = this.data.label.class_name || [];
2196		this.data.label.class_name.push('o-form__label', 'o-form__label--main', 'o-form__label--floating');
2197		label = BaseController.new('atoms-label', this.data.label);
2198	}
2199
2200	return {
2201		class_name: this.data.class_name,
2202		textarea: textarea,
2203		label: label,
2204		tooltip: this.data.tooltip,
2205		addon: this.data.addon,
2206		mod: this.data.mod,
2207		tag: this.data.tag,
2208		hook: this.data.hook,
2209		icon: this.data.icon
2210	};
2211};
2212
2213module.exports = MoleculesTextarea;
2214
2215},{"BaseController":"BaseController"}],92:[function(require,module,exports){
2216"use strict";
2217var BaseController = require('BaseController');
2218var MoleculesTextarea = require('./textarea');
2219var Validatable = require('../../validatable');
2220var MoleculesTextarea_Validatable = BaseController.create('MoleculesTextarea_Validatable', MoleculesTextarea, Validatable);
2221
2222MoleculesTextarea_Validatable.prototype.addListeners = function () {
2223	Validatable.prototype.addListeners.call(this);
2224	MoleculesTextarea.prototype.addListeners.call(this);
2225
2226	this.addDOMListener('textarea', 'change', this.validate);
2227};
2228
2229MoleculesTextarea_Validatable.prototype.helper = function () {
2230	this.data.tooltip && (this.data.tooltip.hook = this.createHook('tooltip'));
2231	return MoleculesTextarea.prototype.helper.call(this);
2232};
2233
2234module.exports = MoleculesTextarea_Validatable;
2235
2236},{"../../validatable":127,"./textarea":91,"BaseController":"BaseController"}],93:[function(require,module,exports){
2237"use strict";
2238var BaseModel = require('BaseModel');
2239var BaseController = require('BaseController');
2240var OrganismsBar_Footer = BaseController.create('OrganismsBar_Footer');
2241
2242OrganismsBar_Footer.prototype.helper = function () {
2243	var WC = BaseModel.instance('WebClient');
2244
2245	return {
2246		class_name: ['o-external__footer'],
2247		section: [
2248			{
2249				mod: ['start'],
2250				footer: WC.getData('restrictions').getValue('disable_copyright') ? false : {
2251					current_year: new Date().getFullYear(),
2252					copyright: __('generic.copyright')
2253				}
2254			},
2255			{
2256				mod: ['center'],
2257				footer: {
2258					social: [
2259						(WC.getData('restrictions').getValue('website_disabled') || !WC.getData('layout_settings').getValue('website_link')) ? false : {
2260							icon: BaseController.new('atoms-icons', {
2261								icon: 'website',
2262								class_name: ['o-external__icon']
2263							}),
2264							href: WC.getData('layout_settings').getValue('website_link')
2265						},
2266						(WC.getData('restrictions').getValue('facebook_disabled') || !WC.getData('layout_settings').getValue('facebook_link')) ? false : {
2267							icon: BaseController.new('atoms-icons', {
2268								icon: 'facebook',
2269								class_name: ['o-external__icon']
2270							}),
2271							href: WC.getData('layout_settings').getValue('facebook_link')
2272						},
2273						(WC.getData('restrictions').getValue('twitter_disabled') || !WC.getData('layout_settings').getValue('twitter_link')) ? false : {
2274							icon: BaseController.new('atoms-icons', {
2275								icon: 'twitter',
2276								class_name: ['o-external__icon']
2277							}),
2278							href: WC.getData('layout_settings').getValue('twitter_link')
2279						},
2280						(WC.getData('restrictions').getValue('linkedin_disabled') || !WC.getData('layout_settings').getValue('linkedin_link')) ? false : {
2281							icon: BaseController.new('atoms-icons', {
2282								icon: 'linkedin',
2283								class_name: ['o-external__icon']
2284							}),
2285							href: WC.getData('layout_settings').getValue('linkedin_link')
2286						}
2287					].filter(Boolean)
2288				}
2289			},
2290			{
2291				mod: ['end'],
2292				footer: WC.getData('restrictions').getValue('disable_copyright') ? false : {
2293					'find-out-more': {
2294						text: __('generic.find_out_more', {
2295							md: true
2296						})
2297					},
2298					version: BaseModel.instance('Server').getData('c_niceversion')
2299				}
2300			}
2301		]
2302	};
2303};
2304
2305module.exports = OrganismsBar_Footer;
2306
2307},{"BaseController":"BaseController","BaseModel":"BaseModel"}],94:[function(require,module,exports){
2308"use strict";
2309var BaseModel = require('BaseModel');
2310var BaseController = require('BaseController');
2311var OrganismsCardHeader = BaseController.create('OrganismsCardHeader');
2312var Escape = require('@icewarp/escape-string');
2313
2314OrganismsCardHeader.prototype.addListeners = function () {};
2315
2316OrganismsCardHeader.prototype.helper = function () {
2317	var Server = BaseModel.instance('Server');
2318	var WebClient = BaseModel.instance('WebClient');
2319	var Login = BaseModel.instance('Login');
2320
2321	var custom_logo = WebClient.getData('layout_settings').getValue('login_logo');
2322
2323	var subtitle = this.data.subtitle === void 0 ? Login.getData('chosen_account').name && {
2324		text: Escape(Login.getData('chosen_account').name),
2325		class_name: ['o-header__subtitle'],
2326		mod: ['normal']
2327	} : this.data.subtitle;
2328
2329	var subsubtitle = this.data.subsubtitle === void 0 ? Login.getData('chosen_account').email && {
2330		text: Escape(Login.getData('chosen_account').email),
2331		class_name: ['o-header__subsubtitle'],
2332		mod: ['normal']
2333	} : this.data.subsubtitle;
2334
2335	var mod = this.data.mod || [];
2336	if (!Array.isArray(mod)) {
2337		mod = [mod];
2338	}
2339	mod.push('default');
2340
2341	if (this.data['card-icon']) {
2342		this.data['card-icon'].data.class_name = ['o-header__image', 'o-header__image--default'];
2343	}
2344
2345	this.data.well = this.data.well || {};
2346	this.data.well.class_name = this.data.well.class_name || [];
2347	this.data.well.class_name.push('o-header__well');
2348
2349	return {
2350		avatar: this.data.avatar !== void 0 ? this.data.avatar : BaseController.new('atoms-avatar', Object.assign({ class_name: ['o-header__avatar'] }, Login.getData('chosen_account'))),
2351		logo: BaseController.new('atoms-image', {
2352			class_name: ['o-header__image', 'o-header__image--default', custom_logo ? '' : 'o-header__default_logo'],
2353			src: custom_logo ? Server.getLogo() : './images/logo.svg'
2354		}),
2355		icon: this.data.icon || BaseController.new('atoms-icons', {
2356			icon: 'icewarp',
2357			class_name: [
2358				'o-header__image',
2359				'o-header__image--default'
2360			]
2361		}),
2362		'card-icon': this.data['card-icon'],
2363		heading: this.data.heading,
2364		hook: this.data.hook,
2365		subtitle: subtitle,
2366		subsubtitle: subsubtitle,
2367		mod: mod,
2368		well: BaseController.new('atoms-well', this.data.well)
2369	};
2370};
2371
2372module.exports = OrganismsCardHeader;
2373
2374},{"@icewarp/escape-string":159,"BaseController":"BaseController","BaseModel":"BaseModel"}],95:[function(require,module,exports){
2375"use strict";
2376var BaseController = require('BaseController');
2377var OrganismsCardHeader = require('./card-header.js');
2378var OrganismsCardHeader_Message = BaseController.create('OrganismsCardHeader_Message', OrganismsCardHeader);
2379
2380OrganismsCardHeader_Message.prototype.helper = function () {
2381	this.data.well && (this.data.well.icon = false);
2382
2383	return OrganismsCardHeader.prototype.helper.call(this);
2384};
2385
2386module.exports = OrganismsCardHeader_Message;
2387
2388},{"./card-header.js":94,"BaseController":"BaseController"}],96:[function(require,module,exports){
2389"use strict";
2390var Window = require('../../window.js');
2391var BaseController = require('BaseController');
2392var OrganismsWindow = BaseController.create('OrganismsWindow', Window);
2393
2394OrganismsWindow.prototype.onCreate = function () {
2395	Window.prototype.onCreate.apply(this, arguments);
2396	this.setup({
2397		//move_selector: ".molecules-window-header",
2398		//draggable_border: 10
2399	});
2400};
2401
2402OrganismsWindow.prototype.beforeFullscreenToggle = function () {
2403	this.DOMElement.classList[this.fullscreen ? 'remove' : 'add']('fullscreen');
2404};
2405
2406module.exports = OrganismsWindow;
2407
2408},{"../../window.js":128,"BaseController":"BaseController"}],97:[function(require,module,exports){
2409"use strict";
2410var BaseController = require('BaseController');
2411var SitesGeneric = BaseController.create('SitesGeneric');
2412
2413SitesGeneric.prototype.afterRender = function () {
2414	this.DOMElement.setAttribute('id', 'content');
2415	this.DOMElement.classList.add('site');
2416};
2417
2418module.exports = SitesGeneric;
2419
2420},{"BaseController":"BaseController"}],98:[function(require,module,exports){
2421"use strict";
2422var Breakpoint = require('Breakpoint');
2423var BaseController = require('BaseController');
2424var GenericSite = require('../generic');
2425var SitesLogin = BaseController.create('SitesLogin', GenericSite);
2426var Browser = require('@icewarp/utils').browser;
2427var extractColors = require('extract-colors');
2428var rgbToHsl = require('rgb-to-hsl');
2429
2430var BaseModel = require('BaseModel');
2431var Hash = require('@icewarp/hash');
2432var LocalStorage = require('@icewarp/localstorage');
2433
2434/**
2435 *
2436 * @param {string} name
2437 * @returns {string|undefined}
2438 */
2439function getCookie(name) {
2440	var value = '; ' + document.cookie + ';';
2441	var parts = value.split('; ' + name + '=');
2442	if (parts.length === 2) {
2443		return parts.pop().split(';').shift();
2444	}
2445}
2446
2447/**
2448 * 
2449 * @param {String} hex 
2450 * @returns {Object}
2451 */
2452function hexToRgb(hex) {
2453	var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
2454	return result ? {
2455		r: parseInt(result[1], 16),
2456		g: parseInt(result[2], 16),
2457		b: parseInt(result[3], 16)
2458	} : null;
2459}
2460
2461SitesLogin.prototype.addListeners = function () {
2462	this.addDOMListener(document.body, 'keydown', this.keydown);
2463	this.addBreakpointListener([Breakpoint.xs, Breakpoint.sm], this.recompileAd);
2464	this.addBreakpointListener([Breakpoint.md, Breakpoint.lg, Breakpoint.xl], this.recompileAd);
2465};
2466
2467SitesLogin.prototype.afterRender = function () {
2468	var backgroundImage;
2469	var layoutSettings = BaseModel.instance('WebClient').getData('layout_settings');
2470	if (!layoutSettings.getValue('login_background_solid') || layoutSettings.getValue('login_background_solid') === 'false') {
2471		backgroundImage = BaseModel.instance('Server').getBackground();
2472		this.DOMElement.style.backgroundImage = 'url(' + backgroundImage + ')';
2473	}
2474	GenericSite.prototype.afterRender.call(this);
2475};
2476
2477SitesLogin.prototype.keydown = function (event) {
2478	if (!document.querySelectorAll('input:focus, textarea:focus, select:focus, button:focus').length && !event.altKey && !event.ctrlKey && !event.metaKey && (!~[8, 9].indexOf(event.which || event.keyCode))) {
2479		this.selectAll('input, textarea').some(function (elem) {
2480			if (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length) {
2481				elem.focus();
2482				return true;
2483			}
2484		});
2485	}
2486};
2487
2488SitesLogin.cards_order = {
2489	unavailable: 0,
2490	'choose-account': 1,
2491	'sign-in': 2,
2492	'sign-in-guest': 3,
2493	'sign-in-password': 3,
2494	'forgot-password': 3,
2495	'create-account': 3,
2496	'join': 3,
2497	'two-factor': 4,
2498	'personal': 4,
2499	'join-username': 4,
2500	'reset-password': 5,
2501	'change-password': 5,
2502	'set-password': 5,
2503	'join-password': 5,
2504	'verification': 6,
2505	'contact-admin': 7,
2506	'tc-join': 101,
2507	'tc-check-email': 102,
2508	'tc-collaboration': 103,
2509	'tc-share': 104,
2510	'tc-actions': 105,
2511	'gateway-login': 301,
2512	'generic-message': 401,
2513	'guest-verify': 500,
2514	'confirm-personality': 501,
2515	'oauth-grant': 601,
2516};
2517
2518SitesLogin['restriction_sign-in-guest'] = async function () {
2519	var config = BaseModel.instance('Config').getData('config');
2520	var Login = BaseModel.instance('Login');
2521	if (config.application !== 'webclient') {
2522		return Login.getDefaultCard();
2523	}
2524};
2525SitesLogin['restriction_sign-in-password'] = async function () {
2526	var Login = BaseModel.instance('Login');
2527	if (!Login.getData('chosen_account').email) {
2528		if (Login.getUsers().length === 1) {
2529			Login.setData('chosen_account', Login.getUsers()[0]);
2530		} else {
2531			return Login.getDefaultCard();
2532		}
2533	}
2534};
2535SitesLogin['restriction_two-factor'] = function () {
2536	var Login = BaseModel.instance('Login');
2537	if (Login.getUsers().length === 1) {
2538		Login.setData('chosen_account', Login.getUsers()[0]);
2539		return 'sign-in-password';
2540	} else {
2541		return Login.getDefaultCard();
2542	}
2543};
2544SitesLogin['restriction_set-password'] = function () {
2545	var Login = BaseModel.instance('Login');
2546	if (!Login.getData('create_account').username || !Login.getData('chosen_account').email) {
2547		return 'create-account';
2548	}
2549};
2550SitesLogin['restriction_generic-message'] = function () {
2551	return !Hash.getParts().tconly && BaseModel.instance('Login').getDefaultCard();
2552};
2553SitesLogin.autoChooseAccount = true;
2554SitesLogin['restriction_choose-account'] = function () {
2555	var last_login;
2556	var config = BaseModel.instance('Config').getData('config');
2557	var Login = BaseModel.instance('Login');
2558	if (Login.getData('chosen_account').email) {
2559		return 'choose-account';
2560	}
2561	if (Login.getUsers().length === 1 && SitesLogin.autoChooseAccount) {
2562		SitesLogin.autoChooseAccount = false;
2563		Login.setData('chosen_account', Login.getUsers()[0]);
2564		return 'sign-in-password';
2565	} else {
2566		last_login = LocalStorage.getItem('last-login-' + config.application);
2567		if (Login.getUsers().length && last_login && Login.getUser(last_login.email)) {
2568			Login.setData('chosen_account', Login.getUser(last_login.email));
2569			return 'sign-in-password';
2570		}
2571	}
2572	if (!Login.getUsers().length || BaseModel.instance('WebClient').getData('restrictions').getValue('disable_autofill')) {
2573		return 'sign-in';
2574	}
2575};
2576SitesLogin['restriction_forgot-password'] = function () {
2577	if (!BaseModel.instance('WebClient').getData('reset_settings').getValue('enabled') || !BaseModel.instance('Login').getData('chosen_account').email) {
2578		return BaseModel.instance('Login').getDefaultCard();
2579	}
2580};
2581SitesLogin['restriction_change-password'] = function () {
2582	if (BaseModel.instance('WebClient').getData('restrictions').getValue('disable_changepass')) {
2583		return BaseModel.instance('Login').getDefaultCard();
2584	}
2585};
2586SitesLogin['restriction_contact-admin'] = function () {
2587	if (!BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support')) {
2588		return BaseModel.instance('Login').getDefaultCard();
2589	}
2590};
2591SitesLogin['restriction_create-account'] = function () {
2592	var WebClient = BaseModel.instance('WebClient');
2593	if (WebClient.getData('restrictions').getValue('disable_signup') || WebClient.getData('restrictions').getValue('disable_signup_ip')) {
2594		return BaseModel.instance('Login').getDefaultCard();
2595	}
2596};
2597SitesLogin['restriction_personal'] = function () {
2598	var WebClient = BaseModel.instance('WebClient');
2599	var Login = BaseModel.instance('Login');
2600	if (WebClient.getData('restrictions').getValue('disable_signup') || WebClient.getData('restrictions').getValue('disable_signup_ip')) {
2601		return Login.getDefaultCard();
2602	}
2603	if (!Login.getData('create_account').username || !WebClient.getData('custom_login_fields').enabledCustomFields().length) {
2604		return 'create-account';
2605	}
2606};
2607SitesLogin['restriction_join'] = function () {
2608	if (!(window.sessionData || {}).domain) {
2609		Hash.change('', { reason: 'signup_invalid_invite_session' }, true, true);
2610		return BaseModel.instance('Login').getDefaultCard();
2611	}
2612};
2613SitesLogin['restriction_join-username'] = function () {
2614	var Login = BaseModel.instance('Login');
2615	if (!(window.sessionData || {}).domain) {
2616		Hash.change('', { reason: 'signup_invalid_invite_session' }, true, true);
2617		return BaseModel.instance('Login').getDefaultCard();
2618	}
2619	if (!Login.getData('create_account').username) {
2620		return 'join';
2621	}
2622};
2623SitesLogin['restriction_join-password'] = function () {
2624	var Login = BaseModel.instance('Login');
2625	if (!(window.sessionData || {}).domain) {
2626		Hash.change('', { reason: 'signup_invalid_invite_session' }, true, true);
2627		return BaseModel.instance('Login').getDefaultCard();
2628	}
2629	if (!Login.getData('chosen_account').email) {
2630		return 'join';
2631	}
2632	if (!Login.getData('create_account').username) {
2633		return 'join';
2634	}
2635};
2636SitesLogin['restriction_verification'] = SitesLogin['restriction_personal'];
2637SitesLogin['restriction_guest-verify'] = function () {
2638	if (!Hash.getParts().email || !Hash.getParts().hash) {
2639		return BaseModel.instance('Login').getDefaultCard();
2640	}
2641};
2642SitesLogin['restriction_confirm-personality'] = function () {
2643	if (!Hash.getParts().email || !Hash.getParts().user || !Hash.getParts().hash) {
2644		return BaseModel.instance('Login').getDefaultCard();
2645	}
2646};
2647SitesLogin['restriction_unavailable'] = function () {
2648	if (BaseModel.instance('WebClient').getData('settings_loaded') && Hash.getParts().error) {
2649		return BaseModel.instance('Login').getDefaultCard();
2650	}
2651	return 'unavailable';
2652};
2653SitesLogin['restriction_tc-*'] = function () {
2654	if (!Hash.getParts().email || !Hash.getParts().sender || !Hash.getParts().hash || !Hash.getParts().room) {
2655		return BaseModel.instance('Login').getDefaultCard();
2656	}
2657};
2658SitesLogin['restriction_tc-action'] = SitesLogin['restriction_tc-*'];
2659SitesLogin['restriction_tc-check-emal'] = SitesLogin['restriction_tc-*'];
2660SitesLogin['restriction_tc-collaboration'] = SitesLogin['restriction_tc-*'];
2661SitesLogin['restriction_tc-join'] = SitesLogin['restriction_tc-*'];
2662SitesLogin['restriction_tc-share'] = SitesLogin['restriction_tc-*'];
2663
2664SitesLogin['restriction_oauth-grant'] = function() {
2665	var OAuth, wa_sid_cookie;
2666	if (!Hash.getParts().auth_id) {
2667		return BaseModel.instance('Login').getDefaultCard();
2668	}
2669	OAuth = BaseModel.instance('OAuth');
2670	wa_sid_cookie = getCookie('waid');
2671	if (!wa_sid_cookie){
2672		return BaseModel.instance('Login').getDefaultCard();
2673	}
2674	OAuth.createAuthConnection(wa_sid_cookie);
2675};
2676
2677SitesLogin.restricted = async function (subpage) {
2678	var restriction;
2679	var _subpage = subpage;
2680	var Login = BaseModel.instance('Login');
2681	var email = (Login.getData('chosen_account') || {}).email || '';
2682	var domain = ~email.indexOf('@') ? email.split('@').pop() : false;
2683	subpage = SitesLogin.cards_order[subpage] !== void 0 ? subpage : BaseModel.instance('Login').getDefaultCard();
2684
2685	if (!this['restriction_' + subpage]) {
2686		return subpage;
2687	}
2688
2689	if (email && _subpage !== 'sign-in-password' && subpage === 'sign-in-password') {
2690		return new Promise((resolve) => {
2691			Login.isGuestDomain(domain, {
2692				success: async function(isGuestDomain) {
2693					var subpage = isGuestDomain ? 'choose-account' : 'sign-in-password';
2694					restriction = await this['restriction_' + subpage]() || subpage;
2695					if (restriction !== subpage) {
2696						Hash.change(restriction, false, false, true);
2697					}
2698					resolve(restriction);
2699				},
2700				context: this
2701			});
2702		});
2703	}
2704
2705	restriction = await this['restriction_' + subpage]() || subpage;
2706	if (restriction !== subpage) {
2707		Hash.change(restriction, false, false, true);
2708	}
2709	return restriction;
2710};
2711
2712SitesLogin.prototype.recompileAd = function () {
2713	this.getChildren('atoms-ad')[0] && this.getChildren('atoms-ad')[0].rerender({
2714		position: ~[Breakpoint.md, Breakpoint.lg, Breakpoint.xl].indexOf(Breakpoint.getCurrent()) ? 'desktop' : 'mobile'
2715	});
2716};
2717
2718SitesLogin.prototype.onHashChange = async function (site, parts, previous_site) {
2719	var card = await SitesLogin.restricted(site);
2720	var prev_subpage = previous_site || BaseModel.instance('Login').getDefaultCard();
2721	prev_subpage !== card && this.getInstanceByElement('form').changeCard({card: card, prepend: SitesLogin.cards_order[card] < SitesLogin.cards_order[prev_subpage], change_hash: false});
2722	return true;
2723};
2724
2725SitesLogin.prototype.helper = function () {
2726	return new Promise(async function (resolve) {
2727		var backgroundImage, img, themeColor, hsl, hex, rgb, greyColor,  lightGreyColor;
2728		var layoutSettings = BaseModel.instance('WebClient').getData('layout_settings');
2729		if (layoutSettings.getValue('login_background_solid') && layoutSettings.getValue('login_background_solid') !== 'false') {
2730			
2731			hex = layoutSettings.getValue('login_interface_color') === 'background' ? layoutSettings.getValue('login_background_color') : layoutSettings.getValue('login_interface_color');
2732			rgb = hexToRgb(hex);
2733			hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
2734			themeColor = 'hsl(' + hsl[0] + ', ' + hsl[1] + ', 45%)';
2735			greyColor = 'hsl(' + hsl[0] + ', 6%, 69%)';
2736			lightGreyColor = 'hsl(' + hsl[0] + ', 11%, 82%)';
2737
2738			this.style = this.style || document.createElement('style');
2739			this.style.textContent = '\
2740				:root {\
2741					--theme-color: ' + themeColor + ';\
2742					--default-color: ' + themeColor + ';\
2743					--deep-purple-color: ' + themeColor + ';\
2744					--default-grey-color: ' + greyColor + ';\
2745					--default-light-grey-color: ' + lightGreyColor + ';\
2746				}\
2747			';
2748			document.head.appendChild(this.style);
2749
2750			resolve({
2751				card: BaseController.new('templates-card~' + await SitesLogin.restricted(this.data.site || Hash.getSite()), this.data.data),
2752				bar: BaseController.new('organisms-bar~footer', {
2753					class_name: ['footer']
2754				}),
2755				theme: 'default',
2756				'background-color': layoutSettings.getValue('login_background_color'),
2757				ie: Browser.isIE() || Browser.isEdge(),
2758				ad: BaseController.new('atoms-ad', {
2759					position: ~[Breakpoint.md, Breakpoint.lg, Breakpoint.xl].indexOf(Breakpoint.getCurrent()) ? 'desktop' : 'mobile'
2760				})
2761			});
2762		} else if (layoutSettings.getValue('login_interface_color') === 'background') {
2763			backgroundImage = BaseModel.instance('Server').getBackground(1280, 720);
2764			img = new Image();
2765			img.addEventListener('load', function() {
2766				extractColors.extractColorsFromImage(img).then(async function(swatches) {
2767					var i, hsl, themeColor, greyColor, lightGreyColor;
2768					var mostPopulous = swatches[0];
2769					for (i in swatches) {
2770						if (swatches[i].area * swatches[i].intensity * swatches[i].saturation * swatches[i].lightness > mostPopulous.area * mostPopulous.intensity * mostPopulous.saturation * mostPopulous.lightness) {
2771							mostPopulous = swatches[i];
2772						}
2773					}
2774
2775					hsl = rgbToHsl(mostPopulous.red, mostPopulous.green, mostPopulous.blue);
2776					themeColor = 'hsl(' + hsl[0] + ', ' + hsl[1] + ', 45%)';
2777					greyColor = 'hsl(' + hsl[0] + ', 6%, 69%)';
2778					lightGreyColor = 'hsl(' + hsl[0] + ', 11%, 82%)';
2779
2780					this.style = this.style || document.createElement('style');
2781					this.style.textContent = '\
2782						:root {\
2783							--theme-color: ' + themeColor + ';\
2784							--default-color: ' + themeColor + ';\
2785							--deep-purple-color: ' + themeColor + ';\
2786							--default-grey-color: ' + greyColor + ';\
2787							--default-light-grey-color: ' + lightGreyColor + ';\
2788						}\
2789					';
2790					document.head.appendChild(this.style);
2791
2792					resolve({
2793						card: BaseController.new('templates-card~' + await SitesLogin.restricted(this.data.site || Hash.getSite()), this.data.data),
2794						bar: BaseController.new('organisms-bar~footer', {
2795							class_name: ['footer']
2796						}),
2797						theme: 'default',
2798						'background-image': backgroundImage,
2799						'background-color': ~['cover', 'tile'].indexOf(layoutSettings.getValue('login_background_wallpaper_size')) ? themeColor : layoutSettings.getValue('login_background_color'),
2800						'background-size': layoutSettings.getValue('login_background_wallpaper_size'),
2801						ie: Browser.isIE() || Browser.isEdge(),
2802						ad: BaseController.new('atoms-ad', {
2803							position: ~[Breakpoint.md, Breakpoint.lg, Breakpoint.xl].indexOf(Breakpoint.getCurrent()) ? 'desktop' : 'mobile'
2804						})
2805					});
2806				}.bind(this)).catch(async function() {
2807					resolve({
2808						card: BaseController.new('templates-card~' + await SitesLogin.restricted(this.data.site || Hash.getSite()), this.data.data),
2809						bar: BaseController.new('organisms-bar~footer', {
2810							class_name: ['footer']
2811						}),
2812						theme: layoutSettings.getValue('login_color'),
2813						'background-image': backgroundImage,
2814						'background-color': ~['cover', 'tile'].indexOf(layoutSettings.getValue('login_background_wallpaper_size')) ? themeColor : layoutSettings.getValue('login_background_color'),
2815						'background-size': layoutSettings.getValue('login_background_wallpaper_size'),
2816						ie: Browser.isIE() || Browser.isEdge(),
2817						ad: BaseController.new('atoms-ad', {
2818							position: ~[Breakpoint.md, Breakpoint.lg, Breakpoint.xl].indexOf(Breakpoint.getCurrent()) ? 'desktop' : 'mobile'
2819						})
2820					});
2821				}.bind(this));
2822			}.bind(this));
2823
2824			img.addEventListener('error', async function() {
2825				resolve({
2826					card: BaseController.new('templates-card~' + await SitesLogin.restricted(this.data.site || Hash.getSite()), this.data.data),
2827					bar: BaseController.new('organisms-bar~footer', {
2828						class_name: ['footer']
2829					}),
2830					theme: layoutSettings.getValue('login_color'),
2831					'background-image': backgroundImage,
2832					'background-color': ~['cover', 'tile'].indexOf(layoutSettings.getValue('login_background_wallpaper_size')) ? themeColor : layoutSettings.getValue('login_background_color'),
2833					'background-size': layoutSettings.getValue('login_background_wallpaper_size'),
2834					ie: Browser.isIE() || Browser.isEdge(),
2835					ad: BaseController.new('atoms-ad', {
2836						position: ~[Breakpoint.md, Breakpoint.lg, Breakpoint.xl].indexOf(Breakpoint.getCurrent()) ? 'desktop' : 'mobile'
2837					})
2838				});
2839			}.bind(this));
2840			img.src = backgroundImage;
2841		} else {
2842			backgroundImage = BaseModel.instance('Server').getBackground(1280, 720);
2843			hex = layoutSettings.getValue('login_interface_color');
2844			rgb = hexToRgb(hex);
2845			hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
2846			themeColor = 'hsl(' + hsl[0] + ', ' + hsl[1] + ', 45%)';
2847			greyColor = 'hsl(' + hsl[0] + ', 6%, 69%)';
2848			lightGreyColor = 'hsl(' + hsl[0] + ', 11%, 82%)';
2849
2850			this.style = this.style || document.createElement('style');
2851			this.style.textContent = '\
2852				:root {\
2853					--theme-color: ' + themeColor + ';\
2854					--default-color: ' + themeColor + ';\
2855					--deep-purple-color: ' + themeColor + ';\
2856					--default-grey-color: ' + greyColor + ';\
2857					--default-light-grey-color: ' + lightGreyColor + ';\
2858				}\
2859			';
2860			document.head.appendChild(this.style);
2861
2862			resolve({
2863				card: BaseController.new('templates-card~' + await SitesLogin.restricted(this.data.site || Hash.getSite()), this.data.data),
2864				bar: BaseController.new('organisms-bar~footer', {
2865					class_name: ['footer']
2866				}),
2867				theme: 'default',
2868				'background-color': ~['cover', 'tile'].indexOf(layoutSettings.getValue('login_background_wallpaper_size')) ? themeColor : layoutSettings.getValue('login_background_color'),
2869				'background-image': backgroundImage,
2870				'background-size': layoutSettings.getValue('login_background_wallpaper_size'),
2871				ie: Browser.isIE() || Browser.isEdge(),
2872				ad: BaseController.new('atoms-ad', {
2873					position: ~[Breakpoint.md, Breakpoint.lg, Breakpoint.xl].indexOf(Breakpoint.getCurrent()) ? 'desktop' : 'mobile'
2874				})
2875			});
2876		}
2877	}.bind(this));
2878};
2879
2880module.exports = SitesLogin;
2881
2882},{"../generic":97,"@icewarp/hash":160,"@icewarp/localstorage":167,"@icewarp/utils":180,"BaseController":"BaseController","BaseModel":"BaseModel","Breakpoint":"Breakpoint","extract-colors":360,"rgb-to-hsl":366}],99:[function(require,module,exports){
2883"use strict";
2884var BaseModel = require('BaseModel');
2885var BaseController = require('BaseController');
2886var Form = require('../../form');
2887var TemplatesCard = BaseController.create('TemplatesCard', Form);
2888var Validatable = require('../../validatable');
2889var animationEnd = require('@icewarp/utils').animations.browserEvent('animationend');
2890var Hash = require('@icewarp/hash');
2891var delayed = require('delayed');
2892var MobileDetect = require('mobile-detect');
2893
2894TemplatesCard.prototype.addListeners = function () {
2895	this.addDelegatedHookListener('sign-with-another-acc', 'click', this.changeCard, {card: 'sign-in', hashData: Hash.getParts()});
2896	this.addDelegatedHookListener('contact-admin', 'click', this.changeCard, {card: 'contact-admin', hashData: Hash.getParts()});
2897	this.addDelegatedHookListener('sign-in', 'click', this.changeCard, {hashData: Hash.getParts()});
2898	this.addDelegatedHookListener('choose-account', 'click', this.changeCard, {card: 'choose-account', hashData: Hash.getParts()});
2899	this.addDelegatedHookListener('create-acc', 'click', this.changeCard, {card: 'create-account'});
2900	this.addDelegatedHookListener('back-to-email', 'click', this.backToEmail);
2901	this.addDelegatedHookListener('back', 'click', this.back);
2902	this.addDelegatedHookListener('language', 'click', this.chooseLanguage);
2903	this.addDOMListener('', 'submit', this.submitForm);
2904
2905	this.addGlobalListener('error-message-hide', this.hideMessage);
2906	this.addGlobalListener('error-message-show', this.showMessage);
2907};
2908
2909TemplatesCard.prototype.onCreate = function () {
2910	Form.prototype.onCreate.call(this);
2911	this.submitted = false;
2912};
2913
2914TemplatesCard.prototype.afterRender = function () {
2915	var md = new MobileDetect(window.navigator.userAgent);
2916	var parts = Hash.getParts();
2917	var error = parts.eid || parts.reason;
2918	document.body.scrollTop = document.documentElement.scrollTop = 0;
2919	error && this.showMessage({
2920		title: __('generic.error'),
2921		text: __('error.' + error, {}, __('error.unspecified', {error: error, md: true})),
2922		type: 'error',
2923		pinned: true
2924	});
2925
2926	parts.notifyuri && parts.eid && BaseModel.instance('Login').callCommunication('teamchatError', parts);
2927
2928	if (!md.mobile() && !md.tablet()) {
2929		setTimeout(function() {
2930			this.setCaret();
2931		}.bind(this), 100);
2932	}
2933};
2934
2935TemplatesCard.prototype.setCaret = function () {
2936	this.selectAll('input, textarea').some(function (elem) {
2937		if (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length) {
2938			elem.focus();
2939			setTimeout(function() {
2940				var range;
2941				try {
2942					if (typeof elem.selectionStart === 'number') {
2943						elem.selectionStart = elem.selectionEnd = elem.value.length;
2944					} else if (typeof elem.createTextRange !== 'undefined') {
2945						elem.focus();
2946						range = elem.createTextRange();
2947						range.collapse(false);
2948						range.select();
2949					}
2950				} catch (e) {
2951					// ignore
2952				}
2953			}, 0);
2954			return true;
2955		}
2956	});
2957};
2958
2959TemplatesCard.prototype.beforeDestroy = function () {
2960	this.autohide_timeout && clearTimeout(this.autohide_timeout);
2961};
2962
2963TemplatesCard.prototype.chooseLanguage = function (event) {
2964	var rect = event.element.getBoundingClientRect();
2965	event.stopPropagation();
2966	this.choose_language = this.choose_language || BaseController.new('molecules-language-picker');
2967	if (this.choose_language.DOMElement) {
2968		return this.removeChooseLanguage();
2969	}
2970	this.choose_language.invoker = this;
2971	this.choose_language.execute().then(function(controller) {
2972		controller.render(this.getParent('sites').DOMElement, 'beforeend');
2973		controller.DOMElement.style.top = rect.bottom + 'px';
2974		if ((rect.left + rect.right - controller.DOMElement.clientWidth) / 2 + controller.DOMElement.clientWidth <= document.body.clientWidth) {
2975			controller.DOMElement.style.left = (rect.left + rect.right - controller.DOMElement.clientWidth) / 2 + 'px';
2976		} else {
2977			controller.DOMElement.style.right = 0;
2978		}
2979		event.element.classList.add('is-open');
2980	}.bind(this));
2981};
2982
2983TemplatesCard.prototype.removeChooseLanguage = function () {
2984	if (animationEnd) {
2985		// this.choose_language.DOMElement.classList.add('is-previous');
2986		// this.choose_language.addDOMListener(this.choose_language.DOMElement, animationEnd, function () {
2987			this.DOMElement && this.hook('language').classList.remove('is-open');
2988			this.choose_language.remove();
2989			this.choose_language = null;
2990		// }.bind(this), {}, true);
2991		// this.choose_language.DOMElement.classList.add('on-destroy');
2992	} else {
2993		this.hook('language').classList.remove('is-open');
2994		this.choose_language.remove();
2995		this.choose_language = null;
2996	}
2997};
2998
2999TemplatesCard.prototype.back = function () {
3000	history.back();
3001};
3002
3003TemplatesCard.prototype.backToEmail = function () {
3004	this.changeCard({card: this.data.prev || 'sign-in'});
3005};
3006
3007TemplatesCard.prototype.submitForm = function (event) {
3008	event.preventDefault();
3009	event.stopPropagation();
3010	event.stopImmediatePropagation();
3011	if (this.submitted) {
3012		return;
3013	}
3014	this.validateForm && this.disable() && this.validateForm();
3015};
3016
3017TemplatesCard.prototype.hasError = function () {
3018	this.enable();
3019	if (animationEnd) {
3020		this.addDOMListener(this.DOMElement, animationEnd, function () {
3021			this.DOMElement.classList.remove('a-error');
3022		}.bind(this), {}, true);
3023		this.DOMElement.classList.add('a-error');
3024	}
3025};
3026
3027TemplatesCard.prototype.genericError = function (error, type, title) {
3028	var captchas = this.getChildren('molecules-captcha');
3029	var validatable;
3030
3031	this.hasError();
3032	if (captchas.length) {
3033		captchas[0].rerender();
3034		this.hook('captcha').value = '';
3035		this.hook('captcha').focus();
3036	}
3037	error && this.showMessage({
3038		title: title || __('generic.error'),
3039		text: __('error.' + error, {}, __('error.unspecified', {error: error, md: true})),
3040		type: type || 'error'
3041	});
3042
3043	if (!this.DOMElement.querySelector(':focus')) {
3044		validatable = this.getChildrenByClass(Validatable)[0];
3045		if (validatable && validatable.focus) {
3046			validatable.focus();
3047		}
3048	}
3049};
3050
3051TemplatesCard.prototype.changeCardCallback = function (data) {
3052	if (!this.DOMElement) {
3053		return;
3054	}
3055	BaseController.new('templates-card~' + data.card).execute(data.data || {}).then(function(controller) {
3056		if (!this.DOMElement) {
3057			return;
3058		}
3059		controller.render(this.DOMElement.parentElement, 'beforeend');
3060		controller.DOMElement.classList.remove(data.prepend ? 'is-previous' : 'is-next');
3061		this.remove();
3062	}.bind(this));
3063};
3064
3065TemplatesCard.prototype.changeCard = function (event, data) {
3066	if (!this.DOMElement) {
3067		return;
3068	}
3069	data = (arguments.length === 1 ? event : data) || {};
3070	data.card = data.card || BaseModel.instance('Login').getDefaultCard();
3071
3072	(data.change_hash === void 0 ? true : data.change_hash) && Hash.change(data.card, data.hashData || {}, true, data.keepHashData);
3073
3074	if (animationEnd) {
3075		this.changeCardCallback(data);
3076		this.DOMElement.classList.add('on-destroy');
3077	} else {
3078		this.changeCardCallback(data);
3079	}
3080};
3081
3082TemplatesCard.prototype.hideMessage = function () {
3083	var well = this.getInstanceByElement(this.hook('well'));
3084	if (well.data.pinned) {
3085		return;
3086	}
3087	if (animationEnd) {
3088		well.addDOMListener(well.DOMElement, animationEnd, function () {
3089			well.DOMElement.classList.remove('on-destroy');
3090			well.DOMElement.classList.remove('is-visible');
3091		}, {}, true);
3092		well.DOMElement.classList.add('on-destroy');
3093	} else {
3094		well.DOMElement.classList.remove('is-visible');
3095	}
3096};
3097
3098TemplatesCard.prototype.showMessage = function (data) {
3099	var well = this.getInstanceByElement(this.hook('well'));
3100	well.data.title = data.title;
3101	well.data.text = data.text;
3102	well.data.type = data.type;
3103	well.data.pinned = data.pinned;
3104	well.data.class_name = well.data.class_name || [];
3105	well.data.class_name.push('is-visible');
3106
3107	well.rerender();
3108	this.autohide_timeout && clearTimeout(this.autohide_timeout);
3109	data.autohide && (this.autohide_timeout = delayed(this.hideMessage, this, data.autohide, this._name + this.id));
3110};
3111
3112TemplatesCard.prototype.helper = function (helper_data) {
3113	var WebClient = BaseModel.instance('WebClient');
3114	var codes = BaseModel.static('language').codes;
3115	var code = WebClient.getData('layout_settings').getUserLanguage().getValue('code');
3116	var i;
3117	for (i in codes) {
3118		if (codes[i] === code) {
3119			code = i;
3120			break;
3121		}
3122	}
3123	return Object.assign({
3124		component: [
3125			(!WebClient.getData('restrictions').getValue('disable_languages') && WebClient.getData('languages').length > 1) && BaseController.new('atoms-dropdown', {
3126				class_name: ['o-card__lang'],
3127				hook: this.createHook('language'),
3128				code: code,
3129				icon: false && BaseController.new('atoms-icons', {
3130					icon: 'planet',
3131					class_name: ['o-dropdown__icon']
3132				})
3133			}),
3134			this.data.back && history.length > 2 && BaseController.new('atoms-link~back', {
3135				class_name: ['o-card__back']
3136			})
3137		].filter(Boolean)
3138	}, helper_data);
3139};
3140
3141module.exports = TemplatesCard;
3142
3143},{"../../form":78,"../../validatable":127,"@icewarp/hash":160,"@icewarp/utils":180,"BaseController":"BaseController","BaseModel":"BaseModel","delayed":"delayed","mobile-detect":364}],100:[function(require,module,exports){
3144"use strict";
3145var BaseModel = require('BaseModel');
3146var BaseController = require('BaseController');
3147var TemplatesCard = require('./card.js');
3148var TemplatesCard_ChangePassword = BaseController.create('TemplatesCard_ChangePassword', TemplatesCard);
3149
3150TemplatesCard_ChangePassword.prototype.addListeners = function () {
3151	TemplatesCard.prototype.addListeners.call(this);
3152	this.addHookListener('change-password', 'click', this.submitForm);
3153};
3154
3155TemplatesCard_ChangePassword.prototype.validateForm = function () {
3156	this.validate(function (isValid) {
3157		if (isValid) {
3158			BaseModel.instance('Login').getAuthChallenge({
3159				success: this.changePassword,
3160				error: function (error) {
3161					this.genericError(error);
3162				},
3163				context: this
3164			});
3165		}
3166	}.bind(this));
3167};
3168
3169TemplatesCard_ChangePassword.prototype.changePassword = function (encrypt) {
3170	BaseModel.instance('WebClient').changePassword({
3171		email: this.hook('username').value,
3172		oldpassword: encrypt(this.hook('current-password').value),
3173		newpassword: encrypt(this.hook('password').value)
3174	}, {
3175		success: function () {
3176			this.changeCard({
3177				data: {
3178					well: {
3179						title: __('generic.success'),
3180						text: __('change-password.success-message'),
3181						type: 'success',
3182						class_name: ['is-visible']
3183					}
3184				}
3185			});
3186		},
3187		error: function (error) {
3188			this.genericError(error);
3189		},
3190		context: this
3191	});
3192};
3193
3194TemplatesCard_ChangePassword.prototype.helper = function () {
3195	return TemplatesCard.prototype.helper.call(this, {
3196		hook: this.createHook('form'),
3197		content: [
3198			{
3199				mod: [],
3200				component: BaseController.new('organisms-card-header', {
3201					heading: __('change-password.heading'),
3202					subtitle: '',
3203					well: this.data.well
3204				})
3205			},
3206			{
3207				mod: ['form'],
3208				component: BaseController.new('molecules-input~validatable', {
3209					input: {
3210						type: 'text',
3211						name: 'username',
3212						hook: this.createHook('username')
3213					},
3214					label: {
3215						text: BaseModel.instance('Server').getData('c_accounts_policies_login_loginsettings') ? __('generic.email') : __('generic.username')
3216					},
3217					rules: [
3218						{
3219							name: 'empty',
3220							message: __('validation.empty')
3221						}
3222					]
3223				})
3224			},
3225			{
3226				mod: ['form'],
3227				component: BaseController.new('molecules-input~password', {
3228					input: {
3229						hook: this.createHook('current-password'),
3230						name: 'current-password',
3231						autocomplete: 'current-password'
3232					},
3233					label: {
3234						text: __('generic.password-current')
3235					},
3236					addon: BaseController.new('atoms-addon~show'),
3237					rules: [
3238						{
3239							name: 'empty',
3240							message: __('validation.empty')
3241						}
3242					]
3243				})
3244			},
3245			{
3246				mod: ['form'],
3247				component: BaseController.new('molecules-input~password-with-policy', {
3248					input: {
3249						hook: this.createHook('password'),
3250						name: 'new-password',
3251						autocomplete: 'new-password'
3252					},
3253					label: {
3254						text: __('generic.password-new')
3255					},
3256					addon: BaseController.new('atoms-addon~show')
3257				})
3258			},
3259			{
3260				mod: ['form'],
3261				component: BaseController.new('molecules-input~password', {
3262					input: {
3263						name: 'confirm-password',
3264						autocomplete: 'new-password'
3265					},
3266					label: {
3267						text: __('generic.password-confirm')
3268					},
3269					addon: BaseController.new('atoms-addon~show'),
3270					rules: [
3271						{
3272							name: 'empty',
3273							message: __('validation.empty')
3274						},
3275						{
3276							name: 'same',
3277							controller: this,
3278							parent_hook: 'form',
3279							counterpart_hook: 'password',
3280							message: __('validation.passwords-no-match')
3281						}
3282					]
3283				})
3284			},
3285			{
3286				mod: ['default', 'space-top'],
3287				component: BaseController.new('molecules-button', {
3288					mod: ['block', 'primary'],
3289					button: {
3290						text: __('generic.save-password'),
3291						hook: this.createHook('change-password'),
3292						name: 'change-password'
3293					}
3294				})
3295			},
3296			{
3297				mod: ['footer'],
3298				component: [
3299					BaseController.new('atoms-info~have-account'),
3300					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
3301				].filter(Boolean)
3302			}
3303		].filter(Boolean)
3304	});
3305};
3306
3307module.exports = TemplatesCard_ChangePassword;
3308
3309},{"./card.js":99,"BaseController":"BaseController","BaseModel":"BaseModel"}],101:[function(require,module,exports){
3310"use strict";
3311var BaseModel = require('BaseModel');
3312var BaseController = require('BaseController');
3313var TemplatesCard = require('./card.js');
3314var Hash = require('@icewarp/hash');
3315var TemplatesCard_ChooseAccount = BaseController.create('TemplatesCard_ChooseAccount', TemplatesCard);
3316
3317TemplatesCard_ChooseAccount.prototype.addListeners = function () {
3318	TemplatesCard.prototype.addListeners.call(this);
3319	this.addHookListener('remove-from-list', 'click', this.removeFromListInit);
3320	this.addHookListener('remove-from-list-done', 'click', this.removeFromListDone);
3321	this.addHookListener('switch', 'click', this.chooseAccount);
3322	this.addHookListener('switch', 'keypress', this.chooseAccountEnter);
3323	this.addDelegatedDOMListener('.is-removed', 'click', this.removeFromListUndo);
3324	this.addDelegatedDOMListener('.is-removable', 'click', this.removeFromListRemove);
3325};
3326
3327TemplatesCard_ChooseAccount.prototype.chooseAccountEnter = function (event, data) {
3328	((event.which || event.keyCode) === 13) && this.chooseAccount(event, data);
3329};
3330
3331TemplatesCard_ChooseAccount.prototype.chooseAccount = function (event) {
3332	var Login = BaseModel.instance('Login');
3333	var email = this.getInstanceByElement(event.element).data.email;
3334	var user = Login.getUser(email);
3335	var config = BaseModel.instance('Config').getData('config');
3336
3337	event.preventDefault();
3338	if (event.element.classList.contains('is-removable') || event.element.classList.contains('is-removed')) {
3339		return;
3340	}
3341
3342	if (user.guestLogin) {
3343		if (config.application === 'webclient') {
3344			BaseModel.instance('Login').guestLogin({
3345				email: email
3346			});
3347		} else {
3348			this.genericError('invalid_account_app');
3349		}
3350		return;
3351	}
3352
3353	Login.setData('chosen_account', user);
3354	this.changeCard({
3355		card: 'sign-in-password',
3356		hashData: Hash.getParts(),
3357		data: {
3358			back: true,
3359			prev: 'choose-account'
3360		}
3361	});
3362};
3363
3364TemplatesCard_ChooseAccount.prototype.removeFromListInit = function () {
3365	var heading = this.hook('heading');
3366	this.hook('remove-from-list-section').classList.add('u-hide');
3367	this.hook('remove-from-list-done-section').classList.add('on-load');
3368	this.hook('remove-from-list-done-section').classList.remove('u-hide');
3369	while (heading.firstChild) {
3370		heading.removeChild(heading.firstChild);
3371	}
3372	heading.insertAdjacentHTML('afterbegin', __('choose-account.remove'));
3373	this.hooks('switch').forEach(function (user) {
3374		user.classList.add('is-removable');
3375	});
3376};
3377
3378TemplatesCard_ChooseAccount.prototype.removeFromListRemove = function (event) {
3379	event.stopPropagation();
3380	event.stopImmediatePropagation();
3381	this.closestHook('switch', event.target).classList.add('is-removed');
3382	this.closestHook('switch', event.target).classList.remove('is-removable');
3383	this.hook('remove-from-list-done').textContent = this.selectAll('[data-hook="switch"].is-removed').length ? __('choose-account.remove-selected') : __('generic.cancel');
3384};
3385
3386TemplatesCard_ChooseAccount.prototype.removeFromListUndo = function (event) {
3387	event.stopPropagation();
3388	event.stopImmediatePropagation();
3389	this.closestHook('switch', event.target).classList.add('is-removable');
3390	this.closestHook('switch', event.target).classList.remove('is-removed');
3391	this.hook('remove-from-list-done').textContent = this.selectAll('[data-hook="switch"].is-removed').length ? __('choose-account.remove-selected') : __('generic.cancel');
3392};
3393
3394TemplatesCard_ChooseAccount.prototype.removeFromListDone = function (event) {
3395	var heading = this.hook('heading');
3396	event.preventDefault();
3397	this.hook('remove-from-list-section').classList.add('on-load');
3398	this.hook('remove-from-list-section').classList.remove('u-hide');
3399	while (heading.firstChild) {
3400		heading.removeChild(heading.firstChild);
3401	}
3402	heading.insertAdjacentHTML('afterbegin', __('choose-account.heading'));
3403	this.hook('remove-from-list-done-section').classList.add('u-hide');
3404	this.selectAll('[data-hook="switch"].is-removed').forEach(function (user) {
3405		var user_controller = this.getInstanceByElement(user);
3406		BaseModel.instance('Login').removeUser({email: user_controller.data.email});
3407		user_controller.remove();
3408	}, this);
3409	this.selectAll('[data-hook="switch"].is-removable').forEach(function (user) {
3410		user.classList.remove('is-removable');
3411	});
3412	if (!BaseModel.instance('Login').getUsers().length) {
3413		this.changeCard({card: 'sign-in'});
3414	}
3415};
3416
3417TemplatesCard_ChooseAccount.prototype.helper = function () {
3418	var WebClient = BaseModel.instance('WebClient');
3419
3420	this.data.back = true;
3421
3422	return TemplatesCard.prototype.helper.call(this, {
3423		hook: this.createHook('form'),
3424		content: [
3425			{
3426				mod: [],
3427				component: BaseController.new('organisms-card-header', {
3428					heading: __('choose-account.heading'),
3429					hook: this.createHook('heading'),
3430					avatar: false,
3431					subtitle: false,
3432					subsubtitle: false,
3433					well: this.data.well
3434				})
3435			},
3436			{
3437				mod: ['form'],
3438				component: BaseModel.instance('Login').getUsers().map(function (user) {
3439					return BaseController.new('atoms-switch', user);
3440				})
3441			},
3442			{
3443				mod: ['form'],
3444				hook: this.createHook('remove-from-list-section'),
3445				component: BaseController.new('atoms-link~remove-from-list')
3446			},
3447			{
3448				mod: ['form'],
3449				class_name: ['u-hide'],
3450				hook: this.createHook('remove-from-list-done-section'),
3451				component: BaseController.new('molecules-button', {
3452					mod: ['block', 'primary', 'small'],
3453					button: {
3454						hook: this.createHook('remove-from-list-done'),
3455						text: __('generic.cancel'),
3456						name: 'done'
3457					}
3458				})
3459			},
3460			WebClient.getData('restrictions').getValue('show_search') && {
3461				mod: ['form'],
3462				component: BaseController.new('molecules-input~search', {
3463					input: {
3464						name: 'search'
3465					},
3466					label: {
3467						text: __('generic.search')
3468					}
3469				})
3470			},
3471			{
3472				mod: ['footer', 'space-top'],
3473				component: [
3474					BaseController.new('atoms-info~sign-with-another-acc'),
3475					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
3476				].filter(Boolean)
3477			}
3478		].filter(Boolean)
3479	});
3480};
3481
3482module.exports = TemplatesCard_ChooseAccount;
3483
3484},{"./card.js":99,"@icewarp/hash":160,"BaseController":"BaseController","BaseModel":"BaseModel"}],102:[function(require,module,exports){
3485"use strict";
3486var BaseController = require('BaseController');
3487var TemplatesCard_GenericMessage = require('./card~generic-message.js');
3488var TemplatesCard_ConfirmPersonality = BaseController.create('TemplatesCard_ConfirmPersonality', TemplatesCard_GenericMessage);
3489var Hash = require('@icewarp/hash');
3490
3491TemplatesCard_ConfirmPersonality.prototype.addListeners = function () {
3492	TemplatesCard_GenericMessage.prototype.addListeners.call(this);
3493};
3494
3495TemplatesCard_ConfirmPersonality.prototype.afterRender = function () {
3496	TemplatesCard_GenericMessage.prototype.afterRender.call(this);
3497
3498	!this.hasResponse && this.callCommunication('confirmPersonality', {
3499		user: Hash.getParts().user,
3500		email: Hash.getParts().email,
3501		hash: Hash.getParts().hash
3502	});
3503};
3504
3505TemplatesCard_ConfirmPersonality.prototype.helper = function () {
3506	this.data.title = __('confirm-personality.heading');
3507	this.data.subtitle = this.data.subtitle === void 0 ? {
3508		text: __('confirm-personality.subheading')
3509	} : this.data.subtitle;
3510	this.data.loading = this.data.loading === void 0 ? true : this.data.loading;
3511	this.data.type = this.data.type || 'none';
3512	return TemplatesCard_GenericMessage.prototype.helper.call(this);
3513};
3514
3515module.exports = TemplatesCard_ConfirmPersonality;
3516
3517},{"./card~generic-message.js":107,"@icewarp/hash":160,"BaseController":"BaseController"}],103:[function(require,module,exports){
3518"use strict";
3519var BaseModel = require('BaseModel');
3520var BaseController = require('BaseController');
3521var TemplatesCard = require('./card.js');
3522var TemplatesCard_ContactAdmin = BaseController.create('TemplatesCard_ContactAdmin', TemplatesCard);
3523
3524TemplatesCard_ContactAdmin.prototype.addListeners = function () {
3525	TemplatesCard.prototype.addListeners.call(this);
3526	this.addHookListener('validate-form', 'click', this.submitForm);
3527	this.addHookListener('validate-form', 'keypress', this.textareaKeypress);
3528};
3529
3530TemplatesCard_ContactAdmin.prototype.validateForm = function () {
3531	this.validate(function (isValid) {
3532		var data;
3533		if (isValid) {
3534			data = this.hook('describe-problem').value;
3535			if (BaseModel.instance('WebClient').getData('restrictions').getValue('support_require_number')) {
3536				data += '\n\n' + __('personal.mobile-phone') + ': ' + this.hook('tel').value;
3537			}
3538			BaseModel.instance('WebClient').contactAdministrator({
3539				email: this.hook('email-address').value,
3540				data: data,
3541				captcha: {
3542					uid: this.getChildren('molecules-captcha')[0].uid,
3543					value: this.hook('captcha').value.toUpperCase()
3544				}
3545			}, {
3546				success: function () {
3547					this.changeCard({
3548						card: 'generic-message',
3549						data: {
3550							type: 'success',
3551							well: {
3552								text: __('contact-admin.success-message')
3553							},
3554							link: ''
3555						},
3556						change_hash: false
3557					});
3558				},
3559				error: function (error) {
3560					this.genericError(error);
3561				},
3562				context: this
3563			});
3564		}
3565	}.bind(this));
3566};
3567
3568TemplatesCard_ContactAdmin.prototype.textareaKeypress = function (event) {
3569	(event.ctrlKey || event.metaKey) && ~[10, 13].indexOf(event.which || event.keyCode) && this.submitForm(event);
3570};
3571
3572TemplatesCard_ContactAdmin.prototype.helper = function () {
3573	var WebClient = BaseModel.instance('WebClient');
3574	var email = BaseModel.instance('Login').getData('chosen_account').email || '';
3575	if (!~email.indexOf('@')) {
3576		email = '';
3577	}
3578
3579	this.data.back = true;
3580
3581	return TemplatesCard.prototype.helper.call(this, {
3582		hook: this.createHook('form'),
3583		content: [
3584			{
3585				mod: [],
3586				component: BaseController.new('organisms-card-header', {
3587					avatar: false,
3588					heading: __('contact-admin.heading'),
3589					subtitle: false,
3590					subsubtitle: false,
3591					well: this.data.well
3592				})
3593			},
3594			{
3595				mod: ['form'],
3596				component: BaseController.new('molecules-input~validatable', {
3597					input: {
3598						hook: this.createHook('email-address'),
3599						type: 'email',
3600						name: 'email-address',
3601						value: email
3602					},
3603					label: {
3604						text: __('generic.email')
3605					},
3606					rules: [
3607						{
3608							name: 'empty',
3609							message: __('validation.empty')
3610						},
3611						{
3612							name: 'email',
3613							message: __('validation.email')
3614						}
3615					],
3616					tooltip_well: {
3617						text: [
3618							__('contact-admin.email-helper')
3619						],
3620						type: 'primary'
3621					}
3622				})
3623			},
3624			BaseModel.instance('WebClient').getData('restrictions').getValue('support_require_number') && {
3625				mod: ['form'],
3626				component: BaseController.new('molecules-input~validatable', {
3627					input: {
3628						hook: this.createHook('tel'),
3629						type: 'tel',
3630						name: 'tel'
3631					},
3632					label: {
3633						text: __('personal.mobile-phone')
3634					},
3635					rules: [
3636						{
3637							name: 'empty',
3638							message: __('validation.empty')
3639						}
3640					],
3641					tooltip_well: {
3642						text: [
3643							__('contact-admin.tel')
3644						],
3645						type: 'primary'
3646					}
3647				})
3648			},
3649			{
3650				mod: ['form'],
3651				component: BaseController.new('molecules-textarea~validatable', {
3652					textarea: {
3653						hook: this.createHook('describe-problem'),
3654						name: 'describe-problem'
3655					},
3656					label: {
3657						text: __('contact-admin.describe-problem')
3658					},
3659					rules: [
3660						{
3661							name: 'empty',
3662							message: __('validation.empty')
3663						}
3664					]
3665				})
3666			},
3667			{
3668				mod: ['form'],
3669				component: BaseController.new('molecules-captcha')
3670			},
3671			{
3672				mod: ['form'],
3673				component: BaseController.new('molecules-input~validatable', {
3674					input: {
3675						hook: this.createHook('captcha'),
3676						type: 'text',
3677						name: 'security-code',
3678						maxlength: 6,
3679						minlength: 6
3680					},
3681					label: {
3682						text: __('generic.security-code')
3683					},
3684					rules: [
3685						{
3686							name: 'empty',
3687							message: __('validation.empty')
3688						},
3689						{
3690							name: 'length',
3691							data: 6,
3692							message: __('validation.length', 6)
3693						}
3694					]
3695				})
3696			},
3697			{
3698				mod: ['default', 'space-top'],
3699				component: [
3700					BaseController.new('molecules-button', {
3701						mod: ['block', 'primary'],
3702						button: {
3703							hook: this.createHook('validate-form'),
3704							text: __('contact-admin.submit'),
3705							name: 'send-message'
3706						}
3707					})
3708				]
3709			},
3710			WebClient.getData('restrictions').getValue('show_search') && {
3711				mod: ['form'],
3712				component: BaseController.new('molecules-input~search', {
3713					input: {
3714						name: 'search'
3715					},
3716					label: {
3717						text: __('generic.search')
3718					}
3719				})
3720			}
3721		].filter(Boolean)
3722	});
3723};
3724
3725module.exports = TemplatesCard_ContactAdmin;
3726
3727},{"./card.js":99,"BaseController":"BaseController","BaseModel":"BaseModel"}],104:[function(require,module,exports){
3728"use strict";
3729var punycode = require('punycode');
3730var BaseModel = require('BaseModel');
3731var BaseController = require('BaseController');
3732var TemplatesCard = require('./card.js');
3733var TemplatesCard_CreateAccount = BaseController.create('TemplatesCard_CreateAccount', TemplatesCard);
3734
3735TemplatesCard_CreateAccount.prototype.addListeners = function () {
3736	TemplatesCard.prototype.addListeners.call(this);
3737	this.addHookListener('save-credentials', 'click', this.submitForm);
3738};
3739
3740TemplatesCard_CreateAccount.prototype.validateForm = function () {
3741	this.validate(function (isValid) {
3742		var Login = BaseModel.instance('Login');
3743		var WebClient = BaseModel.instance('WebClient');
3744		if (isValid) {
3745			Login.setData('chosen_account', {
3746				name: this.hook('full-name').value,
3747				email: this.hook('username').value + '@' + punycode.toUnicode(this.hook('select').value),
3748				avatar_token: false
3749			});
3750			Login.setData('create_account', {
3751				domain: this.hook('select').value,
3752				username: this.hook('username').value,
3753				fullname: this.hook('full-name').value,
3754				alternativeemail: this.hook('alternate-email').value,
3755				card: {}
3756			});
3757			this.changeCard({ card: WebClient.getData('custom_login_fields').enabledCustomFields().length || WebClient.getData('custom_login_fields').getValue('login_verification_enabled') ? 'personal' : 'set-password' });
3758		}
3759	}.bind(this));
3760};
3761
3762TemplatesCard_CreateAccount.prototype.helper = function () {
3763	var WebClient = BaseModel.instance('WebClient');
3764	var Login = BaseModel.instance('Login');
3765
3766	var signup_domains = WebClient.getData('signup_domains').map(function (domain) {
3767		return {
3768			value: domain.getData('value'),
3769			text: punycode.toUnicode(domain.getData('value')),
3770			selected: Login.getData('create_account').domain === domain.getData('value')
3771		};
3772	}).sort(function (a, b) {
3773		return b.value > a.value ? -1 : a.value > b.value;
3774	});
3775
3776	return TemplatesCard.prototype.helper.call(this, {
3777		hook: this.createHook('form'),
3778		content: [
3779			{
3780				mod: [],
3781				component: BaseController.new('organisms-card-header', {
3782					heading: __('create-account.heading'),
3783					avatar: false,
3784					subtitle: false,
3785					well: this.data.well
3786				})
3787			},
3788			{
3789				mod: ['form'],
3790				component: BaseController.new('molecules-input~validatable', {
3791					input: {
3792						type: 'text',
3793						hook: this.createHook('username'),
3794						name: 'username',
3795						value: Login.getData('create_account').username,
3796						autocomplete: 'username'
3797					},
3798					label: {
3799						text: __('generic.username')
3800					},
3801					rules: [
3802						{
3803							name: 'empty',
3804							message: __('validation.empty')
3805						},
3806						{
3807							name: 'not_contains',
3808							counterpart_value: '@',
3809							message: __('validation.username')
3810						}
3811					]
3812				})
3813			},
3814			{
3815				mod: ['form'],
3816				component: BaseController.new('molecules-select', {
3817					select: {
3818						hook: this.createHook('select'),
3819						name: 'select',
3820						options: signup_domains
3821					},
3822					label: {
3823						text: __('create-account.domain')
3824					},
3825					rules: [
3826						{
3827							name: 'empty',
3828							message: __('validation.empty')
3829						}
3830					]
3831				})
3832			},
3833			{
3834				mod: ['form'],
3835				component: BaseController.new('molecules-input~validatable', {
3836					input: {
3837						type: 'text',
3838						hook: this.createHook('full-name'),
3839						name: 'full-name',
3840						value: Login.getData('create_account').fullname,
3841						autocomplete: 'name'
3842					},
3843					label: {
3844						text: __('create-account.full-name')
3845					},
3846					rules: [
3847						{
3848							name: 'empty',
3849							message: __('validation.empty')
3850						}
3851					]
3852				})
3853			},
3854			{
3855				mod: ['form'],
3856				component: BaseController.new('molecules-input~validatable', {
3857					input: {
3858						type: 'email',
3859						hook: this.createHook('alternate-email'),
3860						name: 'alternate-email',
3861						value: Login.getData('create_account').alternativeemail,
3862						autocomplete: 'email'
3863					},
3864					label: {
3865						text: __('create-account.alternative-email')
3866					},
3867					rules: [
3868						{
3869							name: 'empty',
3870							message: __('validation.empty')
3871						},
3872						{
3873							name: 'email',
3874							message: __('validation.email')
3875						}
3876					]
3877				})
3878			},
3879			{
3880				mod: ['default', 'space-top'],
3881				component: BaseController.new('molecules-button', {
3882					mod: ['block', 'primary'],
3883					button: {
3884						hook: this.createHook('save-credentials'),
3885						text: WebClient.getData('custom_login_fields').enabledCustomFields().length ? __('create-account.next-step') : __('create-account.last-step'),
3886						name: 'next'
3887					}
3888				})
3889			},
3890			{
3891				mod: ['footer'],
3892				component: [
3893					BaseController.new('atoms-info~have-account'),
3894					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
3895				].filter(Boolean)
3896			}
3897		].filter(Boolean)
3898	});
3899};
3900
3901module.exports = TemplatesCard_CreateAccount;
3902
3903},{"./card.js":99,"BaseController":"BaseController","BaseModel":"BaseModel","punycode":355}],105:[function(require,module,exports){
3904"use strict";
3905var BaseModel = require('BaseModel');
3906var BaseController = require('BaseController');
3907var TemplatesCard = require('./card.js');
3908var TemplatesCard_ForgotPassword = BaseController.create('TemplatesCard_ForgotPassword', TemplatesCard);
3909
3910TemplatesCard_ForgotPassword.prototype.addListeners = function () {
3911	TemplatesCard.prototype.addListeners.call(this);
3912	this.addHookListener('send-message', 'click', this.submitForm);
3913};
3914
3915TemplatesCard_ForgotPassword.prototype.validateForm = function () {
3916	this.validate(function (isValid) {
3917		if (isValid) {
3918			BaseModel.instance('WebClient').resetPasswordEmail({
3919				email: BaseModel.instance('Login').getData('chosen_account').email,
3920				captcharequest: {
3921					uid: this.getChildren('molecules-captcha')[0].uid,
3922					value: this.hook('captcha').value.toUpperCase()
3923				}
3924			}, {
3925				success: function (response) {
3926					if (response == 3) {
3927						this.changeCard({
3928							card: 'reset-password',
3929							data: {
3930								user: BaseModel.instance('Login').getData('chosen_account').email,
3931								sms: true
3932							},
3933							change_hash: false
3934						});
3935					} else {
3936						this.changeCard({
3937							card: 'generic-message',
3938							data: {
3939								type: 'success',
3940								well: {
3941									text: __('forgot-password.success-message' + (response * 1 === 2 ? '-guest' : ''))
3942								},
3943								link: ''
3944							},
3945							change_hash: false
3946						});
3947					}
3948				},
3949				error: function (error) {
3950					switch (error) {
3951						case 'account_alternative_email':
3952							this.changeCard({
3953								card: 'contact-admin',
3954								data: {
3955									well: {
3956										title: __('generic.error'),
3957										text: __('error.' + error),
3958										type: 'error',
3959										class_name: ['is-visible']
3960									}
3961								}
3962							});
3963							break;
3964						default:
3965							this.genericError.apply(this, arguments);
3966					}
3967				},
3968				context: this
3969			});
3970		}
3971	}.bind(this));
3972};
3973
3974TemplatesCard_ForgotPassword.prototype.helper = function () {
3975	return TemplatesCard.prototype.helper.call(this, {
3976		hook: this.createHook('form'),
3977		content: [
3978			{
3979				mod: [],
3980				component: BaseController.new('organisms-card-header', {
3981					heading: __('forgot-password.heading'),
3982					well: this.data.well
3983				})
3984			},
3985			{
3986				mod: ['form'],
3987				component: BaseController.new('molecules-captcha')
3988			},
3989			{
3990				mod: ['form'],
3991				component: BaseController.new('molecules-input~validatable', {
3992					input: {
3993						hook: this.createHook('captcha'),
3994						type: 'text',
3995						name: 'security-code',
3996						maxlength: 6,
3997						minlength: 6
3998					},
3999					label: {
4000						text: __('generic.security-code')
4001					},
4002					rules: [
4003						{
4004							name: 'empty',
4005							message: __('validation.empty')
4006						},
4007						{
4008							name: 'length',
4009							data: 6,
4010							message: __('validation.length', 6)
4011						}
4012					]
4013				})
4014			},
4015			{
4016				mod: ['default', 'space-top'],
4017				component: BaseController.new('molecules-button', {
4018					mod: ['block', 'primary'],
4019					button: {
4020						hook: this.createHook('send-message'),
4021						text: __('forgot-password.submit'),
4022						name: 'send-message'
4023					}
4024				})
4025			},
4026			{
4027				mod: ['footer'],
4028				component: [
4029					BaseController.new('atoms-info~not-you'),
4030					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
4031				].filter(Boolean)
4032			}
4033		].filter(Boolean)
4034	});
4035};
4036
4037module.exports = TemplatesCard_ForgotPassword;
4038
4039},{"./card.js":99,"BaseController":"BaseController","BaseModel":"BaseModel"}],106:[function(require,module,exports){
4040"use strict";
4041var BaseModel = require('BaseModel');
4042var BaseController = require('BaseController');
4043var TemplatesCard = require('./card.js');
4044var TemplatesCard_GatewayLogin = BaseController.create('TemplatesCard_GatewayLogin', TemplatesCard);
4045
4046TemplatesCard_GatewayLogin.prototype.addListeners = function () {
4047	TemplatesCard.prototype.addListeners.call(this);
4048	this.addHookListener('gateway-sign-in', 'click', this.validateForm);
4049};
4050
4051TemplatesCard_GatewayLogin.prototype.validateForm = function () {
4052	this.validate(function (isValid) {
4053		if (isValid) {
4054			BaseModel.instance('WebClient').sendGatewayAuthentication({
4055				email: this.hook('email').value,
4056				captcharequest: {
4057					uid: this.getChildren('molecules-captcha')[0].uid,
4058					value: this.hook('captcha').value.toUpperCase()
4059				}
4060			}, {
4061				success: function () {
4062					this.changeCard({
4063						card: 'generic-message',
4064						data: {
4065							type: 'success',
4066							well: {
4067								text: __('gateway-login.success-message')
4068							},
4069							link: ''
4070						},
4071						change_hash: false
4072					});
4073				},
4074				error: function (error) {
4075					this.genericError(error);
4076				},
4077				context: this
4078			});
4079		}
4080	}.bind(this));
4081};
4082
4083TemplatesCard_GatewayLogin.prototype.helper = function () {
4084	var config = BaseModel.instance('Config').getData('config');
4085	return TemplatesCard.prototype.helper.call(this, {
4086		hook: this.createHook('form'),
4087		content: [
4088			{
4089				mod: [],
4090				component: BaseController.new('organisms-card-header', {
4091					heading: __('sign-in-generic.heading.' + config.application),
4092					subtitle: {
4093						text: __('gateway-login.subheading')
4094					},
4095					well: this.data.well
4096				})
4097			},
4098			{
4099				mod: ['form'],
4100				component: BaseController.new('molecules-input~validatable', {
4101					input: {
4102						type: 'email',
4103						name: 'email-address',
4104						hook: this.createHook('email')
4105					},
4106					label: {
4107						text: __('generic.email')
4108					},
4109					rules: [
4110						{
4111							name: 'empty',
4112							message: __('validation.empty')
4113						},
4114						{
4115							name: 'email',
4116							message: __('validation.email')
4117						}
4118					].filter(Boolean)
4119				})
4120			},
4121			{
4122				mod: ['form'],
4123				component: BaseController.new('molecules-captcha')
4124			},
4125			{
4126				mod: ['form'],
4127				component: BaseController.new('molecules-input~validatable', {
4128					input: {
4129						hook: this.createHook('captcha'),
4130						type: 'text',
4131						name: 'security-code',
4132						maxlength: 6,
4133						minlength: 6
4134					},
4135					label: {
4136						text: __('generic.security-code')
4137					},
4138					rules: [
4139						{
4140							name: 'empty',
4141							message: __('validation.empty')
4142						},
4143						{
4144							name: 'length',
4145							data: 6,
4146							message: __('validation.length', 6)
4147						}
4148					]
4149				})
4150			},
4151			{
4152				mod: ['default', 'space-top'],
4153				component: BaseController.new('molecules-button', {
4154					mod: ['block', 'primary'],
4155					button: {
4156						text: __('generic.sign-in'),
4157						name: 'gateway-sign-in',
4158						hook: this.createHook('gateway-sign-in')
4159					}
4160				})
4161			},
4162			{
4163				mod: ['footer'],
4164				component: BaseController.new('atoms-link~sign-with-another-acc')
4165			}
4166		].filter(Boolean)
4167	});
4168};
4169
4170module.exports = TemplatesCard_GatewayLogin;
4171
4172},{"./card.js":99,"BaseController":"BaseController","BaseModel":"BaseModel"}],107:[function(require,module,exports){
4173"use strict";
4174var BaseModel = require('BaseModel');
4175var BaseController = require('BaseController');
4176var TemplatesCard = require('./card.js');
4177var TemplatesCard_GenericMessage = BaseController.create('TemplatesCard_GenericMessage', TemplatesCard);
4178var delayed = require('delayed');
4179var Hash = require('@icewarp/hash');
4180
4181TemplatesCard_GenericMessage.prototype.addListeners = function () {
4182	TemplatesCard.prototype.addListeners.call(this);
4183	this.addDelegatedHookListener('redirect', 'click', this.changeCard, {card: this.data.link});
4184};
4185
4186TemplatesCard_GenericMessage.prototype.onCreate = function () {
4187	this.delayMessage = true;
4188};
4189
4190TemplatesCard_GenericMessage.prototype.afterRender = function () {
4191	var parts = Hash.getParts();
4192	TemplatesCard.prototype.afterRender.call(this);
4193
4194	if (parts.tconly) {
4195		if (parts.token && parts.notifyuri) {
4196			this.callCommunication('logoutTeamChatOnly', parts, BaseModel.instance('Login'));
4197		} else {
4198			return this.changeCard({
4199				card: 'sign-in',
4200				hashData: Hash.getParts()
4201			});
4202		}
4203	}
4204
4205	delayed(function () {
4206		this.delayMessage = false;
4207	}, this, 400, 'delay' + this._mod);
4208};
4209
4210TemplatesCard_GenericMessage.prototype.callCommunication = function (method, data, model) {
4211	(model || BaseModel.instance('WebClient'))[method](data, {
4212		success: function () {
4213			this.communicationCallback('success');
4214		},
4215		error: function (error) {
4216			this.communicationCallback('error', error);
4217		},
4218		context: this
4219	});
4220};
4221
4222TemplatesCard_GenericMessage.prototype.communicationCallback = function (type, error) {
4223	this.data.type = type;
4224	this.data.well = type === 'error' ? {
4225		text: __('error.' + error, {error: error, md: true})
4226	} : {
4227		text: __(this._mod + '.success-message')
4228	};
4229	this.data.subtitle = false;
4230	this.data.link = '';
4231	this.data.loading = false;
4232	this.hasResponse = true;
4233	Hash.change(false, false, true);
4234	if (this.delayMessage) {
4235		delayed(function () {
4236			this.rerender();
4237		}, this, 400, 'rerender' + this._mod);
4238	} else {
4239		this.rerender();
4240	}
4241};
4242
4243TemplatesCard_GenericMessage.prototype.helper = function () {
4244	if (this.data.well) {
4245		this.data.well.type = this.data.type;
4246		this.data.well.class_name = this.data.class_name || [];
4247		this.data.well.class_name.push('is-visible');
4248	}
4249
4250	return TemplatesCard.prototype.helper.call(this, {
4251		content: [
4252			{
4253				mod: [],
4254				component: BaseController.new('organisms-card-header~message', {
4255					mod: this.data.type,
4256					'card-icon': function () {
4257						switch (this.data.type) {
4258							case 'success':
4259								return BaseController.new('atoms-icons', {
4260									icon: 'success'
4261								});
4262							case 'error':
4263								return BaseController.new('atoms-icons', {
4264									icon: 'error'
4265								});
4266							case 'none':
4267								return false;
4268							default:
4269								return BaseController.new('atoms-icons', {
4270									icon: 'information'
4271								});
4272						}
4273					}.call(this),
4274					heading: this.data.title === void 0 ? __('generic.' + this.data.type) : this.data.title,
4275					avatar: this.data.avatar,
4276					subtitle: this.data.subtitle,
4277					subsubtitle: this.data.subsubtitle,
4278					well: this.data.well
4279				})
4280			},
4281			this.data.loading && {
4282				mod: ['form', 'space-top'],
4283				component: BaseController.new('atoms-loader', {
4284					mod: ['large']
4285				})
4286			},
4287			this.data.link || {
4288				mod: ['form', 'space-top'],
4289				component: BaseController.new('molecules-button', {
4290					mod: ['block', 'primary'],
4291					button: {
4292						text: __('generic.understand'),
4293						name: 'redirect',
4294						hook: this.createHook('redirect')
4295					}
4296				})
4297			},
4298			this.data.footer || {
4299				mod: ['footer'],
4300				component: BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
4301			}
4302		].filter(Boolean)
4303	});
4304};
4305
4306module.exports = TemplatesCard_GenericMessage;
4307
4308},{"./card.js":99,"@icewarp/hash":160,"BaseController":"BaseController","BaseModel":"BaseModel","delayed":"delayed"}],108:[function(require,module,exports){
4309"use strict";
4310var BaseModel = require('BaseModel');
4311var BaseController = require('BaseController');
4312var TemplatesCard_GenericMessage = require('./card~generic-message.js');
4313var TemplatesCard_GuestVerify = BaseController.create('TemplatesCard_GuestVerify', TemplatesCard_GenericMessage);
4314var Hash = require('@icewarp/hash');
4315
4316TemplatesCard_GuestVerify.prototype.addListeners = function () {
4317	TemplatesCard_GenericMessage.prototype.addListeners.call(this);
4318};
4319
4320TemplatesCard_GuestVerify.prototype.afterRender = function () {
4321	BaseModel.instance('Login').setData('guestLogin', true);
4322	TemplatesCard_GenericMessage.prototype.afterRender.call(this);
4323
4324	!this.hasResponse && this.callCommunication('guestVerify', {
4325		email: Hash.getParts().email,
4326		hash: Hash.getParts().hash
4327	});
4328};
4329
4330TemplatesCard_GuestVerify.prototype.helper = function () {
4331	this.data.avatar = false;
4332	this.data.title = __('guest-verify.heading');
4333	this.data.subtitle = this.data.subtitle === void 0 ? {
4334		text: __('guest-verify.subheading')
4335	} : this.data.subtitle;
4336	this.data.subsubtitle = {
4337		text: Hash.getParts().email
4338	};
4339	this.data.loading = this.data.loading === void 0 ? true : this.data.loading;
4340	this.data.type = this.data.type || 'none';
4341	return TemplatesCard_GenericMessage.prototype.helper.call(this);
4342};
4343
4344module.exports = TemplatesCard_GuestVerify;
4345
4346},{"./card~generic-message.js":107,"@icewarp/hash":160,"BaseController":"BaseController","BaseModel":"BaseModel"}],109:[function(require,module,exports){
4347"use strict";
4348var BaseModel = require('BaseModel');
4349var BaseController = require('BaseController');
4350var TemplatesCard = require('./card.js');
4351var AtomsAddon = require('../../atoms/addon/addon');
4352var TemplatesCard_JoinPassword = BaseController.create('TemplatesCard_JoinPassword', TemplatesCard);
4353
4354TemplatesCard_JoinPassword.prototype.onCreate = function () {
4355	TemplatesCard.prototype.onCreate.call(this);
4356
4357	this.password = BaseController.new('molecules-input~password-with-policy', {
4358		hook: this.createHook('password1'),
4359		input: {
4360			name: 'new-password',
4361			hook: this.createHook('password'),
4362			autocomplete: 'new-password'
4363		},
4364		label: {
4365			text: __('generic.password-new')
4366		},
4367		addon: BaseController.new('atoms-addon~show'),
4368		tooltip_well_pinned: true
4369	});
4370};
4371
4372TemplatesCard_JoinPassword.prototype.addListeners = function () {
4373	TemplatesCard.prototype.addListeners.call(this);
4374	this.addHookListener('create-account', 'click', this.submitForm);
4375	this.addHookListener('password', 'change', this.crossValidatePasswordCheck);
4376	this.addHookListener('password-check', 'change', this.crossValidatePassword);
4377};
4378
4379TemplatesCard_JoinPassword.prototype.afterRender = function () {
4380	var addons;
4381	TemplatesCard.prototype.afterRender.call(this);
4382
4383	this.trigger('error-message-show', this.password.data.tooltip_well);
4384	addons = this.password.getChildrenByClass(AtomsAddon);
4385	addons[1] && addons[1].DOMElement.setAttribute('hidden', '');
4386};
4387
4388TemplatesCard_JoinPassword.prototype.validateForm = function () {
4389	this.validate(function (isValid) {
4390		var Login = BaseModel.instance('Login');
4391		if (isValid) {
4392			Login.getData('create_account').password = this.hook('password').value;
4393			Login.getData('create_account').session = window.sessionData.id;
4394
4395			Login.getAuthChallenge({
4396				success: this.signupAccount,
4397				error: function (error) {
4398					this.genericError(error);
4399				},
4400				context: this
4401			});
4402		}
4403	}.bind(this));
4404};
4405
4406TemplatesCard_JoinPassword.prototype.signupAccount = function (encrypt) {
4407	BaseModel.instance('WebClient').signupAccount(encrypt, {
4408		success: function () {
4409			this.changeCard({
4410				data: {
4411					well: {
4412						title: __('generic.success'),
4413						text: __('set-password.success-message'),
4414						type: 'success',
4415						class_name: ['is-visible']
4416					}
4417				}
4418			});
4419		},
4420		error: function (error) {
4421			this.genericError(error);
4422		},
4423		context: this
4424	});
4425};
4426
4427TemplatesCard_JoinPassword.prototype.crossValidatePasswordCheck = function () {
4428	this.hook('password-check').value.trim().length && this.getInstanceByElement(this.hook('password2')).validate();
4429};
4430TemplatesCard_JoinPassword.prototype.crossValidatePassword = function () {
4431	this.hook('password').value.trim().length && this.getInstanceByElement(this.hook('password1')).validate();
4432};
4433
4434TemplatesCard_JoinPassword.prototype.helper = function () {
4435	var Login = BaseModel.instance('Login');
4436
4437	this.data.back = true;
4438
4439	return TemplatesCard.prototype.helper.call(this, {
4440		hook: this.createHook('form'),
4441		content: [
4442			{
4443				mod: [],
4444				component: BaseController.new('organisms-card-header', {
4445					heading: __('set-password.heading'),
4446					avatar: false,
4447					well: this.data.well
4448				})
4449			},
4450			{
4451				class_name: ['u-hide'],
4452				component: BaseController.new('molecules-input', {
4453					input: {
4454						type: 'text',
4455						name: 'username',
4456						hook: this.createHook('username'),
4457						value: Login.getData('chosen_account').email,
4458						autocomplete: 'username'
4459					}
4460				})
4461			},
4462			{
4463				mod: ['form', 'space-top'],
4464				component: this.password
4465			},
4466			{
4467				mod: ['form'],
4468				component: BaseController.new('molecules-input~password', {
4469					hook: this.createHook('password2'),
4470					input: {
4471						name: 'password-check',
4472						hook: this.createHook('password-check'),
4473						autocomplete: 'new-password'
4474					},
4475					label: {
4476						text: __('generic.password-confirm')
4477					},
4478					rules: [
4479						{
4480							name: 'empty',
4481							message: __('validation.empty')
4482						},
4483						{
4484							name: 'same',
4485							controller: this,
4486							parent_hook: 'form',
4487							counterpart_hook: 'password',
4488							message: __('validation.passwords-no-match')
4489						}
4490					],
4491					addon: BaseController.new('atoms-addon~show')
4492				})
4493			},
4494			{
4495				mod: ['default'],
4496				component: BaseController.new('molecules-button', {
4497					mod: ['block', 'primary'],
4498					button: {
4499						text: __('set-password.submit'),
4500						hook: this.createHook('create-account'),
4501						name: 'create-account'
4502					}
4503				})
4504			}
4505		]
4506	});
4507};
4508
4509module.exports = TemplatesCard_JoinPassword;
4510
4511},{"../../atoms/addon/addon":49,"./card.js":99,"BaseController":"BaseController","BaseModel":"BaseModel"}],110:[function(require,module,exports){
4512"use strict";
4513var punycode = require('punycode');
4514var delayed = require('delayed');
4515var BaseModel = require('BaseModel');
4516var BaseController = require('BaseController');
4517var TemplatesCard = require('./card.js');
4518var Validator = BaseModel.instance('Validator');
4519var TemplatesCard_JoinUsername = BaseController.create('TemplatesCard_JoinUsername', TemplatesCard);
4520
4521TemplatesCard_JoinUsername.prototype.onCreate = function () {
4522	TemplatesCard.prototype.onCreate.call(this);
4523
4524	this.ico = BaseController.new('atoms-icons', {
4525		icon: 'success',
4526		class_name: ['success']
4527	});
4528};
4529
4530TemplatesCard_JoinUsername.prototype.addListeners = function () {
4531	TemplatesCard.prototype.addListeners.call(this);
4532	this.addHookListener('username', 'change keyup', function() {
4533		delayed(this.validateUsername.bind(this, this.hook('username').value), this, 200, 'username_available');
4534	});
4535	this.addHookListener('save-credentials', 'click', this.submitForm);
4536};
4537
4538TemplatesCard_JoinUsername.prototype.validateUsername = function (value, callback) {
4539	var Login = BaseModel.instance('Login');
4540
4541	this.ico.data.icon = 'hint';
4542	this.ico.data.class_name = ['hint'];
4543	this.ico.rerender();
4544
4545	Login.usernameAvailable({
4546		username: value,
4547		domain: window.sessionData.domain,
4548		session: window.sessionData.id
4549	}, {
4550		success: function() {
4551			this.ico.data.icon = 'success';
4552			this.ico.data.class_name = ['success'];
4553			this.ico.rerender();
4554
4555			callback && callback(true);
4556		},
4557		error: function () {
4558			this.ico.data.icon = 'xmark';
4559			this.ico.data.class_name = ['error'];
4560			this.ico.rerender();
4561
4562			callback && callback(false);
4563		},
4564		context: this
4565	});
4566};
4567
4568TemplatesCard_JoinUsername.prototype.validateForm = function () {
4569	var Login = BaseModel.instance('Login');
4570	this.validate(function (isValid) {
4571		if (isValid) {
4572			Login.setData('chosen_account', Object.assign(Login.getData('chosen_account'), {
4573				email: this.hook('username').value + '@' + punycode.toUnicode(window.sessionData.domain),
4574			}));
4575			Login.setData('create_account', Object.assign(Login.getData('create_account'), {
4576				username: this.hook('username').value,
4577			}));
4578			this.changeCard({ card: 'join-password' });
4579		}
4580	}.bind(this));
4581};
4582
4583TemplatesCard_JoinUsername.prototype.helper = function () {
4584	var Login = BaseModel.instance('Login');
4585	var domain = punycode.toUnicode(window.sessionData.domain);
4586
4587	this.data.back = true;
4588
4589	return TemplatesCard.prototype.helper.call(this, {
4590		hook: this.createHook('form'),
4591		content: [
4592			{
4593				mod: [],
4594				component: BaseController.new('organisms-card-header', {
4595					avatar: false,
4596					heading: __('join.heading', { domain: domain }),
4597					subtitle: false,
4598					subsubtitle: {
4599						text: __('create-account.suggestion'),
4600						class_name: ['o-header__subsubtitle'],
4601						mod: ['small']
4602					},
4603					well: this.data.well
4604				})
4605			},
4606			{
4607				mod: ['form'],
4608				component: BaseController.new('molecules-input~validatable', {
4609					mod: ['wide'],
4610					input: {
4611						type: 'text',
4612						hook: this.createHook('username'),
4613						name: 'username',
4614						value: Login.getData('create_account').username
4615					},
4616					label: {
4617						text: __('create-account.email-address')
4618					},
4619					rules: [
4620						{
4621							name: 'empty',
4622							message: __('validation.empty')
4623						},
4624						{
4625							name: 'callback',
4626							callback: function(value, callback) {
4627								Validator.email(false, value + '@' + domain, callback);
4628							},
4629							message: __('validation.email')
4630						},
4631						{
4632							name: 'callback',
4633							callback: this.validateUsername.bind(this),
4634							message: __('validation.username-taken')
4635						}
4636					],
4637					addon: [
4638						{
4639							mod: 'ico',
4640							icon: this.ico
4641						},
4642						{
4643							mod: 'static',
4644							text: '@' + domain
4645						}
4646					]
4647				})
4648			},
4649			{
4650				mod: ['default', 'space-top'],
4651				component: BaseController.new('molecules-button', {
4652					mod: ['block', 'primary'],
4653					button: {
4654						hook: this.createHook('save-credentials'),
4655						text: __('generic.next')
4656					}
4657				})
4658			}
4659		]
4660	});
4661};
4662
4663module.exports = TemplatesCard_JoinUsername;
4664
4665},{"./card.js":99,"BaseController":"BaseController","BaseModel":"BaseModel","delayed":"delayed","punycode":355}],111:[function(require,module,exports){
4666"use strict";
4667var punycode = require('punycode');
4668var BaseModel = require('BaseModel');
4669var BaseController = require('BaseController');
4670var removeAccents = require('@icewarp/utils').string.removeAccents;
4671var TemplatesCard = require('./card.js');
4672var TemplatesCard_Join = BaseController.create('TemplatesCard_Join', TemplatesCard);
4673
4674TemplatesCard_Join.prototype.addListeners = function () {
4675	TemplatesCard.prototype.addListeners.call(this);
4676	this.addHookListener('save-credentials', 'click', this.submitForm);
4677	this.addHookListener('full-name', 'keyup', this.fullnameHandler);
4678};
4679
4680TemplatesCard_Join.prototype.validateForm = function () {
4681	this.validate(function (isValid) {
4682		if (isValid) {
4683			this.validateUsername();
4684		}
4685	}.bind(this));
4686};
4687
4688TemplatesCard_Join.prototype.validateUsername = function (index) {
4689	var Login = BaseModel.instance('Login');
4690	var fullname = this.hook('first-name').value + ' ' + this.hook('last-name').value;
4691	var username = removeAccents(fullname.toLowerCase().split(' ').join('.') + (index ? index : ''));
4692	Login.usernameAvailable({
4693		username: username,
4694		domain: window.sessionData.domain,
4695		session: window.sessionData.id
4696	}, {
4697		success: function() {
4698			Login.setData('chosen_account', {
4699				name: fullname,
4700				email: username + '@' + punycode.toUnicode(window.sessionData.domain),
4701				avatar_token: false
4702			});
4703			Login.setData('create_account', {
4704				username: username,
4705				domain: window.sessionData.domain,
4706				fullname: fullname,
4707				card: {}
4708			});
4709
4710			this.changeCard({ card: 'join-username' });
4711		},
4712		error: function (error) {
4713			switch(error) {
4714				case 'signup_invalid_invite_domain':
4715				case 'signup_invalid_invite_session':
4716					return this.showMessage({
4717						title: __('generic.error'),
4718						text: __('error.' + error),
4719						type: 'error'
4720					});
4721			}
4722			if (index > 9) {
4723				return this.validateUsername(Math.floor(Math.random() * 999999));
4724			}
4725			this.validateUsername((index || 0) + 1);
4726		},
4727		context: this
4728	});
4729};
4730
4731TemplatesCard_Join.prototype.helper = function () {
4732	var Login = BaseModel.instance('Login');
4733
4734	var fullname = (Login.getData('create_account').fullname || '').split(' ');
4735	var firstname = fullname[0] || '';
4736	var lastname = fullname[1] || '';
4737
4738	return TemplatesCard.prototype.helper.call(this, {
4739		hook: this.createHook('form'),
4740		content: [
4741			{
4742				mod: [],
4743				component: BaseController.new('organisms-card-header', {
4744					heading: __('join.heading', { domain: window.sessionData.domain }),
4745					avatar: false,
4746					subtitle: false,
4747					subsubtitle: false,
4748					well: this.data.well
4749				})
4750			},
4751			{
4752				mod: ['form'],
4753				component: BaseController.new('molecules-input~validatable', {
4754					input: {
4755						type: 'text',
4756						hook: this.createHook('first-name'),
4757						name: 'first-name',
4758						value: firstname,
4759						autocomplete: 'given-name'
4760					},
4761					label: {
4762						text: firstname ? __('create-account.first-name') : __('create-account.enter-first-name')
4763					},
4764					rules: [
4765						{
4766							name: 'empty',
4767							message: __('validation.empty')
4768						}
4769					]
4770				})
4771			},
4772			{
4773				mod: ['form'],
4774				component: BaseController.new('molecules-input~validatable', {
4775					input: {
4776						type: 'text',
4777						hook: this.createHook('last-name'),
4778						name: 'last-name',
4779						value: lastname,
4780						autocomplete: 'family-name'
4781					},
4782					label: {
4783						text: lastname ? __('create-account.last-name') : __('create-account.enter-last-name')
4784					},
4785					rules: [
4786						{
4787							name: 'empty',
4788							message: __('validation.empty')
4789						}
4790					]
4791				})
4792			},
4793			{
4794				mod: ['default', 'space-top'],
4795				component: BaseController.new('molecules-button', {
4796					mod: ['block', 'primary'],
4797					button: {
4798						hook: this.createHook('save-credentials'),
4799						text: __('generic.next')
4800					}
4801				})
4802			}
4803		]
4804	});
4805};
4806
4807module.exports = TemplatesCard_Join;
4808
4809},{"./card.js":99,"@icewarp/utils":180,"BaseController":"BaseController","BaseModel":"BaseModel","punycode":355}],112:[function(require,module,exports){
4810"use strict";
4811var Hash = require('@icewarp/hash');
4812var BaseModel = require('BaseModel');
4813var BaseController = require('BaseController');
4814var TemplatesCard = require('./card.js');
4815var TemplatesCard_Unavailable = require('./card~unavailable');
4816var TemplatesCard_OauthGrant = BaseController.create(
4817	'TemplatesCard_OauthGrant',
4818	TemplatesCard
4819);
4820
4821TemplatesCard_OauthGrant.prototype.addListeners = function () {
4822	TemplatesCard.prototype.addListeners.call(this);
4823	this.addHookListener('accept', 'click', this.accept);
4824	this.addHookListener('decline', 'click', this.decline);
4825};
4826
4827TemplatesCard_OauthGrant.prototype.accept = function () {
4828	var OAuth = BaseModel.instance('OAuth');
4829	OAuth.GrantOauthAuthorization(
4830		this.hook('description') ? this.hook('description').value : '',
4831		{
4832			success: function () {
4833				window.location.replace(OAuth.getRedirectURL());
4834			}.bind(this),
4835			error: function (error) {
4836				this.genericError(error);
4837			}.bind(this)
4838		}
4839	);
4840};
4841TemplatesCard_OauthGrant.prototype.decline = function () {
4842	window.location.replace(
4843		'/oauth/v2/code?auth_id=' + Hash.getParts().auth_id
4844	);
4845};
4846
4847TemplatesCard_OauthGrant.prototype.helperDataBuilder = function () {
4848	var OAuth = BaseModel.instance('OAuth');
4849	var account_data = OAuth.getData('account_data');
4850	var image = account_data.A_Image;
4851
4852	var client = {
4853		client: OAuth.getData('name')
4854	};
4855
4856	return TemplatesCard.prototype.helper.call(this, {
4857		hook: this.createHook('form'),
4858		content: [
4859			{
4860				mod: [],
4861				component: BaseController.new('organisms-card-header', {
4862					heading: __('sign-in-generic.heading.oauth', client),
4863					well: {
4864						title: __('oauth.grant_title', client),
4865						text:
4866							OAuth.getData('scopes').map(function (scope) {
4867								return '- ' + __('oauth.' + scope) + '\n';
4868							}) + __('oauth.info', client),
4869						class_name: ['is-visible']
4870					},
4871					avatar: {
4872						image: image && image.url,
4873						letter: !image && account_data.A_Name[0][0]
4874					}
4875				})
4876			},
4877			{
4878				mod: ['form'],
4879				component: BaseController.new('molecules-input', {
4880					input: {
4881						type: 'text',
4882						name: 'description',
4883						hook: this.createHook('description')
4884					},
4885					label: {
4886						text: __('oauth.description')
4887					}
4888				})
4889			},
4890			{
4891				mod: ['default', 'space-top'],
4892				component: [
4893					BaseController.new('molecules-button', {
4894						mod: ['block', 'primary', 'flex'],
4895						button: {
4896							hook: this.createHook('accept'),
4897							text: __('generic.authorize'),
4898							name: 'next'
4899						}
4900					}),
4901					BaseController.new('molecules-button', {
4902						mod: ['block', 'flex', 'error'],
4903						button: {
4904							hook: this.createHook('decline'),
4905							text: __('generic.decline'),
4906							name: 'next'
4907						}
4908					})
4909				]
4910			}
4911		]
4912	});
4913};
4914
4915TemplatesCard_OauthGrant.prototype.checkAlreadyExistingGrant = function (
4916	callback
4917) {
4918	var OAuth = BaseModel.instance('OAuth');
4919	OAuth.checkExistingGrant({
4920		success: function () {
4921			this.accept();
4922		}.bind(this),
4923		error: function () {
4924			callback.success.call(callback.context || this);
4925		}.bind(this)
4926	});
4927};
4928
4929TemplatesCard_OauthGrant.prototype.helper = function () {
4930	var OAuth = BaseModel.instance('OAuth');
4931	var account_data = OAuth.getData('account_data');
4932	var controller_this = this;
4933	if (!account_data) {
4934		return new Promise(function (resolve) {
4935			OAuth.initAlreadyLoggedIn({
4936				success: function () {
4937					controller_this.checkAlreadyExistingGrant({
4938						success: function () {
4939							resolve(controller_this.helperDataBuilder());
4940						}
4941					});
4942				},
4943				error: function (error) {
4944					controller_this.data.title = error;
4945					resolve(
4946						TemplatesCard_Unavailable.prototype.helper.call(
4947							controller_this
4948						)
4949					);
4950				},
4951				context: this
4952			});
4953		});
4954	}
4955	return new Promise(function (resolve) {
4956		controller_this.checkAlreadyExistingGrant({
4957			success: function () {
4958				resolve(controller_this.helperDataBuilder());
4959			}
4960		});
4961	});
4962	// return this.helperDataBuilder();
4963};
4964
4965module.exports = TemplatesCard_OauthGrant;
4966
4967},{"./card.js":99,"./card~unavailable":126,"@icewarp/hash":160,"BaseController":"BaseController","BaseModel":"BaseModel"}],113:[function(require,module,exports){
4968"use strict";
4969var BaseModel = require('BaseModel');
4970var BaseController = require('BaseController');
4971var TemplatesCard = require('./card.js');
4972var TemplatesCard_Personal = BaseController.create('TemplatesCard_Personal', TemplatesCard);
4973
4974TemplatesCard_Personal.prototype.addListeners = function () {
4975	TemplatesCard.prototype.addListeners.call(this);
4976	this.addHookListener('save-personal', 'click', this.submitForm);
4977};
4978
4979TemplatesCard_Personal.prototype.validateForm = function () {
4980	this.validate(function (isValid) {
4981		var Login = BaseModel.instance('Login');
4982		var WebClient = BaseModel.instance('WebClient');
4983		var CLF = WebClient.getData('custom_login_fields');
4984		var sms_verification = CLF.getValue('login_verification_type') === 'sms';
4985		var create_account = Login.getData('create_account');
4986		var selector;
4987
4988		if (isValid) {
4989			CLF.enabledCustomFields().map(function (field) {
4990				create_account.card[this.hook(field.name).getAttribute('name')] = this.hook(field.name).value;
4991			}, this);
4992
4993			create_account.card.classname = 'taccountcard';
4994			Login.setData('create_account', create_account);
4995
4996			if (!WebClient.getData('custom_login_fields').getValue('login_verification_enabled')) {
4997				return this.changeCard({ card: 'set-password' });
4998			}
4999
5000			selector = sms_verification ? create_account.card.mobiletelephonenumber : create_account.alternativeemail;
5001			Login.getVerification({
5002				verificationtype: +sms_verification,
5003				verificationselector: selector,
5004				captcharequest: {
5005					uid: this.getChildren('molecules-captcha')[0].uid,
5006					value: this.hook('captcha').value.toUpperCase()
5007				}
5008			}, {
5009				success: function () {
5010					this.changeCard({
5011						card: 'set-password',
5012						data: {
5013							well: {
5014								title: __('generic.success'),
5015								text: __('set-password.code_sent_to', { to: selector }),
5016								type: 'success',
5017								class_name: ['is-visible']
5018							}
5019						}
5020					});
5021				},
5022				error: function (error) {
5023					this.genericError(error);
5024				},
5025				context: this
5026			});
5027		}
5028	}.bind(this));
5029};
5030
5031TemplatesCard_Personal.prototype.customFieldsHelper = function () {
5032	var Login = BaseModel.instance('Login');
5033	var WebClient = BaseModel.instance('WebClient');
5034
5035	var autocomplete = {
5036		birthday: 'bday',
5037		company: 'organization',
5038		job: 'organization-title',
5039		mobile_phone: 'tel'
5040	};
5041
5042	return WebClient.getData('custom_login_fields').enabledCustomFields().map(function (custom_field) {
5043		switch (custom_field.type) {
5044			case 'select':
5045				return {
5046					mod: ['form'],
5047					component: BaseController.new('molecules-select~validatable', {
5048						select: {
5049							hook: this.createHook(custom_field.name),
5050							name: custom_field.name,
5051							options: custom_field.options.map(function (option) {
5052								option.selected = Login.getData('create_account').card[custom_field.name] == option.value;
5053								return option;
5054							})
5055						},
5056						label: {
5057							text: custom_field.label
5058						},
5059						rules: WebClient.getData('custom_login_fields').getValue(custom_field.id + '_required') ? [
5060							{
5061								name: 'empty',
5062								message: __('validation.empty')
5063							}
5064						] : false
5065					})
5066				};
5067			default:
5068				return {
5069					mod: ['form'],
5070					component: BaseController.new('molecules-input~validatable', {
5071						input: {
5072							type: custom_field.type || 'text',
5073							hook: this.createHook(custom_field.name),
5074							name: custom_field.name,
5075							value: Login.getData('create_account').card[custom_field.name],
5076							maxDate: custom_field.maxDate,
5077							autocomplete: autocomplete[custom_field.name] || custom_field.name
5078						},
5079						label: {
5080							text: custom_field.label
5081						},
5082						rules: (WebClient.getData('custom_login_fields').getValue(custom_field.id + '_required') || (custom_field.id === 'mobile_phone' && WebClient.getData('custom_login_fields').getValue('login_verification_enabled') && (WebClient.getData('custom_login_fields').getValue('login_verification_type') === 'sms'))) ? [
5083							{
5084								name: 'empty',
5085								message: __('validation.empty')
5086							}
5087						] : false
5088					})
5089				};
5090		}
5091	}, this);
5092};
5093
5094TemplatesCard_Personal.prototype.helper = function () {
5095	var WebClient = BaseModel.instance('WebClient');
5096
5097	this.data.back = true;
5098
5099	return TemplatesCard.prototype.helper.call(this, {
5100		hook: this.createHook('form'),
5101		content: [
5102			{
5103				mod: [],
5104				component: BaseController.new('organisms-card-header', {
5105					heading: __('personal.heading'),
5106					avatar: false,
5107					subtitle: false,
5108					well: this.data.well
5109				})
5110			}
5111		].concat(
5112			this.customFieldsHelper(),
5113			WebClient.getData('custom_login_fields').getValue('login_verification_enabled') && {
5114				mod: ['form'],
5115				component: BaseController.new('molecules-captcha')
5116			},
5117			WebClient.getData('custom_login_fields').getValue('login_verification_enabled') && {
5118				mod: ['form'],
5119				component: BaseController.new('molecules-input~validatable', {
5120					input: {
5121						hook: this.createHook('captcha'),
5122						type: 'text',
5123						name: 'security-code',
5124						maxlength: 6,
5125						minlength: 6
5126					},
5127					label: {
5128						text: __('generic.security-code')
5129					},
5130					rules: [
5131						{
5132							name: 'empty',
5133							message: __('validation.empty')
5134						},
5135						{
5136							name: 'length',
5137							data: 6,
5138							message: __('validation.length', 6)
5139						}
5140					]
5141				})
5142			},
5143			{
5144				mod: ['default', 'space-top'],
5145				component: BaseController.new('molecules-button', {
5146					mod: ['block', 'primary'],
5147					button: {
5148						hook: this.createHook('save-personal'),
5149						text: __('create-account.last-step'),
5150						name: 'next'
5151					}
5152				})
5153			},
5154			{
5155				mod: ['footer'],
5156				component: [
5157					BaseController.new('atoms-info~have-account'),
5158					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
5159				].filter(Boolean)
5160			}
5161		).filter(Boolean)
5162	});
5163};
5164
5165module.exports = TemplatesCard_Personal;
5166
5167},{"./card.js":99,"BaseController":"BaseController","BaseModel":"BaseModel"}],114:[function(require,module,exports){
5168"use strict";
5169var BaseModel = require('BaseModel');
5170var BaseController = require('BaseController');
5171var TemplatesCard = require('./card.js');
5172var TemplatesCard_ResetPassword = BaseController.create('TemplatesCard_ResetPassword', TemplatesCard);
5173var Hash = require('@icewarp/hash');
5174
5175TemplatesCard_ResetPassword.prototype.addListeners = function () {
5176	TemplatesCard.prototype.addListeners.call(this);
5177	this.addHookListener('confirm', 'click', this.submitForm);
5178};
5179
5180TemplatesCard_ResetPassword.prototype.validateForm = function () {
5181	this.validate(function (isValid) {
5182		if (isValid) {
5183			BaseModel.instance('Login').getAuthChallenge({
5184				success: this.resetPassword,
5185				error: function (error) {
5186					this.genericError(error);
5187				},
5188				context: this
5189			});
5190		}
5191	}.bind(this));
5192};
5193
5194TemplatesCard_ResetPassword.prototype.resetPassword = function (encrypt) {
5195	BaseModel.instance('WebClient').resetPassword({
5196		newpassword: encrypt(this.hook('password').value),
5197		resethash: this.data.sms && this.hook('resethash').value,
5198		user: this.data.user
5199	}, {
5200		success: function () {
5201			this.changeCard({
5202				card: 'generic-message',
5203				data: {
5204					type: 'success',
5205					well: {
5206						text: __('reset-password.success-message')
5207					},
5208					link: ''
5209				},
5210				change_hash: false
5211			});
5212		},
5213		error: function (error) {
5214			this.genericError(error);
5215		},
5216		context: this
5217	});
5218};
5219
5220TemplatesCard_ResetPassword.prototype.helper = function () {
5221	var Login = BaseModel.instance('Login');
5222	Login.setData('chosen_account', Login.getUser(this.data.user || Hash.getParts().user) || {});
5223
5224	return TemplatesCard.prototype.helper.call(this, {
5225		hook: this.createHook('form'),
5226		content: [
5227			{
5228				mod: [],
5229				component: BaseController.new('organisms-card-header', {
5230					heading: __('reset-password.heading'),
5231					well: this.data.well
5232				})
5233			},
5234			{
5235				class_name: ['u-hide'],
5236				component: BaseController.new('molecules-input', {
5237					input: {
5238						type: 'text',
5239						name: 'username',
5240						hook: this.createHook('username'),
5241						value: (this.data.user || Hash.getParts().user || '').replace(/@.*/, '')
5242					}
5243				})
5244			},
5245			{
5246				mod: ['form'],
5247				component: BaseController.new('molecules-input~password-with-policy', {
5248					input: {
5249						name: 'password',
5250						hook: this.createHook('password')
5251					},
5252					label: {
5253						text: __('generic.password-new')
5254					},
5255					addon: BaseController.new('atoms-addon~show')
5256				})
5257			},
5258			{
5259				mod: ['form'],
5260				component: BaseController.new('molecules-input~password', {
5261					input: {
5262						name: 'confirm-password'
5263					},
5264					label: {
5265						text: __('generic.password-confirm')
5266					},
5267					addon: BaseController.new('atoms-addon~show'),
5268					rules: [
5269						{
5270							name: 'empty',
5271							message: __('validation.empty')
5272						},
5273						{
5274							name: 'same',
5275							controller: this,
5276							parent_hook: 'form',
5277							counterpart_hook: 'password',
5278							message: __('validation.passwords-no-match')
5279						}
5280					]
5281				})
5282			},
5283			this.data.sms && {
5284				mod: ['form'],
5285				component: BaseController.new('molecules-input', {
5286					input: {
5287						name: 'resethash',
5288						hook: this.createHook('resethash')
5289					},
5290					label: {
5291						text: __('reset-password.resethash')
5292					},
5293					rules: [{
5294						name: 'empty',
5295						message: __('validation.empty')
5296					}]
5297				})
5298			},
5299			{
5300				mod: ['default', 'space-top'],
5301				component: BaseController.new('molecules-button', {
5302					mod: ['block', 'primary'],
5303					button: {
5304						text: __('generic.save-password'),
5305						hook: this.createHook('confirm'),
5306						name: 'confirm'
5307					}
5308				})
5309			},
5310			{
5311				mod: ['footer'],
5312				component: [
5313					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
5314				].filter(Boolean)
5315			}
5316		].filter(Boolean)
5317	});
5318};
5319
5320module.exports = TemplatesCard_ResetPassword;
5321
5322},{"./card.js":99,"@icewarp/hash":160,"BaseController":"BaseController","BaseModel":"BaseModel"}],115:[function(require,module,exports){
5323"use strict";
5324var BaseModel = require('BaseModel');
5325var BaseController = require('BaseController');
5326var TemplatesCard = require('./card.js');
5327var AtomsAddon = require('../../atoms/addon/addon');
5328var TemplatesCard_SetPassword = BaseController.create('TemplatesCard_SetPassword', TemplatesCard);
5329
5330TemplatesCard_SetPassword.prototype.onCreate = function () {
5331	TemplatesCard.prototype.onCreate.call(this);
5332
5333	this.password = BaseController.new('molecules-input~password-with-policy', {
5334		hook: this.createHook('password1'),
5335		input: {
5336			name: 'password',
5337			hook: this.createHook('password'),
5338			autocomplete: 'new-password'
5339		},
5340		label: {
5341			text: __('generic.password-new')
5342		},
5343		addon: BaseController.new('atoms-addon~show'),
5344		tooltip_well_pinned: true
5345	});
5346};
5347TemplatesCard_SetPassword.prototype.addListeners = function () {
5348	TemplatesCard.prototype.addListeners.call(this);
5349	this.addHookListener('create-account', 'click', this.submitForm);
5350	this.addHookListener('password', 'change', this.crossValidatePasswordCheck);
5351	this.addHookListener('password-check', 'change', this.crossValidatePassword);
5352};
5353
5354TemplatesCard_SetPassword.prototype.afterRender = function () {
5355	var addons;
5356	TemplatesCard.prototype.afterRender.call(this);
5357
5358	this.trigger('error-message-show', this.password.data.tooltip_well);
5359	addons = this.password.getChildrenByClass(AtomsAddon);
5360	addons[1] && addons[1].DOMElement.setAttribute('hidden', '');
5361};
5362
5363TemplatesCard_SetPassword.prototype.validateForm = function () {
5364	this.validate(function (isValid) {
5365		var WebClient = BaseModel.instance('WebClient');
5366		var Login = BaseModel.instance('Login');
5367
5368		if (isValid) {
5369			Login.getData('create_account').password = this.hook('password').value;
5370
5371			if (WebClient.getData('custom_login_fields').getValue('login_verification_enabled')) {
5372				Login.getData('create_account').verificationrequest.code = this.hook('verification_code').value;
5373			} else {
5374				Login.getData('create_account').captcharequest = {
5375					uid: this.getChildren('molecules-captcha')[0].uid,
5376					value: this.hook('captcha').value.toUpperCase()
5377				};
5378			}
5379
5380			Login.getAuthChallenge({
5381				success: this.signupAccount,
5382				error: function (error) {
5383					this.genericError(error);
5384				},
5385				context: this
5386			});
5387		}
5388	}.bind(this));
5389};
5390
5391TemplatesCard_SetPassword.prototype.signupAccount = function (encrypt) {
5392	BaseModel.instance('WebClient').signupAccount(encrypt, {
5393		success: function () {
5394			this.changeCard({
5395				data: {
5396					well: {
5397						title: __('generic.success'),
5398						text: __('set-password.success-message'),
5399						type: 'success',
5400						class_name: ['is-visible']
5401					}
5402				}
5403			});
5404		},
5405		error: function (error) {
5406			this.genericError(error);
5407		},
5408		context: this
5409	});
5410};
5411
5412TemplatesCard_SetPassword.prototype.crossValidatePasswordCheck = function () {
5413	this.hook('password-check').value.trim().length && this.getInstanceByElement(this.hook('password2')).validate();
5414};
5415TemplatesCard_SetPassword.prototype.crossValidatePassword = function () {
5416	this.hook('password').value.trim().length && this.getInstanceByElement(this.hook('password1')).validate();
5417};
5418
5419TemplatesCard_SetPassword.prototype.helper = function () {
5420	var Login = BaseModel.instance('Login');
5421	var WebClient = BaseModel.instance('WebClient');
5422
5423	this.data.back = true;
5424
5425	return TemplatesCard.prototype.helper.call(this, {
5426		hook: this.createHook('form'),
5427		content: [
5428			{
5429				mod: [],
5430				component: BaseController.new('organisms-card-header', {
5431					heading: __('set-password.heading'),
5432					well: this.data.well
5433				})
5434			},
5435			{
5436				class_name: ['u-hide'],
5437				component: BaseController.new('molecules-input', {
5438					input: {
5439						type: 'text',
5440						name: 'username',
5441						hook: this.createHook('username'),
5442						value: Login.getData('chosen_account').email,
5443						autocomplete: 'username'
5444					}
5445				})
5446			},
5447			{
5448				mod: ['form'],
5449				component: this.password
5450			},
5451			{
5452				mod: ['form'],
5453				component: BaseController.new('molecules-input~password', {
5454					hook: this.createHook('password2'),
5455					input: {
5456						name: 'password-check',
5457						hook: this.createHook('password-check'),
5458						autocomplete: 'new-password'
5459					},
5460					label: {
5461						text: __('generic.password-confirm')
5462					},
5463					rules: [
5464						{
5465							name: 'empty',
5466							message: __('validation.empty')
5467						},
5468						{
5469							name: 'same',
5470							controller: this,
5471							parent_hook: 'form',
5472							counterpart_hook: 'password',
5473							message: __('validation.passwords-no-match')
5474						}
5475					],
5476					addon: BaseController.new('atoms-addon~show')
5477				})
5478			},
5479			WebClient.getData('custom_login_fields').getValue('login_verification_enabled') ? {
5480				mod: ['form'],
5481				component: BaseController.new('molecules-input~validatable', {
5482					input: {
5483						hook: this.createHook('verification_code'),
5484						type: 'text',
5485						name: 'verification_code',
5486						maxlength: 6,
5487						minlength: 6
5488					},
5489					label: {
5490						text: __('set-password.verification_code')
5491					},
5492					rules: [
5493						{
5494							name: 'empty',
5495							message: __('validation.empty')
5496						},
5497						{
5498							name: 'length',
5499							data: 6,
5500							message: __('validation.length', 6)
5501						}
5502					]
5503				})
5504			} : {
5505				mod: ['form'],
5506				component: BaseController.new('molecules-captcha')
5507			},
5508			WebClient.getData('custom_login_fields').getValue('login_verification_enabled') ? false : {
5509				mod: ['form'],
5510				component: BaseController.new('molecules-input~validatable', {
5511					input: {
5512						hook: this.createHook('captcha'),
5513						type: 'text',
5514						name: 'security-code',
5515						maxlength: 6,
5516						minlength: 6
5517					},
5518					label: {
5519						text: __('generic.security-code')
5520					},
5521					rules: [
5522						{
5523							name: 'empty',
5524							message: __('validation.empty')
5525						},
5526						{
5527							name: 'length',
5528							data: 6,
5529							message: __('validation.length', 6)
5530						}
5531					]
5532				})
5533			},
5534			{
5535				mod: ['default', 'space-top'],
5536				component: BaseController.new('molecules-button', {
5537					mod: ['block', 'primary'],
5538					button: {
5539						text: __('set-password.submit'),
5540						hook: this.createHook('create-account'),
5541						name: 'create-account'
5542					}
5543				})
5544			},
5545			{
5546				mod: ['footer'],
5547				component: [
5548					BaseController.new('atoms-info~have-account'),
5549					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
5550				].filter(Boolean)
5551			}
5552		].filter(Boolean)
5553	});
5554};
5555
5556module.exports = TemplatesCard_SetPassword;
5557
5558},{"../../atoms/addon/addon":49,"./card.js":99,"BaseController":"BaseController","BaseModel":"BaseModel"}],116:[function(require,module,exports){
5559"use strict";
5560var BaseModel = require('BaseModel');
5561var BaseController = require('BaseController');
5562var TemplatesCard = require('./card.js');
5563var TemplatesCard_SignInGuest = BaseController.create('TemplatesCard_SignInGuest', TemplatesCard);
5564var Hash = require('@icewarp/hash');
5565var domainRegEx = /^(((?!-))(xn--|_)?[a-z0-9-]{0,61}[a-z0-9]{1,1}\.)*(xn--)?([a-z0-9][a-z0-9-]{0,60}|[a-z0-9-]{1,30}\.[a-z]{2,})$/;
5566
5567TemplatesCard_SignInGuest.prototype.addListeners = function () {
5568	TemplatesCard.prototype.addListeners.call(this);
5569	this.addHookListener('validate-email', 'click', this.submitForm);
5570};
5571
5572TemplatesCard_SignInGuest.prototype.validateForm = function () {
5573	this.validate(function (isValid) {
5574		var Login = BaseModel.instance('Login');
5575		var email = this.hook('email').value.toLowerCase();
5576		var domain = email.indexOf('@') ? email.split('@').pop() : '..';
5577
5578		if (!isValid) {
5579			return;
5580		}
5581
5582		if (domain && !domainRegEx.test(domain)) {
5583			return setTimeout(function() {
5584				this.genericError('invalid_domain');
5585			}.bind(this), 5);
5586		}
5587
5588		Login.isGuestDomain(domain, {
5589			success: function(response) {
5590				if (response) {
5591					Login.setData('chosen_account', {
5592						email: email,
5593						guestLogin: true
5594					});
5595					BaseModel.instance('Login').guestLogin({
5596						email: email
5597					});
5598				} else {
5599					Login.setData('chosen_account', {
5600						email: email
5601					});
5602					this.changeCard({ card: 'sign-in-password', hashData: Hash.getParts(), data: { back: true }});
5603				}
5604			},
5605			context: this
5606		});
5607	}.bind(this));
5608};
5609
5610TemplatesCard_SignInGuest.prototype.helper = function () {
5611	var Login = BaseModel.instance('Login');
5612	var WebClient = BaseModel.instance('WebClient');
5613
5614	this.data.back = true;
5615	return TemplatesCard.prototype.helper.call(this, {
5616		hook: this.createHook('form'),
5617		content: [
5618			{
5619				mod: [],
5620				component: BaseController.new('organisms-card-header', {
5621					heading: __('sign-in.sign-in-as-guest'),
5622					subtitle: {
5623						text: __('sign-in.guest-helper', {
5624							title: WebClient.getData('layout_settings').getValue('title') || 'IceWarp'
5625						}),
5626						class_name: ['o-header__subsubtitle'],
5627						mod: ['normal']
5628					},
5629					subsubtitle: false,
5630					avatar: false,
5631					well: this.data.well
5632				})
5633			},
5634			{
5635				mod: ['form'],
5636				component: BaseController.new('molecules-input~validatable', {
5637					input: {
5638						type: 'email',
5639						name: 'email-address',
5640						hook: this.createHook('email'),
5641						value: ''
5642					},
5643					label: {
5644						text: __('generic.email')
5645					},
5646					rules: [{
5647						name: 'empty',
5648						message: __('validation.empty')
5649					}, {
5650						name: 'email',
5651						message: __('validation.email')
5652					}]
5653				})
5654			},
5655			{
5656				mod: ['default', 'space-bottom'],
5657				component: BaseController.new('molecules-button', {
5658					mod: ['block', 'primary'],
5659					button: {
5660						hook: this.createHook('validate-email'),
5661						text: __('generic.continue'),
5662						name: 'next'
5663					}
5664				})
5665			},
5666			{
5667				mod: ['footer'],
5668				component: [
5669					Login.getUsers().length ? BaseController.new('atoms-info~choose-account') : BaseController.new('atoms-info~have-account'),
5670					WebClient.getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
5671				].filter(Boolean)
5672			},
5673		].filter(Boolean)
5674	});
5675};
5676
5677module.exports = TemplatesCard_SignInGuest;
5678
5679},{"./card.js":99,"@icewarp/hash":160,"BaseController":"BaseController","BaseModel":"BaseModel"}],117:[function(require,module,exports){
5680"use strict";
5681var BaseModel = require('BaseModel');
5682var BaseController = require('BaseController');
5683var TemplatesCard = require('./card.js');
5684var TemplatesCard_SignInPassword = BaseController.create('TemplatesCard_SignInPassword', TemplatesCard);
5685var QueryParams = require('@icewarp/query-params');
5686var MobileDetect = require('mobile-detect');
5687var Hash = require('@icewarp/hash');
5688
5689TemplatesCard_SignInPassword.prototype.loginOauth = function (password) {
5690	var Login = BaseModel.instance('Login');
5691	var OAuth = BaseModel.instance('OAuth');
5692	OAuth.login(Login.getData('chosen_account').email, password, Login.getData('useRSA'), {
5693		success: function () {
5694			this.changeCard({
5695				card: 'oauth-grant',
5696				hashData: Hash.getParts()
5697			});
5698		},
5699		error: function (error) {
5700			this.genericError(error);
5701		},
5702		context: this
5703	});
5704};
5705
5706TemplatesCard_SignInPassword.prototype.loginApp = function (response) {
5707	var WebClient = BaseModel.instance('WebClient');
5708	var Login = BaseModel.instance('Login');
5709	var i, ctz;
5710	var params = QueryParams.parse();
5711	var hash_parts = Hash.getParts();
5712	var user_interface = this.getUserInterface();
5713
5714	this.submitted = true;
5715	for (i in hash_parts) {
5716		params[i] = hash_parts[i];
5717	}
5718	params.atoken = response.authtoken;
5719	params.language = WebClient.getData('layout_settings').getUserLanguageCode();
5720	params.remember = this.getPersistentLoginValue();
5721	ctz = (new Date()).getTimezoneOffset();
5722	params.ctz = ctz ? -ctz : 0;
5723	this.hook('username').value = Login.getData('chosen_account').email;
5724
5725	if (params.conference) {
5726		params.account = Login.getData('chosen_account');
5727		return window.parent.postMessage(params, '*');
5728	}
5729
5730	document.location.href = document.location.protocol + '//' + location.host + (location.pathname + (user_interface ? '/' + user_interface : '') + '/?' + QueryParams.stringify(params)).replace(/\/\//g, '/') + document.location.hash;
5731};
5732
5733TemplatesCard_SignInPassword.prototype.loginError = function (error, response) {
5734	var phone;
5735
5736	if (!isNaN(response.query.error)) {
5737		phone = +response.query.error;
5738	}
5739	if (error === 'auth_digest_expired') {
5740		return this.validateForm();
5741	} else if (error === 'auth_two_factor_required' || phone) {
5742		return this.changeCard({
5743			card: 'two-factor',
5744			hashData: Hash.getParts(),
5745			data: {
5746				password: this.hook('password').value,
5747				persistentLogin: this.getPersistentLoginValue(),
5748				user_interface: this.getUserInterface(),
5749				well: {
5750					title: __('two_step.heading'),
5751					text: __('two_step.subheading' + (phone ? '-phone' : ''), {
5752						phone: phone
5753					}),
5754					type: 'info',
5755					class_name: ['is-visible']
5756				}
5757			}
5758		});
5759	}
5760	this.hook('password') && this.hook('password').removeAttribute('readonly');
5761	this.genericError(error);
5762};
5763
5764TemplatesCard_SignInPassword.prototype.getPersistentLoginValue = function () {
5765	var WebClient = BaseModel.instance('WebClient');
5766	return (Hash.getParts().auth_id || WebClient.getData('restrictions').getValue('disable_remember')) ? 0 : +this.hook('persistentlogin').checked;
5767};
5768
5769TemplatesCard_SignInPassword.prototype.getUserInterface = function () {
5770	var user_interface = this.hook('user_interface') && this.hook('user_interface').value;
5771	return (user_interface || '').replace('desktop', '');
5772};
5773
5774TemplatesCard_SignInPassword.prototype.addListeners = function () {
5775	TemplatesCard.prototype.addListeners.call(this);
5776	this.addDelegatedHookListener('forgot-password', 'click', function() {
5777		var Login = BaseModel.instance('Login');
5778		if (!Login.getData('chosen_account').email || Login.getData('chosen_account').email.indexOf('@') === -1) {
5779			return this.genericError('forgot-missing-domain', '', ' ');
5780		}
5781		this.changeCard({
5782			card: 'forgot-password',
5783			data: { back: true }
5784		});
5785	}.bind(this));
5786	this.addHookListener('validate-password', 'click', this.submitForm);
5787};
5788
5789TemplatesCard_SignInPassword.prototype.validateForm = function () {
5790	this.hook('password') && this.hook('password').setAttribute('readonly', '');
5791	this.validate(function (isValid) {
5792		if (isValid) {
5793			BaseModel.instance('Login').getAuthChallenge({
5794				success: this.authenticate,
5795				error: function (error) {
5796					this.genericError(error);
5797				},
5798				context: this
5799			});
5800		} else {
5801			this.hook('password') && this.hook('password').removeAttribute('readonly');
5802		}
5803	}.bind(this));
5804};
5805
5806TemplatesCard_SignInPassword.prototype.authenticate = function (encrypt) {
5807	var password = encrypt(this.hook('password').value);
5808	var WebClient = BaseModel.instance('WebClient');
5809	var Login = BaseModel.instance('Login');
5810
5811	if (Hash.getParts().auth_id) {
5812		return this.loginOauth(password);
5813	}
5814
5815	WebClient.getAuthToken({
5816		email: Login.getData('chosen_account').email,
5817		password: password,
5818		persistentlogin: this.getPersistentLoginValue()
5819	}, {
5820		success: this.loginApp,
5821		error: this.loginError,
5822		context: this
5823	});
5824};
5825
5826TemplatesCard_SignInPassword.prototype.helper = function () {
5827	var config = BaseModel.instance('Config').getData('config');
5828	var WebClient = BaseModel.instance('WebClient');
5829	var Login = BaseModel.instance('Login');
5830
5831	var md = new MobileDetect(window.navigator.userAgent);
5832	var interfaces = WebClient.getData('layout_settings').getValue('interfaces') || '';
5833	var params = QueryParams.parse();
5834
5835	interfaces = [
5836		(!interfaces || ~interfaces.indexOf('a')) && {
5837			selected: md.tablet() && md.mobileGrade() === 'A',
5838			text: __('interface.desktop'),
5839			value: 'desktop'
5840		},
5841		(!interfaces || ~interfaces.indexOf('b')) && {
5842			selected: md.tablet() && md.mobileGrade() !== 'A',
5843			text: __('interface.tablet'),
5844			value: 'basic'
5845		},
5846		((params.interface === 'pda') && (!interfaces || ~interfaces.indexOf('p'))) && {
5847			selected: params.interface === 'pda',
5848			text: __('interface.phone'),
5849			value: 'pda'
5850		}
5851	].filter(Boolean);
5852
5853	return new Promise(function(resolve) {
5854		var remember = !(Hash.getParts().auth_id || WebClient.getData('restrictions').getValue('disable_remember'));
5855
5856		resolve(TemplatesCard.prototype.helper.call(this, {
5857			hook: this.createHook('form'),
5858			content: [
5859				{
5860					mod: [],
5861					component: BaseController.new('organisms-card-header', {
5862						heading: __('sign-in-generic.heading.' + (params.conference ? 'conference' : config.application)),
5863						well: this.data.well
5864					})
5865				},
5866				{
5867					class_name: ['u-hide'],
5868					component: BaseController.new('molecules-input', {
5869						input: {
5870							type: 'text',
5871							name: 'username',
5872							hook: this.createHook('username'),
5873							value: Login.getData('chosen_account').email,
5874							autocomplete: 'username'
5875						}
5876					})
5877				},
5878				{
5879					mod: ['form'],
5880					component: BaseController.new('molecules-input~password', {
5881						input: {
5882							name: 'password',
5883							hook: this.createHook('password'),
5884							maxlength: 240,
5885							autocomplete: 'current-password'
5886						},
5887						label: {
5888							text: __('generic.password')
5889						},
5890						rules: [{
5891							name: 'empty',
5892							message: __('validation.empty')
5893						},
5894						{
5895							name: 'min_length',
5896							data: 1,
5897							message: __('validation.min_length', 1)
5898						}
5899						],
5900						addon: [
5901							BaseController.new('atoms-addon~show'),
5902							WebClient.getData('reset_settings').getValue('enabled') && {
5903								text: __('sign-in-password.forgot'),
5904								hook: this.createHook('forgot-password'),
5905								mod: ['floating']
5906							}
5907						].filter(Boolean)
5908					})
5909				},
5910				(config.application === 'webclient' && (md.mobile() || params.mobile)) ? {
5911					mod: ['form'],
5912
5913					class_name: interfaces.length > 1 ? [] : ['u-hide'],
5914					component: BaseController.new('molecules-select', {
5915						select: {
5916							name: 'user_interface',
5917							hook: this.createHook('user_interface'),
5918							options: interfaces
5919						},
5920						label: {
5921							text: __('interface.label')
5922						}
5923					})
5924				} : false,
5925				remember && {
5926					mod: ['form'],
5927					component: BaseController.new('molecules-checkbox', {
5928						label: __('sign-in-password.remember'),
5929						input: {
5930							name: 'remember-me',
5931							hook: this.createHook('persistentlogin')
5932						}
5933					})
5934				},
5935				{
5936					mod: ['default', 'space-bottom'],
5937					component: BaseController.new('molecules-button', {
5938						mod: ['block', 'primary'],
5939						button: {
5940							hook: this.createHook('validate-password'),
5941							text: __('generic.sign-in'),
5942							name: 'next'
5943						}
5944					})
5945				},
5946				WebClient.getData('restrictions').getValue('show_search') && {
5947					mod: ['form'],
5948					component: BaseController.new('molecules-input~search', {
5949						input: {
5950							name: 'search'
5951						},
5952						label: {
5953							text: __('generic.search')
5954						}
5955					})
5956				},
5957				{
5958					mod: ['footer'],
5959					component: [
5960						BaseController.new('atoms-info~not-you'),
5961						BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
5962					].filter(Boolean)
5963				}
5964			].filter(Boolean)
5965
5966		}));
5967	}.bind(this));
5968
5969};
5970
5971module.exports = TemplatesCard_SignInPassword;
5972
5973},{"./card.js":99,"@icewarp/hash":160,"@icewarp/query-params":170,"BaseController":"BaseController","BaseModel":"BaseModel","mobile-detect":364}],118:[function(require,module,exports){
5974"use strict";
5975var BaseModel = require('BaseModel');
5976var BaseController = require('BaseController');
5977var TemplatesCard = require('./card.js');
5978var TemplatesCard_SignIn = BaseController.create('TemplatesCard_SignIn', TemplatesCard);
5979var Hash = require('@icewarp/hash');
5980var domainRegEx = /^(((?!-))(xn--|_)?[a-z0-9-]{0,61}[a-z0-9]{1,1}\.)*(xn--)?([a-z0-9][a-z0-9-]{0,60}|[a-z0-9-]{1,30}\.[a-z]{2,})$/;
5981
5982TemplatesCard_SignIn.prototype.addListeners = function () {
5983	TemplatesCard.prototype.addListeners.call(this);
5984	this.addHookListener('validate-email', 'click', this.submitForm);
5985	this.addHookListener('apple', 'click', this.signInAsGuest, { service_provider: 'apple' });
5986	this.addHookListener('google', 'click', this.signInAsGuest, { service_provider: 'google' });
5987	this.addHookListener('microsoft', 'click', this.signInAsGuest, { service_provider: 'microsoft' });
5988	this.addHookListener('mail', 'click', this.signInAsGuestWithEmail, {}, true);
5989};
5990
5991TemplatesCard_SignIn.prototype.validateForm = function () {
5992	this.validate(function (isValid) {
5993		var Login = BaseModel.instance('Login');
5994		var email = this.hook('email').value.toLowerCase();
5995		var domain = ~email.indexOf('@') ? email.split('@').pop() : false;
5996
5997		if (!isValid) {
5998			return;
5999		}
6000
6001		if (domain && !domainRegEx.test(domain)) {
6002			return setTimeout(function() {
6003				this.genericError('invalid_domain');
6004			}.bind(this), 5);
6005		}
6006
6007		Login.setData('chosen_account', {
6008			email: email
6009		});
6010		this.changeCard({ card: 'sign-in-password', hashData: Hash.getParts(), data: { back: true }}
6010);
6011	}.bind(this));
6012};
6013
6014TemplatesCard_SignIn.prototype.signInAsGuest = function(e, data) {
6015	BaseModel.instance('Login').guestLogin(data);
6016};
6017
6018TemplatesCard_SignIn.prototype.signInAsGuestWithEmail = function() {
6019	this.changeCard({ card: 'sign-in-guest', hashData: Hash.getParts(), data: { back: true }});
6020};
6021
6022TemplatesCard_SignIn.prototype.helper = function () {
6023	var config = BaseModel.instance('Config').getData('config');
6024	var WebClient = BaseModel.instance('WebClient');
6025	var Server = BaseModel.instance('Server');
6026	var Login = BaseModel.instance('Login');
6027	var guest_signin = config.application === 'webclient' && !WebClient.getData('restrictions').getValue('disable_guest_signin');
6028
6029	this.data.back = true;
6030
6031	return TemplatesCard.prototype.helper.call(this, {
6032		hook: this.createHook('form'),
6033		content: [
6034			{
6035				mod: [],
6036				component: BaseController.new('organisms-card-header', {
6037					heading: __('sign-in-generic.heading.' + config.application),
6038					subtitle: {
6039						text: __('sign-in.subtitle', {
6040							title: WebClient.getData('layout_settings').getValue('title') || 'IceWarp'
6041						}),
6042						class_name: ['o-header__subsubtitle'],
6043						mod: ['normal']
6044					},
6045					subsubtitle: false,
6046					avatar: false,
6047					well: this.data.well
6048				})
6049			},
6050			{
6051				mod: ['form'],
6052				component: BaseController.new('molecules-input~validatable', {
6053					input: {
6054						type: 'email',
6055						name: 'email-address',
6056						hook: this.createHook('email'),
6057						value: Login.getData('chosen_account').email || Hash.getParts().email || Hash.getParts().username
6058					},
6059					label: {
6060						text: (+Server.getData('c_accounts_policies_login_loginsettings') || Login.getData('guestLogin')) ? __('generic.email') : __('generic.username')
6061					},
6062					rules: [
6063						{
6064							name: 'empty',
6065							message: __('validation.empty')
6066						},
6067						+Server.getData('c_accounts_policies_login_loginsettings') ? {
6068							name: 'email',
6069							message: __('validation.email')
6070						} : false
6071					].filter(Boolean)
6072				})
6073			},
6074			{
6075				mod: ['default', 'space-bottom'],
6076				component: BaseController.new('molecules-button', {
6077					mod: ['block', 'primary'],
6078					button: {
6079						hook: this.createHook('validate-email'),
6080						text: __('generic.continue'),
6081						name: 'next'
6082					}
6083				})
6084			},
6085			WebClient.getData('restrictions').getValue('show_search') && {
6086				mod: ['form'],
6087				component: BaseController.new('molecules-input~search', {
6088					input: {
6089						name: 'search'
6090					},
6091					label: {
6092						text: __('generic.search')
6093					}
6094				})
6095			},
6096			{
6097				mod: ['footer', 'form'],
6098				component: [
6099					(!WebClient.getData('restrictions').getValue('disable_signup') && !WebClient.getData('restrictions').getValue('disable_signup_ip')) && BaseController.new('atoms-info~dont-have-account'),
6100					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
6101				].filter(Boolean)
6102			},
6103			guest_signin && {
6104				mod: ['separator', 'form'],
6105				component: BaseController.new('atoms-label', {
6106					text: __('sign-in.sign-in-as-guest'),
6107				})
6108			},
6109			guest_signin && {
6110				mod: ['form'],
6111				component: BaseController.new('atoms-label', {
6112					text: __('sign-in.guest-helper', {
6113						title: WebClient.getData('layout_settings').getValue('title') || 'IceWarp'
6114					}),
6115				})
6116			},
6117			guest_signin &&  {
6118				mod: ['default', 'sideBySide'],
6119				component: [
6120					BaseController.new('molecules-button', {
6121						mod: ['block', 'dark', 'icon', 'wide', 'service'],
6122						button:  {
6123							hook: this.createHook('apple'),
6124							name: 'apple',
6125							icon: 'apple'
6126						}
6127					}),
6128					BaseController.new('molecules-button', {
6129						mod: ['block', 'dark', 'icon', 'wide', 'service'],
6130						button:  {
6131							hook: this.createHook('google'),
6132							name: 'google',
6133							icon: 'google'
6134						}
6135					}),
6136					BaseController.new('molecules-button', {
6137						mod: ['block', 'dark', 'icon', 'wide', 'service'],
6138						button:  {
6139							hook: this.createHook('microsoft'),
6140							name: 'microsoft',
6141							icon: 'microsoft'
6142						}
6143					}),
6144					BaseController.new('molecules-button', {
6145						mod: ['block', 'dark', 'icon', 'wide', 'service'],
6146						button:  {
6147							hook: this.createHook('mail'),
6148							name: 'mail',
6149							icon: 'email'
6150						}
6151					})
6152				]
6153			}
6154		].filter(Boolean)
6155	});
6156};
6157
6158module.exports = TemplatesCard_SignIn;
6159
6160},{"./card.js":99,"@icewarp/hash":160,"BaseController":"BaseController","BaseModel":"BaseModel"}],119:[function(require,module,exports){
6161"use strict";
6162var BaseController = require('BaseController');
6163var TemplatesCard = require('./card.js');
6164var TemplatesCard_TcActions = BaseController.create('TemplatesCard_TcActions', TemplatesCard);
6165var Hash = require('@icewarp/hash');
6166
6167TemplatesCard_TcActions.prototype.addListeners = function () {
6168	var hash_data = Hash.getParts();
6169	TemplatesCard.prototype.addListeners.call(this);
6170	this.addHookListener('next', 'click', this.changeCard, {card: hash_data.return || 'tc-join', hashData: hash_data});
6171	this.addHookListener('skip', 'click', this.changeCard, {card: hash_data.return || 'tc-join', hashData: hash_data});
6172};
6173
6174TemplatesCard_TcActions.prototype.helper = function () {
6175	return TemplatesCard.prototype.helper.call(this, {
6176		content: [
6177			{
6178				mod: [],
6179				component: BaseController.new('organisms-card-header', {
6180					'card-icon': BaseController.new('atoms-icons', {
6181						icon: 'teamchat'
6182					}),
6183					heading: __('tc-actions.heading'),
6184					subtitle: {
6185						text: __('tc-actions.subheading')
6186					},
6187					well: this.data.well
6188				})
6189			},
6190			{
6191				mod: ['form', 'no-padding'],
6192				component: BaseController.new('AtomsImage', {
6193					class_name: ['u-margin-auto'],
6194					src: './images/teamchat/actions.png'
6195				})
6196			},
6197			{
6198				mod: ['default', 'space-top'],
6199				component: [
6200					BaseController.new('molecules-button', {
6201						mod: ['primary', 'inverted', 'flex'],
6202						button: {
6203							text: __('generic.skip'),
6204							name: 'skip',
6205							hook: this.createHook('skip')
6206						}
6207					}),
6208					BaseController.new('molecules-button', {
6209						mod: ['primary', 'flex'],
6210						button: {
6211							text: __('generic.next'),
6212							name: 'next',
6213							hook: this.createHook('next')
6214						}
6215					})
6216				]
6217			}
6218		].filter(Boolean)
6219	});
6220};
6221
6222module.exports = TemplatesCard_TcActions;
6223
6224},{"./card.js":99,"@icewarp/hash":160,"BaseController":"BaseController"}],120:[function(require,module,exports){
6225"use strict";
6226var BaseModel = require('BaseModel');
6227var BaseController = require('BaseController');
6228var TemplatesCard = require('./card.js');
6229var TemplatesCard_TcCheckEmail = BaseController.create('TemplatesCard_TcCheckEmail', TemplatesCard);
6230var Hash = require('@icewarp/hash');
6231
6232TemplatesCard_TcCheckEmail.prototype.addListeners = function () {
6233	TemplatesCard.prototype.addListeners.call(this);
6234	this.addHookListener('what-is-teamchat', 'click', this.changeCard, {card: 'tc-collaboration', hashData: Hash.getParts(), keepHashData: true});
6235};
6236
6237TemplatesCard_TcCheckEmail.prototype.helper = function () {
6238	return TemplatesCard.prototype.helper.call(this, {
6239		content: [
6240			{
6241				mod: [],
6242				component: BaseController.new('organisms-card-header', {
6243					'card-icon': BaseController.new('atoms-icons', {
6244						icon: 'teamchat'
6245					}),
6246					avatar: false,
6247					heading: __('tc-check-email.heading'),
6248					subtitle: {
6249						text: __('tc-check-email.subheading', {md: true, room: this.data.room || (Hash.getParts().room || '').replace(/\+/g, ' ')}),
6250						class_name: 'o-header__subtitle'
6251					},
6252					subsubtitle: false,
6253					well: this.data.well
6254				})
6255			},
6256			{
6257				mod: ['footer', 'space-top'],
6258				component: [
6259					BaseController.new('atoms-link~what-is-teamchat'),
6260					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
6261				].filter(Boolean)
6262			}
6263		].filter(Boolean)
6264	});
6265};
6266
6267module.exports = TemplatesCard_TcCheckEmail;
6268
6269},{"./card.js":99,"@icewarp/hash":160,"BaseController":"BaseController","BaseModel":"BaseModel"}],121:[function(require,module,exports){
6270"use strict";
6271var BaseController = require('BaseController');
6272var TemplatesCard = require('./card.js');
6273var TemplatesCard_TcCollaboration = BaseController.create('TemplatesCard_TcCollaboration', TemplatesCard);
6274var Hash = require('@icewarp/hash');
6275
6276TemplatesCard_TcCollaboration.prototype.addListeners = function () {
6277	var hash_data = Hash.getParts();
6278	TemplatesCard.prototype.addListeners.call(this);
6279	this.addHookListener('next', 'click', this.changeCard, {card: 'tc-share', hashData: hash_data});
6280	this.addHookListener('skip', 'click', this.changeCard, {card: hash_data.return || 'tc-join', hashData: hash_data});
6281};
6282
6283TemplatesCard_TcCollaboration.prototype.helper = function () {
6284	return TemplatesCard.prototype.helper.call(this, {
6285		content: [
6286			{
6287				mod: [],
6288				component: BaseController.new('organisms-card-header', {
6289					'card-icon': BaseController.new('atoms-icons', {
6290						icon: 'teamchat'
6291					}),
6292					heading: __('tc-collaboration.heading'),
6293					subtitle: {
6294						text: __('tc-collaboration.subheading')
6295					},
6296					well: this.data.well
6297				})
6298			},
6299			{
6300				mod: ['form', 'no-padding'],
6301				component: BaseController.new('AtomsImage', {
6302					class_name: ['u-margin-auto'],
6303					src: './images/teamchat/collaboration.png'
6304				})
6305			},
6306			{
6307				mod: ['default', 'space-top'],
6308				component: [
6309					BaseController.new('molecules-button', {
6310						mod: ['primary', 'inverted', 'flex'],
6311						button: {
6312							text: __('generic.skip'),
6313							name: 'skip',
6314							hook: this.createHook('skip')
6315						}
6316					}),
6317					BaseController.new('molecules-button', {
6318						mod: ['primary', 'flex'],
6319						button: {
6320							text: __('generic.next'),
6321							name: 'next',
6322							hook: this.createHook('next')
6323						}
6324					})
6325				]
6326			}
6327		].filter(Boolean)
6328	});
6329};
6330
6331module.exports = TemplatesCard_TcCollaboration;
6332
6333},{"./card.js":99,"@icewarp/hash":160,"BaseController":"BaseController"}],122:[function(require,module,exports){
6334"use strict";
6335var BaseModel = require('BaseModel');
6336var BaseController = require('BaseController');
6337var TemplatesCard = require('./card.js');
6338var TemplatesCard_TcJoin = BaseController.create('TemplatesCard_TcJoin', TemplatesCard);
6339var Hash = require('@icewarp/hash');
6340
6341TemplatesCard_TcJoin.prototype.addListeners = function () {
6342	TemplatesCard.prototype.addListeners.call(this);
6343	this.addHookListener('verify-email', 'click', this.validateForm);
6344	this.addHookListener('what-is-teamchat', 'click', this.changeCard, { card: 'tc-collaboration', hashData: Hash.getParts(), keepHashData: true });
6345};
6346
6347TemplatesCard_TcJoin.prototype.validateForm = function () {
6348	this.validate(function (isValid) {
6349		if (isValid) {
6350			BaseModel.instance('Login').getAuthChallenge({
6351				success: this.guestConfirm,
6352				error: function (error) {
6353					this.genericError(error);
6354				},
6355				context: this
6356			});
6357		}
6358
6359	}.bind(this));
6360};
6361
6362TemplatesCard_TcJoin.prototype.guestConfirm = function (encrypt) {
6363	var hash_parts = Hash.getParts();
6364	hash_parts.room = (hash_parts.room || '').replace(/\+/g, ' ');
6365	BaseModel.instance('WebClient').guestConfirm({
6366		password: encrypt(this.hook('password').value),
6367		fullname: this.hook('username').value,
6368		email: hash_parts.email,
6369		sender: hash_parts.sender,
6370		hash: hash_parts.hash
6371	}, {
6372		success: function () {
6373			this.changeCard({
6374				data: {
6375					well: {
6376						title: __('generic.success'),
6377						text: __('tc-join.success-message', { room: hash_parts.room }),
6378						type: 'success',
6379						class_name: ['is-visible']
6380					},
6381					room: hash_parts.room
6382				},
6383				card: 'tc-check-email',
6384				hashData: {
6385					room: hash_parts.room,
6386					return: 'tc-check-email'
6387				}
6388			});
6389		},
6390		error: function (error) {
6391			this.genericError(error);
6392		},
6393		context: this
6394	});
6395};
6396
6397TemplatesCard_TcJoin.prototype.helper = function () {
6398	var hash_parts = Hash.getParts();
6399	hash_parts.room = (hash_parts.room || '').replace(/\+/g, ' ');
6400	return TemplatesCard.prototype.helper.call(this, {
6401		hook: this.createHook('form'),
6402		content: [
6403			{
6404				mod: [],
6405				component: BaseController.new('organisms-card-header', {
6406					'card-icon': BaseController.new('atoms-icons', {
6407						icon: 'teamchat'
6408					}),
6409					avatar: false,
6410					heading: __('tc-join.heading'),
6411					subtitle: {
6412						text: __('tc-join.subheading', { name: (hash_parts.sendername || '').replace(/\+/g, ' ') || hash_parts.sender, room: hash_parts.room, md: true })
6413					},
6414					subsubtitle: false,
6415					well: this.data.well
6416				})
6417			},
6418			{
6419				mod: ['form'],
6420				component: BaseController.new('molecules-input~validatable', {
6421					input: {
6422						type: 'text',
6423						name: 'username',
6424						hook: this.createHook('username')
6425					},
6426					label: {
6427						text: __('tc-join.username')
6428					},
6429					rules: [
6430						{
6431							name: 'empty',
6432							message: __('validation.empty')
6433						}
6434					],
6435					tooltip_well: {
6436						title: __('tc-join.username-helper'),
6437						type: 'primary'
6438					}
6439				})
6440			},
6441			{
6442				mod: ['form'],
6443				component: BaseController.new('molecules-input~password-with-policy', {
6444					input: {
6445						name: 'password',
6446						hook: this.createHook('password'),
6447						autocomplete: 'new-password'
6448					},
6449					label: {
6450						text: __('generic.password-new')
6451					},
6452					addon: BaseController.new('atoms-addon~show')
6453				})
6454			},
6455			{
6456				mod: ['form'],
6457				component: BaseController.new('molecules-input~password', {
6458					input: {
6459						name: 'confirm-password'
6460					},
6461					label: {
6462						text: __('generic.password-confirm')
6463					},
6464					addon: BaseController.new('atoms-addon~show'),
6465					rules: [
6466						{
6467							name: 'empty',
6468							message: __('validation.empty')
6469						},
6470						{
6471							name: 'same',
6472							controller: this,
6473							parent_hook: 'form',
6474							counterpart_hook: 'password',
6475							message: __('validation.passwords-no-match')
6476						}
6477					]
6478				})
6479			},
6480			{
6481				mod: ['default', 'space-top'],
6482				component: BaseController.new('molecules-button', {
6483					mod: ['block', 'primary'],
6484					button: {
6485						text: __('tc-join.submit'),
6486						name: 'verify-email',
6487						hook: this.createHook('verify-email')
6488					}
6489				})
6490			},
6491			{
6492				mod: ['footer'],
6493				component: BaseController.new('atoms-link~what-is-teamchat')
6494			}
6495		].filter(Boolean)
6496	});
6497};
6498
6499module.exports = TemplatesCard_TcJoin;
6500
6501},{"./card.js":99,"@icewarp/hash":160,"BaseController":"BaseController","BaseModel":"BaseModel"}],123:[function(require,module,exports){
6502"use strict";
6503var BaseController = require('BaseController');
6504var TemplatesCard = require('./card.js');
6505var TemplatesCard_TcShare = BaseController.create('TemplatesCard_TcShare', TemplatesCard);
6506var Hash = require('@icewarp/hash');
6507
6508TemplatesCard_TcShare.prototype.addListeners = function () {
6509	var hash_data = Hash.getParts();
6510	TemplatesCard.prototype.addListeners.call(this);
6511	this.addHookListener('next', 'click', this.changeCard, {card: 'tc-actions', hashData: hash_data});
6512	this.addHookListener('skip', 'click', this.changeCard, {card: hash_data.return || 'tc-join', hashData: hash_data});
6513};
6514
6515TemplatesCard_TcShare.prototype.helper = function () {
6516	return TemplatesCard.prototype.helper.call(this, {
6517		content: [
6518			{
6519				mod: [],
6520				component: BaseController.new('organisms-card-header', {
6521					'card-icon': BaseController.new('atoms-icons', {
6522						icon: 'teamchat'
6523					}),
6524					heading: __('tc-share.heading'),
6525					subtitle: {
6526						text: __('tc-share.subheading')
6527					},
6528					well: this.data.well
6529				})
6530			},
6531			{
6532				mod: ['form', 'no-padding'],
6533				component: BaseController.new('AtomsImage', {
6534					class_name: ['u-margin-auto'],
6535					src: './images/teamchat/share.png'
6536				})
6537			},
6538			{
6539				mod: ['default', 'space-top'],
6540				component: [
6541					BaseController.new('molecules-button', {
6542						mod: ['primary', 'inverted', 'flex'],
6543						button: {
6544							text: __('generic.skip'),
6545							name: 'skip',
6546							hook: this.createHook('skip')
6547						}
6548					}),
6549					BaseController.new('molecules-button', {
6550						mod: ['primary', 'flex'],
6551						button: {
6552							text: __('generic.next'),
6553							name: 'next',
6554							hook: this.createHook('next')
6555						}
6556					})
6557				]
6558			}
6559		].filter(Boolean)
6560	});
6561};
6562
6563module.exports = TemplatesCard_TcShare;
6564
6565},{"./card.js":99,"@icewarp/hash":160,"BaseController":"BaseController"}],124:[function(require,module,exports){
6566"use strict";
6567var BaseModel = require('BaseModel');
6568var BaseController = require('BaseController');
6569var TemplatesCard = require('./card.js');
6570var TemplatesCard_TouchId = BaseController.create('TemplatesCard_TouchId', TemplatesCard);
6571
6572TemplatesCard_TouchId.prototype.addListeners = function () {
6573	TemplatesCard.prototype.addListeners.call(this);
6574};
6575
6576TemplatesCard_TouchId.prototype.helper = function () {
6577	return TemplatesCard.prototype.helper.call(this, {
6578		content: [
6579			{
6580				mod: [],
6581				component: BaseController.new('organisms-card-header', {
6582					heading: __('tc-touch-id.heading'),
6583					well: this.data.well
6584				})
6585			},
6586			{
6587				mod: ['form'],
6588				component: { _name: 'atoms-touch-id' }
6589			},
6590			{
6591				mod: ['footer'],
6592				component: [
6593					BaseController.new('atoms-link', {
6594						text: __('tc-touch-id.use-password'),
6595						mod: ['switch'],
6596						class_name: ['u-align-center']
6597					}),
6598					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
6599				].filter(Boolean)
6600			}
6601		]
6602	});
6603};
6604
6605module.exports = TemplatesCard_TouchId;
6606
6607},{"./card.js":99,"BaseController":"BaseController","BaseModel":"BaseModel"}],125:[function(require,module,exports){
6608"use strict";
6609var BaseModel = require('BaseModel');
6610var BaseController = require('BaseController');
6611var TemplatesCard = require('./card');
6612var TemplatesCard_SignInPassword = require('./card~sign-in-password');
6613var TemplatesCard_TwoFactor = BaseController.create('TemplatesCard_TwoFactor', TemplatesCard_SignInPassword);
6614var QueryParams = require('@icewarp/query-params');
6615var MobileDetect = require('mobile-detect');
6616var Hash = require('@icewarp/hash');
6617
6618TemplatesCard_TwoFactor.prototype.addListeners = function () {
6619	TemplatesCard_SignInPassword.prototype.addListeners.call(this);
6620	this.addHookListener('validate-totp', 'click', this.submitForm);
6621};
6622
6623TemplatesCard_TwoFactor.prototype.authenticate = function (encrypt) {
6624	var password = encrypt(this.data.password);
6625	var WebClient = BaseModel.instance('WebClient');
6626	var Login = BaseModel.instance('Login');
6627
6628	if (Hash.getParts().auth_id) {
6629		return this.loginOauth(password);
6630	}
6631
6632	WebClient.getAuthToken({
6633		email: Login.getData('chosen_account').email,
6634		password: password,
6635		persistentlogin: this.getPersistentLoginValue.call(this),
6636		totpcode: this.hook('totpcode').value
6637	}, {
6638		success: this.loginApp,
6639		error: function(error) {
6640			if (error === 'auth_digest_expired') {
6641				return this.validateForm();
6642			}
6643
6644			this.genericError(error);
6645		},
6646		context: this
6647	});
6648};
6649
6650TemplatesCard_TwoFactor.prototype.helper = function () {
6651	var config = BaseModel.instance('Config').getData('config');
6652	var WebClient = BaseModel.instance('WebClient');
6653	var Login = BaseModel.instance('Login');
6654
6655	var md = new MobileDetect(window.navigator.userAgent);
6656	var interfaces = WebClient.getData('layout_settings').getValue('interfaces') || '';
6657	var params = QueryParams.parse();
6658
6659	interfaces = [
6660		(!interfaces || ~interfaces.indexOf('a')) ? {
6661			selected: md.tablet() && md.mobileGrade() === 'A',
6662			text: __('interface.desktop'),
6663			value: 'desktop'
6664		} : false,
6665		(!interfaces || ~interfaces.indexOf('b')) ? {
6666			selected: md.tablet() && md.mobileGrade() !== 'A',
6667			text: __('interface.tablet'),
6668			value: 'basic'
6669		} : false,
6670		((params.interface === 'pda') && (!interfaces || ~interfaces.indexOf('p'))) ? {
6671			selected: params.interface === 'pda',
6672			text: __('interface.phone'),
6673			value: 'pda'
6674		} : false
6675	].filter(Boolean);
6676
6677	return TemplatesCard.prototype.helper.call(this, {
6678		password: this.data.password,
6679		hook: this.createHook('form'),
6680		content: [
6681			{
6682				mod: [],
6683				component: BaseController.new('organisms-card-header', {
6684					heading: __('sign-in-generic.heading.' + config.application),
6685					well: this.data.well
6686				})
6687			},
6688			{
6689				class_name: ['u-hide'],
6690				component: BaseController.new('molecules-input', {
6691					input: {
6692						type: 'text',
6693						name: 'username',
6694						hook: this.createHook('username'),
6695						value: Login.getData('chosen_account').email
6696					}
6697				})
6698			},
6699			{
6700				mod: ['form'],
6701				component: BaseController.new('molecules-input~validatable', {
6702					input: {
6703						name: 'totpcode',
6704						type: 'number',
6705						hook: this.createHook('totpcode'),
6706						maxlength: 6,
6707						autocomplete: 'off'
6708					},
6709					label: {
6710						text: __('two_step.verification_code')
6711					},
6712					rules: [
6713						{
6714							name: 'length',
6715							data: 6,
6716							message: __('validation.length', 6)
6717						}
6718					]
6719				})
6720			},
6721			!WebClient.getData('restrictions').getValue('disable_remember') && {
6722				mod: ['form'],
6723				component: BaseController.new('molecules-checkbox', {
6724					label: __('sign-in-password.remember'),
6725					input: {
6726						name: 'remember-me',
6727						checked: this.data.persistentLogin,
6728						hook: this.createHook('persistentlogin')
6729					}
6730				})
6731			},
6732			(config.application === 'webclient' && (md.mobile() || QueryParams.parse().mobile)) && {
6733				mod: ['form'],
6734				class_name: interfaces.length > 1 ? [] : ['u-hide'],
6735				component: BaseController.new('molecules-select', {
6736					select: {
6737						name: 'user_interface',
6738						hook: this.createHook('user_interface'),
6739						options: interfaces
6740					},
6741					label: {
6742						text: __('interface.label')
6743					}
6744				})
6745			},
6746			{
6747				mod: ['default', 'space-top'],
6748				component: BaseController.new('molecules-button', {
6749					mod: ['block', 'primary'],
6750					button: {
6751						hook: this.createHook('validate-totp'),
6752						text: __('generic.sign-in'),
6753						name: 'next'
6754					}
6755				})
6756			},
6757			WebClient.getData('restrictions').getValue('show_search') && {
6758				mod: ['form'],
6759				component: BaseController.new('molecules-input~search', {
6760					input: {
6761						name: 'search'
6762					},
6763					label: {
6764						text: __('generic.search')
6765					}
6766				})
6767			},
6768			{
6769				mod: ['footer'],
6770				component: [
6771					BaseController.new('atoms-info~not-you'),
6772					BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
6773				].filter(Boolean)
6774			}
6775		].filter(Boolean)
6776	});
6777
6778};
6779
6780module.exports = TemplatesCard_TwoFactor;
6781
6782},{"./card":99,"./card~sign-in-password":117,"@icewarp/hash":160,"@icewarp/query-params":170,"BaseController":"BaseController","BaseModel":"BaseModel","mobile-detect":364}],126:[function(require,module,exports){
6783"use strict";
6784var BaseModel = require('BaseModel');
6785var BaseController = require('BaseController');
6786var TemplatesCard_GenericMessage = require('./card~generic-message.js');
6787var TemplatesCard_Unavailable = BaseController.create('TemplatesCard_Unavailable', TemplatesCard_GenericMessage);
6788
6789TemplatesCard_Unavailable.prototype.addListeners = function () {
6790	TemplatesCard_GenericMessage.prototype.addListeners.call(this);
6791};
6792
6793TemplatesCard_Unavailable.prototype.helper = function () {
6794	this.data.title = this.data.title || __('error.unavailable');
6795	this.data.type = this.data.type || 'error';
6796	this.data.footer = {
6797		mod: ['footer'],
6798		component: [
6799			BaseController.new('atoms-link~retry', {
6800				link: this.data.retry_link
6801			}),
6802			BaseModel.instance('WebClient').getData('restrictions').getValue('contact_support') && BaseController.new('atoms-info~contact-admin')
6803		].filter(Boolean)
6804	};
6805	return TemplatesCard_GenericMessage.prototype.helper.call(this);
6806};
6807
6808module.exports = TemplatesCard_Unavailable;
6809
6810},{"./card~generic-message.js":107,"BaseController":"BaseController","BaseModel":"BaseModel"}],127:[function(require,module,exports){
6811"use strict";
6812var BaseController = require('BaseController');
6813var Validatable = BaseController.create('Validatable');
6814var BaseModel = require('BaseModel');
6815var Validator = BaseModel.instance('Validator');
6816
6817Validatable.prototype.addListeners = function () {
6818	this.addDelegatedHookListener('tooltip', 'click', this.showMessage);
6819};
6820
6821Validatable.prototype.validate = function (event, callback) {
6822	var target = event && event.target ? event.target : this.select('input, textarea, select'),
6823		rules = (this.data.rules || []).slice();
6824
6825	callback = callback instanceof Function ? callback : false,
6826
6827	this.trigger('error-message-hide');
6828
6829	/**
6830	 * @returns {Boolean}
6831	 */
6832	function validate() {
6833		var rule = rules.shift();
6834
6835		if (rule) {
6836			if (!Validator[rule.name]) {
6837				console.error('missing validation', rule.name);
6838				return validate.call(this);
6839			}
6840			rule.controller = this;
6841			Validator[rule.name](rule, target.value, function(isValid) {
6842				if (!isValid) {
6843					this.trigger('validation-error', rule);
6844					this.DOMElement.classList.add('has-error');
6845					callback && callback(false);
6846				} else {
6847					validate.call(this);
6848				}
6849			}.bind(this));
6850		} else {
6851			this.trigger('validation-success', {
6852				controller: this
6853			});
6854			this.DOMElement.classList.remove('has-error');
6855			callback && callback(true);
6856		}
6857	}
6858
6859	validate.call(this);
6860};
6861
6862Validatable.prototype.showMessage = function () {
6863	this.trigger('error-message-show', this.data.tooltip_well);
6864};
6865
6866module.exports = Validatable;
6867
6868},{"BaseController":"BaseController","BaseModel":"BaseModel"}],128:[function(require,module,exports){
6869"use strict";
6870var BaseController = require('BaseController');
6871var IndexManager = require('@icewarp/index-manager');
6872
6873var Window = BaseController.create('Window');
6874
6875/** 
6876 * West Bit
6877 * @type Number
6878 */
6879var W = 1;
6880
6881/** 
6882 * East bit
6883 * @type Number
6884 */
6885var E = 2;
6886/** 
6887 * North bit
6888 * @type Number
6889 */
6890var N = 4;
6891
6892/** 
6893 * South bit
6894 * @type Number
6895 */
6896var S = 8;
6897
6898/**
6899 * 
6900 * @param {object} e
6901 * @returns {undefined}
6902 */
6903function dragStart(e) {
6904	if (this.fullscreen || !this.move_selector) {
6905		return;
6906	}
6907	updateIndex.call(this);
6908	this.drag_start = {x: e.clientX, y: e.clientY};
6909	if (this.resize) {
6910		e.preventDefault();
6911		this.resizing = true;
6912		this.start_width = this.DOMElement.offsetWidth;
6913		this.start_height = this.DOMElement.offsetHeight;
6914		this.start_top = this.DOMElement.offsetTop;
6915		this.start_left = this.DOMElement.offsetLeft;
6916		return;
6917	}
6918	if (e.target === this.select(this.move_selector)) {
6919		e.preventDefault();
6920		this.moving = true;
6921	}
6922}
6923
6924/**
6925 * 
6926 * @param {object} e
6927 * @returns {undefined}
6928 */
6929function stopDrag(e) {
6930	var coords;
6931	if (this.moving) {
6932		coords = calculateCoordinates.call(this, e, true);
6933		this.x = coords.x;
6934		this.y = coords.y;
6935		this.DOMElement.style.transform = 'none';
6936		this.DOMElement.style.left = this.x + 'px';
6937		this.DOMElement.style.top = this.y + 'px';
6938		this.moving = false;
6939	}
6940	if (this.resizing) {
6941		this.resizing = false;
6942		this.x = this.DOMElement.offsetLeft;
6943		this.y = this.DOMElement.offsetTop;
6944	}
6945
6946}
6947
6948/**
6949 * 
6950 * @param {object} e
6951 * @returns {undefined}
6952 */
6953function move(e) {
6954	var coords, width, height, top, left;
6955	if (this.moving) {
6956		coords = calculateCoordinates.call(this, e);
6957		(this.DOMElement.style.transform = 'translateX(' + coords.x + 'px' + ') translateY(' + coords.y + 'px' + ') translateZ(0)');
6958	}
6959	if (this.resizing) {
6960		width = getWidth.call(this, e);
6961		height = getHeight.call(this, e);
6962		top = getTop.call(this, e);
6963		left = getLeft.call(this, e);
6964		width && (this.resize & W || this.resize & E) && (this.DOMElement.style.width = width + 'px');
6965		height && (this.resize & N || this.resize & S) && (this.DOMElement.style.height = height + 'px');
6966		height && (this.resize & N) && (this.DOMElement.style.top = top + 'px');
6967		width && (this.resize & W) && (this.DOMElement.style.left = left + 'px');
6968	}
6969}
6970
6971/**
6972 * 
6973 * @param {type} e
6974 * @returns {undefined}
6975 */
6976function resize(e) {
6977	var dir = 0;
6978	if (this.resizing) {
6979		return;
6980	}
6981	this.DOMElement.style.cursor = 'auto';
6982	(Math.abs(e.clientX - this.x) < this.draggable_border) && (dir = dir | W);
6983	(Math.abs(e.clientX - (this.x + this.DOMElement.offsetWidth)) < this.draggable_border) && (dir = dir | E);
6984	(Math.abs(e.clientY - this.y) < this.draggable_border) && (dir = dir | N);
6985	(Math.abs(e.clientY - (this.y + this.DOMElement.offsetHeight)) < this.draggable_border) && (dir = dir | S);
6986	if (dir & W || dir & E) {
6987		this.DOMElement.style.cursor = 'ew-resize';
6988	}
6989	if (dir & N || dir & S) {
6990		this.DOMElement.style.cursor = 'ns-resize';
6991	}
6992	if ((dir & W && dir & S) || (dir & E && dir & N)) {
6993		this.DOMElement.style.cursor = 'nesw-resize';
6994	}
6995	if ((dir & E && dir & S) || (dir & W && dir & N)) {
6996		this.DOMElement.style.cursor = 'nwse-resize';
6997	}
6998	this.resize = dir;
6999}
7000
7001/**
7002 * 
7003 * @param {object} e
7004 * @param {boolean} fixed
7005 * @returns {nm$_window.Window.prototype.calculateCoordinates.windowAnonym$0}
7006 */
7007function calculateCoordinates(e, fixed) {
7008	var x_diff = e.clientX - this.drag_start.x;
7009	var y_diff = e.clientY - this.drag_start.y;
7010	var x = x_diff;
7011	var y = y_diff;
7012	if ((this.x + x_diff + this.DOMElement.offsetWidth) > document.body.offsetWidth) {
7013		x = (document.body.offsetWidth - this.DOMElement.offsetWidth - this.x);
7014	}
7015	if ((this.x + x_diff) < 0) {
7016		x = -this.x;
7017	}
7018	if ((this.y + y_diff + this.DOMElement.offsetHeight) > document.body.offsetHeight) {
7019		y = (document.body.offsetHeight - this.DOMElement.offsetHeight - this.y);
7020	}
7021	if ((this.y + y_diff) < 0) {
7022		y = -this.y;
7023	}
7024	return {x: fixed ? this.x + x : x, y: fixed ? this.y + y : y};
7025}
7026/**
7027 * 
7028 * @param {object} e
7029 * @returns {Number}
7030 */
7031function getTop(e) {
7032	var top = this.start_top + (e.clientY - this.drag_start.y);
7033	return top > 0 ? top : 0;
7034}
7035/**
7036 * 
7037 * @param {object} e
7038 * @returns {Number}
7039 */
7040function getLeft(e) {
7041	var left = this.start_left + (e.clientX - this.drag_start.x);
7042	return left > 0 ? left : 0;
7043}
7044/**
7045 * 
7046 * @param {object} e
7047 * @returns {Number}
7048 */
7049function getWidth(e) {
7050	var width = this.start_width + ((e.clientX - this.drag_start.x) * (this.resize & W ? -1 : 1));
7051	var space_right = (document.body.offsetWidth - this.DOMElement.offsetLeft);
7052	var space_left = (this.DOMElement.offsetLeft > 0 ? this.DOMElement.offsetLeft : 0) + this.DOMElement.offsetWidth;
7053	if (width < this.min_width) {
7054		return this.min_width;
7055	}
7056	if ((document.body.offsetWidth - this.DOMElement.offsetLeft - this.DOMElement.offsetWidth) < 0) {
7057		return 0;
7058	}
7059	return (this.resize & W) ? (width > space_left ? space_left : width) : (width > space_right ? space_right : width);
7060}
7061/**
7062 * 
7063 * @param {object} e
7064 * @returns {Number}
7065 */
7066function getHeight(e) {
7067	var height = this.start_height + ((e.clientY - this.drag_start.y) * (this.resize & N ? -1 : 1));
7068	var space_bottom = (document.body.offsetHeight - this.DOMElement.offsetTop);
7069	var space_top = (this.DOMElement.offsetTop < 0 ? 0 : this.DOMElement.offsetTop) + this.DOMElement.offsetHeight;
7070	if (height < this.min_height) {
7071		return this.min_height;
7072	}
7073	if ((space_bottom - this.DOMElement.offsetHeight) < 0 || this.DOMElement.offsetTop < 0) {
7074		return 0;
7075	}
7076	return (this.resize & N) ? (height > space_top ? space_top : height) : (height > space_bottom ? space_bottom : height);
7077}
7078
7079/**
7080 * 
7081 * @returns {undefined}
7082 */
7083function updateIndex() {
7084	this.DOMElement.style.zIndex = IndexManager.add(this) + 200;
7085}
7086
7087/** Generic class_name for floating windows
7088 * 
7089 * @returns {Window}
7090 */
7091Window.prototype.onCreate = function () {
7092	/** 
7093	 * Border for resizing
7094	 * @type Number
7095	 */
7096	this.draggable_border = 0;
7097
7098	/** 
7099	 * Selector for moving window
7100	 * @type String
7101	 */
7102	this.move_selector = false;
7103
7104	/**
7105	 * 
7106	 * @type Number
7107	 */
7108	this.min_width = 100;
7109
7110	/**
7111	 * 
7112	 * @type Number
7113	 */
7114	this.min_height = 100;
7115
7116	this.drag_start = false;
7117	this.x = 0;
7118	this.y = 0;
7119	this.fullscreen = false;
7120};
7121
7122Window.prototype.addListeners = function () {
7123	if (this.move_selector) {
7124		this.addDOMListener('', 'mousedown', dragStart.bind(this));
7125		this.addDOMListener(document, 'mouseup', stopDrag.bind(this));
7126		this.addDOMListener(document, 'mousemove', move.bind(this));
7127		this.addDelegatedDOMListener(this.move_selector, 'dblclick', this.toggleFullscreen);
7128	}
7129	this.draggable_border && this.addDOMListener('', 'mousemove', resize.bind(this));
7130};
7131
7132/** Setup 
7133 * 
7134 * @param {object} options
7135 * @returns {undefined}
7136 */
7137Window.prototype.setup = function (options) {
7138	var i;
7139	for (i in (options || {})) {
7140		this[i] = options[i];
7141	}
7142};
7143Window.prototype.toggleFullscreen = function (e) {
7144	this.beforeFullScreenToggle && this.beforeFullScreenToggle(e);
7145	if (!this.fullscreen) {
7146		this.beforeFullScreenOn && this.beforeFullScreenOn(e);
7147		this.fullscreen = {
7148			top: this.DOMElement.style.top,
7149			left: this.DOMElement.style.left,
7150			width: this.DOMElement.style.width,
7151			height: this.DOMElement.style.height,
7152			x: this.x,
7153			y: this.y
7154		};
7155		this.DOMElement.style.top = 0;
7156		this.DOMElement.style.left = 0;
7157		this.DOMElement.style.width = this.DOMElement.style.height = '100%';
7158		this.x = 0;
7159		this.y = 0;
7160		this.afterFullScreenOn && this.afterFullScreenOn(e);
7161	} else {
7162		this.beforeFullScreenOff(e);
7163		this.DOMElement.style.top = this.fullscreen.top;
7164		this.DOMElement.style.left = this.fullscreen.left;
7165		this.DOMElement.style.width = this.fullscreen.width;
7166		this.DOMElement.style.height = this.fullscreen.height;
7167		this.x = this.fullscreen.x;
7168		this.y = this.fullscreen.y;
7169		this.fullscreen = false;
7170		this.afterFullScreenOff && this.afterFullScreenOff(e);
7171	}
7172	this.afterFullScreenToggle && this.afterFullScreenToggle(e);
7173};
7174
7175/**
7176 * 
7177 * @returns {undefined}
7178 */
7179Window.prototype.afterRender = function () {
7180	this.DOMElement.classList.add('o-window');
7181	this.x = this.DOMElement.offsetLeft;
7182	this.y = this.DOMElement.offsetTop;
7183	updateIndex.call(this);
7184};
7185
7186module.exports = Window;
7187
7188}
7188,{"@icewarp/index-manager":164,"BaseController":"BaseController"}],129:[function(require,module,exports){
7189"use strict";
7190module.exports={'form':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/form.js')},'validatable':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/validatable.js')},'window':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/window.js')},'molecules-button':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/button/button.js')},'molecules-captcha':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/captcha/captcha.js')},'molecules-input':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/input/input.js')},'molecules-input~password-with-policy':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/input/input~password-with-policy.js')},'molecules-input~password':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/input/input~password.js')},'molecules-input~search':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/input/input~search.js')},'molecules-input~validatable':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/input/input~validatable.js')},'molecules-language-picker':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/language-picker/language-picker.js')},'molecules-select':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/select/select.js')},'molecules-select~validatable':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/select/select~validatable.js')},'molecules-checkbox':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/checkbox/checkbox.js')},'molecules-static':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/static/static.js')},'molecules-textarea':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/textarea/textarea.js')},'molecules-textarea~validatable':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/molecules/textarea/textarea~validatable.js')},'organisms-bar~footer':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/organisms/bar/bar~footer.js')},'organisms-card-header':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/organisms/card-section/card-header.js')},'organisms-card-header~message':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/organisms/card-section/card-header~message.js')},'organisms-window':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/organisms/window/window.js')},'sites-generic':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/sites/generic.js')},'sites-login':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/sites/login/login.js')},'templates-card':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card.js')},'templates-card~change-password':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~change-password.js')},'templates-card~choose-account':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~choose-account.js')},'templates-card~confirm-personality':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~confirm-personality.js')},'templates-card~contact-admin':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~contact-admin.js')},'templates-card~create-account':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~create-account.js')},'templates-card~forgot-password':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~forgot-password.js')},'templates-card~gateway-login':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~gateway-login.js')},'templates-card~generic-message':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~generic-message.js')},'templates-card~guest-verify':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~guest-verify.js')},'templates-card~join-password':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~join-password.js')},'templates-card~join-username':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~join-username.js')},'templates-card~join':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~join.js')},'templates-card~oauth-grant':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~oauth-grant.js')},'templates-card~personal':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~personal.js')},'templates-card~reset-password':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~reset-password.js')},'templates-card~set-password':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~set-password.js')},'templates-card~sign-in-guest':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~sign-in-guest.js')},'templates-card~sign-in-password':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~sign-in-password.js')},'templates-card~sign-in':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~sign-in.js')},'templates-card~tc-actions':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~tc-actions.js')},'templates-card~tc-check-email':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~tc-check-email.js')},'templates-card~tc-collaboration':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~tc-collaboration.js')},'templates-card~tc-join':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~tc-join.js')},'templates-card~tc-share':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~tc-share.js')},'templates-card~touch-id':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~touch-id.js')},'templates-card~two-factor':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~two-factor.js')},'templates-card~unavailable':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~unavailable.js')},'atoms-ad-adsense':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/
7190atoms/ad/ad-adsense.js')},'atoms-ad':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/ad/ad.js')},'atoms-addon':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/addon/addon.js')},'atoms-addon~show':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/addon/addon~show.js')},'atoms-dropdown':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/dropdown/dropdown.js')},'atoms-avatar':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/avatar/avatar.js')},'atoms-element-button':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/form-elements/element-button.js')},'atoms-element-input':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/form-elements/element-input.js')},'atoms-element-input~date':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/form-elements/element-input~date.js')},'atoms-element-select':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/form-elements/element-select.js')},'atoms-element-textarea':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/form-elements/element-textarea.js')},'atoms-info':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info.js')},'atoms-info~choose-account':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~choose-account.js')},'atoms-info~contact-admin':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~contact-admin.js')},'atoms-info~dont-have-account':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~dont-have-account.js')},'atoms-info~have-account':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~have-account.js')},'atoms-info~not-you':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~not-you.js')},'atoms-info~sign-with-another-acc':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~sign-with-another-acc.js')},'atoms-label':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/label/label.js')},'atoms-link~back':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~back.js')},'atoms-link~check-account':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~check-account.js')},'atoms-link~choose-account':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~choose-account.js')},'atoms-link~contact-admin':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~contact-admin.js')},'atoms-link~create-acc':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~create-acc.js')},'atoms-link~remove-from-list':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~remove-from-list.js')},'atoms-link~retry':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~retry.js')},'atoms-link~sign-in':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~sign-in.js')},'atoms-link~sign-with-another-acc':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~sign-with-another-acc.js')},'atoms-link~what-is-teamchat':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~what-is-teamchat.js')},'atoms-switch':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/switch/switch.js')},'atoms-well':function(){return require('/tc-build/builds/e24a4084e6e20918/merged/components/atoms/well/well.js')}};
7191}
7191,{"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/ad/ad-adsense.js":47,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/ad/ad.js":48,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/addon/addon.js":49,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/addon/addon~show.js":50,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/avatar/avatar.js":51,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/dropdown/dropdown.js":52,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/form-elements/element-button.js":53,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/form-elements/element-input.js":54,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/form-elements/element-input~date.js":55,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/form-elements/element-select.js":56,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/form-elements/element-textarea.js":57,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info.js":58,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~choose-account.js":59,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~contact-admin.js":60,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~dont-have-account.js":61,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~have-account.js":62,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~not-you.js":63,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/info/info~sign-with-another-acc.js":64,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/label/label.js":65,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~back.js":66,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~check-account.js":67,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~choose-account.js":68,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~contact-admin.js":69,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~create-acc.js":70,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~remove-from-list.js":71,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~retry.js":72,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~sign-in.js":73,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~sign-with-another-acc.js":74,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/link/link~what-is-teamchat.js":75,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/switch/switch.js":76,"/tc-build/builds/e24a4084e6e20918/merged/components/atoms/well/well.js":77,"/tc-build/builds/e24a4084e6e20918/merged/components/form.js":78,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/button/button.js":79,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/captcha/captcha.js":80,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/checkbox/checkbox.js":81,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/input/input.js":82,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/input/input~password-with-policy.js":83,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/input/input~password.js":84,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/input/input~search.js":85,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/input/input~validatable.js":86,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/language-picker/language-picker.js":87,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/select/select.js":88,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/select/select~validatable.js":89,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/static/static.js":90,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/textarea/textarea.js":91,"/tc-build/builds/e24a4084e6e20918/merged/components/molecules/textarea/textarea~validatable.js":92,"/tc-build/builds/e24a4084e6e20918/merged/components/organisms/bar/bar~footer.js":93,"/tc-build/builds/e24a4084e6e20918/merged/components/organisms/card-section/card-header.js":94,"/tc-build/builds/e24a4084e6e20918/merged/components/organisms/card-section/card-header~message.js":95,"/tc-build/builds/e24a4084e6e20918/merged/components/organisms/window/window.js":96,"/tc-build/builds/e24a4084e6e20918/merged/components/sites/generic.js":97,"/tc-build/builds/e24a4084e6e20918/merged/components/sites/login/login.js":98,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card.js":99,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~change-password.js":100,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~choose-account.js":101,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~confirm-personality.js":102,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~contact-admin.js":103,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~create-account.js":104,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~forgot-password.js":105,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~gateway-login.js":106,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~generic-message.js":107,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~guest-verify.js":108,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~join-password.js":109,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~join-username.js":110,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~join.js":111,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~oauth-grant.js":112,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~personal.js":113,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~reset-password.js":114,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~set-password.js":115,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~sign-in-guest.js":116,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~sign-in-password.js":117,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~sign-in.js":118,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~tc-actions.js":119,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~tc-check-email.js":120,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~tc-collaboration.js":121,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~tc-join.js":122,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~tc-share.js":123,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~touch-id.js":124,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~two-factor.js":125,"/tc-build/builds/e24a4084e6e20918/merged/components/templates/card/card~unavailable.js":126,"/tc-build/builds/e24a4084e6e20918/merged/components/validatable.js":127,"/tc-build/builds/e24a4084e6e20918/merged/components/window.js":128}],130:[function(require,module,exports){
7192module.exports={"calendar":{"day":{"monday":"Monday","tuesday":"Tuesday","wednesday":"Wednesday","thursday":"Thursday","friday":"Friday","saturday":"Saturday","
7192sunday":"Sunday"},"day_short":{"mon":"Mon","tue":"Tue","wed":"Wed","thu":"Thu","fri":"Fri","sat":"Sat","sun":"Sun"},"month":{"january":"January","february":"February","march":"March","april":"April","may":"May","june":"June","july":"July","august":"August","september":"September","october":"October","november":"November","december":"December"},"next_month":"Next month","previous_month":"Previous month"},"change-password":{"heading":"Change password","submit":"Change password","success-message":"Password has been changed"},"choose-account":{"heading":"Choose an account","remove":"Manage Accounts","remove-selected":"Remove selected"},"confirm-personality":{"heading":"Confirm personality","subheading":"Please wait while your account is being verified","success-message":"Your account has been verified"},"contact-admin":{"describe-problem":"Describe your problem","email-helper":"The address which will be used to reply to you.","having-problems":"Having problems?","heading":"Contact administrator","submit":"Send message","success-message":"Admin has been notified","tel":"Please leave us here your mobile phone number"},"create-account":{"alternative-email":"Alternative email","domain":"Domain","email-address":"Your email address","enter-first-name":"Enter your first name","enter-last-name":"Enter your last name","first-name":"First name","full-name":"Full name","heading":"Create an account","last-name":"Last name","last-step":"Last step","next-step":"Next step","suggestion":"This is your email address suggested based on the first and last\nname indicated in the previous step. The address is created under\nyour custom domain. Feel free to adjust the name as needed."},"error":{"invalid_login":"Incorrect username or password. Please try again.","expired":"Expired session","connection":"Unable to reach server. Please check your internet connection or contact administrator.","servererror":"Unable to access this service. Please try again later or contact administrator.","overloaded":"The server is currently overloaded. Please try again later or contact administrator.","wc_disabled":"WebClient is disabled.","invalid_rsa":"Unable to create RSA password.","no_db":"Database Connection Error","no_data":"No Data Available","access_error":"Unable to access mailbox folder, please contact administrator.","ip_mismatch":"Your IP has changed, you will be logged out. To prevent this problem in the future, please access WebClient via HTTPS connection.","sso_login_not_allowed":"SSO login not allowed","sso_unable_to_use":"Unable to use SSO","sso_error":"Error when trying to use SSO login","auth_login_invalid":"Invalid login username or password","auth_login_blocked":"Account blocked","account_already_exists":"Account already exists","account_alternative_email":"Account has no alternate email address. Please contact admin","account_disabled_1":"Could not login because of IP Restriction","account_disabled_2":"Could not login because account is disabled","account_disabled_3":"Could not login because password is expired","account_disabled_4":"Could not login because account expired","account_disabled_5":"Could not login because of SMTP access mode","account_disabled_6":"Could not login because of POP/IMAP access mode","account_disabled_7":"Could not login because account is IMAP only","account_disabled_8":"Could not login because account is POP3 only","account_disabled_9":"Could not login because account has no access rights to WebClient","account_disabled_10":"Could not login because of access mode","account_disabled_11":"Could not login because login to this domain is disabled","account_disabled_12":"Could not login because domain expired","account_disabled_13":"Could not login because of license","account_invalid":"Account invalid","account_does_not_exist":"Specified account doesn't exist","account_missing_required_property":"Some of the required properties is missing","account_no_password":"Account password is missing or empty","account_no_username":"Account username is missing or empty","account_no_domain":"Domain is missing","account_password_policy":"Password does not match the password policy","account_signup_disabled":"Self sign-up disabled","account_signup_disabled_ip":"Admin has disabled signup from your IP","auth_digest_expired":"Login expired, please login again","auth_plan_exceeded":"The user count allowed by the license has been exceeded. Only administrators are allowed to sign in until the issue is resolved.","auth_two_factor_invalid":"Invalid verification code","auth_webadmin_session_not_found":"Webadmin session not found","capslock":"Caps Lock on","captcha_confirmation":"Wrong security code","contact_support_no_admin_email":"Administrator has not set up an email address","db_auto_create":"Cannot auto create the database","db_create_sqlitefile":"Cannot create SQLite DB file","db_create_tables":"Cannot create tables","db_invalid_statement":"Invalid statement type","domain_invali
7192d":"Invalid domain","folder_get_list":"Cannot get the list of folders","folder_open":"Cannot open folder","forgot-missing-domain":"Please enter your full email address first to continue with password reset.","group_open":"Cannot open group","groupware_authenticate":"Login to GroupWare failed","groupware_db_connection":"GroupWare is unable to connect to database","groupware_timeout":"GroupWare timeout","groupware_upgrade_task":"GroupWare service update procedure is running. Please try again later.","guest_invalid_hash":"Wrong verification hash","gw_init_error":"GroupWare initialization error","invalid_account_app":"Cannot use this account with this app","invalid_domain":"Invalid domain","language_path_not_found":"Language path not found","language-not-found":"Language file not found","logdir_create":"Cannot create logging directory","login_account_valid":"Invalid account","login_invalid":"Invalid login for user","login_invalid_keypair":"RSA validation failed. Try again.","login_ip_invalid":"Login IP restriction","migration_in_progress":"Migration of account is in progress, please try again later","missing_request_params":"Missing request parameters","no_teamchat_folders":"Unable to login due to missing teamchat folder","password_not_changed":"New password cannot be the same as old password","personality_confirmation_invalid_hashid":"Email address cannot be confirmed: Invalid Hash","personality_confirmation_invalid_user":"Email address cannot be confirmed: Invalid User","reset_disabled":"Reset password has been disabled","reset_password_invalid_hashid":"Invalid hash ID","reset_password_no_hash":"Invalid hash ID","reset_password_uid_file":"UID file doesn't exist","reset_too_old":"Password reset link has expired","rsa_create_key_pair":"Unable to create RSA key pair","server":"Unable to access this service. Please try again later or contact administrator.","session_cookie_mismatch":"Session cookie mismatch","session_expired":"Session expired","session_ip_mismatch":"Session IP mismatch","session_mismatch":"Session mismatch","session_no_user":"Session user object cannot be retrieved","settings_user_set":"Cannot load user settings","setting_file_corrupted":"Webmail server settings are corrupted. Please, contact the administrator.","signup_expired":"Signup session has expired. Contact the sender to invite you again.","signup_invalid_invite_domain":"Invite domain invalid","signup_invalid_invite_session":"Invite session invalid","signup_verification_failed_sms":"Unable to send SMS verification","signup_verification_failed_email":"Unable to send email verification","signup_verification_not_initialized":"Verification not initialized","signup_verification_failed":"Verification failed","storage_get_dom":"Unable to load setting file","unavailable":"Temporary unavailable","unspecified":"Server returned an error **%{error}**","user_settings_global":"Unable to load settings","oauth_not_found":"Invalid OAuth authorization code","oauth_expired":"OAuth authorization code expired"},"forgot-password":{"heading":"Forgot password","submit":"Send me instructions","success-message":"Email has been sent to your alternative email address","success-message-guest":"Email has been sent to your email address"},"gateway-login":{"subheading":"Sign in with an administrator account to manage domains and users","success-message":"We have sent you an e-mail which contains a secure link. Clicking the link will let you access spam management for a limited time."},"generic":{"accept":"Accept","authorize":"Authorize","back":"Back","cancel":"Cancel","captcha-generate":"Generate new","check-account":"Check your account again","choose-different-account":"Choose different account","confirm":"Confirm","contact-admin":"Contact admin","continue":"Continue","copyright":"Powered by IceWarp","create-acc":"Create an account","decline":"Decline","done":"Done","email":"Email address","error":"Something went wrong","female":"Female","find_out_more":"[www.icewarp.com](//www.icewarp.com)","fullscreen-enter":"Enter fullscreen","fullscreen-exit":"Exit fullscreen","have-account":"Already have an account?","dont-have-account":"Don't have an account yet?","hide":"Hide","male":"Male","next":"Next","not-you":"Not you?","password":"Password","password-confirm":"Confirm password","password-current":"Current password","password-new":"New password","password-policy":"Password policy","retry":"Retry","save-password":"Save new password","search":"Search","security-code":"Security code","send":"Send","show":"Show","
7192sign-in":"Sign in","sign-with-another-acc":"Sign in with another account","skip":"Skip","success":"Success","undefined":"Undefined","understand":"OK, I understand","undisclosed_participant":"Undisclosed participant","username":"Username"},"guest-verify":{"heading":"Guest verification","subheading":"Please wait while your account is being verified","success-message":"Your account has been verified"},"interface":{"label":"Interface","desktop":"Desktop","tablet":"Tablet","phone":"Phone"},"join":{"heading":"Join %{domain}"},"oauth":{"grant_title":"Application %{client} needs to access your account and asks for following permissions:","Admin":"Admin API access","User":"WebClient API access","info":"%{client} will be listed among your OAuth applications in WebClient and can be removed any time. You may optionally fill the description below.","description":"Description (optional)"},"personal":{"heading":"Personal Information","nickname":"Nickname","birthday":"Birthday","company":"Company","job":"Job","profession":"Profession","mobile-phone":"Mobile Phone","work-phone":"Work Phone","home-phone":"Home Phone","im":"IM","gender":"Gender","homepage":"Homepage"},"reset-password":{"heading":"Reset password","success-message":"Password has been changed","resethash":"Hash from SMS"},"set-password":{"code_sent_to":"Verification code has been sent to *%{to}*.","verification_code":"Verification code","heading":"You're almost done!","submit":"Create an Account","success-message":"Account has been created"},"sign-in":{"guest-helper":"Use this option if you do not have existing IceWarp account","sign-in-as-guest":"Sign in as guest","subtitle":"Please enter your e-mail address for IceWarp account"},"sign-in-generic":{"heading":{"conference":"Sign in to conference","oauth":"%{client} requires permissions","webclient":"Sign in to WebClient","webadmin":"Sign in to WebAdmin"}},"sign-in-password":{"forgot":"Forgot?","or":"or","remember":"Keep me signed in","
7192sign-in-with-my-service":"Sign in with my service"},"tc-actions":{"heading":"Plus button actions","subheading":"Make it easy to manage all TeamChat actions using the multi action '+' button."},"tc-check-email":{"heading":"Check your email","subheading":"Verify your email address and then use the **combination of your email address and password to join in** and chat with other users in TeamChat room **%{room}**","submit":"Go to sign in page","success-message":"Email has been verified"},"tc-collaboration":{"heading":"Collaboration in teams","subheading":"Exchange ideas, files or other data and discuss in different groups in real-time."},"tc-join":{"heading":"Join our TeamChat","subheading":"%{name} invited you to join TeamChat room _%{room}_","submit":"Verify my email address","success-message":"You have joined %{room}","username":"Name","username-helper":"Add name as it will appear in TeamChat","what-is-teamchat":"What is TeamChat?"},"tc-share":{"heading":"Share everything easily","subheading":"Drag & drop any documents or media - share and edit them right within the app."},"title":{"webadmin":"IceWarp WebAdmin","webclient":"IceWarp WebClient","oauth":"IceWarp OAuth"},"touch-id":{"heading":"Sign in with touch ID","use-password":"Use password instead"},"two_step":{"verification_code":"Verification code","heading":"Two step verification","subheading":"Please enter 6 digit code from IceWarp Authenticator app","subheading-phone":"Please enter 6 digit code sent to your phone number ending -%{phone}"},"validation":{"alpha_chars":"Field has to contain at least %{amount} letter||||Field has to contain at least %{amount} letters","email":"Invalid Email","empty":"Field cannot be empty","length":"Length must be %{amount} characters","min_length":"Minimum length is %{amount} characters","non_alpha_num_chars":"Field has to contain at least %{amount} non-alphanumeric character||||Field has to contain at least %{amount} non-alphanumeric characters","numeric_chars":"Field has to contain at least %{amount} number||||Field has to contain at least %{amount} numbers","passwords-no-match":"Passwords do not match","upper_alpha_chars":"Field has to contain at least %{amount} uppercase letter||||Field has to contain at least %{amount} uppercase letters","user_alias":"Field cannot contain username","username":"Username cannot contain \"@\" character","username-taken":"Username already taken"},"languages":{"ar":"اللغة العربية","bg":"български","cn":"简体中文","cs":"Čeština","de":"Deutsch","dk":"Dansk","el":"Ελληνικά","en":"English","es":"Español","fa":"فارسی","fi":"Suomi","fr":"Français","he":"עִבְרִית","hi":"हिन्दी","hr":"Hrvatski","hu":"Magyar","id":"Indonesia","is":"Íslenska","it":"Italiano","jp":"日本語","kr":"한국어","lv":"Latviešu","nl":"Nederlands","no":"Norsk","pl":"Polski","pt":"Português","ru":"Pусский","se":"Svenska","sk":"Slovenčina","th":"ไทย","tr":"Türkçe","ro":"Română","ua":"Українська","vi":"Tiếng Việt"}}
7193},{}],131:[function(require,module,exports){
7194module.exports={"en":{"label":"English","direction":"ltr"},"ar":{"label":"‫العربية‬","direction":"rtl"},"bg":{"label":"български език","direction":"ltr"},"cs":{"label":"čeština","direction":"ltr"},"da":{"label":"dansk","direction":"ltr"},"de":{"label":"Deutsch","direction":"ltr"},"el":{"label":"Ελληνικά","direction":"ltr"},"es":{"label":"español","direction":"ltr"},"fa":{"label":"‫فارسی‬","direction":"rtl"},"fi":{"label":"Suomen kieli","direction":"ltr"},"fr":{"label":"français","direction":"ltr"},"he":{"label":"‫עברית‬","direction":"rtl"},"hi":{"label":"हिन्दी","direction":"ltr"},"hr":{"label":"Hrvatski","direction":"ltr"},"hu":{"label":"Magyar","direction":"ltr"},"id":{"label":"Bahasa Indonesia","direction":"ltr"},"is":{"label":"Íslenska","direction":"ltr"},"it":{"label":"Italiano","direction":"ltr"},"ja":{"label":"日本語 (にほんご)","direction":"ltr"},"ko":{"label":"한국어 (韓國語)","direction":"ltr"},"la":{"label":"latine","direction":"ltr"},"lv":{"label":"latviešu valoda","direction":"ltr"},"nl":{"label":"Nederlands","direction":"ltr"},"no":{"label":"Norsk","direction":"ltr"},"pl":{"label":"Polski","direction":"ltr"},"pt":{"label":"Português","direction":"ltr"},"ro":{"label":"română","direction":"ltr"},"ru":{"label":"русский язык","direction":"ltr"},"sk":{"label":"slovenčina","direction":"ltr"},"sv":{"label":"Svenska","direction":"ltr"},"th":{"label":"ไทย","direction":"ltr"},"tr":{"label":"Türkçe","direction":"ltr"},"ua":{"label":"українська мова","direction":"ltr"},"vi":{"label":"Tiếng Việt","direction":"ltr"},"zh":{"label":"中文","direction":"ltr"}}
7195},{}
7195],132:[function(require,module,exports){
7196"use strict";
7197/**
7198 * @see {@link https://stackoverflow.com/a/48275932}
7199 * @param {*} target 
7200 * @param {*} source 
7201 */
7202function mergeDeep(target, source) {
7203	var key;
7204	if (typeof target == "object" && typeof source == "object") {
7205		for (key in source) {
7206			if (source[key] === null && (target[key] === undefined || target[key] === null)) {
7207				target[key] = null;
7208			} else if (source[key] instanceof Array) {
7209				if (!target[key]) target[key] = [];
7210				//concatenate arrays
7211				target[key] = target[key].concat(source[key]);
7212			} else if (typeof source[key] == "object") {
7213				if (!target[key]) target[key] = {};
7214				mergeDeep(target[key], source[key]);
7215			} else {
7216				target[key] = source[key];
7217			}
7218		}
7219	}
7220	return target;
7221}
7222
7223module.exports = mergeDeep;
7224
7225},{}],133:[function(require,module,exports){
7226"use strict";
7227var I18n = require('@icewarp/i18n');
7228var config = require('/tc-build/builds/e24a4084e6e20918/src/_config.json');
7229
7230/**
7231 * Init translations
7232 * @param {Object} data
7233 * @param {*} next
7234 * @returns {undefined}
7235 */
7236function i18n(data, next) {
7237	config.i18n = config.i18n || {};
7238
7239	I18n.init({
7240		url: config.i18n.url || 'locale/',
7241		map: config.i18n.map || {},
7242		expose: config.i18n.expose || '__',
7243		default_locale: config.i18n.default_locale || 'en',
7244		default_locale_dictionary: config.i18n.default_locale_dictionary || require('./../locale/en.json'),
7245		supported_languages: config.i18n.supported_languages || require('./../locale/languages.json'),
7246		external_url: config.i18n.external_url,
7247		version: config.i18n.version,
7248		project_name: config.project_name
7249	});
7250	next();
7251}
7252
7253module.exports = i18n;
7254
7255},{"./../locale/en.json":130,"./../locale/languages.json":131,"/tc-build/builds/e24a4084e6e20918/src/_config.json":368,"@icewarp/i18n":161}],134:[function(require,module,exports){
7256"use strict";
7257var Debugger = require('debugger');
7258var config = require('/tc-build/builds/e24a4084e6e20918/src/_config.json');
7259
7260/**
7261 * Init Debugger
7262 * 
7263 * @param {*} data
7264 * @param {function} next
7265 * @returns {undefined}
7266 * @ignore
7267 */
7268function initDebugger(data, next) {
7269	if(config.debugger) {
7270		window.Debugger = Debugger;
7271	}
7272
7273	config.debugger = config.debugger || {};
7274
7275	Debugger.init({
7276		level: config.debugger.level || (Debugger.levels.ERROR | Debugger.levels.EVENT | Debugger.levels.HASHCHANGE | Debugger.levels.MOUSE_TRACKING),
7277		log_length: config.debugger.log_length || 10,
7278		mouse_log_length: config.debugger.mouse_log_length || 5000,
7279		dump: {
7280			fn: function (type, data) {
7281				/* eslint-disable no-console*/
7282				console.log(type, data);
7283				/* eslint-enable no-console*/
7284			}
7285		}
7286	});
7287	next();
7288}
7289module.exports = initDebugger;
7290
7291},{"/tc-build/builds/e24a4084e6e20918/src/_config.json":368,"debugger":"debugger"}],135:[function(require,module,exports){
7292"use strict";
7293var BaseModel = require('BaseModel');
7294var BaseController = require('BaseController');
7295var Template = require('icebrace-runtime');
7296
7297/**
7298 * Environment initialization
7299 * set models, controllers, templates
7300 * 
7301 * @param {*} data
7302 * @param {function} next
7303 * @returns {undefined}
7304 * @ignore
7305 */
7306function initEnvironment(data, next) {
7307	BaseModel.setModels(require('./../models-list.js'));
7308	BaseController.setControllers(require('./../controllers-list.js'));
7309	Template.setTemplates(require('./../templates-list.js'));
7310	next();
7311}
7312
7313module.exports = initEnvironment;
7314
7315},{"./../controllers-list.js":129,"./../models-list.js":139,"./../templates-list.js":157,"BaseController":"BaseController","BaseModel":"BaseModel","icebrace-runtime":"icebrace-runtime"}],136:[function(require,module,exports){
7316"use strict";
7317var config = require('/tc-build/builds/e24a4084e6e20918/src/_config.json');
7318var BaseModel = require('BaseModel');
7319var Request = require('request');
7320var mergeDeep = require('./helpers/merge-deep');
7321
7322/**
7323 * @description Load config from URL, if provided
7324 * @param {string} url
7325 * @param {function} callback
7326 * @returns {undefined}
7327 */
7328function request(url, callback) {
7329	if (!url) {
7330		return callback();
7331	}
7332	new Request({
7333		url: url
7334	})
7335		.on('load', function(e, xhr) {
7336			try {
7337				mergeDeep(config, JSON.parse(xhr.response || xhr.responseText));
7338			} catch (e) {
7339				console.info('Error while loading config', url, 'fallback', config);
7340			}
7341			callback();
7342		})
7343		.on('error', function() {
7344			console.info('Error while loading config', url, 'fallback', config);
7345			callback();
7346		})
7347		.send();
7348}
7349
7350/**
7351 * Load config from ./_config, extend it by ./external_config.json and config from config.remote_config_url
7352 *
7353 * @param {*} data
7354 * @param {function} next
7355 * @returns {undefined}
7356 * @ignore
7357 */
7358module.exports = function(data, next) {
7359	var external_config_url =
7360		config.external_config_url ||
7361		(location.origin || location.protocol + '//' + location.hostname) +
7362			(location.pathname + '/external_config.json').replace('//', '/');
7363
7364	BaseModel.instance('Config').setData('config', config);
7365	request(external_config_url, function() {
7366		request(config.remote_config_url, next);
7367	});
7368};
7369
7370},{"./helpers/merge-deep":132,"/tc-build/builds/e24a4084e6e20918/src/_config.json":368,"BaseModel":"BaseModel","request":"request"}],137:[function(require,module,exports){
7371"use strict";
7372/**
7373 * @returns {undefined}
7374 */
7375function Middleware() {
7376	if (!arguments[0]) {
7377		throw new Error('No middlewares specified');
7378	}
7379
7380	runMiddleware(void 0, [].slice.call(arguments));
7381}
7382
7383/**
7384 * 
7385 * @param {*} data 
7386 * @param {middleware[]} middlewares 
7387 * @returns {undefined}
7388 */
7389function runMiddleware(data, middlewares) {
7390	if (!middlewares.length) {
7391		return;
7392	}
7393	middlewares.shift()(data, function(data) {
7394		runMiddleware(data, middlewares.slice(0));
7395	});
7396}
7397
7398module.exports = Middleware;
7399
7400},{}],138:[function(require,module,exports){
7401"use strict";
7402var logger = require('logger');
7403var config = require('/tc-build/builds/e24a4084e6e20918/src/_config.json');
7404
7405/**
7406 * Set logger log level
7407 * 
7408 * @param {*} data
7409 * @param {function} next
7410 * @returns {undefined}
7411 * @ignore
7412 */
7413function setLogLevel(data, next) {
7414	logger.setLevel((config.logger || {}).level || (logger.INFO | logger.WARN | logger.ERROR));
7415	next();
7416}
7417module.exports = setLogLevel;
7418
7419},{"/tc-build/builds/e24a4084e6e20918/src/_config.json":368,"logger":"logger"}],139:[function(require,module,exports){
7420"use strict";
7421module.exports={'Config':function(){return require('./models/Config.js')},'LegacyURL':function(){return require('./models/LegacyURL.js')},'OAuth':function(){return require('./models/OAuth.js')},'Login':function(){return require('./models/Login.js')},'Server':function(){return require('./models/Server.js')},'Validator':function(){return require('./models/Validator.js')},'WebClient':function(){return require('./models/WebClient.js')},'Setting':function(){return require('./models/WebClientSettings/Setting.js')},'Settings':function(){return require('./models/WebClientSettings/Settings.js')},'banner_options':function(){return require('./models/WebClientSettings/banner_options.js')},'custom_login_fields':function(){return require('./models/WebClientSettings/custom_login_fields.js')},'language':function(){return require('./models/WebClientSettings/language.js')},'layout_settings':function(){return require('./models/WebClientSettings/layout_settings.js')},'password_policy':function(){return require('./models/WebClientSettings/password_policy.js')},'restrictions':function(){return require('./models/WebClientSettings/restrictions.js')},'reset_settings':function(){return require('./models/WebClientSettings/reset_settings.js')},'signup_domain':function(){return require('./models/WebClientSettings/signup_domain.js')}};
7422},{"./models/Config.js":140,"./models/LegacyURL.js":141,"./models/Login.js":142,"./models/OAuth.js":143,"./models/Server.js":144,"./models/Validator.js":145,"./models/WebClient.js":146,"./models/WebClientSettings/Setting.js":147,"./models/WebClientSettings/Settings.js":148,"./models/WebClientSettings/banner_options.js":149,"./models/WebClientSettings/custom_login_fields.js":150,"./models/WebClientSettings/language.js":151,"./models/WebClientSettings/layout_settings.js":152,"./models/WebClientSettings/password_policy.js":153,"./models/WebClientSettings/reset_settings.js":154,"./models/WebClientSettings/restrictions.js":155,"./models/WebClientSettings/signup_domain.js":156}],140:[function(require,module,exports){
7423"use strict";
7424var BaseModel = require('BaseModel');
7425
7426var Config = BaseModel.create('Config');
7427
7428Config.singleton = true;
7429
7430module.exports = Config;
7431
7432},{"BaseModel":"BaseModel"}],141:[function(require,module,exports){
7433"use strict";
7434var BaseModel = require('BaseModel');
7435var Hash = require('@icewarp/hash');
7436var LegacyURL = BaseModel.create('LegacyURL');
7437var QueryParams = require('@icewarp/query-params');
7438
7439var legacy = function () {
7440	return {
7441		atoken: BaseModel.instance('Login').getDefaultCard(),
7442		resetpwd: 'reset-password',
7443		changePwd: 'change-password',
7444		changepwd: 'change-password',
7445		reset: 'forgot-password',
7446		selfSignUp: 'create-account',
7447		guestSignUp: 'tc-join',
7448		guestVerify: 'guest-verify',
7449		'_s[action]': {
7450			error: BaseModel.instance('Login').getDefaultCard()
7451		},
7452		action: {
7453			confirm_personality: 'confirm-personality'
7454		},
7455		view: {
7456			gateway_login: 'gateway-login'
7457		},
7458		username: 'sign-in',
7459		eid: BaseModel.instance('Login').getDefaultCard(),
7460		tconly: 'generic-message',
7461		auth_id: 'oauth-grant'
7462	};
7463};
7464
7465LegacyURL.redirect = function () {
7466	var parts = QueryParams.parse(),
7467		type,
7468		site;
7469
7470	var Legacy = legacy();
7471	for (type in Legacy) {
7472		site =
7473			typeof Legacy[type] === 'string' && parts[type]
7474				? Legacy[type]
7475				: (Legacy[type] || {})[parts[type]];
7476		if (site) {
7477			return Hash.change(
7478				site,
7479				parts,
7480				true,
7481				false,
7482				location.protocol +
7483					'//' +
7484					location.host +
7485					location.pathname +
7486					'?legacy'
7487			);
7488		}
7489	}
7490};
7491
7492module.exports = LegacyURL;
7493
7494},{"@icewarp/hash":160,"@icewarp/query-params":170,"BaseModel":"BaseModel"}],142:[function(require,module,exports){
7495"use strict";
7496var BaseModel = require('BaseModel');
7497var Login = BaseModel.create('Login');
7498var LocalStorage = require('@icewarp/localstorage');
7499var i18n = require('@icewarp/i18n');
7500var CssLoader = require('@icewarp/css-loader');
7501
7502Login.singleton = true;
7503
7504Login.guestLoginURL = 'https://external-users.stage1.k8s.icewarp.com/app/';
7505Login.prototype.onCreate = function () {
7506	this.setData('guestLogin', false)
7507		.setData('useRSA', true)
7508		.setData('chosen_account', {})
7509		.setData('create_account', {});
7510};
7511
7512Login.prototype.getUser = function (email) {
7513	return this.getUsers().filter(function (user) {
7514		return user.email === email;
7515	})[0];
7516};
7517
7518Login.prototype.getUsers = function () {
7519	!LocalStorage.getItem('logins') && LocalStorage.setItem('logins', []);
7520	return LocalStorage.getItem('logins');
7521};
7522
7523Login.prototype.removeUser = function (condition) {
7524	LocalStorage.setItem('logins', this.getUsers().filter(function (login) {
7525		return !Object.keys(condition).some(function (key) {
7526			return login[key] === condition[key];
7527		});
7528	}));
7529	return this;
7530};
7531
7532Login.prototype.addUser = function (new_user) {
7533	var logins, i;
7534	if (BaseModel.instance('WebClient').getData('restrictions').getValue('disable_autofill')) {
7535		return this;
7536	}
7537	logins = this.getUsers();
7538	logins.unshift(new_user);
7539	new_user.color = new_user.color || Math.floor(Math.random() * 6);
7540	LocalStorage.setItem('logins', logins.filter(function (value, index, arr) {
7541		var found = false;
7542		for (i = 0; i <= index; i++) {
7543			if (arr[i].email === value.email) {
7544				found = i;
7545				break;
7546			}
7547		}
7548		return index === found;
7549	}));
7550	return this;
7551};
7552
7553Login.prototype.getDefaultCard = function () {
7554	return (this.getUsers().length && !BaseModel.instance('WebClient').getData('restrictions').getValue('disable_autofill')) ? ((this.getData('chosen_account') || {}).email ? 'sign-in-password' : 'choose-account') : 'sign-in';
7555};
7556
7557Login.prototype.getAuthChallenge = function (callback) {
7558	this.callCommunication('getAuthChallenge', callback);
7559};
7560
7561Login.prototype.usernameAvailable = function (data, callback) {
7562	this.callCommunication('usernameAvailable', data, callback);
7563};
7564
7565Login.prototype.getVerification = function (data, callback) {
7566	this.callCommunication('getVerification', data, {
7567		success: function (verification_id) {
7568			this.getData('create_account').verificationrequest = {
7569				id: verification_id
7570			};
7571			callback.success.call(callback.context);
7572		},
7573		error: function () {
7574			callback.error.apply(callback.context, arguments);
7575		},
7576		context: this
7577	});
7578};
7579
7580Login.prototype.logoutTeamChatOnly = function (data, callback) {
7581	this.callCommunication('logoutTeamChatOnly', data, callback);
7582};
7583
7584
7585Login.prototype.isGuestDomain = function (data, callback) {
7586	this.callCommunication('isGuestDomain', data, callback);
7587};
7588
7589Login.prototype.changeLanguage = function (language, callback) {
7590	var Language = BaseModel.static('language');
7591	i18n.changeLanguage(Language.codes_reversed[language] || language, changeLanguage.bind(null, callback), changeLanguage.bind(null, callback));
7592};
7593
7594Login.prototype.guestLogin = function(data) {
7595	var config = BaseModel.instance('Config').getData('config') || {};
7596	if (data.email) {
7597		this.addUser({
7598			email: data.email,
7599			guestLogin: true
7600		});
7601		data.service_provider = 'email';
7602	}
7603	document.location = (config.guest_login_url || Login.guestLoginURL) + (data.email || '') + '?service_provider=' + data.service_provider + '&iw_host=' + location.hostname + '&iw_access=standard&autologin=webclient&autologout=1';
7604};
7605
7606/**
7607 * 
7608 * @param {Object} callback
7609 * @param {String} language_code 
7610 * @returns {undefined}
7611 */
7612function changeLanguage(callback, language_code) {
7613	var WebClient = BaseModel.instance('WebClient');
7614	var styles = [].map.call(document.head.querySelectorAll('meta[name="stylesheet"]'), function (meta) {
7615		return document.head.querySelector('style[content="' + meta.getAttribute('content') + '"], link[href^="' + meta.getAttribute('content') + '"]');
7616	}).filter(Boolean);
7617	var codes = BaseModel.static('language').codes;
7618	language_code = codes[language_code] || language_code;
7619
7620	WebClient.getData('layout_settings').setUserLanguageCode(language_code);
7621
7622	document.body.setAttribute('dir', WebClient.getData('layout_settings').getUserLanguage().isRTL() ? 'rtl' : 'ltr');
7623	CssLoader.setRTL(WebClient.getData('layout_settings').getUserLanguage().isRTL(), function () {
7624		var color, colors = {};
7625		getComputedStyle(document.getElementById('theme-colors')).getPropertyValue('font-family').replace(/([\w-]+):(#\w+),?/g, function (all, key, value) {
7626			colors[key] = value;
7627		});
7628		color = WebClient.getData('layout_settings').getValue('login_color');
7629
7630		CssLoader.load(function () {
7631			styles.forEach(function (style) {
7632				style.parentNode.removeChild(style);
7633			});
7634			callback.success && callback.success.call(callback.context || this);
7635		}, {
7636			'theme-color': colors[color],
7637			'theme-grey-color': colors[color + '-grey'],
7638			'theme-light-grey-color': colors[color + '-light-grey']
7639		});
7640	});
7641}
7642
7643module.exports = Login;
7644
7645},{"@icewarp/css-loader":158,"@icewarp/i18n":161,"@icewarp/localstorage":167,"BaseModel":"BaseModel"}],143:[function(require,module,exports){
7646"use strict";
7647var OldCommunication = require('@icewarp/old-communication');
7648var Hash = require('@icewarp/hash');
7649var BaseModel = require('BaseModel');
7650const Callback = require('Callback');
7651var OAuth = BaseModel.create('OAuth');
7652
7653OAuth.singleton = true;
7654
7655/**
7656 *
7657 *
7658 * @param {Callback} callback
7659 * @param {function} sideEffect
7660 * @returns {Callback}
7661 */
7662function callbackChainBuilder(callback) {
7663	var effects = [].slice.call(arguments, 1);
7664	var context =
7665		typeof effects[effects.length - 1] !== 'function'
7666			? effects.pop()
7667			: null;
7668	var constructed_callback = callback;
7669	effects.reverse().forEach(function (sideEffect) {
7670		var current_level = constructed_callback;
7671		constructed_callback = {
7672			success: function (result) {
7673				sideEffect.call(
7674					context || null,
7675					{
7676						success: function () {
7677							current_level.success.apply(
7678								current_level.context,
7679								arguments
7680							);
7681						},
7682						error: function () {
7683							current_level.error.apply(
7684								current_level.context,
7685								arguments
7686							);
7687						}
7688					},
7689					result
7690				);
7691			},
7692			error: function () {
7693				current_level.error.apply(current_level.context, arguments);
7694			},
7695			context: current_level.context
7696		};
7697	});
7698	return constructed_callback;
7699}
7700
7701/**
7702 *
7703 * @description Creates new Connection with admin SID
7704 * @param {string} sid - session id
7705 * @returns {undefined}
7706 */
7707OAuth.prototype.createAuthConnection = function (sid) {
7708	new OldCommunication(OldCommunication.XHR, 'admin-auth', {
7709		host:
7710			(BaseModel.instance('Config').getData('config').icewarpapiUrl ||
7711				'//' + location.host + '/icewarpapi') + '/',
7712		xmlns: 'admin:iq:rpc',
7713		session_id: sid
7714	});
7715};
7716
7717/**
7718 * @description Set initial data to the model
7719 * @property {string} auth_id - ID of the auth request, used for grant
7720 * @property {string} email - Email of the user that should grant access
7721 * @property {array} scopes - Array of scopes that user should grant to the application
7722 * @returns {undefined}
7723 */
7724OAuth.prototype.onCreate = function () {
7725	this.setData('account_data', null).initArray('scopes');
7726};
7727
7728OAuth.prototype.initAlreadyLoggedIn = function (callback) {
7729	var constructed_callback = callbackChainBuilder(
7730		callback,
7731		function (callback, result) {
7732			this.getAccountDetail(result.email, callback);
7733		},
7734		function (callback, account) {
7735			this.setData('account_data', account);
7736			this.GetOauthAuthorizationRequest(callback);
7737		},
7738		function (callback, response) {
7739			var prop;
7740			for (prop in response) {
7741				if (response[prop] && response[prop].item !== void 0) {
7742					this.setData(
7743						prop,
7744						Array.isArray(response[prop].item)
7745							? response[prop].item
7746							: [response[prop].item]
7747					);
7748				} else {
7749					this.setData(prop, response[prop]);
7750				}
7751			}
7752			this.GetOauthClientInfo(response.clientid, callback);
7753		},
7754		function (callback, response) {
7755			var prop;
7756			for (prop in response) {
7757				this.setData(prop, response[prop]);
7758			}
7759			callback.success.call(callback.context);
7760		},
7761		this
7762	);
7763	this.getSessionInfo(constructed_callback);
7764};
7765
7766/**
7767 * @param {string} email
7768 * @param {string} password
7769 * @param {Number} authtype
7770 * @param {Callback} callback
7771 * @returns {undefined}
7772 */
7773OAuth.prototype.login = function (email, password, authtype, callback) {
7774	var constructed_callback = callbackChainBuilder(
7775		callback,
7776		function (callback, sid) {
7777			this.createAuthConnection(sid);
7778			this.getAccountDetail(email, callback);
7779		},
7780		function (callback, account) {
7781			this.setData('account_data', account);
7782			this.GetOauthAuthorizationRequest(callback);
7783		},
7784		function (callback, response) {
7785			var prop;
7786			for (prop in response) {
7787				if (response[prop] && response[prop].item !== void 0) {
7788					this.setData(
7789						prop,
7790						Array.isArray(response[prop].item)
7791							? response[prop].item
7792							: [response[prop].item]
7793					);
7794				} else {
7795					this.setData(prop, response[prop]);
7796				}
7797			}
7798			this.GetOauthClientInfo(response.clientid, callback);
7799		},
7800		function (callback, response) {
7801			var prop;
7802			for (prop in response) {
7803				this.setData(prop, response[prop]);
7804			}
7805			callback.success.call(callback.context);
7806		},
7807		this
7808	);
7809	this.callCommunication(
7810		'login',
7811		{
7812			user: email,
7813			password: password,
7814			authtype: authtype
7815		},
7816		constructed_callback
7817	);
7818};
7819
7820/**
7821 * @description Gets detail of the logged in account, this data should be used for card heading and avatar
7822 * @param {String} email
7823 * @param {Callback} callback
7824 * @returns {undefined}
7825 */
7826OAuth.prototype.getAccountDetail = function (email, callback) {
7827	return this.callCommunication(
7828		'getAccountDetail',
7829		{
7830			email: email
7831		},
7832		callback
7833	);
7834};
7835
7836/**
7837 * @description Get information about currently active session
7838 * @param {Callback} callback
7839 * @returns {undefined}
7840 */
7841OAuth.prototype.getSessionInfo = function (callback) {
7842	return this.callCommunication('GetSessionInfo', {}, callback);
7843};
7844
7845OAuth.prototype.checkExistingGrant = function (callback) {
7846	var auth_id = Hash.getParts().auth_id;
7847
7848	if (!auth_id) {
7849		return Callback(Callback.SUCCESS, callback, {});
7850	}
7851
7852	return this.callCommunication(
7853		'OauthAuthorizationExists',
7854		{
7855			requestid: Hash.getParts().auth_id
7856		},
7857		callback
7858	);
7859};
7860
7861OAuth.prototype.GetOauthClientInfo = function (clientid, callback) {
7862	if (!clientid) {
7863		return Callback(Callback.SUCCESS, callback, {});
7864	}
7865
7866	return this.callCommunication(
7867		'GetOauthClientInfo',
7868		{
7869			clientid: clientid
7870		},
7871		callback
7872	);
7873};
7874
7875OAuth.prototype.GetOauthAuthorizationRequest = function (callback) {
7876	var auth_id = Hash.getParts().auth_id;
7877
7878	if (!auth_id) {
7879		return Callback(Callback.SUCCESS, callback, {});
7880	}
7881
7882	return this.callCommunication(
7883		'GetOauthAuthorizationRequest',
7884		{
7885			requestid: Hash.getParts().auth_id
7886		},
7887		callback
7888	);
7889};
7890
7891/**
7892 * @description Grant app permissions to access required scopes
7893 * @param {String} description
7894 * @param {Callback} callback
7895 * @returns {undefined}
7896 */
7897OAuth.prototype.GrantOauthAuthorization = function (description, callback) {
7898	return this.callCommunication(
7899		'GrantOauthAuthorization',
7900		{
7901			requestid: Hash.getParts().auth_id,
7902			description: description
7903		},
7904		callback
7905	);
7906};
7907
7908OAuth.prototype.getRedirectURL = function () {
7909	return '/oauth/v2/code?auth_id=' + Hash.getParts().auth_id;
7910};
7911
7912module.exports = OAuth;
7913
7914},{"@icewarp/hash":160,"@icewarp/old-communication":168,"BaseModel":"BaseModel","Callback":"Callback"}],144:[function(require,module,exports){
7915"use strict";
7916var BaseModel = require('BaseModel');
7917var Server = BaseModel.create('Server');
7918
7919Server.singleton = true;
7920
7921Server.prototype.getLogo = function () {
7922	return this.getResource({class: 'logo', fullpath: document.location.hostname, uid: BaseModel.instance('WebClient').getData('layout_settings').getValue('logo_uid')});
7923};
7924
7925Server.prototype.getBackground = function (width, height) {
7926	return this.getResource({
7927		class: 'background',
7928		fullpath: document.location.hostname,
7929		uid: BaseModel.instance('WebClient').getData('layout_settings').getValue('login_background_uid').toString().substring(0, 32),
7930		resize: 1,
7931		width: width || (window.screen.width * window.devicePixelRatio),
7932		height: height || (window.screen.height * window.devicePixelRatio)
7933	});
7934};
7935
7936Server.noCacheHash = (0 | Math.random() * 6.04e7).toString(36);
7937Server.prototype.getAvatar = function (data) {
7938	var config = BaseModel.instance('Config').getData('config');
7939	data.internal = 1;
7940	data.uid = Server.noCacheHash;
7941	return this.getResource(data, config.avatarResourcePath);
7942};
7943
7944Server.prototype.getResource = function (data, resourcePath) {
7945	var config = BaseModel.instance('Config').getData('config');
7946	return document.location.origin + (resourcePath || (document.location.pathname + config.resourcePath)) + '?' + Object.keys(data).map(function (key) {
7947		return key + '=' + data[key];
7948	}).join('&');
7949};
7950
7951module.exports = Server;
7952
7953},{"BaseModel":"BaseModel"}],145:[function(require,module,exports){
7954"use strict";
7955var BaseModel = require('BaseModel');
7956var Validator = BaseModel.create('Validator');
7957
7958/**
7959 * @param {Object} options 
7960 * @param {String} value 
7961 * @returns {Boolean}
7962 */
7963function same(options, value) {
7964	return (options.counterpart_value || options.controller.closestHook(options.parent_hook).querySelector('[data-hook="' + options.counterpart_hook + '"]').value) === value;
7965}
7966
7967/**
7968 * @param {Object} options 
7969 * @param {String} value 
7970 * @returns {Boolean}
7971 */
7972function contains(options, value) {
7973	return !!(value.match(new RegExp(options.counterpart_value === void 0 ? options.controller.closestHook(options.parent_hook).querySelector('[data-hook="' + options.counterpart_hook + '"]').value : options.counterpart_value, 'gi')) || []).length;
7974}
7975
7976Validator.prototype.empty = function (options, value, callback) {
7977	callback(value.trim().length);
7978};
7979Validator.prototype.length = function (options, value, callback) {
7980	callback(value.trim().length === +options.data);
7981};
7982Validator.prototype.min_length = function (options, value, callback) {
7983	callback(value.trim().length >= options.data);
7984};
7985Validator.prototype.numeric_chars = function (options, value, callback) {
7986	callback((value.match(/\d/g) || []).length >= options.data);
7987};
7988Validator.prototype.non_alpha_num_chars = function (options, value, callback) {
7989	callback((value.match(/[^A-Za-z0-9]/g) || []).length >= options.data);
7990};
7991Validator.prototype.alpha_chars = function (options, value, callback) {
7992	callback((value.match(/\w/g) || []).length >= options.data);
7993};
7994Validator.prototype.upper_alpha_chars = function (options, value, callback) {
7995	callback((value.match(/[A-Z]/g) || []).length >= options.data);
7996};
7997Validator.prototype.email = function (options, value, callback) {
7998	callback(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(value));
7999};
8000Validator.prototype.same = function (options, value, callback) {
8001	callback(same(options, value));
8002};
8003Validator.prototype.different = function (options, value, callback) {
8004	callback(!same(options, value));
8005};
8006Validator.prototype.contains = function (options, value, callback) {
8007	callback(contains(options, value));
8008};
8009Validator.prototype.not_contains = function (options, value, callback) {
8010	callback(!contains(options, value));
8011};
8012Validator.prototype.callback = function (options, value, callback) {
8013	options.callback(value, callback);
8014};
8015module.exports = Validator;
8016
8017},{"BaseModel":"BaseModel"}],146:[function(require,module,exports){
8018"use strict";
8019var BaseModel = require('BaseModel');
8020var WebClient = BaseModel.create('WebClient');
8021
8022WebClient.singleton = true;
8023
8024WebClient.prototype.onCreate = function () {
8025	this.initArray('languages');
8026	this.initArray('signup_domains');
8027	this.setData('custom_login_fields', BaseModel.instance('custom_login_fields'));
8028	this.setData('layout_settings', BaseModel.instance('layout_settings'));
8029	this.setData('password_policy', BaseModel.instance('password_policy'));
8030	this.setData('reset_settings', BaseModel.instance('reset_settings'));
8031	this.setData('restrictions', BaseModel.instance('restrictions'));
8032	this.setData('banner_options', BaseModel.instance('banner_options'));
8033};
8034
8035WebClient.prototype.initialize = function (data) {
8036	var lvl0 = Array.isArray(data.list.item) ? data.list.item : [data.list.item];
8037	var lvl2, i, lvl1, j;
8038	for (i in lvl0) {
8039		lvl1 = lvl0[i];
8040		switch (lvl1.name) {
8041			case 'languages':
8042				lvl2 = Array.isArray(lvl1.list.item) ? lvl1.list.item : [lvl1.list.item];
8043				for (j in lvl2) {
8044					this.pushData('languages', BaseModel.instance('language').initialize(lvl2[j].list.item));
8045				}
8046				break;
8047			case 'signup_domains':
8048				if (!lvl1.list.item.list) {
8049					continue;
8050				}
8051				lvl2 = Array.isArray(lvl1.list.item.list.item) ? lvl1.list.item.list.item : [lvl1.list.item.list.item];
8052				for (j in lvl2) {
8053					this.pushData('signup_domains', BaseModel.instance('signup_domain').initialize(lvl2[j]));
8054				}
8055				break;
8056			default:
8057				if (!lvl1.list || !lvl1.list.item) {
8058					continue;
8059				}
8060				lvl2 = Array.isArray(lvl1.list.item) ? lvl1.list.item : [lvl1.list.item];
8061				for (j in lvl2) {
8062					lvl2[j].list && lvl2[j].list.item && this.setData(lvl1.name, BaseModel.instance(lvl1.name).initialize(lvl2[j].list.item));
8063				}
8064		}
8065	}
8066	this.setData('settings_loaded', true);
8067
8068	return this;
8069};
8070
8071/**
8072 *
8073 * @param {function} encrypt
8074 * @param {@icewarp/callback} callback callback object
8075 * @returns {undefined}
8076 */
8077WebClient.prototype.signupAccount = function (encrypt, callback) {
8078	var Login = BaseModel.instance('Login');
8079	var i, data = {};
8080	for (i in Login.getData('create_account')) {
8081		data[i] = Login.getData('create_account')[i];
8082	}
8083
8084	data.password = encrypt(Login.getData('create_account').password);
8085	data.authtype = +Login.getData('useRSA');
8086	this.callCommunication('signupAccount', data, {
8087		success: function() {
8088			Login.addUser(Login.getData('chosen_account'));
8089			Login.setData('create_account', {card: {}});
8090			callback.success.call(callback.context);
8091		},
8092		error: function(response) {
8093			callback.error.call(callback.context, response);
8094		},
8095		context: callback.context
8096	});
8097};
8098
8099WebClient.prototype.getAuthToken = function(data, callback) {
8100	this.callCommunication('getAuthToken', data, {
8101		success: function(response) {
8102			var config = BaseModel.instance('Config').getData('config');
8103			var LocalStorage = require('@icewarp/localstorage');
8104			var punycode = require('punycode');
8105			var Login = BaseModel.instance('Login');
8106			var chosen_account = Login.getData('chosen_account');
8107			chosen_account.name = [response.name.name || '', response.name.surname || ''].join(' ').trim();
8108			chosen_account.email = punycode.toUnicode(response.email || '');
8109			chosen_account.avatar_token = response.avatartoken;
8110			Login.setData('chosen_account', chosen_account);
8111			if (this.getData('restrictions').getValue('remember_login_accounts')) {
8112				Login.addUser(Login.getData('chosen_account'));
8113				LocalStorage.setItem('last-login-' + config.application, response);
8114			}
8115			callback.success.call(callback.context, response);
8116		},
8117		error: function(error, response) {
8118			callback.error.call(callback.context, error, response);
8119		},
8120		context: this
8121	});
8122};
8123
8124WebClient.prototype.getCaptcha = function(callback) {
8125	this.callCommunication('getCaptcha', callback);
8126};
8127
8128WebClient.prototype.changePassword = function(data, callback) {
8129	this.callCommunication('changePassword', data, callback);
8130};
8131
8132WebClient.prototype.resetPassword = function(data, callback) {
8133	this.callCommunication('resetPassword', data, callback);
8134};
8135
8136WebClient.prototype.confirmPersonality = function(data, callback) {
8137	this.callCommunication('confirmPersonality', data, callback);
8138};
8139
8140WebClient.prototype.contactAdministrator = function(data, callback) {
8141	this.callCommunication('contactAdministrator', data, callback);
8142};
8143
8144WebClient.prototype.resetPasswordEmail = function(data, callback) {
8145	this.callCommunication('resetPasswordEmail', data, callback);
8146};
8147
8148WebClient.prototype.sendGatewayAuthentication = function(data, callback) {
8149	this.callCommunication('sendGatewayAuthentication', data, callback);
8150};
8151
8152WebClient.prototype.guestConfirm = function(data, callback) {
8153	this.callCommunication('guestConfirm', data, callback);
8154};
8155
8156WebClient.prototype.guestVerify = function(data, callback) {
8157	this.callCommunication('guestVerify', data, callback);
8158};
8159
8160module.exports = WebClient;
8161
8162},{"@icewarp/localstorage":167,"BaseModel":"BaseModel","punycode":355}],147:[function(require,module,exports){
8163"use strict";
8164var BaseModel = require('BaseModel');
8165var Setting = BaseModel.create('Setting');
8166
8167Setting.prototype.onCreate = function () {
8168	this.setData('domainadminaccesslevel', 0)
8169		.setData('useraccesslevel', 0)
8170		.setData('accesslevel', 0)
8171		.setData('name', '')
8172		.setData('value', '')
8173		.setData('setdefault', 0);
8174};
8175
8176Setting.prototype.initialize = function (data) {
8177	var key;
8178	for (key in data) {
8179		data[key] !== null && data[key] !== void 0 && this.setData(key, parseInt(data[key]) == data[key] ? parseInt(data[key]) : data[key]);
8180	}
8181
8182	return this;
8183};
8184
8185module.exports = Setting;
8186
8187},{"BaseModel":"BaseModel"}],148:[function(require,module,exports){
8188"use strict";
8189var BaseModel = require('BaseModel');
8190var Settings = BaseModel.create('Settings');
8191
8192Settings.singleton = true;
8193
8194Settings.prototype.initialize = function (data) {
8195	var j;
8196	data = Array.isArray(data) ? data : [data];
8197	for (j in data) {
8198		this.setData(data[j].name, BaseModel.instance('Setting', data[j].name).initialize(data[j]));
8199	}
8200
8201	return this;
8202};
8203
8204Settings.prototype.getValue = function (name) {
8205	return this.getData(name) ? this.getData(name).getData('value') : void 0;
8206};
8207
8208module.exports = Settings;
8209
8210},{"BaseModel":"BaseModel"}],149:[function(require,module,exports){
8211"use strict";
8212var BaseModel = require('BaseModel');
8213var Settings = require('./Settings');
8214var banner_options = BaseModel.create('banner_options', Settings);
8215
8216banner_options.prototype.onCreate = function () {
8217	[
8218		{name: 'top_type', value: 'none'},
8219		{name: 'top_url', value: ''},
8220		{name: 'top_code', value: ''},
8221		{name: 'below_type', value: 'none'},
8222		{name: 'below_url', value: ''},
8223		{name: 'below_code', value: ''},
8224		{name: 'desktop_type', value: 'none'},
8225		{name: 'desktop_url', value: ''},
8226		{name: 'desktop_code', value: ''},
8227		{name: 'mobile_type', value: 'none'},
8228		{name: 'mobile_url', value: ''},
8229		{name: 'mobile_code', value: ''},
8230		{name: 'customer_id', value: ''}
8231	].forEach(function (setting) {
8232		this.setData(setting.name, BaseModel.instance('Setting', setting.name).initialize(setting));
8233	}, this);
8234};
8235
8236module.exports = banner_options;
8237
8238},{"./Settings":148,"BaseModel":"BaseModel"}],150:[function(require,module,exports){
8239"use strict";
8240var BaseModel = require('BaseModel');
8241var Settings = require('./Settings');
8242var custom_login_fields = BaseModel.create('custom_login_fields', Settings);
8243
8244var available_custom_fields = [
8245	{
8246		id: 'nickname',
8247		name: 'nickname',
8248		label: __('personal.nickname')
8249	}, {
8250		id: 'birthday',
8251		name: 'birthday',
8252		label: __('personal.birthday'),
8253		type: 'date',
8254		maxDate: new Date()
8255	}, {
8256		id: 'company',
8257		name: 'companyname',
8258		label: __('personal.company')
8259	}, {
8260		id: 'job',
8261		name: 'jobtitle',
8262		label: __('personal.job')
8263	}, {
8264		id: 'profession',
8265		name: 'profession',
8266		label: __('personal.profession')
8267	}, {
8268		id: 'mobile_phone',
8269		name: 'mobiletelephonenumber',
8270		label: __('personal.mobile-phone'),
8271		type: 'tel'
8272	}, {
8273		id: 'work_phone',
8274		name: 'businesstelephonenumber',
8275		label: __('personal.work-phone'),
8276		type: 'tel'
8277	}, {
8278		id: 'home_phone',
8279		name: 'hometelephonenumber',
8280		label: __('personal.home-phone'),
8281		type: 'tel'
8282	}, {
8283		id: 'im',
8284		name: 'imaddress',
8285		label: __('personal.im')
8286	}, {
8287		id: 'gender',
8288		name: 'gender',
8289		label: __('personal.gender'),
8290		type: 'select',
8291		options: [
8292			{
8293				text: '',
8294				value: 0
8295			},
8296			{
8297				text: __('generic.male'),
8298				value: 2
8299			},
8300			{
8301				text: __('generic.female'),
8302				value: 1
8303			}
8304		]
8305	}, {
8306		id: 'homepage',
8307		name: 'homepage',
8308		label: __('personal.homepage')
8309	}
8310];
8311
8312custom_login_fields.prototype.onCreate = function () {
8313	[{name: 'login_verification_enabled', value: 0},
8314		{name: 'login_verification_type', value: 'none'}
8315	].forEach(function (setting) {
8316		this.setData(setting.name, BaseModel.instance('Setting', setting.name).initialize(setting));
8317	}, this);
8318};
8319
8320custom_login_fields.prototype.enabledCustomFields = function () {
8321	var WebClient = BaseModel.instance('WebClient');
8322	return available_custom_fields.map(function (field) {
8323		if (field.id === 'mobile_phone' && WebClient.getData('custom_login_fields').getValue('login_verification_enabled') && (WebClient.getData('custom_login_fields').getValue('login_verification_type') === 'sms')) {
8324			return field;
8325		}
8326		return this.getValue(field.id + '_enabled') ? field : false;
8327	}, this).filter(Boolean);
8328};
8329
8330module.exports = custom_login_fields;
8331
8332},{"./Settings":148,"BaseModel":"BaseModel"}],151:[function(require,module,exports){
8333"use strict";
8334var BaseModel = require('BaseModel');
8335var language = BaseModel.create('language');
8336
8337language.codes = {
8338	zh: 'cn',
8339	da: 'dk',
8340	ja: 'jp',
8341	ko: 'kr',
8342	sv: 'se'
8343};
8344
8345language.codes_reversed = {
8346	cn: 'zh',
8347	dk: 'da',
8348	jp: 'ja',
8349	kr: 'ko',
8350	se: 'sv'
8351};
8352
8353language.prototype.initialize = function (data) {
8354	var k;
8355	data = Array.isArray(data) ? data : [data];
8356	for (k in data) {
8357		if (data[k].name === 'code') {
8358			data[k].value = language.codes[data[k].value] || data[k].value;
8359		}
8360		this.setData(data[k].name, BaseModel.instance('Setting').initialize(data[k]));
8361	}
8362
8363	return this;
8364};
8365
8366language.prototype.isRTL = function () {
8367	return this.getValue('rtl') === 'true';
8368};
8369
8370language.prototype.getValue = function (name) {
8371	return this.getData(name).getData('value');
8372};
8373
8374module.exports = language;
8375
8376},{"BaseModel":"BaseModel"}],152:[function(require,module,exports){
8377"use strict";
8378var BaseModel = require('BaseModel');
8379var LocalStorage = require('@icewarp/localstorage');
8380var Settings = require('./Settings');
8381var layout_settings = BaseModel.create('layout_settings', Settings);
8382
8383var detected_language;
8384
8385layout_settings.prototype.onCreate = function () {
8386	var config = BaseModel.instance('Config').getData('config');
8387	[{name: 'language', value: 'en'},
8388		{name: 'logo_uid', value: ''},
8389		{name: 'login_background_uid', value: ''},
8390		{name: 'login_background_color', value: ''},
8391		{name: 'login_background_solid', value: false},
8392		{name: 'login_background_wallpaper_size', value: 'cover'},
8393		{name: 'login_interface_color', value: 'background'},
8394		{name: 'login_title', value: __('title.' + config.application)},
8395		{name: 'title', value: __('title.' + config.application)},
8396		{name: 'skin_style', value: 'blue'},
8397		{name: 'login_color', value: 'default'},
8398		{name: 'website_link', value: ''},
8399		{name: 'facebook_link', value: 'https://www.facebook.com/IceWarpInc'},
8400		{name: 'twitter_link', value: 'https://twitter.com/icewarp'},
8401		{name: 'linkedin_link', value: 'https://www.linkedin.com/company/IceWarp'},
8402		{name: 'disable_copyright', value: false},
8403		{name: 'search_phrase', value: ''}
8404	].forEach(function (setting) {
8405		this.setData(setting.name, BaseModel.instance('Setting', setting.name).initialize(setting));
8406	}, this);
8407};
8408
8409/**
8410 * @returns {String}
8411 */
8412function getBrowserLanguageCode() {
8413	var browser_languages, allowed_languages, index, language,
8414		WebClient = BaseModel.instance('WebClient'),
8415		Language = BaseModel.static('language');
8416	if (detected_language !== void 0) {
8417		return detected_language;
8418	}
8419	browser_languages = (navigator.languages || []).concat([navigator.language || navigator.userLanguage]);
8420	allowed_languages = WebClient.getData('languages').map(function (language) {
8421		return Language.codes_reversed[language.getValue('code')] || language.getValue('code');
8422	});
8423	detected_language = false;
8424	for (index in browser_languages) {
8425		language = browser_languages[index].split('-')[0].toLowerCase();
8426		if (~allowed_languages.indexOf(language)) {
8427			detected_language = language;
8428			break;
8429		}
8430	}
8431	return detected_language;
8432}
8433
8434layout_settings.prototype.getDefaultLanguageCode = function () {
8435	var WebClient = BaseModel.instance('WebClient');
8436	return WebClient.getData('restrictions').getValue('disable_languages') ? this.getValue('language') : this.getUserLanguageCode();
8437};
8438
8439layout_settings.prototype.getUserLanguageCode = function () {
8440	return LocalStorage.getItem('language') || getBrowserLanguageCode() || this.getValue('language') || 'en';
8441};
8442
8443layout_settings.prototype.setUserLanguageCode = function (language) {
8444	LocalStorage.setItem('language', language);
8445};
8446
8447layout_settings.prototype.getUserLanguage = function () {
8448	var i;
8449	var browser_language;
8450	var default_language;
8451	var ulc = this.getUserLanguageCode();
8452	var blc = getBrowserLanguageCode();
8453	var languages = BaseModel.instance('WebClient').getData('languages') || [];
8454	var lang_length = languages.length;
8455	for (i = 0; i < lang_length; i++) {
8456		switch (languages[i].getValue('code')) {
8457			case ulc:
8458				return languages[i];
8459			case blc:
8460				browser_language = browser_language || languages[i];
8461				break;
8462			case this.getValue('language'):
8463				default_language = default_language || languages[i];
8464				break;
8465		}
8466	}
8467
8468	return browser_language || default_language || languages.filter(function(language) {
8469		return language.getValue('code') === 'en';
8470	})[0] || BaseModel.instance('language').initialize([{'name': 'code', value: 'en'}, {name: 'rtl', value: false}]);
8471};
8472
8473module.exports = layout_settings;
8474
8475},{"./Settings":148,"@icewarp/localstorage":167,"BaseModel":"BaseModel"}],153:[function(require,module,exports){
8476"use strict";
8477var BaseModel = require('BaseModel');
8478var Settings = require('./Settings');
8479var password_policy = BaseModel.create('password_policy', Settings);
8480
8481module.exports = password_policy;
8482
8483},{"./Settings":148,"BaseModel":"BaseModel"}],154:[function(require,module,exports){
8484"use strict";
8485var BaseModel = require('BaseModel');
8486var Settings = require('./Settings');
8487var reset_settings = BaseModel.create('reset_settings', Settings);
8488
8489reset_settings.prototype.onCreate = function () {
8490	[
8491		{name: 'enabled', value: 1}
8492	].forEach(function (setting) {
8493		this.setData(setting.name, BaseModel.instance('Setting', setting.name).initialize(setting));
8494	}, this);
8495};
8496
8497module.exports = reset_settings;
8498
8499},{"./Settings":148,"BaseModel":"BaseModel"}],155:[function(require,module,exports){
8500"use strict";
8501var BaseModel = require('BaseModel');
8502var Settings = require('./Settings');
8503var restrictions = BaseModel.create('restrictions', Settings);
8504
8505restrictions.prototype.onCreate = function () {
8506	[{name: 'disable_languages', value: false},
8507		{name: 'disable_guest_signin', value: false},
8508		{name: 'disable_signup', value: true},
8509		{name: 'disable_signup_ip', value: false},
8510		{name: 'disable_remember', value: false},
8511		{name: 'disable_autofill', value: false},
8512		{name: 'contact_support', value: true},
8513		{name: 'disable_changepass', value: false},
8514		{name: 'website_disabled', value: false},
8515		{name: 'facebook_disabled', value: false},
8516		{name: 'twitter_disabled', value: false},
8517		{name: 'linkedin_disabled', value: false},
8518		{name: 'show_search', value: false},
8519		{name: 'remember_login_accounts', value: true},
8520	].forEach(function (setting) {
8521		this.setData(setting.name, BaseModel.instance('Setting', setting.name).initialize(setting));
8522	}, this);
8523};
8524module.exports = restrictions;
8525
8526},{"./Settings":148,"BaseModel":"BaseModel"}],156:[function(require,module,exports){
8527"use strict";
8528var BaseModel = require('BaseModel');
8529var Setting = require('./Setting');
8530var signup_domain = BaseModel.create('signup_domain', Setting);
8531
8532signup_domain.prototype.initialize = function (data) {
8533	var key;
8534	for (key in data) {
8535		data[key] !== null && data[key] !== void 0 && this.setData(key, parseInt(data[key]) == data[key] ? parseInt(data[key]) : data[key]);
8536	}
8537	this.setId(this.getData('value'));
8538
8539	return this;
8540};
8541
8542module.exports = signup_domain;
8543
8544},{"./Setting":147,"BaseModel":"BaseModel"}],157:[function(require,module,exports){
8545"use strict";
8546module.exports={'atoms-ad-adsense':function(){return require('./_compiled/atoms-ad-adsense.js')},'atoms-ad':function(){return require('./_compiled/atoms-ad.js')},'atoms-addon':function(){return require('./_compiled/atoms-addon.js')},'atoms-avatar':function(){return require('./_compiled/atoms-avatar.js')},'atoms-element-button':function(){return require('./_compiled/atoms-element-button.js')},'atoms-dropdown':function(){return require('./_compiled/atoms-dropdown.js')},'atoms-element-input':function(){return require('./_compiled/atoms-element-input.js')},'atoms-element-textarea':function(){return require('./_compiled/atoms-element-textarea.js')},'atoms-element-select':function(){return require('./_compiled/atoms-element-select.js')},'atoms-icons':function(){return require('./_compiled/atoms-icons.js')},'atoms-info':function(){return require('./_compiled/atoms-info.js')},'atoms-image':function(){return require('./_compiled/atoms-image.js')},'atoms-label':function(){return require('./_compiled/atoms-label.js')},'atoms-link':function(){return require('./_compiled/atoms-link.js')},'atoms-loader':function(){return require('./_compiled/atoms-loader.js')},'atoms-static':function(){return require('./_compiled/atoms-static.js')},'atoms-section':function(){return require('./_compiled/atoms-section.js')},'atoms-switch':function(){return require('./_compiled/atoms-switch.js')},'atoms-tooltip':function(){return require('./_compiled/atoms-tooltip.js')},'atoms-tag':function(){return require('./_compiled/atoms-tag.js')},'atoms-video':function(){return require('./_compiled/atoms-video.js')},'meta-head':function(){return require('./_compiled/meta-head.js')},'atoms-well':function(){return require('./_compiled/atoms-well.js')},'meta-index':function(){return require('./_compiled/meta-index.js')},'molecules-captcha':function(){return require('./_compiled/molecules-captcha.js')},'molecules-button':function(){return require('./_compiled/molecules-button.js')},'molecules-input':function(){return require('./_compiled/molecules-input.js')},'molecules-checkbox':function(){return require('./_compiled/molecules-checkbox.js')},'molecules-language-picker-item':function(){return require('./_compiled/molecules-language-picker-item.js')},'molecules-language-picker':function(){return require('./_compiled/molecules-language-picker.js')},'molecules-select':function(){return require('./_compiled/molecules-select.js')},'molecules-static':function(){return require('./_compiled/molecules-static.js')},'molecules-textarea':function(){return require('./_compiled/molecules-textarea.js')},'molecules-window-header':function(){return require('./_compiled/molecules-window-header.js')},'organisms-bar':function(){return require('./_compiled/organisms-bar.js')},'organisms-card-header':function(){return require('./_compiled/organisms-card-header.js')},'organisms-card-section':function(){return require('./_compiled/organisms-card-section.js')},'organisms-window':function(){return require('./_compiled/organisms-window.js')},'sites-login':function(){return require('./_compiled/sites-login.js')},'templates-card':function(){return require('./_compiled/templates-card.js')}};
8547},{"./_compiled/atoms-ad-adsense.js":1,"./_compiled/atoms-ad.js":2,"./_compiled/atoms-addon.js":3,"./_compiled/atoms-avatar.js":4,"./_compiled/atoms-dropdown.js":5,"./_compiled/atoms-element-button.js":6,"./_compiled/atoms-element-input.js":7,"./_compiled/atoms-element-select.js":8,"./_compiled/atoms-element-textarea.js":9,"./_compiled/atoms-icons.js":10,"./_compiled/atoms-image.js":11,"./_compiled/atoms-info.js":12,"./_compiled/atoms-label.js":13,"./_compiled/atoms-link.js":14,"./_compiled/atoms-loader.js":15,"./_compiled/atoms-section.js":16,"./_compiled/atoms-static.js":17,"./_compiled/atoms-switch.js":18,"./_compiled/atoms-tag.js":19,"./_compiled/atoms-tooltip.js":20,"./_compiled/atoms-video.js":21,"./_compiled/atoms-well.js":22,"./_compiled/meta-head.js":23,"./_compiled/meta-index.js":24,"./_compiled/molecules-button.js":25,"./_compiled/molecules-captcha.js":26,"./_compiled/molecules-checkbox.js":27,"./_compiled/molecules-input.js":28,"./_compiled/molecules-language-picker-item.js":29,"./_compiled/molecules-language-picker.js":30,"./_compiled/molecules-select.js":31,"./_compiled/molecules-static.js":32,"./_compiled/molecules-textarea.js":33,"./_compiled/molecules-window-header.js":34,"./_compiled/organisms-bar.js":35,"./_compiled/organisms-card-header.js":36,"./_compiled/organisms-card-section.js":37,"./_compiled/organisms-window.js":38,"./_compiled/sites-login.js":39,"./_compiled/templates-card.js":40}],158:[function(require,module,exports){
8548var Request = require('request');
8549/*
8550 * store the number of loaded CSS's
8551 * @type Number
8552 */
8553var passed;
8554/**
8555 * store the number of CSS's to pass
8556 * @type Number
8557 */
8558var to_pass;
8559/**
8560 * Flag for browsers supporting css variables
8561 * @type Boolean
8562 */
8563var supports_css_variables = !!(window.CSS && window.CSS.supports && window.CSS.supports('--v', 0));
8564
8565/**
8566 * CSS loader class
8567 */
8568var loader = {};
8569
8570var forced_definitions = {};
8571
8572/**
8573 * Loads styles defined in meta name="stylesheet" head tags
8574 * @param {function} callback Callback to call after loading all styles
8575 * @param {Object} custom_definitions object with definitions to use
8576 * @returns {undefined}
8577 */
8578loader.load = function (callback, custom_definitions) {
8579	forced_definitions = custom_definitions || forced_definitions;
8580	var metas = [].slice.call(document.head.querySelectorAll('meta[name="stylesheet"]'));
8581	passed = 0;
8582	to_pass = metas.length;
8583	if (!to_pass) {
8584		return callback && callback();
8585	}
8586	metas.forEach(function (meta) {
8587		var uses_variables = meta.getAttribute('variables') && meta.getAttribute('variables') !== "fal
8587se";
8588		if (!uses_variables || supports_css_variables) {
8589			createTag('link', meta.getAttribute('content'), function () {
8590				runCallback(callback);
8591			});
8592		} else {
8593			requestCss.call(this, meta, callback);
8594		}
8595	}.bind(this));
8596};
8597
8598loader.setRTL = function (isRTL, callback) {
8599	[].forEach.call(document.head.querySelectorAll('meta[name="stylesheet"]'), function (meta) {
8600		var href = meta.getAttribute('content');
8601		if (isRTL) {
8602			href = href.replace(/(\.rtl)?.css$/, '.rtl.css');
8603		} else {
8604			href = href.replace(/.rtl.css$/, '.css');
8605		}
8606		meta.setAttribute('content', href);
8607	});
8608	callback && callback();
8609};
8610
8611/**
8612 * Substitutes css variables for their values
8613 * @param {string} cssText
8614 * @returns {string} parsed text
8615 */
8616loader.replace = function (cssText) {
8617	cssText = cssText || '';
8618	var match;
8619	var regExpDefinition = /(?:^|\s+)--(.+?):\s*(.+?);/g;
8620	var regExpSubstitution = /var\(--(.+?)\)/g;
8621	var repeat = true;
8622
8623	while (repeat) {
8624		var definitions = {};
8625		while ((match = regExpDefinition.exec(cssText)) !== null) {
8626			definitions[match[1]] = match[2];
8627		}
8628		repeat = false;
8629		cssText = cssText.replace(regExpSubstitution, function (whole, match) {
8630			repeat = true;
8631			return forced_definitions[match] || definitions[match];
8632		});
8633	}
8634	return cssText;
8635};
8636
8637/**
8638 * requests css form the server
8639 * @param {DOMElement} meta meta tag
8640 * @param {function} callback
8641 * @returns {undefined}
8642 */
8643function requestCss(meta, callback) {
8644	var url = meta.getAttribute('content');
8645	var base = document.head.getElementsByTagName('base')[0];
8646	base = base ? base.getAttribute('href') : '';
8647	base = ~base.indexOf('{') ? '' : base;
8648	var version = document.querySelector('meta[name="version"]');
8649	if (version) {
8650		version = version.getAttribute('content');
8651	}
8652	var request = new Request({
8653		url: base + url + (version ? '?version=' + version : ''),
8654		method: "GET"
8655	});
8656	request.on('load', function (event, xhr) {
8657		var replace = new RegExp('(\\.\\.[/\\\\]){' + (meta.getAttribute('content').match(/\//g) || []).length + '}', 'g');
8658		createTag('style', this.replace(xhr.responseText).replace(replace, ''), function (style) {
8659			style.setAttribute('content', url);
8660			runCallback(callback);
8661		});
8662	}.bind(this));
8663	request.on('error', console.error);
8664	request.on('abort', console.error);
8665	request.send();
8666}
8667
8668/**
8669 * Appends "style" or "link" element to head
8670 * @param {string} type "style" or "link" element
8671 * @param {string} src href for "link" element and textContent for "style" element
8672 * @param {function} callback
8673 * @returns {undefined}
8674 */
8675function createTag(type, src, callback) {
8676	var style = document.createElement(type);
8677	style.setAttribute('type', 'text/css');
8678	switch (type) {
8679		case 'link':
8680			var version = document.querySelector('meta[name="version"]');
8681			if (version) {
8682				version = version.getAttribute('content');
8683			}
8684			style.setAttribute('rel', 'stylesheet');
8685			style.setAttribute('href', src + (version ? '?version=' + version : ''));
8686			style.onload = callback;
8687			style.onerror = function () {
8688				console.error('Unable to load ' + src);
8689				callback(style);
8690			};
8691			document.head.appendChild(style);
8692			break;
8693		case 'style':
8694			style.textContent = src;
8695			document.head.appendChild(style);
8696			callback && callback(style);
8697	}
8698}
8699
8700/**
8701 * Removes original meta element from head and calls callback if called last time
8702 * @param {function} callback
8703 * @returns {undefined}
8704 */
8705function runCallback(callback) {
8706	(++passed === to_pass) && callback && callback();
8707}
8708
8709module.exports = loader;
8710
8711},{"request":"request"}],159:[function(require,module,exports){
8712/**
8713 * map of substitutions
8714 */
8715var entity_map = {
8716	'&': '&amp;',
8717	'<': '&lt;',
8718	'>': '&gt;',
8719	'"': '&quot;',
8720	"'": '&#39;',
8721	'/': '&#x2F;',
8722	'`': '&#x60;',
8723	'=': '&#x3D;'
8724};
8725
8726/**
8727 * function to escape &<>"'`=\/ in string
8728 * @param string string to escape
8729 */
8730var escapeString = function(string) {
8731	return String(string).replace(/[&<>"'`=/]/g, function (match) {
8732		return entity_map[match];
8733	});
8734};
8735
8736/**
8737 * @module escape-string
8738 */
8739module.exports = escapeString;
8740
8741},{}],160:[function(require,module,exports){
8742var hashchange = require('hashchange');
8743var Debugger = require('debugger');
8744Debugger.addLogLevel("HASHCHANGE");
8745
8746/**
8747 * Current site
8748 * @type String
8749 */
8750var _site = '';
8751
8752/**
8753 * Current hash parts
8754 * @type String[]
8755 */
8756var _parts = {};
8757
8758/**
8759 * Previous site
8760 * @type String
8761 */
8762var _previous_site = '';
8763
8764/**
8765 * Previous hash parts
8766 * @type String[]
8767 */
8768var _previous_parts = [];
8769
8770/**
8771 * Flag to skip callback on hash change
8772 * @type Boolean
8773 */
8774var _skip_callback = false;
8775
8776/**
8777 * @class Hash
8778 */
8779var Hash = {}; 
8780
8781/**
8782 * Set hash change function or trigger hash change event
8783 * @param {function} callback
8784 * @returns {unresolved}
8785 */
8786Hash.update = function (callback) {
8787	return hashchange.update(callback ? function (hashFragment) {
8788		updateParts(hashFragment);
8789		Debugger.logAction({site: _site, parts: _parts}, Debugger.levels.HASHCHANGE);
8790		!_skip_callback && callback(_site, _parts, _previous_site, _previous_parts);
8791		_skip_callback = false;
8792		_previous_site = _site;
8793		_previous_parts = _parts;
8794	} : void 0);
8795};
8796
8797/**
8798 * Change browser URL hash
8799 * @param {String} site
8800 * @param {String[]} parts
8801 * @param {Boolean} skip_callback
8802 * @param {Boolean} keep_parts 
8803 * @param {String} root 
8804 * @returns {Hash}
8805 */
8806Hash.change = function (site, parts, skip_callback, keep_parts, root) {
8807	_site = site || _site;
8808	_parts = keep_parts ? Hash.getParts() : {};
8809	if(parts) {
8810		for(var i in parts) {
8811			if(parts[i] === null) {
8812				delete _parts[i];
8813			} else {
8814				_parts[i] = parts[i];
8815			}
8816		}
8817	}
8818	var data = [];
8819	for (i in _parts) {
8820		data.push(encodeURIComponent(i) + (_parts[i] !== void 0 ? '=' + encodeURIComponent(_parts[i]) : ''));
8821	}
8822	Debugger.logAction({site: _site, parts: _parts}, Debugger.levels.HASHCHANGE);
8823	_skip_callback = skip_callback;
8824	if(root !== void 0) {
8825		location.replace(root + '#' + _site + (data.length ? '&' + data.join('&') : ''));
8826	} else {
8827		location.hash = _site + (data.length ? '&' + data.join('&') : '');
8828	}
8829	return this;
8830};
8831
8832/**
8833 * Returns current site
8834 * @returns {String}
8835 */
8836Hash.getSite = function () {
8837	return _site;
8838};
8839
8840/**
8841 * Returns URL hash parts
8842 * @returns {String[]}
8843 */
8844Hash.getParts = function () {
8845	return _parts;
8846};
8847
8848function updateParts(hashFragment) {
8849	hashFragment = hashFragment || location.hash;
8850	var parts = hashFragment.replace('#', '').split('&');
8851	_site = ~parts[0].indexOf('=') ? '' : parts.shift();
8852	_parts = {};
8853	parts.forEach(function (part) {
8854		part = part.split('=');
8855		_parts[decodeURIComponent(part.splice(0, 1))] = decodeURIComponent(part.join('='));
8856	});
8857}
8858updateParts();
8859
8860/**
8861 * @module Hash
8862 */
8863module.exports = Hash;
8864
8865}
8865,{"debugger":"debugger","hashchange":362}],161:[function(require,module,exports){
8866var Request = require('request');
8867var logger = require('logger');
8868var Polyglot = require('./polyglot.js');
8869var polyglot = null;
8870
8871/**
8872 * object to store loaded languages
8873 */
8874var language_dictionaries = {};
8875/**
8876 * object to store supported languages
8877 */
8878var supported_languages = {
8879	en: {
8880		direction: 'ltr',
8881		label: 'English'
8882	}
8883};
8884
8885/**
8886 * i18n settings
8887 */
8888var settings = {};
8889
8890var default_locale = 'en';
8891
8892/**
8893 * 
8894 * @param {function} fn
8895 * @param {string} language
8896 * @param {Event} event
8897 * @param {XmlHttpRequest} xhr
8898 * @returns {i18n}
8899 */
8900var loadSuccess = function (fn, language, event, xhr) {
8901	try {
8902		language_dictionaries[language] = JSON.parse(event.target.responseText);
8903	} catch (e) {
8904		//
8905	}
8906
8907	polyglot.extend(language_dictionaries[default_locale]);
8908	polyglot.extend(language_dictionaries[language]);
8909	polyglot.locale(language);
8910	fn(language);
8911	return this;
8912};
8913
8914/**
8915 * 
8916 * @param {string} error_message
8917 * @param {function} fn
8918 * @param {string} language
8919 * @param {XmlHttpRequest} xhr
8920 * @returns {unresolved}
8921 */
8922var loadError = function (error_message, fn, language, xhr) {
8923	polyglot.locale(language);
8924	return fn ? fn(polyglot.locale()) : logger.error(error_message);
8925};
8926
8927function compareVersions(a, b) {
8928	return compareVersions.parts(a.split('.'), b.split('.'), 0);
8929}
8930compareVersions.parts = function (a_parts, b_parts, index) {
8931	var diff;
8932	return ((a_parts.length - 1) < index && (b_parts.length - 1) < index) ? 0 : (!(diff = (+a_parts[index] || 0) - (+b_parts[index] || 0)) ? compareVersions.parts(a_parts, b_parts, index + 1) : (diff < 0 ? -1 : 1));
8933};
8934
8935/**
8936 * Class for frontend translations
8937 * @class i18n
8938 */
8939function i18n() {}
8940
8941/**
8942 * Initialize i18n library
8943 * @param {object} options
8944 * @param {string} url - url of local dictionaries
8945 * @param {string} [default_locale] - ISO code of default locale
8946 * @param {string} [external_url] - url of external dictionaries (required for external dictionaries)
8947 * @param {Object} [default_locale_dictionary] - dictionary that is build in application
8948 * @param {string} [version] - version of local dictionaries (required for external dictionaries)
8949 * @param {string} [project_name] - name of project (required for external dictionaries)
8950 * @param {boolean} [options.dynamic] - switches translate function from regular to dynamic
8951 * @param {function} [callback] - callback function called on i18n initialization
8952 * @returns {i18n}
8953 */
8954i18n.init = function (options, callback) {
8955	settings = options || {};
8956	polyglot = new Polyglot(settings);
8957
8958	if (settings.default_locale) {
8959		default_locale = settings.default_locale;
8960		if (settings.default_locale_dictionary) {
8961			language_dictionaries[settings.default_locale] = settings.default_locale_dictionary;
8962		}
8963	}
8964
8965	supported_languages = settings.supported_languages || supported_languages;
8966	checkExternalDictionary.call(this, function () {
8967		i18n.changeLanguage(default_locale, callback);
8968	});
8969
8970	settings.expose && (window[settings.expose] = (settings.dynamic ? i18n.tDynamic : i18n.tRegular).bind(i18n));
8971};
8972
8973i18n.getSupportedLanguages = function () {
8974	return supported_languages;
8975};
8976
8977/**
8978 * @summary Check and download external dictionary, if it's missing or it's old fallback to local
8979 * @description First check if settings necessary for external loading are present. Then create request for remote dictionary version, compare this version with settings.version this property contains version of locale dictionary from app build process. If external version is higher than local download external dictionary and save that external version for that language so it's not checked another time and fallback directly to error handler. Error handler checks if there is dictionary already in memory so there will be no other xhr. 
8980 * @param {function} callback
8981 * @returns {undefined}
8982 */
8983function checkExternalDictionary(callback) {
8984	if (!settings.external_url || !settings.version) {
8985		logger.info('Missing settings for external dictionary');
8986		return callback();
8987	}
8988
8989	this.download(settings.external_url + '/version.json', function (event) {
8990		var version;
8991		try {
8992			version = JSON.parse(event.target.responseText).version;
8993		} catch (error) {
8994			return callback();
8995		}
8996		if (compareVersions(version, settings.version) === 1) {
8997			settings.url = settings.external_url;
8998			this.download(settings.url + '/languages.json', function (event) {
8999				try {
9000					supported_languages = JSON.parse(event.target.responseText);
9001				} catch (e) {
9002					//
9003				}
9004				language_dictionaries = {};
9005				callback();
9006			}.bind(this));
9007		} else {
9008			callback();
9009		}
9010	}.bind(this), callback);
9011}
9012
9013i18n.download = function (url, success, error) {
9014	var options = {
9015		url: url
9016	};
9017	new Request(options)
9018		.on('load', success)
9019		.on('error', error)
9020		.send();
9021};
9022
9023function downloadDictionary(url, language, fn, error_fn) {
9024	fn = fn || function () {};
9025	error_fn = error_fn || fn;
9026	this.download(url, loadSuccess.bind(this, fn, language), loadError.bind(this, error_fn, language));
9027}
9028
9029/**
9030 * Change output language. Automatically loads new language file if not loaded yet
9031 * @param {string} language
9032 * @param {function} fn
9033 * @param {function} error_fn
9034 * @returns {i18n}
9035 */
9036i18n.changeLanguage = function (language, fn, error_fn) {
9037	if (!supported_languages[language]) {
9038		return loadError.call(this, language + ' language not supported', error_fn || fn, language);
9039	}
9040
9041	if (language_dictionaries[language]) {
9042		polyglot.extend(language_dictionaries[default_locale]);
9043		polyglot.extend(language_dictionaries[language]);
9044		polyglot.locale(language);
9045		fn && fn(language);
9046		return;
9047	}
9048	downloadDictionary.call(this, ~settings.url.indexOf('%s') ? settings.url.replace('%s', settings.map ? settings.map[language] || language : language) : (settings.url + '/' + (settings.map ? settings.map[language] || language : language) + '.json'), language, fn, error_fn);
9049	return this;
9050};
9051
9052/**
9053 * function to translate text
9054 * 
9055 * @returns {string}
9056 */
9057i18n.tRegular = function () {
9058	return polyglot.t.apply(polyglot, arguments);
9059};
9060
9061/**
9062 * function to translate text, returns new lambda that will return translated string
9063 * 
9064 * @returns {function}
9065 */
9066i18n.tDynamic = function () {
9067	var args = arguments;
9068	return function () {
9069		return polyglot.t.apply(polyglot, args);
9070	};
9071};
9072
9073i18n.t = i18n.tRegular;
9074
9075/** 
9076 * @module @icewarp/i18n 
9077 * @requires @icewarp/request
9078 * @requires @icewarp/logger
9079 * @requires node-polyglot
9080 */
9081module.exports = i18n;
9082
9083},{"./polyglot.js":163,"logger":"logger","request":"request"}],162:[function(require,module,exports){
9084/**
9085 * function to parse MD syntax
9086 * @param input input text to parse
9087 */
9088module.exports = function (input) {
9089	return input.replace(/(\*{1,2}|_{1,2})(.*?)\1/gi, function (match, m1, m2) {
9090		var tag = ['em', 'strong'][m1.length - 1];
9091		return '<' + tag + '>' + m2 + '</' + tag + '>';
9092	}).replace(/\[(.*?)\]\((.*?)\)/gi, '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>');
9093};
9094},{}],163:[function(require,module,exports){
9095var logger = require('logger');
9096var Escape = require('@icewarp/escape-string');
9097var markdown = require('./markdown.js');
9098/**
9099 * Polyglot dictionary
9100 */
9101var phrases = {};
9102/**
9103 * Supress errors on missing translation
9104 * @type Boolean
9105 */
9106var allowMissing = false;
9107/**
9108 * Current locale
9109 * @type String
9110 */
9111var current_locale = '';
9112/**
9113 * Current plural type function
9114 * @type function
9115 */
9116var current_plural_type = null;
9117/**
9118 * Plural forms delimiter
9119 * @type String
9120 */
9121var delimiter = '||||';
9122
9123var start_tag = '%{';
9124
9125var end_tag = '}';
9126
9127/**
9128 * Types of plural
9129 */
9130var pluralTypes = {
9131	chinese: function (n) {
9132		return 0;
9133	},
9134	german: function (n) {
9135		return n !== 1 ? 1 : 0;
9136	},
9137	french: function (n) {
9138		return n > 1 ? 1 : 0;
9139	},
9140	russian: function (n) {
9141		return n % 10 === 1 && n % 100 !== 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2;
9142	},
9143	czech: function (n) {
9144		return (n === 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2;
9145	},
9146	polish: function (n) {
9147		return (n === 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
9148	},
9149	icelandic: function (n) {
9150		return (n % 10 !== 1 || n % 100 === 11) ? 1 : 0;
9151	}
9152};
9153
9154/**
9155 * List of languages for each plural type
9156 */
9157var pluralTypeToLanguages = {
9158	chinese: ['fa', 'id', 'ja', 'ko', 'lo', 'ms', 'th', 'tr', 'zh'],
9159	german: ['da', 'de', 'en', 'es', 'fi', 'el', 'he', 'hu', 'it', 'nl', 'no', 'pt', 'sv'],
9160	french: ['fr', 'tl', 'pt-br'],
9161	russian: ['hr', 'ru'],
9162	czech: ['cs', 'sk'],
9163	polish: ['pl'],
9164	icelandic: ['is']
9165};
9166
9167/**
9168 * Return type of plural for locale
9169 * @param {String} locale
9170 * @returns {String}
9171 */
9172function pluralType(locale) {
9173	for (var type in pluralTypeToLanguages) {
9174		if (~pluralTypeToLanguages[type].indexOf(locale)) {
9175			return type;
9176		}
9177	}
9178	return 'german';
9179}
9180
9181/**
9182 * Return index of plural form for count
9183 * @param {Number} count
9184 * @returns {Number}
9185 */
9186function pluralIndex(count) {
9187	return pluralTypes[current_plural_type](count);
9188}
9189
9190/**
9191 * Return plural translation for text specified by count
9192 * @param {String} text
9193 * @param {Number} count
9194 * @returns {String}
9195 */
9196function plural(text, count) {
9197	var texts = text.split(delimiter);
9198	return (texts[pluralIndex(count)] || texts[0]).trim();
9199}
9200
9201/**
9202 * Substitute %{placeholder}'s for options[placeholder]'s
9203 * @param {String} phrase
9204 * @param {Object} options
9205 * @returns {String}
9206 */
9207function substitute(phrase, options) {
9208	if (Array.isArray(options)) {
9209		var _options = {};
9210		options.forEach(function (value, index) {
9211			_options[index] = value;
9212		});
9213		options = _options;
9214	}
9215	phrase = (options.md === void 0 || options.md) ? markdown(phrase) : phrase;
9216	var escape = options.escape === void 0 ? true : options.escape;
9217	delete(options.md);
9218	delete(options.escape);
9219	for (var arg in options) {
9220		phrase = phrase.replace(new RegExp(start_tag + arg + end_tag, 'g'), escape ? Escape(options[arg]) : options[arg]);
9221	}
9222	var substitution_index = 0;
9223	phrase = phrase.replace(/%s/g, function () {
9224		return options[substitution_index++];
9225	});
9226	return phrase;
9227}
9228
9229/**
9230 * Polyglot class
9231 * @param {Object} options
9232 * @returns {Polyglot}
9233 */
9234function Polyglot(options) {
9235	this.options = options || {};
9236	allowMissing = !!options.allowMissing;
9237	options.delimiter && (delimiter = options.delimiter);
9238	options.start_tag && (start_tag = options.start_tag);
9239	options.end_tag && (end_tag = options.end_tag);
9240	this.locale(options.default_locale || 'en');
9241	if (options.default_locale_dictionary) {
9242		this.extend(options.default_locale_dictionary);
9243		this.defaultLocaleDictionary = JSON.parse(JSON.stringify(phrases));
9244	}
9245}
9246
9247/**
9248 * Get and/or set current_locale
9249 * @param {type} new_locale
9250 * @returns {String} current_locale
9251 */
9252Polyglot.prototype.locale = function (new_locale) {
9253	new_locale && (current_locale = new_locale) && (current_plural_type = pluralType(current_locale));
9254	return current_locale;
9255};
9256
9257/**
9258 * Extend polyglot dictionary with morePhrases
9259 * @param {Object} morePhrases
9260 * @returns {Polyglot}
9261 */
9262Polyglot.prototype.extend = function (morePhrases) {
9263	for (var key in morePhrases) {
9264		var phrase = morePhrases[key];
9265		var prefixedKey = (arguments[1] || '') + key;
9266		if (typeof phrase === 'object') {
9267			this.extend(phrase, prefixedKey + '.');
9268		} else {
9269			phrases[prefixedKey] = phrase;
9270		}
9271	}
9272	return this;
9273};
9274
9275/**
9276 * Translate function
9277 * @param {String} key
9278 * @param {Object} options
9279 * @returns {String}
9280 */
9281Polyglot.prototype.t = function (key, options, fallback) {
9282	var usedPhrases = phrases;
9283	options = (options === null || options === void 0) ? {} : (typeof options === 'number' ? {amount: options} : options);
9284	if (options.useDefaultDictionary && this.defaultLocaleDictionary) {
9285		usedPhrases = this.defaultLocaleDictionary;
9286	}
9287	if (typeof usedPhrases[key] !== 'string') {
9288		switch (typeof fallback) {
9289			case 'function':
9290				return fallback(key, options);
9291			case 'string':
9292				return fallback;
9293		}
9294		usedPhrases[key] = key;
9295		allowMissing || logger.warning('Missing translation for key: "' + key + '"');
9296	}
9297	return substitute(plural(usedPhrases[key], options.amount === void 0 ? 1 : (+options.amount || 1)), options);
9298};
9299
9300/**
9301 * @module Polyglot
9302 */
9303module.exports = Polyglot;
9304
9305},{"./markdown.js":162,"@icewarp/escape-string":159,"logger":"logger"}],164:[function(require,module,exports){
9306/**
9307 * array of objects (properties: object, index) to store their indexes
9308 */
9309var objects = [];
9310
9311/**
9312 * Variable to store max window index
9313 * @type Number|maxIndex
9314 */
9315var maxIndex = 0;
9316
9317/**
9318 * class to store and assign object indexes
9319 * @returns {IndexManager}
9320 */
9321function IndexManager() {}
9322
9323/**
9324 * Add object to the storage and return its assigned index.
9325 * Index of a duplicate is overwritten by a new index
9326 * @param {object} object to store
9327 * @returns {Number} maxIndex
9328 */
9329IndexManager.add = function (object) {
9330	if (!objects.some(function (obj) {
9331		if (obj.object === object && obj.index !== maxIndex) {
9332			obj.index = ++maxIndex;
9333		}
9334		return obj.object === object;
9335	})) {
9336		objects.push({
9337			object: object,
9338			index: ++maxIndex
9339		});
9340	}
9341	return maxIndex;
9342};
9343
9344/**
9345 * Remove object from the storage and return highest index
9346 * @param {object} object to remove
9347 * @returns {Number} maxIndex
9348 */
9349IndexManager.remove = function (object) {
9350	for (var i in objects) {
9351		if (objects[i].object === object) {
9352			objects.splice(i, 1);
9353			return maxIndex = objects.length ? maxIndex : 0;
9354		}
9355	}
9356};
9357
9358/**
9359 * @module IndexManager
9360 * @exports IndexManager
9361 */
9362module.exports = IndexManager;
9363
9364},{}],165:[function(require,module,exports){
9365/**
9366 * Options for IQ setup.
9367 * @typedef {Object} IQOptions
9368 * @property {array} arguments - array of arguments to be addet to IQ tag (Optional).
9369 * @property {string} id_attr - Custom rename of ID attribute (optional).
9370 * @property {string} format - Change format of response (optional).
9371 */
9372
9373/**
9374 * Messages ID auto increment
9375 * @type Number
9376 */
9377var i = 1;
9378/**
9379 * Crate IQ message and handle response for it.
9380 * @class IQ
9381 * @param {IQOptions} options
9382 * @returns {IQ}
9383 */
9384function IQ(options) {
9385	options = options || {};
9386	/**
9387	 * IQ callbacks storage
9388	 * @type object
9389	 */
9390	this.iqs = {};
9391	/**
9392	 * Arguments to add to IQ
9393	 * @type Array
9394	 */
9395	this.arguments = options.arguments || [];
9396	/**
9397	 * Custom rename of ID attribute
9398	 * @type string
9399	 */
9400	this.id_attr = options.id_attr || 'id';
9401	/**
9402	 * Change type of response
9403	 * @type string
9404	 */
9405	this.format = options.format || 'text/xml';
9406	
9407	this.id = i++;
9408
9409	this.query = {
9410		arguments: [],
9411		addAttribute: function (name, value) {
9412			this.arguments.push({name: name, value: value});
9413			return this;
9414		}
9415	};
9416}
9417/**
9418 * Add attribute to IQ tag
9419 * @param {string} name
9420 * @param {*} value
9421 * @returns {undefined}
9422 */
9423IQ.prototype.addAttribute = function (name, value) {
9424	this.arguments.push({name: name, value: value});
9425	return this;
9426};
9427/**
9428 * Create IQ message, auto increment ID and save callbacks
9429 * @param {string} body
9430 * @param {object} callback
9431 * @returns {String}
9432 */
9433IQ.prototype.getIQ = function (body, callback) {
9434	this.iqs[this.id] = callback;
9435	return "<iq " + this.id_attr + '="' + this.id + '" ' + (this.arguments.map(function (argument) {
9436		return argument.name + '="' + argument.value + '" ';
9437	}).join(' ')) + " format=\"" + this.format + "\"><query " + (this.query.arguments.map(function (argument) {
9438		return argument.name + '="' + argument.value + '" ';
9439	}).join(' ')) + ">" + body + "</query></iq>";
9440};
9441/**
9442 * Process response and return callbacks by ID
9443 * @param {string} response
9444 * @returns {object}
9445 */
9446IQ.prototype.getCallbacks = function (response, id) {
9447	var xml = new DOMParser().parseFromString(response.replace(/>\s+</g, '><'), "text/xml");
9448	var iq;
9449	var callback;
9450	if ((iq = xml.getElementsByTagName('iq')).length) {
9451		callback = this.iqs[id || iq[0].getAttribute(this.id_attr)];
9452		delete this.iqs[id || iq[0].getAttribute(this.id_attr)];
9453		return {callback: callback, document: xml};
9454	}
9455	throw new Error("Malformed message");
9456};
9457/**
9458 * Get IQ by it's ID
9459 * @param {number} id
9460 * @returns {object}
9461 */
9462IQ.prototype.getCallbacksById = function (id) {
9463	return this.iqs[id];
9464};
9465/**
9466 * Get All pending IQs
9467 * @returns {object}
9468 */
9469IQ.prototype.getPendingIqs = function () {
9470	return this.iqs;
9471};
9472
9473module.exports = IQ;
9474
9475},{}],166:[function(require,module,exports){
9476/**
9477 * @class Json
9478 */
9479var Json = {};
9480
9481/**
9482 * Converts JSON object to XML string
9483 * @param {object} json
9484 * @returns {string} XML string
9485 */
9486Json.toXmlString = function(json) {
9487	if (Array.isArray(json)) {
9488		return json.map(function (item) {
9489			return this.toXmlString(item);
9490		}, this).join('');
9491	} else if (typeof json === 'object') {
9492		return Object.keys(json).map(function (key) {
9493			return '<' + key + '>' + this.toXmlString(json[key]) + '</' + key + '>';
9494		}, this).join('');
9495	}
9496	return json;
9497};
9498
9499/**
9500 * Converts JSON object to XML object
9501 * @param {object} json
9502 * @returns {object} xml
9503 */
9504Json.toXml = function(json) {
9505	return this.XmlStringToXml(this.toXmlString(json));
9506};
9507
9508/**
9509 * Parses XML string to XML
9510 * @param {string} xml xml string
9511 * @returns {object} XML
9512 */
9513Json.XmlStringToXml = function(xml) {
9514	return (new DOMParser()).parseFromString(xml, "text/xml");
9515};
9516
9517/**
9518 * Converts XML to JSON
9519 * @param {object} xml
9520 * @returns {object} converted json
9521 */
9522Json.fromXml = function(xml) {
9523	var obj = {};
9524
9525	if (xml.nodeType === 3 || (!(xml.attributes || []).length && !xml.hasChildNodes())) {
9526		return xml.nodeValue;
9527	}
9528	
9529	if ((xml.attributes || []).length > 0) {
9530		obj._attributes = {};
9531		for (var j = 0; j < xml.attributes.length; j++) {
9532			var attribute = xml.attributes.item(j);
9533			obj._attributes[attribute.nodeName] = attribute.nodeValue;
9534		}
9535	}
9536
9537	for (var i = 0; i < (xml.childNodes || []).length; i++) {
9538		var item = xml.childNodes.item(i);
9539		var nodeName = item.nodeName;
9540		if (nodeName === '#text') {
9541			if(typeof obj === 'string') {
9542				obj += this.fromXml(item);
9543			} else {
9544				obj = this.fromXml(item);
9545			}
9546		} else if (obj[nodeName] === void 0) {
9547			obj[nodeName] = this.fromXml(item);
9548		} else {
9549			if (obj[nodeName].push === void 0) {
9550				var old = obj[nodeName];
9551				obj[nodeName] = [];
9552				obj[nodeName].push(old);
9553			}
9554			obj[nodeName].push(this.fromXml(item));
9555		}
9556	}
9557	return obj;
9558};
9559
9560/**
9561 * Converts XML string to JSON
9562 * @param {type} xml
9563 * @returns {unresolved}
9564 */
9565Json.fromXmlString = function(xml) {
9566	return this.fromXml(this.XmlStringToXml(xml));
9567};
9568
9569/**
9570 * @module Json
9571 */
9572module.exports = Json;
9573
9574},{}],167:[function(require,module,exports){
9575function migrate() {
9576	for (var i = 0; i < localStorage.length; i++) {
9577		var key = localStorage.key(i);
9578		fakeEngine.setItem(key, localStorage.getItem(key));
9579	}
9580}
9581
9582var fakeStorage = {};
9583var fakeEngine = {};
9584
9585fakeEngine.getItem = function (key) {
9586	return fakeStorage[key];
9587};
9588fakeEngine.setItem = function (key, value) {
9589	fakeStorage[key] = value;
9590};
9591fakeEngine.removeItem = function (key) {
9592	delete(fakeStorage[key]);
9593};
9594
9595var LocalStorage = {};
9596LocalStorage.getItem = function (key) {
9597	var value = _engine.getItem(key);
9598	try {
9599		return JSON.parse(value);
9600	} catch (e) {
9601		return value;
9602	}
9603};
9604LocalStorage.setItem = function (key, value) {
9605	try {
9606		_engine.setItem(key, JSON.stringify(value));
9607	} catch (e) {
9608		if (~['QUOTA_EXCEEDED_ERR', 'NS_ERROR_DOM_QUOTA_REACHED'].indexOf(e.name) || ~e.toString().indexOf("QUOTA_EXCEEDED_ERR") || ~e.toString().indexOf("QuotaExceededError")) {
9609			_engine = fakeEngine;
9610			migrate();
9611			return this.set(key, value);
9612		}
9613	}
9614	return this;
9615};
9616LocalStorage.removeItem = function (key) {
9617	_engine.removeItem(key);
9618	return this;
9619};
9620
9621LocalStorage.setEngine = function (engine) {
9622	if(!engine.getItem) {
9623		throw new Error('Engine is missing getItem function');
9624	}
9625	if(!engine.setItem) {
9626		throw new Error('Engine is missing setItem function');
9627	}
9628	if(!engine.removeItem) {
9629		throw new Error('Engine is missing removeItem function');
9630	}
9631	_engine = engine;
9632};
9633
9634var _engine = fakeEngine;
9635try {
9636	localStorage.setItem('_privateSafari', 'sucks');
9637	_engine = localStorage;
9638	localStorage.removeItem('_privateSafari');
9639} catch (e) {
9640	console.log('safari private');
9641}
9642module.exports = LocalStorage;
9643
9644},{}],168:[function(require,module,exports){
9645var IQ = require('@icewarp/iq-protocol');
9646var Json = require('@icewarp/json-xml');
9647var processResponse = require('./processResponse');
9648var connections = {};
9649var main = 'default';
9650
9651function createConnection(type) {
9652	this.setConnection(new OldCommunication.connections[type](this.getOptions()));
9653}
9654/**
9655 * @class OldCommunication
9656 * @param {number} type type of connection XHR|Scoket
9657 * @param {string} name will be used as ke for storing this instance in global storage
9658 * @param {object} options
9659 * @returns {OldCommunication}
9660 */
9661function OldCommunication(type, name, options) {
9662	this.host = options.host;
9663	this.email = options.email;
9664	this.subscriptions = options.subscriptions || [];
9665	this.password = options.password;
9666	this.login_type = options.login_type || OldCommunication.PLAIN;
9667	this.send_type = options.send_type || OldCommunication.XML;
9668	options.iq_options = options.iq_options || {};
9669	options.iq_options.id_attr = options.iq_options.id_attr || 'uid';
9670	this.iq = new IQ(options.iq_options);
9671	this.iq.query.addAttribute('xmlns', options.xmlns || "admin:iq:rpc");
9672	options.session_id && this.iq.addAttribute('sid', options.session_id);
9673	createConnection.call(this, type);
9674	connections[name || main] = this;
9675}
9676/**
9677 * @constant
9678 * XHR connection
9679 */
9680OldCommunication.XHR = 1;
9681/**
9682 * @constant
9683 * Socket connection
9684 */
9685OldCommunication.SOCKET = 2;
9686/**
9687 * @type {object}
9688 * @static
9689 * @description List of connection libs
9690 */
9691OldCommunication.connections = {};
9692OldCommunication.connections[OldCommunication.XHR] = require('@icewarp/xhr-connection');
9693OldCommunication.connections[OldCommunication.SOCKET] = require('socket');
9694
9695/**
9696 * @constant
9697 * Plain auth const
9698 */
9699OldCommunication.PLAIN = 1;
9700/**
9701 * @constant
9702 * Auth via RSA digest
9703 */
9704OldCommunication.DIGEST = 2;
9705
9706OldCommunication.XML = 'xml';
9707
9708/**
9709 * @static
9710 * @type {object}
9711 * Error types
9712 */
9713OldCommunication.ERRORS = {
9714	UNSPECIFIED: 'unspecified',
9715	SERVER: 'server'
9716};
9717
9718OldCommunication.prototype.callback = require('Callback');
9719
9720OldCommunication.prototype.getOptions = function () {
9721	return {
9722		protocol: "xmpp",
9723		listeners: {
9724			onopen: {
9725				func: processResponse.onOpen,
9726				context: this
9727			},
9728			onclose: {
9729				func: processResponse.onClose,
9730				context: this
9731			},
9732			onerror: {
9733				func: processResponse.onError,
9734				context: this
9735			},
9736			onmessage: {
9737				func: processResponse.onMessage,
9738				context: this
9739			}
9740		},
9741		host: this.host
9742	};
9743};
9744
9745/**
9746 *
9747 * @param {object} json
9748 * @param {@icewarp/Callback} callback
9749 * @returns {undefined}
9750 */
9751OldCommunication.prototype.send = function (json, callback) {
9752	this.connection.send(this.iq.getIQ(Json.toXmlString(json), callback), this.iq.id);
9753};
9754/**
9755 * Set chosen connection instance
9756 * @param {Xhr|Socket} connection
9757 * @returns {Xhr|Socket}
9758 */
9759OldCommunication.prototype.setConnection = function (connection) {
9760	return this.connection = connection;
9761};
9762/**
9763 * get OldCommunication from global storage
9764 * @param {string} name
9765 * @returns {OldCommunication}
9766 */
9767OldCommunication.getConnection = function (name) {
9768	if (!connections[name || main]) {
9769		throw new Error("Missing connection : " + name);
9770	}
9771	return connections[name || main];
9772};
9773
9774module.exports = OldCommunication;
9775
9776},{"./processResponse":169,"@icewarp/iq-protocol":165,"@icewarp/json-xml":166,"@icewarp/xhr-connection":181,"Callback":"Callback","socket":"socket"}],169:[function(require,module,exports){
9777var Json = require('@icewarp/json-xml');
9778var processResponse = {};
9779
9780function processData(message) {
9781	var response = Json.fromXml(message.document.querySelector('iq'));
9782	if (response._attributes.type === 'error' || response.query.result === '0') {
9783		var error = message.document.querySelector('error');
9784		return this.callback(
9785			'error',
9786			message.callback,
9787			error ? error.getAttribute('uid') || error.textContent : this.constructor.ERRORS.UNSPECIFIED,
9788			response
9789		);
9790	}
9791	this.callback('success', message.callback, response.query.result, response);
9792}
9793
9794processResponse.onMessage = function (data, id) {
9795	processData.call(this, this.iq.getCallbacks(data, id));
9796};
9797processResponse.onError = function (id) {
9798	var iqs = [];
9799	if (id) {
9800		iqs = [this.iq.getCallbacksById(id)];
9801	} else {
9802		var iqs_obj = this.iq.getPendingIqs();
9803		for (var i in iqs_obj) {
9804			iqs.push(iqs_obj[i]);
9805		}
9806	}
9807	iqs.forEach(function (callback) {
9808		this.callback('error', callback, this.constructor.ERRORS.SERVER);
9809	}, this);
9810};
9811processResponse.onClose = function () {
9812
9813};
9814processResponse.onOpen = function () {
9815
9816};
9817
9818module.exports = processResponse;
9819
9820},{"@icewarp/json-xml":166}],170:[function(require,module,exports){
9821var QueryParams = {};
9822QueryParams.parse = function(query) {
9823	var parts = {};
9824	decodeURIComponent(query || location.search || '').replace(/^\?/, '').split('&').forEach(function (val) {
9825		var part = val.split('=');
9826		if(!part[0]) {
9827			return;
9828		}
9829		parts[part.splice(0, 1)] = part.join('=');
9830	});
9831	return parts;
9832};
9833QueryParams.stringify = function(parts) {
9834	return Object.keys(parts).map(function(key) {
9835		return encodeURIComponent(key) + '=' + encodeURIComponent(parts[key]);
9836	}).join('&');
9837};
9838module.exports = QueryParams;
9839},{}],171:[function(require,module,exports){
9840// Copyright (c) 2005  Tom Wu
9841// All Rights Reserved.
9842// See "LICENSE" for details.
9843
9844// Basic JavaScript BN library - subset useful for RSA encryption.
9845
9846// Bits per digit
9847var dbits;
9848
9849// JavaScript engine analysis
9850var canary = 0xdeadbeefcafe;
9851var j_lm = ((canary & 0xffffff) == 0xefcafe);
9852
9853// (public) Constructor
9854function BigInteger(a, b, c) {
9855    if (a != null)
9856        if ("number" == typeof a) this.fromNumber(a, b, c);
9857        else if (b == null && "string" != typeof a) this.fromString(a, 256);
9858        else this.fromString(a, b);
9859}
9860
9861// return new, unset BigInteger
9862function nbi() { return new BigInteger(null); }
9863
9864// am: Compute w_j += (x*this_i), propagate carries,
9865// c is initial carry, returns final carry.
9866// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
9867// We need to select the fastest one that works in this environment.
9868
9869// am1: use a single mult and divide to get the high bits,
9870// max digit bits should be 26 because
9871// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
9872function am1(i, x, w, j, c, n) {
9873    while (--n >= 0) {
9874        var v = x * this[i++] + w[j] + c;
9875        c = Math.floor(v / 0x4000000);
9876        w[j++] = v & 0x3ffffff;
9877    }
9878    return c;
9879}
9880// am2 avoids a big mult-and-extract completely.
9881// Max digit bits should be <= 30 because we do bitwise ops
9882// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
9883function am2(i, x, w, j, c, n) {
9884    var xl = x & 0x7fff, xh = x >> 15;
9885    while (--n >= 0) {
9886        var l = this[i] & 0x7fff;
9887        var h = this[i++] >> 15;
9888        var m = xh * l + h * xl;
9889        l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
9890        c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
9891        w[j++] = l & 0x3fffffff;
9892    }
9893    return c;
9894}
9895// Alternately, set max digit bits to 28 since some
9896// browsers slow down when dealing with 32-bit numbers.
9897function am3(i, x, w, j, c, n) {
9898    var xl = x & 0x3fff, xh = x >> 14;
9899    while (--n >= 0) {
9900        var l = this[i] & 0x3fff;
9901        var h = this[i++] >> 14;
9902        var m = xh * l + h * xl;
9903        l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
9904        c = (l >> 28) + (m >> 14) + xh * h;
9905        w[j++] = l & 0xfffffff;
9906    }
9907    return c;
9908}
9909if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
9910    BigInteger.prototype.am = am2;
9911    dbits = 30;
9912}
9913else if (j_lm && (navigator.appName != "Netscape")) {
9914    BigInteger.prototype.am = am1;
9915    dbits = 26;
9916}
9917else { // Mozilla/Netscape seems to prefer am3
9918    BigInteger.prototype.am = am3;
9919    dbits = 28;
9920}
9921
9922BigInteger.prototype.DB = dbits;
vendor: 14,717 bytes, lines 9923-10416
9923BigInteger.prototype.DM = ((1 << dbits) - 1);
9924BigInteger.prototype.DV = (1 << dbits);
9925
9926var BI_FP = 52;
9927BigInteger.prototype.FV = Math.pow(2, BI_FP);
9928BigInteger.prototype.F1 = BI_FP - dbits;
9929BigInteger.prototype.F2 = 2 * dbits - BI_FP;
9930
9931// Digit conversions
9932var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
9933var BI_RC = new Array();
9934var rr, vv;
9935rr = "0".charCodeAt(0);
9936for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
9937rr = "a".charCodeAt(0);
9938for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
9939rr = "A".charCodeAt(0);
9940for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
9941
9942function int2char(n) { return BI_RM.charAt(n); }
9943function intAt(s, i) {
9944    var c = BI_RC[s.charCodeAt(i)];
9945    return (c == null) ? -1 : c;
9946}
9947
9948// (protected) copy this to r
9949function bnpCopyTo(r) {
9950    for (var i = this.t - 1; i >= 0; --i) r[i] = this[i];
9951    r.t = this.t;
9952    r.s = this.s;
9953}
9954
9955// (protected) set from integer value x, -DV <= x < DV
9956function bnpFromInt(x) {
9957    this.t = 1;
9958    this.s = (x < 0) ? -1 : 0;
9959    if (x > 0) this[0] = x;
9960    else if (x < -1) this[0] = x + this.DV;
9961    else this.t = 0;
9962}
9963
9964// return bigint initialized to value
9965function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
9966
9967// (protected) set from string and radix
9968function bnpFromString(s, b) {
9969    var k;
9970    if (b == 16) k = 4;
9971    else if (b == 8) k = 3;
9972    else if (b == 256) k = 8; // byte array
9973    else if (b == 2) k = 1;
9974    else if (b == 32) k = 5;
9975    else if (b == 4) k = 2;
9976    else { this.fromRadix(s, b); return; }
9977    this.t = 0;
9978    this.s = 0;
9979    var i = s.length, mi = false, sh = 0;
9980    while (--i >= 0) {
9981        var x = (k == 8) ? s[i] & 0xff : intAt(s, i);
9982        if (x < 0) {
9983            if (s.charAt(i) == "-") mi = true;
9984            continue;
9985        }
9986        mi = false;
9987        if (sh == 0)
9988            this[this.t++] = x;
9989        else if (sh + k > this.DB) {
9990            this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh;
9991            this[this.t++] = (x >> (this.DB - sh));
9992        }
9993        else
9994            this[this.t - 1] |= x << sh;
9995        sh += k;
9996        if (sh >= this.DB) sh -= this.DB;
9997    }
9998    if (k == 8 && (s[0] & 0x80) != 0) {
9999        this.s = -1;
10000        if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh;
10001    }
10002    this.clamp();
10003    if (mi) BigInteger.ZERO.subTo(this, this);
10004}
10005
10006// (protected) clamp off excess high words
10007function bnpClamp() {
10008    var c = this.s & this.DM;
10009    while (this.t > 0 && this[this.t - 1] == c) --this.t;
10010}
10011
10012// (public) return string representation in given radix
10013function bnToString(b) {
10014    if (this.s < 0) return "-" + this.negate().toString(b);
10015    var k;
10016    if (b == 16) k = 4;
10017    else if (b == 8) k = 3;
10018    else if (b == 2) k = 1;
10019    else if (b == 32) k = 5;
10020    else if (b == 4) k = 2;
10021    else return this.toRadix(b);
10022    var km = (1 << k) - 1, d, m = false, r = "", i = this.t;
10023    var p = this.DB - (i * this.DB) % k;
10024    if (i-- > 0) {
10025        if (p < this.DB && (d = this[i] >> p) > 0) { m = true; r = int2char(d); }
10026        while (i >= 0) {
10027            if (p < k) {
10028                d = (this[i] & ((1 << p) - 1)) << (k - p);
10029                d |= this[--i] >> (p += this.DB - k);
10030            }
10031            else {
10032                d = (this[i] >> (p -= k)) & km;
10033                if (p <= 0) { p += this.DB; --i; }
10034            }
10035            if (d > 0) m = true;
10036            if (m) r += int2char(d);
10037        }
10038    }
10039    return m ? r : "0";
10040}
10041
10042// (public) -this
10043function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this, r); return r; }
10044
10045// (public) |this|
10046function bnAbs() { return (this.s < 0) ? this.negate() : this; }
10047
10048// (public) return + if this > a, - if this < a, 0 if equal
10049function bnCompareTo(a) {
10050    var r = this.s - a.s;
10051    if (r != 0) return r;
10052    var i = this.t;
10053    r = i - a.t;
10054    if (r != 0) return (this.s < 0) ? -r : r;
10055    while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r;
10056    return 0;
10057}
10058
10059// returns bit length of the integer x
10060function nbits(x) {
10061    var r = 1, t;
10062    if ((t = x >>> 16) != 0) { x = t; r += 16; }
10063    if ((t = x >> 8) != 0) { x = t; r += 8; }
10064    if ((t = x >> 4) != 0) { x = t; r += 4; }
10065    if ((t = x >> 2) != 0) { x = t; r += 2; }
10066    if ((t = x >> 1) != 0) { x = t; r += 1; }
10067    return r;
10068}
10069
10070// (public) return the number of bits in "this"
10071function bnBitLength() {
10072    if (this.t <= 0) return 0;
10073    return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM));
10074}
10075
10076// (protected) r = this << n*DB
10077function bnpDLShiftTo(n, r) {
10078    var i;
10079    for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i];
10080    for (i = n - 1; i >= 0; --i) r[i] = 0;
10081    r.t = this.t + n;
10082    r.s = this.s;
10083}
10084
10085// (protected) r = this >> n*DB
10086function bnpDRShiftTo(n, r) {
10087    for (var i = n; i < this.t; ++i) r[i - n] = this[i];
10088    r.t = Math.max(this.t - n, 0);
10089    r.s = this.s;
10090}
10091
10092// (protected) r = this << n
10093function bnpLShiftTo(n, r) {
10094    var bs = n % this.DB;
10095    var cbs = this.DB - bs;
10096    var bm = (1 << cbs) - 1;
10097    var ds = Math.floor(n / this.DB), c = (this.s << bs) & this.DM, i;
10098    for (i = this.t - 1; i >= 0; --i) {
10099        r[i + ds + 1] = (this[i] >> cbs) | c;
10100        c = (this[i] & bm) << bs;
10101    }
10102    for (i = ds - 1; i >= 0; --i) r[i] = 0;
10103    r[ds] = c;
10104    r.t = this.t + ds + 1;
10105    r.s = this.s;
10106    r.clamp();
10107}
10108
10109// (protected) r = this >> n
10110function bnpRShiftTo(n, r) {
10111    r.s = this.s;
10112    var ds = Math.floor(n / this.DB);
10113    if (ds >= this.t) { r.t = 0; return; }
10114    var bs = n % this.DB;
10115    var cbs = this.DB - bs;
10116    var bm = (1 << bs) - 1;
10117    r[0] = this[ds] >> bs;
10118    for (var i = ds + 1; i < this.t; ++i) {
10119        r[i - ds - 1] |= (this[i] & bm) << cbs;
10120        r[i - ds] = this[i] >> bs;
10121    }
10122    if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs;
10123    r.t = this.t - ds;
10124    r.clamp();
10125}
10126
10127// (protected) r = this - a
10128function bnpSubTo(a, r) {
10129    var i = 0, c = 0, m = Math.min(a.t, this.t);
10130    while (i < m) {
10131        c += this[i] - a[i];
10132        r[i++] = c & this.DM;
10133        c >>= this.DB;
10134    }
10135    if (a.t < this.t) {
10136        c -= a.s;
10137        while (i < this.t) {
10138            c += this[i];
10139            r[i++] = c & this.DM;
10140            c >>= this.DB;
10141        }
10142        c += this.s;
10143    }
10144    else {
10145        c += this.s;
10146        while (i < a.t) {
10147            c -= a[i];
10148            r[i++] = c & this.DM;
10149            c >>= this.DB;
10150        }
10151        c -= a.s;
10152    }
10153    r.s = (c < 0) ? -1 : 0;
10154    if (c < -1) r[i++] = this.DV + c;
10155    else if (c > 0) r[i++] = c;
10156    r.t = i;
10157    r.clamp();
10158}
10159
10160// (protected) r = this * a, r != this,a (HAC 14.12)
10161// "this" should be the larger one if appropriate.
10162function bnpMultiplyTo(a, r) {
10163    var x = this.abs(), y = a.abs();
10164    var i = x.t;
10165    r.t = i + y.t;
10166    while (--i >= 0) r[i] = 0;
10167    for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
10168    r.s = 0;
10169    r.clamp();
10170    if (this.s != a.s) BigInteger.ZERO.subTo(r, r);
10171}
10172
10173// (protected) r = this^2, r != this (HAC 14.16)
10174function bnpSquareTo(r) {
10175    var x = this.abs();
10176    var i = r.t = 2 * x.t;
10177    while (--i >= 0) r[i] = 0;
10178    for (i = 0; i < x.t - 1; ++i) {
10179        var c = x.am(i, x[i], r, 2 * i, 0, 1);
10180        if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
10181            r[i + x.t] -= x.DV;
10182            r[i + x.t + 1] = 1;
10183        }
10184    }
10185    if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
10186    r.s = 0;
10187    r.clamp();
10188}
10189
10190// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
10191// r != q, this != m.  q or r may be null.
10192function bnpDivRemTo(m, q, r) {
10193    var pm = m.abs();
10194    if (pm.t <= 0) return;
10195    var pt = this.abs();
10196    if (pt.t < pm.t) {
10197        if (q != null) q.fromInt(0);
10198        if (r != null) this.copyTo(r);
10199        return;
10200    }
10201    if (r == null) r = nbi();
10202    var y = nbi(), ts = this.s, ms = m.s;
10203    var nsh = this.DB - nbits(pm[pm.t - 1]);	// normalize modulus
10204    if (nsh > 0) { pm.lShiftTo(nsh, y); pt.lShiftTo(nsh, r); }
10205    else { pm.copyTo(y); pt.copyTo(r); }
10206    var ys = y.t;
10207    var y0 = y[ys - 1];
10208    if (y0 == 0) return;
10209    var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0);
10210    var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2;
10211    var i = r.t, j = i - ys, t = (q == null) ? nbi() : q;
10212    y.dlShiftTo(j, t);
10213    if (r.compareTo(t) >= 0) {
10214        r[r.t++] = 1;
10215        r.subTo(t, r);
10216    }
10217    BigInteger.ONE.dlShiftTo(ys, t);
10218    t.subTo(y, y);	// "negative" y so we can replace sub with am later
10219    while (y.t < ys) y[y.t++] = 0;
10220    while (--j >= 0) {
10221        // Estimate quotient digit
10222        var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
10223        if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) {	// Try it out
10224            y.dlShiftTo(j, t);
10225            r.subTo(t, r);
10226            while (r[i] < --qd) r.subTo(t, r);
10227        }
10228    }
10229    if (q != null) {
10230        r.drShiftTo(ys, q);
10231        if (ts != ms) BigInteger.ZERO.subTo(q, q);
10232    }
10233    r.t = ys;
10234    r.clamp();
10235    if (nsh > 0) r.rShiftTo(nsh, r);	// Denormalize remainder
10236    if (ts < 0) BigInteger.ZERO.subTo(r, r);
10237}
10238
10239// (public) this mod a
10240function bnMod(a) {
10241    var r = nbi();
10242    this.abs().divRemTo(a, null, r);
10243    if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r);
10244    return r;
10245}
10246
10247// Modular reduction using "classic" algorithm
10248function Classic(m) { this.m = m; }
10249function cConvert(x) {
10250    if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
10251    else return x;
10252}
10253function cRevert(x) { return x; }
10254function cReduce(x) { x.divRemTo(this.m, null, x); }
10255function cMulTo(x, y, r) { x.multiplyTo(y, r); this.reduce(r); }
10256function cSqrTo(x, r) { x.squareTo(r); this.reduce(r); }
10257
10258Classic.prototype.convert = cConvert;
10259Classic.prototype.revert = cRevert;
10260Classic.prototype.reduce = cReduce;
10261Classic.prototype.mulTo = cMulTo;
10262Classic.prototype.sqrTo = cSqrTo;
10263
10264// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
10265// justification:
10266//         xy == 1 (mod m)
10267//         xy =  1+km
10268//   xy(2-xy) = (1+km)(1-km)
10269// x[y(2-xy)] = 1-k^2m^2
10270// x[y(2-xy)] == 1 (mod m^2)
10271// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
10272// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
10273// JS multiply "overflows" differently from C/C++, so care is needed here.
10274function bnpInvDigit() {
10275    if (this.t < 1) return 0;
10276    var x = this[0];
10277    if ((x & 1) == 0) return 0;
10278    var y = x & 3;		// y == 1/x mod 2^2
10279    y = (y * (2 - (x & 0xf) * y)) & 0xf;	// y == 1/x mod 2^4
10280    y = (y * (2 - (x & 0xff) * y)) & 0xff;	// y == 1/x mod 2^8
10281    y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff;	// y == 1/x mod 2^16
10282    // last step - calculate inverse mod DV directly;
10283    // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
10284    y = (y * (2 - x * y % this.DV)) % this.DV;		// y == 1/x mod 2^dbits
10285    // we really want the negative inverse, and -DV < y < DV
10286    return (y > 0) ? this.DV - y : -y;
10287}
10288
10289// Montgomery reduction
10290function Montgomery(m) {
10291    this.m = m;
10292    this.mp = m.invDigit();
10293    this.mpl = this.mp & 0x7fff;
10294    this.mph = this.mp >> 15;
10295    this.um = (1 << (m.DB - 15)) - 1;
10296    this.mt2 = 2 * m.t;
10297}
10298
10299// xR mod m
10300function montConvert(x) {
10301    var r = nbi();
10302    x.abs().dlShiftTo(this.m.t, r);
10303    r.divRemTo(this.m, null, r);
10304    if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r);
10305    return r;
10306}
10307
10308// x/R mod m
10309function montRevert(x) {
10310    var r = nbi();
10311    x.copyTo(r);
10312    this.reduce(r);
10313    return r;
10314}
10315
10316// x = x/R mod m (HAC 14.32)
10317function montReduce(x) {
10318    while (x.t <= this.mt2)	// pad x so am has enough room later
10319        x[x.t++] = 0;
10320    for (var i = 0; i < this.m.t; ++i) {
10321        // faster way of calculating u0 = x[i]*mp mod DV
10322        var j = x[i] & 0x7fff;
10323        var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM;
10324        // use am to combine the multiply-shift-add into one call
10325        j = i + this.m.t;
10326        x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
10327        // propagate carry
10328        while (x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
10329    }
10330    x.clamp();
10331    x.drShiftTo(this.m.t, x);
10332    if (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
10333}
10334
10335// r = "x^2/R mod m"; x != r
10336function montSqrTo(x, r) { x.squareTo(r); this.reduce(r); }
10337
10338// r = "xy/R mod m"; x,y != r
10339function montMulTo(x, y, r) { x.multiplyTo(y, r); this.reduce(r); }
10340
10341Montgomery.prototype.convert = montConvert;
10342Montgomery.prototype.revert = montRevert;
10343Montgomery.prototype.reduce = montReduce;
10344Montgomery.prototype.mulTo = montMulTo;
10345Montgomery.prototype.sqrTo = montSqrTo;
10346
10347// (protected) true iff this is even
10348function bnpIsEven() { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; }
10349
10350// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
10351function bnpExp(e, z) {
10352    if (e > 0xffffffff || e < 1) return BigInteger.ONE;
10353    var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1;
10354    g.copyTo(r);
10355    while (--i >= 0) {
10356        z.sqrTo(r, r2);
10357        if ((e & (1 << i)) > 0) z.mulTo(r2, g, r);
10358        else { var t = r; r = r2; r2 = t; }
10359    }
10360    return z.revert(r);
10361}
10362
10363// (public) this^e % m, 0 <= e < 2^32
10364function bnModPowInt(e, m) {
10365    var z;
10366    if (e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
10367    return this.exp(e, z);
10368}
10369
10370// protected
10371BigInteger.prototype.copyTo = bnpCopyTo;
10372BigInteger.prototype.fromInt = bnpFromInt;
10373BigInteger.prototype.fromString = bnpFromString;
10374BigInteger.prototype.clamp = bnpClamp;
10375BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
10376BigInteger.prototype.drShiftTo = bnpDRShiftTo;
10377BigInteger.prototype.lShiftTo = bnpLShiftTo;
10378BigInteger.prototype.rShiftTo = bnpRShiftTo;
10379BigInteger.prototype.subTo = bnpSubTo;
10380BigInteger.prototype.multiplyTo = bnpMultiplyTo;
10381BigInteger.prototype.squareTo = bnpSquareTo;
10382BigInteger.prototype.divRemTo = bnpDivRemTo;
10383BigInteger.prototype.invDigit = bnpInvDigit;
10384BigInteger.prototype.isEven = bnpIsEven;
10385BigInteger.prototype.exp = bnpExp;
10386
10387// public
10388BigInteger.prototype.toString = bnToString;
10389BigInteger.prototype.negate = bnNegate;
10390BigInteger.prototype.abs = bnAbs;
10391BigInteger.prototype.compareTo = bnCompareTo;
10392BigInteger.prototype.bitLength = bnBitLength;
10393BigInteger.prototype.mod = bnMod;
10394BigInteger.prototype.modPowInt = bnModPowInt;
10395
10396// "constants"
10397BigInteger.ZERO = nbv(0);
10398BigInteger.ONE = nbv(1);
10399
10400module.exports = BigInteger;
10401},{}],172:[function(require,module,exports){
10402// prng4.js - uses Arcfour as a PRNG
10403
10404function Arcfour() {
10405    this.i = 0;
10406    this.j = 0;
10407    this.S = new Array();
10408}
10409
10410// Initialize arcfour context from key, an array of ints, each from [0..255]
10411function ARC4init(key) {
10412    var i, j, t;
10413    for (i = 0; i < 256; ++i)
10414        this.S[i] = i;
10415    j = 0;
10416    for (i = 0; i < 256; ++i) {
10417        j = (j + this.S[i] + key[i % key.length]) & 255;
10418        t = this.S[i];
10419        this.S[i] = this.S[j];
10420        this.S[j] = t;
10421    }
10422    this.i = 0;
10423    this.j = 0;
10424}
10425
10426function ARC4next() {
10427    var t;
10428    this.i = (this.i + 1) & 255;
10429    this.j = (this.j + this.S[this.i]) & 255;
10430    t = this.S[this.i];
10431    this.S[this.i] = this.S[this.j];
10432    this.S[this.j] = t;
10433    return this.S[(t + this.S[this.i]) & 255];
10434}
10435
10436Arcfour.prototype.init = ARC4init;
10437Arcfour.prototype.next = ARC4next;
10438
10439// Plug in your RNG constructor here
10440function prng_newstate() {
10441    return new Arcfour();
10442}
10443
10444// Pool size must be a multiple of 4 and greater than 32.
10445// An array of bytes the size of the pool will be passed to init()
10446var rng_psize = 256;
10447
10448module.exports = {
10449    prng_newstate: prng_newstate,
10450    rng_psize: rng_psize
10451};
10452},{}],173:[function(require,module,exports){
10453// Random number generator - requires a PRNG backend, e.g. prng4.js
10454var prng4 = require('./prng4');
10455var prng_newstate = prng4.prng_newstate;
10456var rng_psize = prng4.rng_psize;
10457
10458// For best results, put code like
10459// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
10460// in your main HTML document.
10461
10462var rng_state;
10463var rng_pool;
10464var rng_pptr;
10465
10466// Mix in a 32-bit integer into the pool
10467function rng_seed_int(x) {
10468    rng_pool[rng_pptr++] ^= x & 255;
10469    rng_pool[rng_pptr++] ^= (x >> 8) & 255;
10470    rng_pool[rng_pptr++] ^= (x >> 16) & 255;
10471    rng_pool[rng_pptr++] ^= (x >> 24) & 255;
10472    if (rng_pptr >= rng_psize) rng_pptr -= rng_psize;
10473}
10474
10475// Mix in the current time (w/milliseconds) into the pool
10476function rng_seed_time() {
10477    rng_seed_int(new Date().getTime());
10478}
10479
10480// Initialize the pool with junk if needed.
10481if (rng_pool == null) {
10482    rng_pool = new Array();
10483    rng_pptr = 0;
10484    var t;
10485    if (window.crypto && window.crypto.getRandomValues) {
10486        // Use webcrypto if available
10487        var ua = new Uint8Array(32);
10488        window.crypto.getRandomValues(ua);
10489        for (t = 0; t < 32; ++t)
10490            rng_pool[rng_pptr++] = ua[t];
10491    }
10492    if (navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
10493        // Extract entropy (256 bits) from NS4 RNG if available
10494        var z = window.crypto.random(32);
10495        for (t = 0; t < z.length; ++t)
10496            rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
10497    }
10498    while (rng_pptr < rng_psize) {  // extract some randomness from Math.random()
10499        t = Math.floor(65536 * Math.random());
10500        rng_pool[rng_pptr++] = t >>> 8;
10501        rng_pool[rng_pptr++] = t & 255;
10502    }
10503    rng_pptr = 0;
10504    rng_seed_time();
10505    //rng_seed_int(window.screenX);
10506    //rng_seed_int(window.screenY);
10507}
10508
10509function rng_get_byte() {
10510    if (rng_state == null) {
10511        rng_seed_time();
10512        rng_state = prng_newstate();
10513        rng_state.init(rng_pool);
10514        for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
10515            rng_pool[rng_pptr] = 0;
10516        rng_pptr = 0;
10517        //rng_pool = null;
10518    }
10519    // TODO: allow reseeding after first request
10520    return rng_state.next();
10521}
10522
10523function rng_get_bytes(ba) {
10524    var i;
10525    for (i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
10526}
10527
10528function SecureRandom() { }
10529
10530SecureRandom.prototype.nextBytes = rng_get_bytes;
10531
10532module.exports = SecureRandom;
10533},{"./prng4":172}],174:[function(require,module,exports){
10534// Depends on jsbn.js and rng.js
10535var BigInteger = require('./jsbn');
10536var SecureRandom = require('./rng');
10537
10538// Version 1.1: support utf-8 encoding in pkcs1pad2
10539
10540// convert a (hex) string to a bignum object
10541function parseBigInt(str, r) {
10542	return new BigInteger(str, r);
10543}
10544
10545function linebrk(s, n) {
10546	var ret = "";
10547	var i = 0;
10548	while (i + n < s.length) {
10549		ret += s.substring(i, i + n) + "\n";
10550		i += n;
10551	}
10552	return ret + s.substring(i, s.length);
10553}
10554
10555function byte2Hex(b) {
10556	if (b < 0x10)
10557		return "0" + b.toString(16);
10558	else
10559		return b.toString(16);
10560}
10561
10562// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
10563function pkcs1pad2(s, n) {
10564	if (n < s.length + 11) { // TODO: fix for utf-8
10565		alert("Message too long for RSA");
10566		return null;
10567	}
10568	var ba = new Array();
10569	var i = s.length - 1;
10570	while (i >= 0 && n > 0) {
10571		var c = s.charCodeAt(i--);
10572		if (c < 128) { // encode using utf-8
10573			ba[--n] = c;
10574		}
10575		else if ((c > 127) && (c < 2048)) {
10576			ba[--n] = (c & 63) | 128;
10577			ba[--n] = (c >> 6) | 192;
10578		}
10579		else {
10580			ba[--n] = (c & 63) | 128;
10581			ba[--n] = ((c >> 6) & 63) | 128;
10582			ba[--n] = (c >> 12) | 224;
10583		}
10584	}
10585	ba[--n] = 0;
10586	var rng = new SecureRandom();
10587	var x = new Array();
10588	while (n > 2) { // random non-zero pad
10589		x[0] = 0;
10590		while (x[0] == 0) rng.nextBytes(x);
10591		ba[--n] = x[0];
10592	}
10593	ba[--n] = 2;
10594	ba[--n] = 0;
10595	return new BigInteger(ba);
10596}
10597
10598// "empty" RSA key constructor
10599function RSAKey() {
10600	this.n = null;
10601	this.e = 0;
10602	this.d = null;
10603	this.p = null;
10604	this.q = null;
10605	this.dmp1 = null;
10606	this.dmq1 = null;
10607	this.coeff = null;
10608}
10609
10610// Set the public key fields N and e from hex strings
10611function RSASetPublic(N, E) {
10612	if (N != null && E != null && N.length > 0 && E.length > 0) {
10613		this.n = parseBigInt(N, 16);
10614		this.e = parseInt(E, 16);
10615	}
10616	else
10617		alert("Invalid RSA public key");
10618}
10619
10620// Perform raw public operation on "x": return x^e (mod n)
10621function RSADoPublic(x) {
10622	return x.modPowInt(this.e, this.n);
10623}
10624
10625// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
10626function RSAEncrypt(text) {
10627	var m = pkcs1pad2(text, (this.n.bitLength() + 7) >> 3);
10628	if (m == null) return null;
10629	var c = this.doPublic(m);
10630	if (c == null) return null;
10631	var h = c.toString(16);
10632	if ((h.length & 1) == 0) return h; else return "0" + h;
10633}
10634
10635// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
10636//function RSAEncryptB64(text) {
10637//  var h = this.encrypt(text);
10638//  if(h) return hex2b64(h); else return null;
10639//}
10640
10641// protected
10642RSAKey.prototype.doPublic = RSADoPublic;
10643
10644// public
10645RSAKey.prototype.setPublic = RSASetPublic;
10646RSAKey.prototype.encrypt = RSAEncrypt;
10647//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
10648
10649module.exports = RSAKey;
10650},{"./jsbn":171,"./rng":173}],175:[function(require,module,exports){
10651var StringUtils = require('./string.js');
10652var Utils = {};
10653
10654var supress_animations = false;
10655/**
10656 * Supress animations
10657 */
10658Utils.supress = function () {
10659	document.body.classList.add('no-animation');
10660	supress_animations = true;
10661};
10662
10663/**
10664 * Allow animations
10665 */
10666Utils.allow = function () {
10667	document.body.classList.remove('no-animation');
10668	supress_animations = false;
10669};
10670
10671/**
10672 * Returns whether animations are enabled
10673 * @returns {Boolean}
10674 */
10675Utils.allowed = function () {
10676	return !supress_animations;
10677};
10678
10679/**
10680 * Return supported browser event type
10681 * @param {String} event
10682 * @returns {String|Boolean} Supported event type or false
10683 */
10684Utils.browserEvent = function (event) {
10685	if (!this.allowed()) {
10686		return false;
10687	}
10688	if (('on' + event) in window || event.replace(/end|start|update$/, '') in document.body.style) {
10689		return event;
10690	}
10691	if (('onwebkit' + event) in window) {
10692		return 'webkit' + StringUtils.capitalize(event[0]).replace(/(end|start|update)$/, StringUtils.capitalize);
10693	}
10694	return false;
10695};
10696
10697module.exports = Utils;
10698},{"./string.js":179}],176:[function(require,module,exports){
10699var Utils = {};
10700
10701/**
10702 * Detect if the browser is IE 9+
10703 * @returns {Boolean}
10704 */
10705Utils.isIE = function () {
10706	return !!(window.ActiveXObject || "ActiveXObject" in window);
10707};
10708
10709/**
10710 * Detect if the browser is MS Edge
10711 * @returns {Boolean}
10712 */
10713Utils.isEdge = function () {
10714	return !Utils.isIE() && !!window.StyleMedia;
10715};
10716
10717module.exports = Utils;
10718},{}],177:[function(require,module,exports){
10719var Utils = {};
10720
10721/**
10722 * Push items from arr array to data object
10723 * @param {*} data
10724 * @param {*} arr
10725 * @returns {Utils.push.data}
10726 */
10727Utils.push = function (data, arr) {
10728	data = data || [];
10729	[].push.apply(data, Array.isArray(arr) ? arr : [arr]);
10730	data = data.filter(function (value, index) {
10731		return value !== void 0 && data.indexOf(value) === index;
10732	});
10733	return data;
10734};
10735
10736/**
10737 * Push items from arr array to data property
10738 * @param {Object} data
10739 * @param {String} property
10740 * @param {*} arr
10741 * @returns {Array}
10742 */
10743Utils.pushToProperty = function (data, property, arr) {
10744	if (data === void 0) {
10745		return data;
10746	}
10747	data[property] = data[property] || [];
10748	[].push.apply(data[property], Array.isArray(arr) ? arr : [arr]);
10749	data[property] = data[property].filter(function (value, index) {
10750		return value !== void 0 && data[property].indexOf(value) === index;
10751	});
10752	return data;
10753};
10754
10755Utils.splice = function (array, item) {
10756	if (!Array.isArray(array)) {
10757		return false;
10758	}
10759	if (Array.isArray(item)) {
10760		return item.forEach(function (i) {
10761			Utils.splice(array, i);
10762		});
10763	}
10764	array.splice(array.indexOf(item), 1);
10765};
10766
10767module.exports = Utils;
10768},{}],178:[function(require,module,exports){
10769var Utils = {};
10770
10771Utils.enabled = function () {
10772	return document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled;
10773};
10774
10775Utils.element = function () {
10776	return document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement;
10777};
10778
10779Utils.exit = function () {
10780	(document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen || function () {}).bind(document)();
10781};
10782
10783Utils.request = function (element) {
10784	(element.requestFullscreen || element.webkitRequestFullscreen || element.mozRequestFullScreen || element.msRequestFullscreen || function () {}).bind(element)();
10785};
10786
10787module.exports = Utils;
10788},{}],179:[function(require,module,exports){
10789var Utils = {};
10790var accentMap;
10791
10792/**
10793 * Capitalize string
10794 * @param {String} string
10795 * @returns {String} capitalized string
10796 */
10797Utils.capitalize = function (string) {
10798	return string[0].toUpperCase() + string.slice(1);
10799};
10800
10801/**
10802 * Escape HTML entities &<>"'
10803 * @param {String} unsafe unescaped string
10804 * @returns {String} escaped string
10805 */
10806Utils.escapeHtml = function (unsafe) {
10807	return unsafe
10808		.replace(/&/g, "&amp;")
10809		.replace(/</g, "&lt;")
10810		.replace(/>/g, "&gt;")
10811		.replace(/"/g, "&quot;")
10812		.replace(/'/g, "&#039;");
10813};
10814
10815/**
10816 * Remove accents from input string
10817 * @param {String} input
10818 * @returns String
10819 */
10820Utils.removeAccents = function (input) {
10821	return input.replace(/[^A-Za-z0-9\s]/g, function (a) {
10822		accentMap = accentMap || buildAccentMap();
10823		return accentMap[a] || a;
10824	});
10825};
10826
10827function buildAccentMap() {
10828	var accentMap = {};
10829	var map = [
10830		{ base: 'A', letters: '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F' },
10831		{ base: 'AA', letters: '\uA732' },
10832		{ base: 'AE', letters: '\u00C6\u01FC\u01E2' },
10833		{ base: 'AO', letters: '\uA734' },
10834		{ base: 'AU', letters: '\uA736' },
10835		{ base: 'AV', letters: '\uA738\uA73A' },
10836		{ base: 'AY', letters: '\uA73C' },
10837		{ base: 'B', letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181' },
10838		{ base: 'C', letters: '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E' },
10839		{ base: 'D', letters: '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779' },
10840		{ base: 'DZ', letters: '\u01F1\u01C4' },
10841		{ base: 'Dz', letters: '\u01F2\u01C5' },
10842		{ base: 'E', letters: '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E' },
10843		{ base: 'F', letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' },
10844		{ base: 'G', letters: '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E' },
10845		{ base: 'H', letters: '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D' },
10846		{ base: 'I', letters: '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197' },
10847		{ base: 'J', letters: '\u004A\u24BF\uFF2A\u0134\u0248' },
10848		{ base: 'K', letters: '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2' },
10849		{ base: 'L', letters: '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780' },
10850		{ base: 'LJ', letters: '\u01C7' },
10851		{ base: 'Lj', letters: '\u01C8' },
10852		{ base: 'M', letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' },
10853		{ base: 'N', letters: '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4' },
10854		{ base: 'NJ', letters: '\u01CA' },
10855		{ base: 'Nj', letters: '\u01CB' },
10856		{ base: 'O', letters: '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C' },
10857		{ base: 'OI', letters: '\u01A2' },
10858		{ base: 'OO', letters: '\uA74E' },
10859		{ base: 'OU', letters: '\u0222' },
10860		{ base: 'P', letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754' },
10861		{ base: 'Q', letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A' },
10862		{ base: 'R', letters: '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782' },
10863		{ base: 'S', letters: '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784' },
10864		{ base: 'T', letters: '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786' },
10865		{ base: 'TZ', letters: '\uA728' },
10866		{ base: 'U', letters: '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244' },
10867		{ base: 'V', letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' },
10868		{ base: 'VY', letters: '\uA760' },
10869		{ base: 'W', letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72' },
10870		{ base: 'X', letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C' },
10871		{ base: 'Y', letters: '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE' },
10872		{ base: 'Z', letters: '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762' },
10873		{ base: 'a', letters: '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250' },
10874		{ base: 'aa', letters: '\uA733' },
10875		{ base: 'ae', letters: '\u00E6\u01FD\u01E3' },
10876		{ base: 'ao', letters: '\uA735' },
10877		{ base: 'au', letters: '\uA737' },
10878		{ base: 'av', letters: '\uA739\uA73B' },
10879		{ base: 'ay', letters: '\uA73D' },
10880		{ base: 'b', letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253' },
10881		{ base: 'c', letters: '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184' },
10882		{ base: 'd', letters: '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A' },
10883		{ base: 'dz', letters: '\u01F3\u01C6' },
10884		{ base: 'e', letters: '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD' },
10885		{ base: 'f', letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' },
10886		{ base: 'g', letters: '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F' },
10887		{ base: 'h', letters: '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265' },
10888		{ base: 'hv', letters: '\u0195' },
10889		{ base: 'i', letters: '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131' },
10890		{ base: 'j', letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' },
10891		{ base: 'k', letters: '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3' },
10892		{ base: 'l', letters: '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747' },
10893		{ base: 'lj', letters: '\u01C9' },
10894		{ base: 'm', letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' },
10895		{ base: 'n', letters: '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5' },
10896		{ base: 'nj', letters: '\u01CC' },
10897		{ base: 'o', letters: '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275' },
10898		{ base: 'oi', letters: '\u01A3' },
10899		{ base: 'ou', letters: '\u0223' },
10900		{ base: 'oo', letters: '\uA74F' },
10901		{ base: 'p', letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755' },
10902		{ base: 'q', letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759' },
10903		{ base: 'r', letters: '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783' },
10904		{ base: 's', letters: '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B' },
10905		{ base: 't', letters: '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787' },
10906		{ base: 'tz', letters: '\uA729' },
10907		{ base: 'u', letters: '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289' },
10908		{ base: 'v', letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' },
10909		{ base: 'vy', letters: '\uA761' },
10910		{ base: 'w', letters: '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73' },
10911		{ base: 'x', letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D' },
10912		{ base: 'y', letters: '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u
109121EF5\u01B4\u024F\u1EFF' },
10913		{ base: 'z', letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763' }
10914	];
10915
10916	for (var i = 0; i < map.length; i++) {
10917		var letters = map[i].letters.split("");
10918		for (var j = 0; j < letters.length; j++) {
10919			accentMap[letters[j]] = map[i].base;
10920		}
10921	}
10922	return accentMap;
10923}
10924
10925module.exports = Utils;
10926},{}],180:[function(require,module,exports){
10927var Utils = {};
10928
10929Utils.animations = require('./src/animations.js');
10930Utils.browser = require('./src/browser.js');
10931Utils.data = require('./src/data.js');
10932Utils.fullscreen = require('./src/fullscreen.js');
10933Utils.string = require('./src/string.js');
10934
10935module.exports = Utils;
10936},{"./src/animations.js":175,"./src/browser.js":176,"./src/data.js":177,"./src/fullscreen.js":178,"./src/string.js":179}],181:[function(require,module,exports){
10937var Request = require('request');
10938
10939function onLoad(id, event, response) {
10940	this.onMessage && this.onMessage.func.call(this.onMessage.context || this, response.response || response.responseText, id);
10941}
10942function onError(id, event, response) {
10943	this.onError && this.onError.func.call(this.onError.context || this, id);
10944}
10945
10946function XHRConnection(options) {
10947	options.listeners = options.listeners || {};
10948	this.onMessage = options.listeners.onmessage;
10949	this.onError = options.listeners.onerror;
10950	this.host = options.host;
10951}
10952
10953XHRConnection.prototype.send = function (payload, id) {
10954	var request = new Request({
10955		url: this.host,
10956		method: "POST"
10957	});
10958	request.on('load', onLoad.bind(this, id));
10959	request.on('error', onError.bind(this, id));
10960	request.on('abort', onError.bind(this, id));
10961	request.send(payload);
10962};
10963
10964module.exports = XHRConnection;
10965
10966},{"request":"request"}],182:[function(require,module,exports){
10967Object.defineProperty(exports, '__esModule', { value: true });
10968
10969const utils = require('@sentry/utils');
10970const core = require('@sentry/core');
10971
10972// exporting a separate copy of `WINDOW` rather than exporting the one from `@sentry/browser`
10973// prevents the browser package from being bundled in the CDN bundle, and avoids a
10974// circular dependency between the browser and feedback packages
10975const WINDOW = utils.GLOBAL_OBJ ;
10976
10977const LIGHT_BACKGROUND = '#ffffff';
10978const INHERIT = 'inherit';
10979const SUBMIT_COLOR = 'rgba(108, 95, 199, 1)';
10980const LIGHT_THEME = {
10981  fontFamily: "system-ui, 'Helvetica Neue', Arial, sans-serif",
10982  fontSize: '14px',
10983
10984  background: LIGHT_BACKGROUND,
10985  backgroundHover: '#f6f6f7',
10986  foreground: '#2b2233',
10987  border: '1.5px solid rgba(41, 35, 47, 0.13)',
10988  borderRadius: '12px',
10989  boxShadow: '0px 4px 24px 0px rgba(43, 34, 51, 0.12)',
10990
10991  success: '#268d75',
10992  error: '#df3338',
10993
10994  submitBackground: 'rgba(88, 74, 192, 1)',
10995  submitBackgroundHover: SUBMIT_COLOR,
10996  submitBorder: SUBMIT_COLOR,
10997  submitOutlineFocus: '#29232f',
10998  submitForeground: LIGHT_BACKGROUND,
10999  submitForegroundHover: LIGHT_BACKGROUND,
11000
11001  cancelBackground: 'transparent',
11002  cancelBackgroundHover: 'var(--background-hover)',
11003  cancelBorder: 'var(--border)',
11004  cancelOutlineFocus: 'var(--input-outline-focus)',
11005  cancelForeground: 'var(--foreground)',
11006  cancelForegroundHover: 'var(--foreground)',
11007
11008  inputBackground: INHERIT,
11009  inputForeground: INHERIT,
11010  inputBorder: 'var(--border)',
11011  inputOutlineFocus: SUBMIT_COLOR,
11012
11013  formBorderRadius: '20px',
11014  formContentBorderRadius: '6px',
11015};
11016
11017const DEFAULT_THEME = {
11018  light: LIGHT_THEME,
11019  dark: {
11020    ...LIGHT_THEME,
11021
11022    background: '#29232f',
11023    backgroundHover: '#352f3b',
11024    foreground: '#ebe6ef',
11025    border: '1.5px solid rgba(235, 230, 239, 0.15)',
11026
11027    success: '#2da98c',
11028    error: '#f55459',
11029  },
11030};
11031
11032const ACTOR_LABEL = 'Report a Bug';
11033const CANCEL_BUTTON_LABEL = 'Cancel';
11034const SUBMIT_BUTTON_LABEL = 'Send Bug Report';
11035const FORM_TITLE = 'Report a Bug';
11036const EMAIL_PLACEHOLDER = '[email protected]';
11037const EMAIL_LABEL = 'Email';
11038const MESSAGE_PLACEHOLDER = "What's the bug? What did you expect?";
11039const MESSAGE_LABEL = 'Description';
11040const NAME_PLACEHOLDER = 'Your Name';
11041const NAME_LABEL = 'Name';
11042const SUCCESS_MESSAGE_TEXT = 'Thank you for your report!';
11043
11044const FEEDBACK_WIDGET_SOURCE = 'widget';
11045const FEEDBACK_API_SOURCE = 'api';
11046
11047/**
11048 * Prepare a feedback event & enrich it with the SDK metadata.
11049 */
11050async function prepareFeedbackEvent({
11051  client,
11052  scope,
11053  event,
11054}) {
11055  const eventHint = {};
11056  if (client.emit) {
11057    client.emit('preprocessEvent', event, eventHint);
11058  }
11059
11060  const preparedEvent = (await core.prepareEvent(
11061    client.getOptions(),
11062    event,
11063    eventHint,
11064    scope,
11065    client,
11066    core.getIsolationScope(),
11067  )) ;
11068
11069  if (preparedEvent === null) {
11070    // Taken from baseclient's `_processEvent` method, where this is handled for errors/transactions
11071    client.recordDroppedEvent('event_processor', 'feedback', event);
11072    return null;
11073  }
11074
11075  // This normally happens in browser client "_prepareEvent"
11076  // but since we do not use this private method from the client, but rather the plain import
11077  // we need to do this manually.
11078  preparedEvent.platform = preparedEvent.platform || 'javascript';
11079
11080  return preparedEvent;
11081}
11082
11083/**
11084 * Send feedback using transport
11085 */
11086async function sendFeedbackRequest(
11087  { feedback: { message, email, name, source, url } },
11088  { includeReplay = true } = {},
11089) {
11090  const client = core.getClient();
11091  const transport = client && client.getTransport();
11092  const dsn = client && client.getDsn();
11093
11094  if (!client || !transport || !dsn) {
11095    return;
11096  }
11097
11098  const baseEvent = {
11099    contexts: {
11100      feedback: {
11101        contact_email: email,
11102        name,
11103        message,
11104        url,
11105        source,
11106      },
11107    },
11108    type: 'feedback',
11109  };
11110
11111  return core.withScope(async scope => {
11112    // No use for breadcrumbs in feedback
11113    scope.clearBreadcrumbs();
11114
11115    if ([FEEDBACK_API_SOURCE, FEEDBACK_WIDGET_SOURCE].includes(String(source))) {
11116      scope.setLevel('info');
11117    }
11118
11119    const feedbackEvent = await prepareFeedbackEvent({
11120      // eslint-disable-next-line @typescript-eslint/no-explicit-any
11121      scope: scope ,
11122      client,
11123      event: baseEvent,
11124    });
11125
11126    if (!feedbackEvent) {
11127      return;
11128    }
11129
11130    if (client.emit) {
11131      client.emit('beforeSendFeedback', feedbackEvent, { includeReplay: Boolean(includeReplay) });
11132    }
11133
11134    const envelope = core.createEventEnvelope(feedbackEvent, dsn, client.getOptions()._metadata, client.getOptions().tunnel);
11135
11136    let response;
11137
11138    try {
11139      response = await transport.send(envelope);
11140    } catch (err) {
11141      const error = new Error('Unable to send Feedback');
11142
11143      try {
11144        // In case browsers don't allow this property to be writable
11145        // @ts-expect-error This needs lib es2022 and newer
11146        error.cause = err;
11147      } catch (e) {
11148        // nothing to do
11149      }
11150      throw error;
11151    }
11152
11153    // TODO (v8): we can remove this guard once transport.send's type signature doesn't include void anymore
11154    if (!response) {
11155      return;
11156    }
11157
11158    // Require valid status codes, otherwise can assume feedback was not sent successfully
11159    if (typeof response.statusCode === 'number' && (response.statusCode < 200 || response.statusCode >= 300)) {
11160      throw new Error('Unable to send Feedback');
11161    }
11162
11163    return response;
11164  });
11165}
11166
11167/*
11168 * For reference, the fully built event looks something like this:
11169 * {
11170 *     "type": "feedback",
11171 *     "event_id": "d2132d31b39445f1938d7e21b6bf0ec4",
11172 *     "timestamp": 1597977777.6189718,
11173 *     "dist": "1.12",
11174 *     "platform": "javascript",
11175 *     "environment": "production",
11176 *     "release": 42,
11177 *     "tags": {"transaction": "/organizations/:orgId/performance/:eventSlug/"},
11178 *     "sdk": {"name": "name", "version": "version"},
11179 *     "user": {
11180 *         "id": "123",
11181 *         "username": "user",
11182 *         "email": "[email protected]",
11183 *         "ip_address": "192.168.11.12",
11184 *     },
11185 *     "request": {
11186 *         "url": None,
11187 *         "headers": {
11188 *             "user-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15"
11189 *         },
11190 *     },
11191 *     "contexts": {
11192 *         "feedback": {
11193 *             "message": "test message",
11194 *             "contact_email": "[email protected]",
11195 *             "type": "feedback",
11196 *         },
11197 *         "trace": {
11198 *             "trace_id": "4C79F60C11214EB38604F4AE0781BFB2",
11199 *             "span_id": "FA90FDEAD5F74052",
11200 *             "type": "trace",
11201 *         },
11202 *         "replay": {
11203 *             "replay_id": "e2d42047b1c5431c8cba85ee2a8ab25d",
11204 *         },
11205 *     },
11206 *   }
11207 */
11208
11209/**
11210 * Public API to send a Feedback item to Sentry
11211 */
11212function sendFeedback(
11213  { name, email, message, source = FEEDBACK_API_SOURCE, url = utils.getLocationHref() },
11214  options = {},
11215) {
11216  if (!message) {
11217    throw new Error('Unable to submit feedback with empty message');
11218  }
11219
11220  return sendFeedbackRequest(
11221    {
11222      feedback: {
11223        name,
11224        email,
11225        message,
11226        url,
11227        source,
11228      },
11229    },
11230    options,
11231  );
11232}
11233
11234/**
11235 * 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.
11236 *
11237 * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
11238 */
11239const DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);
11240
11241/**
11242 * Quick and dirty deep merge for the Feedback integration options
11243 */
11244function mergeOptions(
11245  defaultOptions,
11246  optionOverrides,
11247) {
11248  return {
11249    ...defaultOptions,
11250    ...optionOverrides,
11251    themeDark: {
11252      ...defaultOptions.themeDark,
11253      ...optionOverrides.themeDark,
11254    },
11255    themeLight: {
11256      ...defaultOptions.themeLight,
11257      ...optionOverrides.themeLight,
11258    },
11259  };
11260}
11261
11262/**
11263 * Creates <style> element for widget actor (button that opens the dialog)
11264 */
11265function createActorStyles(d) {
11266  const style = d.createElement('style');
11267  style.textContent = `
11268.widget__actor {
11269  line-height: 25px;
11270
11271  display: flex;
11272  align-items: center;
11273  gap: 8px;
11274
11275  border-radius: var(--border-radius);
11276  cursor: pointer;
11277  font-size: 14px;
11278  font-weight: 600;
11279  padding: 12px 16px;
11280  text-decoration: none;
11281  z-index: 9000;
11282
11283  color: var(--foreground);
11284  background-color: var(--background);
11285  border: var(--border);
11286  box-shadow: var(--box-shadow);
11287  opacity: 1;
11288  transition: opacity 0.1s ease-in-out;
11289}
11290
11291.widget__actor:hover {
11292  background-color: var(--background-hover);
11293}
11294
11295.widget__actor svg {
11296  width: 16px;
11297  height: 16px;
11298}
11299
11300.widget__actor--hidden {
11301  opacity: 0;
11302  pointer-events: none;
11303  visibility: hidden;
11304}
11305
11306.widget__actor__text {
11307}
11308
11309.feedback-icon path {
11310  fill: var(--foreground);
11311}
11312`;
11313
11314  return style;
11315}
11316
11317/**
11318 * Creates <style> element for widget dialog
11319 */
11320function createDialogStyles(d) {
11321  const style = d.createElement('style');
11322
11323  style.textContent = `
11324.dialog {
11325  line-height: 25px;
11326  background-color: rgba(0, 0, 0, 0.05);
11327  border: none;
11328  position: fixed;
11329  inset: 0;
11330  z-index: 10000;
11331  width: 100vw;
11332  height: 100vh;
11333  display: flex;
11334  align-items: center;
11335  justify-content: center;
11336  opacity: 1;
11337  transition: opacity 0.2s ease-in-out;
11338}
11339
11340.dialog:not([open]) {
11341  opacity: 0;
11342  pointer-events: none;
11343  visibility: hidden;
11344}
11345.dialog:not([open]) .dialog__content {
11346  transform: translate(0, -16px) scale(0.98);
11347}
11348
11349.dialog__content {
11350  position: fixed;
11351  left: var(--left);
11352  right: var(--right);
11353  bottom: var(--bottom);
11354  top: var(--top);
11355
11356  border: var(--border);
11357  border-radius: var(--form-border-radius);
11358  background-color: var(--background);
11359  color: var(--foreground);
11360
11361  width: 320px;
11362  max-width: 100%;
11363  max-height: calc(100% - 2rem);
11364  display: flex;
11365  flex-direction: column;
11366  box-shadow: var(--box-shadow);
11367  transition: transform 0.2s ease-in-out;
11368  transform: translate(0, 0) scale(1);
11369}
11370
11371.dialog__header {
11372  display: flex;
11373  align-items: center;
11374  justify-content: space-between;
11375  font-size: 20px;
11376  font-weight: 600;
11377  padding: 24px 24px 0 24px;
11378  margin: 0;
11379  margin-bottom: 16px;
11380}
11381
11382.brand-link {
11383  display: inline-flex;
11384}
11385
11386.error {
11387  color: var(--error);
11388  margin-bottom: 16px;
11389}
11390
11391.form {
11392  display: grid;
11393  overflow: auto;
11394  flex-direction: column;
11395  gap: 16px;
11396  padding: 0 24px 24px;
11397}
11398
11399.form__error-container {
11400  color: var(--error);
11401}
11402
11403.form__error-container--hidden {
11404  display: none;
11405}
11406
11407.form__label {
11408  display: flex;
11409  flex-direction: column;
11410  gap: 4px;
11411  margin: 0px;
11412}
11413
11414.form__label__text {
11415  display: grid;
11416  gap: 4px;
11417  align-items: center;
11418  grid-auto-flow: column;
11419  grid-auto-columns: max-content;
11420}
11421
11422.form__label__text--required {
11423  font-size: 0.85em;
11424}
11425
11426.form__input {
11427  font-family: inherit;
11428  line-height: inherit;
11429  background-color: var(--input-background);
11430  box-sizing: border-box;
11431  border: var(--input-border);
11432  border-radius: var(--form-content-border-radius);
11433  color: var(--input-foreground);
11434  font-size: 14px;
11435  font-weight: 500;
11436  padding: 6px 12px;
11437}
11438
11439.form__input:focus-visible {
11440  outline: 1px auto var(--input-outline-focus);
11441}
11442
11443.form__input--textarea {
11444  font-family: inherit;
11445  resize: vertical;
11446}
11447
11448.btn-group {
11449  display: grid;
11450  gap: 8px;
11451  margin-top: 8px;
11452}
11453
11454.btn {
11455  line-height: inherit;
11456  border: var(--cancel-border);
11457  border-radius: var(--form-content-border-radius);
11458  cursor: pointer;
11459  font-size: 14px;
11460  font-weight: 600;
11461  padding: 6px 16px;
11462}
11463.btn[disabled] {
11464  opacity: 0.6;
11465  pointer-events: none;
11466}
11467
11468.btn--primary {
11469  background-color: var(--submit-background);
11470  border-color: var(--submit-border);
11471  color: var(--submit-foreground);
11472}
11473.btn--primary:hover {
11474  background-color: var(--submit-background-hover);
11475  color: var(--submit-foreground-hover);
11476}
11477.btn--primary:focus-visible {
11478  outline: 1px auto var(--submit-outline-focus);
11479}
11480
11481.btn--default {
11482  background-color: var(--cancel-background);
11483  color: var(--cancel-foreground);
11484  font-weight: 500;
11485}
11486.btn--default:hover {
11487  background-color: var(--cancel-background-hover);
11488  color: var(--cancel-foreground-hover);
11489}
11490.btn--default:focus-visible {
11491  outline: 1px auto var(--cancel-outline-focus);
11492}
11493
11494.success-message {
11495  background-color: var(--background);
11496  border: var(--border);
11497  border-radius: var(--border-radius);
11498  box-shadow: var(--box-shadow);
11499  font-weight: 600;
11500  color: var(--success);
11501  padding: 12px 24px;
11502  line-height: 25px;
11503  display: grid;
11504  align-items: center;
11505  grid-auto-flow: column;
11506  gap: 6px;
11507  cursor: default;
11508}
11509
11510.success-icon path {
11511  fill: var(--success);
11512}
11513`;
11514
11515  return style;
11516}
11517
11518function getThemedCssVariables(theme) {
11519  return `
11520  --background: ${theme.background};
11521  --background-hover: ${theme.backgroundHover};
11522  --foreground: ${theme.foreground};
11523  --error: ${theme.error};
11524  --success: ${theme.success};
11525  --border: ${theme.border};
11526  --border-radius: ${theme.borderRadius};
11527  --box-shadow: ${theme.boxShadow};
11528
11529  --submit-background: ${theme.submitBackground};
11530  --submit-background-hover: ${theme.submitBackgroundHover};
11531  --submit-border: ${theme.submitBorder};
11532  --submit-outline-focus: ${theme.submitOutlineFocus};
11533  --submit-foreground: ${theme.submitForeground};
11534  --submit-foreground-hover: ${theme.submitForegroundHover};
11535
11536  --cancel-background: ${theme.cancelBackground};
11537  --cancel-background-hover: ${theme.cancelBackgroundHover};
11538  --cancel-border: ${theme.cancelBorder};
11539  --cancel-outline-focus: ${theme.cancelOutlineFocus};
11540  --cancel-foreground: ${theme.cancelForeground};
11541  --cancel-foreground-hover: ${theme.cancelForegroundHover};
11542
11543  --input-background: ${theme.inputBackground};
11544  --input-foreground: ${theme.inputForeground};
11545  --input-border: ${theme.inputBorder};
11546  --input-outline-focus: ${theme.inputOutlineFocus};
11547
11548  --form-border-radius: ${theme.formBorderRadius};
11549  --form-content-border-radius: ${theme.formContentBorderRadius};
11550  `;
11551}
11552
11553/**
11554 * Creates <style> element for widget actor (button that opens the dialog)
11555 */
11556function createMainStyles(
11557  d,
11558  colorScheme,
11559  themes,
11560) {
11561  const style = d.createElement('style');
11562  style.textContent = `
11563:host {
11564  --bottom: 1rem;
11565  --right: 1rem;
11566  --top: auto;
11567  --left: auto;
11568  --z-index: 100000;
11569  --font-family: ${themes.light.fontFamily};
11570  --font-size: ${themes.light.fontSize};
11571
11572  position: fixed;
11573  left: var(--left);
11574  right: var(--right);
11575  bottom: var(--bottom);
11576  top: var(--top);
11577  z-index: var(--z-index);
11578
11579  font-family: var(--font-family);
11580  font-size: var(--font-size);
11581
11582  ${getThemedCssVariables(colorScheme === 'dark' ? themes.dark : themes.light)}
11583}
11584
11585${
11586  colorScheme === 'system'
11587    ? `
11588@media (prefers-color-scheme: dark) {
11589  :host {
11590    ${getThemedCssVariables(themes.dark)}
11591  }
11592}`
11593    : ''
11594}
11595}`;
11596
11597  return style;
11598}
11599
11600/**
11601 * Creates shadow host
11602 */
11603function createShadowHost({ id, colorScheme, themeDark, themeLight })
11604
11605 {
11606  try {
11607    const doc = WINDOW.document;
11608
11609    // Create the host
11610    const host = doc.createElement('div');
11611    host.id = id;
11612
11613    // Create the shadow root
11614    const shadow = host.attachShadow({ mode: 'open' });
11615
11616    shadow.appendChild(createMainStyles(doc, colorScheme, { dark: themeDark, light: themeLight }));
11617    shadow.appendChild(createDialogStyles(doc));
11618
11619    return { shadow, host };
11620  } catch (e) {
11621    // Shadow DOM probably not supported
11622    utils.logger.warn('[Feedback] Browser does not support shadow DOM API');
11623    throw new Error('Browser does not support shadow DOM API.');
11624  }
11625}
11626
11627/**
11628 * Handles UI behavior of dialog when feedback is submitted, calls
11629 * `sendFeedback` to send feedback.
11630 */
11631async function handleFeedbackSubmit(
11632  dialog,
11633  feedback,
11634  options,
11635) {
11636  if (!dialog) {
11637    // Not sure when this would happen
11638    return;
11639  }
11640
11641  const showFetchError = () => {
11642    if (!dialog) {
11643      return;
11644    }
11645    dialog.showError('There was a problem submitting feedback, please wait and try again.');
11646  };
11647
11648  dialog.hideError();
11649
11650  try {
11651    const resp = await sendFeedback({ ...feedback, source: FEEDBACK_WIDGET_SOURCE }, options);
11652
11653    // Success!
11654    return resp;
11655  } catch (err) {
11656    DEBUG_BUILD && utils.logger.error(err);
11657    showFetchError();
11658  }
11659}
11660
11661/**
11662 * Helper function to set a dict of attributes on element (w/ specified namespace)
11663 */
11664function setAttributesNS(el, attributes) {
11665  Object.entries(attributes).forEach(([key, val]) => {
11666    el.setAttributeNS(null, key, val);
11667  });
11668  return el;
11669}
11670
11671const SIZE = 20;
11672const XMLNS$2 = 'http://www.w3.org/2000/svg';
11673
11674/**
11675 * Feedback Icon
11676 */
11677function Icon() {
11678  const createElementNS = (tagName) =>
11679    WINDOW.document.createElementNS(XMLNS$2, tagName);
11680  const svg = setAttributesNS(createElementNS('svg'), {
11681    class: 'feedback-icon',
11682    width: `${SIZE}`,
11683    height: `${SIZE}`,
11684    viewBox: `0 0 ${SIZE} ${SIZE}`,
11685    fill: 'none',
11686  });
11687
11688  const g = setAttributesNS(createElementNS('g'), {
11689    clipPath: 'url(#clip0_57_80)',
11690  });
11691
11692  const path = setAttributesNS(createElementNS('path'), {
11693    ['fill-rule']: 'evenodd',
11694    ['clip-rule']: 'evenodd',
11695    d: 'M15.6622 15H12.3997C12.2129 14.9959 12.031 14.9396 11.8747 14.8375L8.04965 12.2H7.49956V19.1C7.4875 19.3348 7.3888 19.5568 7.22256 19.723C7.05632 19.8892 6.83435 19.9879 6.59956 20H2.04956C1.80193 19.9968 1.56535 19.8969 1.39023 19.7218C1.21511 19.5467 1.1153 19.3101 1.11206 19.0625V12.2H0.949652C0.824431 12.2017 0.700142 12.1783 0.584123 12.1311C0.468104 12.084 0.362708 12.014 0.274155 11.9255C0.185602 11.8369 0.115689 11.7315 0.0685419 11.6155C0.0213952 11.4995 -0.00202913 11.3752 -0.00034808 11.25V3.75C-0.00900498 3.62067 0.0092504 3.49095 0.0532651 3.36904C0.0972798 3.24712 0.166097 3.13566 0.255372 3.04168C0.344646 2.94771 0.452437 2.87327 0.571937 2.82307C0.691437 2.77286 0.82005 2.74798 0.949652 2.75H8.04965L11.8747 0.1625C12.031 0.0603649 12.2129 0.00407221 12.3997 0H15.6622C15.9098 0.00323746 16.1464 0.103049 16.3215 0.278167C16.4966 0.453286 16.5964 0.689866 16.5997 0.9375V3.25269C17.3969 3.42959 18.1345 3.83026 18.7211 4.41679C19.5322 5.22788 19.9878 6.32796 19.9878 7.47502C19.9878 8.62209 19.5322 9.72217 18.7211 10.5333C18.1345 11.1198 17.3969 11.5205 16.5997 11.6974V14.0125C16.6047 14.1393 16.5842 14.2659 16.5395 14.3847C16.4948 14.5035 16.4268 14.6121 16.3394 14.7042C16.252 14.7962 16.147 14.8698 16.0307 14.9206C15.9144 14.9714 15.7891 14.9984 15.6622 15ZM1.89695 10.325H1.88715V4.625H8.33715C8.52423 4.62301 8.70666 4.56654 8.86215 4.4625L12.6872 1.875H14.7247V13.125H12.6872L8.86215 10.4875C8.70666 10.3835 8.52423 10.327 8.33715 10.325H2.20217C2.15205 10.3167 2.10102 10.3125 2.04956 10.3125C1.9981 10.3125 1.94708 10.3167 1.89695 10.325ZM2.98706 12.2V18.1625H5.66206V12.2H2.98706ZM16.5997 9.93612V5.01393C16.6536 5.02355 16.7072 5.03495 16.7605 5.04814C17.1202 5.13709 17.4556 5.30487 17.7425 5.53934C18.0293 5.77381 18.2605 6.06912 18.4192 6.40389C18.578 6.73866 18.6603 7.10452 18.6603 7.47502C18.6603 7.84552 18.578 8.21139 18.4192 8.54616C18.2605 8.88093 18.0293 9.17624 17.7425 9.41071C17.4556 9.64518 17.1202 9.81296 16.7605 9.90191C16.7072 9.91509 16.6536 9.9265 16.5997 9.93612Z',
11696  });
11697  svg.appendChild(g).appendChild(path);
11698
11699  const speakerDefs = createElementNS('defs');
11700  const speakerClipPathDef = setAttributesNS(createElementNS('clipPath'), {
11701    id: 'clip0_57_80',
11702  });
11703
11704  const speakerRect = setAttributesNS(createElementNS('rect'), {
11705    width: `${SIZE}`,
11706    height: `${SIZE}`,
11707    fill: 'white',
11708  });
11709
11710  speakerClipPathDef.appendChild(speakerRect);
11711  speakerDefs.appendChild(speakerClipPathDef);
11712
11713  svg.appendChild(speakerDefs).appendChild(speakerClipPathDef).appendChild(speakerRect);
11714
11715  return {
11716    get el() {
11717      return svg;
11718    },
11719  };
11720}
11721
11722/**
11723 * Helper function to create an element. Could be used as a JSX factory
11724 * (i.e. React-like syntax).
11725 */
11726function createElement(
11727  tagName,
11728  attributes,
11729  ...children
11730) {
11731  const doc = WINDOW.document;
11732  const element = doc.createElement(tagName);
11733
11734  if (attributes) {
11735    Object.entries(attributes).forEach(([attribute, attributeValue]) => {
11736      if (attribute === 'className' && typeof attributeValue === 'string') {
11737        // JSX does not allow class as a valid name
11738        element.setAttribute('class', attributeValue);
11739      } else if (typeof attributeValue === 'boolean' && attributeValue) {
11740        element.setAttribute(attribute, '');
11741      } else if (typeof attributeValue === 'string') {
11742        element.setAttribute(attribute, attributeValue);
11743      } else if (attribute.startsWith('on') && typeof attributeValue === 'function') {
11744        element.addEventListener(attribute.substring(2).toLowerCase(), attributeValue);
11745      }
11746    });
11747  }
11748  for (const child of children) {
11749    appendChild(element, child);
11750  }
11751
11752  return element;
11753}
11754
11755function appendChild(parent, child) {
11756  const doc = WINDOW.document;
11757  if (typeof child === 'undefined' || child === null) {
11758    return;
11759  }
11760
11761  if (Array.isArray(child)) {
11762    for (const value of child) {
11763      appendChild(parent, value);
11764    }
11765  } else if (child === false) ; else if (typeof child === 'string') {
11766    parent.appendChild(doc.createTextNode(child));
11767  } else if (child instanceof Node) {
11768    parent.appendChild(child);
11769  } else {
11770    parent.appendChild(doc.createTextNode(String(child)));
11771  }
11772}
11773
11774/**
11775 *
11776 */
11777function Actor({ buttonLabel, onClick }) {
11778  function _handleClick(e) {
11779    onClick && onClick(e);
11780  }
11781
11782  const el = createElement(
11783    'button',
11784    {
11785      type: 'button',
11786      className: 'widget__actor',
11787      ['aria-label']: buttonLabel,
11788      ['aria-hidden']: 'false',
11789    },
11790    Icon().el,
11791    buttonLabel
11792      ? createElement(
11793          'span',
11794          {
11795            className: 'widget__actor__text',
11796          },
11797          buttonLabel,
11798        )
11799      : null,
11800  );
11801
11802  el.addEventListener('click', _handleClick);
11803
11804  return {
11805    get el() {
11806      return el;
11807    },
11808    show: () => {
11809      el.classList.remove('widget__actor--hidden');
11810      el.setAttribute('aria-hidden', 'false');
11811    },
11812    hide: () => {
11813      el.classList.add('widget__actor--hidden');
11814      el.setAttribute('aria-hidden', 'true');
11815    },
11816  };
11817}
11818
11819/**
11820 *
11821 */
11822function SubmitButton({ label }) {
11823  const el = createElement(
11824    'button',
11825    {
11826      type: 'submit',
11827      className: 'btn btn--primary',
11828      ['aria-label']: label,
11829    },
11830    label,
11831  );
11832
11833  return {
11834    el,
11835  };
11836}
11837
11838function retrieveStringValue(formData, key) {
11839  const value = formData.get(key);
11840  if (typeof value === 'string') {
11841    return value.trim();
11842  }
11843  return '';
11844}
11845
11846/**
11847 * Creates the form element
11848 */
11849function Form({
11850  nameLabel,
11851  namePlaceholder,
11852  emailLabel,
11853  emailPlaceholder,
11854  messageLabel,
11855  messagePlaceholder,
11856  cancelButtonLabel,
11857  submitButtonLabel,
11858
11859  showName,
11860  showEmail,
11861  isNameRequired,
11862  isEmailRequired,
11863
11864  defaultName,
11865  defaultEmail,
11866  onCancel,
11867  onSubmit,
11868}) {
11869  const { el: submitEl }
11869 = SubmitButton({
11870    label: submitButtonLabel,
11871  });
11872
11873  function handleSubmit(e) {
11874    e.preventDefault();
11875
11876    if (!(e.target instanceof HTMLFormElement)) {
11877      return;
11878    }
11879
11880    try {
11881      if (onSubmit) {
11882        const formData = new FormData(e.target );
11883        const feedback = {
11884          name: retrieveStringValue(formData, 'name'),
11885          email: retrieveStringValue(formData, 'email'),
11886          message: retrieveStringValue(formData, 'message'),
11887        };
11888
11889        onSubmit(feedback);
11890      }
11891    } catch (e2) {
11892      // pass
11893    }
11894  }
11895
11896  const errorEl = createElement('div', {
11897    className: 'form__error-container form__error-container--hidden',
11898    ['aria-hidden']: 'true',
11899  });
11900
11901  function showError(message) {
11902    errorEl.textContent = message;
11903    errorEl.classList.remove('form__error-container--hidden');
11904    errorEl.setAttribute('aria-hidden', 'false');
11905  }
11906
11907  function hideError() {
11908    errorEl.textContent = '';
11909    errorEl.classList.add('form__error-container--hidden');
11910    errorEl.setAttribute('aria-hidden', 'true');
11911  }
11912
11913  const nameEl = createElement('input', {
11914    id: 'name',
11915    type: showName ? 'text' : 'hidden',
11916    ['aria-hidden']: showName ? 'false' : 'true',
11917    name: 'name',
11918    required: isNameRequired,
11919    className: 'form__input',
11920    placeholder: namePlaceholder,
11921    value: defaultName,
11922  });
11923
11924  const emailEl = createElement('input', {
11925    id: 'email',
11926    type: showEmail ? 'text' : 'hidden',
11927    ['aria-hidden']: showEmail ? 'false' : 'true',
11928    name: 'email',
11929    required: isEmailRequired,
11930    className: 'form__input',
11931    placeholder: emailPlaceholder,
11932    value: defaultEmail,
11933  });
11934
11935  const messageEl = createElement('textarea', {
11936    id: 'message',
11937    autoFocus: 'true',
11938    rows: '5',
11939    name: 'message',
11940    required: true,
11941    className: 'form__input form__input--textarea',
11942    placeholder: messagePlaceholder,
11943  });
11944
11945  const cancelEl = createElement(
11946    'button',
11947    {
11948      type: 'button',
11949      className: 'btn btn--default',
11950      ['aria-label']: cancelButtonLabel,
11951      onClick: (e) => {
11952        onCancel && onCancel(e);
11953      },
11954    },
11955    cancelButtonLabel,
11956  );
11957
11958  const formEl = createElement(
11959    'form',
11960    {
11961      className: 'form',
11962      onSubmit: handleSubmit,
11963    },
11964    [
11965      errorEl,
11966
11967      showName &&
11968        createElement(
11969          'label',
11970          {
11971            htmlFor: 'name',
11972            className: 'form__label',
11973          },
11974          [
11975            createElement(
11976              'span',
11977              { className: 'form__label__text' },
11978              nameLabel,
11979              isNameRequired && createElement('span', { className: 'form__label__text--required' }, ' (required)'),
11980            ),
11981            nameEl,
11982          ],
11983        ),
11984      !showName && nameEl,
11985
11986      showEmail &&
11987        createElement(
11988          'label',
11989          {
11990            htmlFor: 'email',
11991            className: 'form__label',
11992          },
11993          [
11994            createElement(
11995              'span',
11996              { className: 'form__label__text' },
11997              emailLabel,
11998              isEmailRequired && createElement('span', { className: 'form__label__text--required' }, ' (required)'),
11999            ),
12000            emailEl,
12001          ],
12002        ),
12003      !showEmail && emailEl,
12004
12005      createElement(
12006        'label',
12007        {
12008          htmlFor: 'message',
12009          className: 'form__label',
12010        },
12011        [
12012          createElement(
12013            'span',
12014            { className: 'form__label__text' },
12015            messageLabel,
12016            createElement('span', { className: 'form__label__text--required' }, ' (required)'),
12017          ),
12018          messageEl,
12019        ],
12020      ),
12021
12022      createElement(
12023        'div',
12024        {
12025          className: 'btn-group',
12026        },
12027        [submitEl, cancelEl],
12028      ),
12029    ],
12030  );
12031
12032  return {
12033    get el() {
12034      return formEl;
12035    },
12036    showError,
12037    hideError,
12038  };
12039}
12040
12041const XMLNS$1 = 'http://www.w3.org/2000/svg';
12042
12043/**
12044 * Sentry Logo
12045 */
12046function Logo({ colorScheme }) {
12047  const createElementNS = (tagName) =>
12048    WINDOW.document.createElementNS(XMLNS$1, tagName);
12049  const svg = setAttributesNS(createElementNS('svg'), {
12050    class: 'sentry-logo',
12051    width: '32',
12052    height: '30',
12053    viewBox: '0 0 72 66',
12054    fill: 'none',
12055  });
12056
12057  const path = setAttributesNS(createElementNS('path'), {
12058    transform: 'translate(11, 11)',
12059    d: 'M29,2.26a4.67,4.67,0,0,0-8,0L14.42,13.53A32.21,32.21,0,0,1,32.17,40.19H27.55A27.68,27.68,0,0,0,12.09,17.47L6,28a15.92,15.92,0,0,1,9.23,12.17H4.62A.76.76,0,0,1,4,39.06l2.94-5a10.74,10.74,0,0,0-3.36-1.9l-2.91,5a4.54,4.54,0,0,0,1.69,6.24A4.66,4.66,0,0,0,4.62,44H19.15a19.4,19.4,0,0,0-8-17.31l2.31-4A23.87,23.87,0,0,1,23.76,44H36.07a35.88,35.88,0,0,0-16.41-31.8l4.67-8a.77.77,0,0,1,1.05-.27c.53.29,20.29,34.77,20.66,35.17a.76.76,0,0,1-.68,1.13H40.6q.09,1.91,0,3.81h4.78A4.59,4.59,0,0,0,50,39.43a4.49,4.49,0,0,0-.62-2.28Z',
12060  });
12061  svg.append(path);
12062
12063  const defs = createElementNS('defs');
12064  const style = createElementNS('style');
12065
12066  style.textContent = `
12067    path {
12068      fill: ${colorScheme === 'dark' ? '#fff' : '#362d59'};
12069    }`;
12070
12071  if (colorScheme === 'system') {
12072    style.textContent += `
12073    @media (prefers-color-scheme: dark) {
12074      path: {
12075        fill: '#fff';
12076      }
12077    }
12078    `;
12079  }
12080
12081  defs.append(style);
12082  svg.append(defs);
12083
12084  return {
12085    get el() {
12086      return svg;
12087    },
12088  };
12089}
12090
12091/**
12092 * Feedback dialog component that has the form
12093 */
12094function Dialog({
12095  formTitle,
12096  showBranding,
12097  showName,
12098  showEmail,
12099  isNameRequired,
12100  isEmailRequired,
12101  colorScheme,
12102  defaultName,
12103  defaultEmail,
12104  onClosed,
12105  onCancel,
12106  onSubmit,
12107  ...textLabels
12108}) {
12109  let el = null;
12110
12111  /**
12112   * Handles when the dialog is clicked. In our case, the dialog is the
12113   * semi-transparent bg behind the form. We want clicks outside of the form to
12114   * hide the form.
12115   */
12116  function handleDialogClick() {
12117    close();
12118
12119    // Only this should trigger `onClose`, we don't want the `close()` method to
12120    // trigger it, otherwise it can cause cycles.
12121    onClosed && onClosed();
12122  }
12123
12124  /**
12125   * Close the dialog
12126   */
12127  function close() {
12128    if (el) {
12129      el.open = false;
12130    }
12131  }
12132
12133  /**
12134   * Opens the dialog
12135   */
12136  function open() {
12137    if (el) {
12138      el.open = true;
12139    }
12140  }
12141
12142  /**
12143   * Check if dialog is currently opened
12144   */
12145  function checkIsOpen() {
12146    return (el && el.open === true) || false;
12147  }
12148
12149  const {
12150    el: formEl,
12151    showError,
12152    hideError,
12153  } = Form({
12154    showEmail,
12155    showName,
12156    isEmailRequired,
12157    isNameRequired,
12158
12159    defaultName,
12160    defaultEmail,
12161    onSubmit,
12162    onCancel,
12163    ...textLabels,
12164  });
12165
12166  el = createElement(
12167    'dialog',
12168    {
12169      className: 'dialog',
12170      open: true,
12171      onClick: handleDialogClick,
12172    },
12173    createElement(
12174      'div',
12175      {
12176        className: 'dialog__content',
12177        onClick: e => {
12178          // Stop event propagation so clicks on content modal do not propagate to dialog (which will close dialog)
12179          e.stopPropagation();
12180        },
12181      },
12182      createElement(
12183        'h2',
12184        { className: 'dialog__header' },
12185        formTitle,
12186        showBranding &&
12187          createElement(
12188            'a',
12189            {
12190              className: 'brand-link',
12191              target: '_blank',
12192              href: 'https://sentry.io/welcome/',
12193              title: 'Powered by Sentry',
12194              rel: 'noopener noreferrer',
12195            },
12196            Logo({ colorScheme }).el,
12197          ),
12198      ),
12199      formEl,
12200    ),
12201  );
12202
12203  return {
12204    get el() {
12205      return el;
12206    },
12207    showError,
12208    hideError,
12209    open,
12210    close,
12211    checkIsOpen,
12212  };
12213}
12214
12215const WIDTH = 16;
12216const HEIGHT = 17;
12217const XMLNS = 'http://www.w3.org/2000/svg';
12218
12219/**
12220 * Success Icon (checkmark)
12221 */
12222function SuccessIcon() {
12223  const createElementNS = (tagName) =>
12224    WINDOW.document.createElementNS(XMLNS, tagName);
12225  const svg = setAttributesNS(createElementNS('svg'), {
12226    class: 'success-icon',
12227    width: `${WIDTH}`,
12228    height: `${HEIGHT}`,
12229    viewBox: `0 0 ${WIDTH} ${HEIGHT}`,
12230    fill: 'none',
12231  });
12232
12233  const g = setAttributesNS(createElementNS('g'), {
12234    clipPath: 'url(#clip0_57_156)',
12235  });
12236
12237  const path2 = setAttributesNS(createElementNS('path'), {
12238    ['fill-rule']: 'evenodd',
12239    ['clip-rule']: 'evenodd',
12240    d: 'M3.55544 15.1518C4.87103 16.0308 6.41775 16.5 8 16.5C10.1217 16.5 12.1566 15.6571 13.6569 14.1569C15.1571 12.6566 16 10.6217 16 8.5C16 6.91775 15.5308 5.37103 14.6518 4.05544C13.7727 2.73985 12.5233 1.71447 11.0615 1.10897C9.59966 0.503466 7.99113 0.34504 6.43928 0.653721C4.88743 0.962403 3.46197 1.72433 2.34315 2.84315C1.22433 3.96197 0.462403 5.38743 0.153721 6.93928C-0.15496 8.49113 0.00346625 10.0997 0.608967 11.5615C1.21447 13.0233 2.23985 14.2727 3.55544 15.1518ZM4.40546 3.1204C5.46945 2.40946 6.72036 2.03 8 2.03C9.71595 2.03 11.3616 2.71166 12.575 3.92502C13.7883 5.13838 14.47 6.78405 14.47 8.5C14.47 9.77965 14.0905 11.0306 13.3796 12.0945C12.6687 13.1585 11.6582 13.9878 10.476 14.4775C9.29373 14.9672 7.99283 15.0953 6.73777 14.8457C5.48271 14.596 4.32987 13.9798 3.42502 13.075C2.52018 12.1701 1.90397 11.0173 1.65432 9.76224C1.40468 8.50718 1.5328 7.20628 2.0225 6.02404C2.5122 4.8418 3.34148 3.83133 4.40546 3.1204Z',
12241  });
12242  const path = setAttributesNS(createElementNS('path'), {
12243    d: 'M6.68775 12.4297C6.78586 12.4745 6.89218 12.4984 7 12.5C7.11275 12.4955 7.22315 12.4664 7.32337 12.4145C7.4236 12.3627 7.51121 12.2894 7.58 12.2L12 5.63999C12.0848 5.47724 12.1071 5.28902 12.0625 5.11098C12.0178 4.93294 11.9095 4.77744 11.7579 4.67392C11.6064 4.57041 11.4221 4.52608 11.24 4.54931C11.0579 4.57254 10.8907 4.66173 
1224310.77 4.79999L6.88 10.57L5.13 8.56999C5.06508 8.49566 4.98613 8.43488 4.89768 8.39111C4.80922 8.34735 4.713 8.32148 4.61453 8.31498C4.51605 8.30847 4.41727 8.32147 4.32382 8.35322C4.23038 8.38497 4.14413 8.43484 4.07 8.49999C3.92511 8.63217 3.83692 8.81523 3.82387 9.01092C3.81083 9.2066 3.87393 9.39976 4 9.54999L6.43 12.24C6.50187 12.3204 6.58964 12.385 6.68775 12.4297Z',
12244  });
12245
12246  svg.appendChild(g).append(path, path2);
12247
12248  const speakerDefs = createElementNS('defs');
12249  const speakerClipPathDef = setAttributesNS(createElementNS('clipPath'), {
12250    id: 'clip0_57_156',
12251  });
12252
12253  const speakerRect = setAttributesNS(createElementNS('rect'), {
12254    width: `${WIDTH}`,
12255    height: `${WIDTH}`,
12256    fill: 'white',
12257    transform: 'translate(0 0.5)',
12258  });
12259
12260  speakerClipPathDef.appendChild(speakerRect);
12261  speakerDefs.appendChild(speakerClipPathDef);
12262
12263  svg.appendChild(speakerDefs).appendChild(speakerClipPathDef).appendChild(speakerRect);
12264
12265  return {
12266    get el() {
12267      return svg;
12268    },
12269  };
12270}
12271
12272/**
12273 * Feedback dialog component that has the form
12274 */
12275function SuccessMessage({ message, onRemove }) {
12276  function remove() {
12277    if (!el) {
12278      return;
12279    }
12280
12281    el.remove();
12282    onRemove && onRemove();
12283  }
12284
12285  const el = createElement(
12286    'div',
12287    {
12288      className: 'success-message',
12289      onClick: remove,
12290    },
12291    SuccessIcon().el,
12292    message,
12293  );
12294
12295  return {
12296    el,
12297    remove,
12298  };
12299}
12300
12301/**
12302 * Creates a new widget. Returns public methods that control widget behavior.
12303 */
12304function createWidget({
12305  shadow,
12306  options: { shouldCreateActor = true, ...options },
12307  attachTo,
12308}) {
12309  let actor;
12310  let dialog;
12311  let isDialogOpen = false;
12312
12313  /**
12314   * Show the success message for 5 seconds
12315   */
12316  function showSuccessMessage() {
12317    if (!shadow) {
12318      return;
12319    }
12320
12321    try {
12322      const success = SuccessMessage({
12323        message: options.successMessageText,
12324        onRemove: () => {
12325          if (timeoutId) {
12326            clearTimeout(timeoutId);
12327          }
12328          showActor();
12329        },
12330      });
12331
12332      if (!success.el) {
12333        throw new Error('Unable to show success message');
12334      }
12335
12336      shadow.appendChild(success.el);
12337
12338      const timeoutId = setTimeout(() => {
12339        if (success) {
12340          success.remove();
12341        }
12342      }, 5000);
12343    } catch (err) {
12344      // TODO: error handling
12345      utils.logger.error(err);
12346    }
12347  }
12348
12349  /**
12350   * Handler for when the feedback form is completed by the user. This will
12351   * create and send the feedback message as an event.
12352   */
12353  async function _handleFeedbackSubmit(feedback) {
12354    if (!dialog) {
12355      return;
12356    }
12357
12358    // Simple validation for now, just check for non-empty required fields
12359    const emptyField = [];
12360    if (options.isNameRequired && !feedback.name) {
12361      emptyField.push(options.nameLabel);
12362    }
12363    if (options.isEmailRequired && !feedback.email) {
12364      emptyField.push(options.emailLabel);
12365    }
12366    if (!feedback.message) {
12367      emptyField.push(options.messageLabel);
12368    }
12369    if (emptyField.length > 0) {
12370      dialog.showError(`Please enter in the following required fields: ${emptyField.join(', ')}`);
12371      return;
12372    }
12373
12374    const result = await handleFeedbackSubmit(dialog, feedback);
12375
12376    // Error submitting feedback
12377    if (!result) {
12378      if (options.onSubmitError) {
12379        options.onSubmitError();
12380      }
12381
12382      return;
12383    }
12384
12385    // Success
12386    removeDialog();
12387    showSuccessMessage();
12388
12389    if (options.onSubmitSuccess) {
12390      options.onSubmitSuccess();
12391    }
12392  }
12393
12394  /**
12395   * Internal handler when dialog is opened
12396   */
12397  function handleOpenDialog() {
12398    // Flush replay if integration exists
12399    const client = core.getClient();
12400    const replay =
12401      client &&
12402      client.getIntegrationByName &&
12403      client.getIntegrationByName('Replay');
12404    if (!replay) {
12405      return;
12406    }
12407    replay.flush().catch(err => {
12408      DEBUG_BUILD && utils.logger.error(err);
12409    });
12410  }
12411
12412  /**
12413   * Displays the default actor
12414   */
12415  function showActor() {
12416    actor && actor.show();
12417  }
12418
12419  /**
12420   * Hides the default actor
12421   */
12422  function hideActor() {
12423    actor && actor.hide();
12424  }
12425
12426  /**
12427   * Removes the default actor element
12428   */
12429  function removeActor() {
12430    actor && actor.el && actor.el.remove();
12431  }
12432
12433  /**
12434   *
12435   */
12436  function openDialog() {
12437    try {
12438      if (dialog) {
12439        dialog.open();
12440        isDialogOpen = true;
12441        if (options.onFormOpen) {
12442          options.onFormOpen();
12443        }
12444        handleOpenDialog();
12445        return;
12446      }
12447
12448      const userKey = options.useSentryUser;
12449      const scope = core.getCurrentScope();
12450      const user = scope && scope.getUser();
12451
12452      dialog = Dialog({
12453        colorScheme: options.colorScheme,
12454        showBranding: options.showBranding,
12455        showName: options.showName || options.isNameRequired,
12456        showEmail: options.showEmail || options.isEmailRequired,
12457        isNameRequired: options.isNameRequired,
12458        isEmailRequired: options.isEmailRequired,
12459        formTitle: options.formTitle,
12460        cancelButtonLabel: options.cancelButtonLabel,
12461        submitButtonLabel: options.submitButtonLabel,
12462        emailLabel: options.emailLabel,
12463        emailPlaceholder: options.emailPlaceholder,
12464        messageLabel: options.messageLabel,
12465        messagePlaceholder: options.messagePlaceholder,
12466        nameLabel: options.nameLabel,
12467        namePlaceholder: options.namePlaceholder,
12468        defaultName: (userKey && user && user[userKey.name]) || '',
12469        defaultEmail: (userKey && user && user[userKey.email]) || '',
12470        onClosed: () => {
12471          showActor();
12472          isDialogOpen = false;
12473
12474          if (options.onFormClose) {
12475            options.onFormClose();
12476          }
12477        },
12478        onCancel: () => {
12479          closeDialog();
12480          showActor();
12481        },
12482        onSubmit: _handleFeedbackSubmit,
12483      });
12484
12485      if (!dialog.el) {
12486        throw new Error('Unable to open Feedback dialog');
12487      }
12488
12489      shadow.appendChild(dialog.el);
12490
12491      // Hides the default actor whenever dialog is opened
12492      hideActor();
12493
12494      if (options.onFormOpen) {
12495        options.onFormOpen();
12496      }
12497      handleOpenDialog();
12498    } catch (err) {
12499      // TODO: Error handling?
12500      utils.logger.error(err);
12501    }
12502  }
12503
12504  /**
12505   * Closes the dialog
12506   */
12507  function closeDialog() {
12508    if (dialog) {
12509      dialog.close();
12510      isDialogOpen = false;
12511
12512      if (options.onFormClose) {
12513        options.onFormClose();
12514      }
12515    }
12516  }
12517
12518  /**
12519   * Removes the dialog element from DOM
12520   */
12521  function removeDialog() {
12522    if (dialog) {
12523      closeDialog();
12524      const dialogEl = dialog.el;
12525      dialogEl && dialogEl.remove();
12526      dialog = undefined;
12527    }
12528  }
12529
12530  /**
12531   *
12532   */
12533  function handleActorClick() {
12534    // Open dialog
12535    if (!isDialogOpen) {
12536      openDialog();
12537    }
12538
12539    // Hide actor button
12540    hideActor();
12541  }
12542
12543  if (attachTo) {
12544    attachTo.addEventListener('click', handleActorClick);
12545  } else if (shouldCreateActor) {
12546    actor = Actor({ buttonLabel: options.buttonLabel, onClick: handleActorClick });
12547    actor.el && shadow.appendChild(actor.el);
12548  }
12549
12550  return {
12551    get actor() {
12552      return actor;
12553    },
12554    get dialog() {
12555      return dialog;
12556    },
12557
12558    showActor,
12559    hideActor,
12560    removeActor,
12561
12562    openDialog,
12563    closeDialog,
12564    removeDialog,
12565  };
12566}
12567
12568const doc = WINDOW.document;
12569
12570const feedbackIntegration = ((options) => {
12571  // eslint-disable-next-line deprecation/deprecation
12572  return new Feedback(options);
12573}) ;
12574
12575/**
12576 * Feedback integration. When added as an integration to the SDK, it will
12577 * inject a button in the bottom-right corner of the window that opens a
12578 * feedback modal when clicked.
12579 *
12580 * @deprecated Use `feedbackIntegration()` instead.
12581 */
12582class Feedback  {
12583  /**
12584   * @inheritDoc
12585   */
12586   static __initStatic() {this.id = 'Feedback';}
12587
12588  /**
12589   * @inheritDoc
12590   */
12591
12592  /**
12593   * Feedback configuration options
12594   */
12595
12596  /**
12597   * Reference to widget element that is created when autoInject is true
12598   */
12599
12600  /**
12601   * List of all widgets that are created from the integration
12602   */
12603
12604  /**
12605   * Reference to the host element where widget is inserted
12606   */
12607
12608  /**
12609   * Refernce to Shadow DOM root
12610   */
12611
12612  /**
12613   * Tracks if actor styles have ever been inserted into shadow DOM
12614   */
12615
12616   constructor({
12617    autoInject = true,
12618    id = 'sentry-feedback',
12619    isEmailRequired = false,
12620    isNameRequired = false,
12621    showBranding = true,
12622    showEmail = true,
12623    showName = true,
12624    useSentryUser = {
12625      email: 'email',
12626      name: 'username',
12627    },
12628
12629    themeDark,
12630    themeLight,
12631    colorScheme = 'system',
12632
12633    buttonLabel = ACTOR_LABEL,
12634    cancelButtonLabel = CANCEL_BUTTON_LABEL,
12635    submitButtonLabel = SUBMIT_BUTTON_LABEL,
12636    formTitle = FORM_TITLE,
12637    emailPlaceholder = EMAIL_PLACEHOLDER,
12638    emailLabel = EMAIL_LABEL,
12639    messagePlaceholder = MESSAGE_PLACEHOLDER,
12640    messageLabel = MESSAGE_LABEL,
12641    namePlaceholder = NAME_PLACEHOLDER,
12642    nameLabel = NAME_LABEL,
12643    successMessageText = SUCCESS_MESSAGE_TEXT,
12644
12645    onFormClose,
12646    onFormOpen,
12647    onSubmitError,
12648    onSubmitSuccess,
12649  } = {}) {
12650    // eslint-disable-next-line deprecation/deprecation
12651    this.name = Feedback.id;
12652
12653    // tsc fails if these are not initialized explicitly constructor, e.g. can't call `_initialize()`
12654    this._host = null;
12655    this._shadow = null;
12656    this._widget = null;
12657    this._widgets = new Set();
12658    this._hasInsertedActorStyles = false;
12659
12660    this.options = {
12661      autoInject,
12662      showBranding,
12663      id,
12664      isEmailRequired,
12665      isNameRequired,
12666      showEmail,
12667      showName,
12668      useSentryUser,
12669
12670      colorScheme,
12671      themeDark: {
12672        ...DEFAULT_THEME.dark,
12673        ...themeDark,
12674      },
12675      themeLight: {
12676        ...DEFAULT_THEME.light,
12677        ...themeLight,
12678      },
12679
12680      buttonLabel,
12681      cancelButtonLabel,
12682      submitButtonLabel,
12683      formTitle,
12684      emailLabel,
12685      emailPlaceholder,
12686      messageLabel,
12687      messagePlaceholder,
12688      nameLabel,
12689      namePlaceholder,
12690      successMessageText,
12691
12692      onFormClose,
12693      onFormOpen,
12694      onSubmitError,
12695      onSubmitSuccess,
12696    };
12697  }
12698
12699  /**
12700   * Setup and initialize feedback container
12701   */
12702   setupOnce() {
12703    if (!utils.isBrowser()) {
12704      return;
12705    }
12706
12707    try {
12708      this._cleanupWidgetIfExists();
12709
12710      const { autoInject } = this.options;
12711
12712      if (!autoInject) {
12713        // Nothing to do here
12714        return;
12715      }
12716
12717      this._createWidget(this.options);
12718    } catch (err) {
12719      DEBUG_BUILD && utils.logger.error(err);
12720    }
12721  }
12722
12723  /**
12724   * Allows user to open the dialog box. Creates a new widget if
12725   * `autoInject` was false, otherwise re-uses the default widget that was
12726   * created during initialization of the integration.
12727   */
12728   openDialog() {
12729    if (!this._widget) {
12730      this._createWidget({ ...this.options, shouldCreateActor: false });
12731    }
12732
12733    if (!this._widget) {
12734      return;
12735    }
12736
12737    this._widget.openDialog();
12738  }
12739
12740  /**
12741   * Closes the dialog for the default widget, if it exists
12742   */
12743   closeDialog() {
12744    if (!this._widget) {
12745      // Nothing to do if widget does not exist
12746      return;
12747    }
12748
12749    this._widget.closeDialog();
12750  }
12751
12752  /**
12753   * Adds click listener to attached element to open a feedback dialog
12754   */
12755   attachTo(el, optionOverrides) {
12756    try {
12757      const options = mergeOptions(this.options, optionOverrides || {});
12758
12759      return this._ensureShadowHost(options, ({ shadow }) => {
12760        const targetEl =
12761          typeof el === 'string' ? doc.querySelector(el) : typeof el.addEventListener === 'function' ? el : null;
12762
12763        if (!targetEl) {
12764          DEBUG_BUILD && utils.logger.error('[Feedback] Unable to attach to target element');
12765          return null;
12766        }
12767
12768        const widget = createWidget({ shadow, options, attachTo: targetEl });
12769        this._widgets.add(widget);
12770
12771        if (!this._widget) {
12772          this._widget = widget;
12773        }
12774
12775        return widget;
12776      });
12777    } catch (err) {
12778      DEBUG_BUILD && utils.logger.error(err);
12779      return null;
12780    }
12781  }
12782
12783  /**
12784   * Creates a new widget. Accepts partial options to override any options passed to constructor.
12785   */
12786   createWidget(
12787    optionOverrides,
12788  ) {
12789    try {
12790      return this._createWidget(mergeOptions(this.options, optionOverrides || {}));
12791    } catch (err) {
12792      DEBUG_BUILD && utils.logger.error(err);
12793      return null;
12794    }
12795  }
12796
12797  /**
12798   * Removes a single widget
12799   */
12800   removeWidget(widget) {
12801    if (!widget) {
12802      return false;
12803    }
12804
12805    try {
12806      if (this._widgets.has(widget)) {
12807        widget.removeActor();
12808        widget.removeDialog();
12809        this._widgets.delete(widget);
12810
12811        if (this._widget === widget) {
12812          // TODO: is more clean-up needed? e.g. call remove()
12813          this._widget = null;
12814        }
12815
12816        return true;
12817      }
12818    } catch (err) {
12819      DEBUG_BUILD && utils.logger.error(err);
12820    }
12821
12822    return false;
12823  }
12824
12825  /**
12826   * Returns the default (first-created) widget
12827   */
12828   getWidget() {
12829    return this._widget;
12830  }
12831
12832  /**
12833   * Removes the Feedback integration (including host, shadow DOM, and all widgets)
12834   */
12835   remove() {
12836    if (this._host) {
12837      this._host.remove();
12838    }
12839    this._initialize();
12840  }
12841
12842  /**
12843   * Initializes values of protected properties
12844   */
12845   _initialize() {
12846    this._host = null;
12847    this._shadow = null;
12848    this._widget = null;
12849    this._widgets = new Set();
12850    this._hasInsertedActorStyles = false;
12851  }
12852
12853  /**
12854   * Clean-up the widget if it already exists in the DOM. This shouldn't happen
12855   * in prod, but can happen in development with hot module reloading.
12856   */
12857   _cleanupWidgetIfExists() {
12858    if (this._host) {
12859      this.remove();
12860    }
12861    const existingFeedback = doc.querySelector(`#${this.options.id}`);
12862    if (existingFeedback) {
12863      existingFeedback.remove();
12864    }
12865  }
12866
12867  /**
12868   * Creates a new widget, after ensuring shadow DOM exists
12869   */
12870   _createWidget(options) {
12871    return this._ensureShadowHost(options, ({ shadow }) => {
12872      const widget = createWidget({ shadow, options });
12873
12874      if (!this._hasInsertedActorStyles && widget.actor) {
12875        shadow.appendChild(createActorStyles(doc));
12876        this._hasInsertedActorStyles = true;
12877      }
12878
12879      this._widgets.add(widget);
12880
12881      if (!this._widget) {
12882        this._widget = widget;
12883      }
12884
12885      return widget;
12886    });
12887  }
12888
12889  /**
12890   * Ensures that shadow DOM exists and is added to the DOM
12891   */
12892   _ensureShadowHost(
12893    options,
12894    cb,
12895  ) {
12896    let needsAppendHost = false;
12897
12898    // Don't create if it already exists
12899    if (!this._shadow || !this._host) {
12900      const { id, colorScheme, themeLight, themeDark } = options;
12901      const { shadow, host } = createShadowHost({
12902        id,
12903        colorScheme,
12904        themeLight,
12905        themeDark,
12906      });
12907      this._shadow = shadow;
12908      this._host = host;
12909      needsAppendHost = true;
12910    }
12911
12912    // set data attribute on host for different themes
12913    this._host.dataset.sentryFeedbackColorscheme = options.colorScheme;
12914
12915    const result = cb({ shadow: this._shadow, host: this._host });
12916
12917    if (needsAppendHost) {
12918      doc.body.appendChild(this._host);
12919    }
12920
12921    return result;
12922  }
12923} Feedback.__initStatic();
12924
12925exports.Feedback = Feedback;
12926exports.feedbackIntegration = feedbackIntegration;
12927exports.sendFeedback = sendFeedback;
12928
12929
12930},{"@sentry/core":250,"@sentry/utils":319}],183:[function(require,module,exports){
12931var {
12932    _optionalChain
12933} = require('@sentry/utils');
12934
12935Object.defineProperty(exports, '__esModule', { value: true });
12936
12937const core = require('@sentry/core');
12938
12939var NodeType;
12940(function (NodeType) {
12941    NodeType[NodeType["Document"] = 0] = "Document";
12942    NodeType[NodeType["DocumentType"] = 1] = "DocumentType";
12943    NodeType[NodeType["Element"] = 2] = "Element";
12944    NodeType[NodeType["Text"] = 3] = "Text";
12945    NodeType[NodeType["CDATA"] = 4] = "CDATA";
12946    NodeType[NodeType["Comment"] = 5] = "Comment";
12947})(NodeType || (NodeType = {}));
12948function elementClassMatchesRegex(el, regex) {
12949    for (let eIndex = el.classList.length; eIndex--;) {
12950        const className = el.classList[eIndex];
12951        if (regex.test(className)) {
12952            return true;
12953        }
12954    }
12955    return false;
12956}
12957function distanceToMatch(node, matchPredicate, limit = Infinity, distance = 0) {
12958    if (!node)
12959        return -1;
12960    if (node.nodeType !== node.ELEMENT_NODE)
12961        return -1;
12962    if (distance > limit)
12963        return -1;
12964    if (matchPredicate(node))
12965        return distance;
12966    return distanceToMatch(node.parentNode, matchPredicate, limit, distance + 1);
12967}
12968function createMatchPredicate(className, selector) {
12969    return (node) => {
12970        const el = node;
12971        if (el === null)
12972            return false;
12973        try {
12974            if (className) {
12975                if (typeof className === 'string') {
12976                    if (el.matches(`.${className}`))
12977                        return true;
12978                }
12979                else if (elementClassMatchesRegex(el, className)) {
12980                    return true;
12981                }
12982            }
12983            if (selector && el.matches(selector))
12984                return true;
12985            return false;
12986        }
12987        catch (e2) {
12988            return false;
12989        }
12990    };
12991}
12992
12993const DEPARTED_MIRROR_ACCESS_WARNING = 'Please stop import mirror directly. Instead of that,' +
12994    '\r\n' +
12995    'now you can use replayer.getMirror() to access the mirror instance of a replayer,' +
12996    '\r\n' +
12997    'or you can use record.mirror to access the mirror instance during recording.';
12998let _mirror = {
12999    map: {},
13000    getId() {
13001        console.error(DEPARTED_MIRROR_ACCESS_WARNING);
13002        return -1;
13003    },
13004    getNode() {
13005        console.error(DEPARTED_MIRROR_ACCESS_WARNING);
13006        return null;
13007    },
13008    removeNodeFromMap() {
13009        console.error(DEPARTED_MIRROR_ACCESS_WARNING);
13010    },
13011    has() {
13012        console.error(DEPARTED_MIRROR_ACCESS_WARNING);
13013        return false;
13014    },
13015    reset() {
13016        console.error(DEPARTED_MIRROR_ACCESS_WARNING);
13017    },
13018};
13019if (typeof window !== 'undefined' && window.Proxy && window.Reflect) {
13020    _mirror = new Proxy(_mirror, {
13021        get(target, prop, receiver) {
13022            if (prop === 'map') {
13023                console.error(DEPARTED_MIRROR_ACCESS_WARNING);
13024            }
13025            return Reflect.get(target, prop, receiver);
13026        },
13027    });
13028}
13029function hookSetter(target, key, d, isRevoked, win = window) {
13030    const original = win.Object.getOwnPropertyDescriptor(target, key);
13031    win.Object.defineProperty(target, key, isRevoked
13032        ? d
13033        : {
13034            set(value) {
13035                setTimeout(() => {
13036                    d.set.call(this, value);
13037                }, 0);
13038                if (original && original.set) {
13039                    original.set.call(this, value);
13040                }
13041            },
13042        });
13043    return () => hookSetter(target, key, original || {}, true);
13044}
13045function patch(source, name, replacement) {
13046    try {
13047        if (!(name in source)) {
13048            return () => {
13049            };
13050        }
13051        const original = source[name];
13052        const wrapped = replacement(original);
13053        if (typeof wrapped === 'function') {
13054            wrapped.prototype = wrapped.prototype || {};
13055            Object.defineProperties(wrapped, {
13056                __rrweb_original__: {
13057                    enumerable: false,
13058                    value: original,
13059                },
13060            });
13061        }
13062        source[name] = wrapped;
13063        return () => {
13064            source[name] = original;
13065        };
13066    }
13067    catch (e2) {
13068        return () => {
13069        };
13070    }
13071}
13072if (!(/[1-9][0-9]{12}/.test(Date.now().toString()))) ;
13073function isBlocked(node, blockClass, blockSelector, unblockSelector, checkAncestors) {
13074    if (!node) {
13075        return false;
vendor: 6,616 bytes, lines 13076-13285
13076    }
13077    const el = node.nodeType === node.ELEMENT_NODE
13078        ? node
13079        : node.parentElement;
13080    if (!el)
13081        return false;
13082    const blockedPredicate = createMatchPredicate(blockClass, blockSelector);
13083    if (!checkAncestors) {
13084        const isUnblocked = unblockSelector && el.matches(unblockSelector);
13085        return blockedPredicate(el) && !isUnblocked;
13086    }
13087    const blockDistance = distanceToMatch(el, blockedPredicate);
13088    let unblockDistance = -1;
13089    if (blockDistance < 0) {
13090        return false;
13091    }
13092    if (unblockSelector) {
13093        unblockDistance = distanceToMatch(el, createMatchPredicate(null, unblockSelector));
13094    }
13095    if (blockDistance > -1 && unblockDistance < 0) {
13096        return true;
13097    }
13098    return blockDistance < unblockDistance;
13099}
13100let cachedRequestAnimationFrameImplementation;
13101function getRequestAnimationFrameImplementation() {
13102    if (cachedRequestAnimationFrameImplementation) {
13103        return cachedRequestAnimationFrameImplementation;
13104    }
13105    const document = window.document;
13106    let requestAnimationFrameImplementation = window.requestAnimationFrame;
13107    if (document && typeof document.createElement === 'function') {
13108        try {
13109            const sandbox = document.createElement('iframe');
13110            sandbox.hidden = true;
13111            document.head.appendChild(sandbox);
13112            const contentWindow = sandbox.contentWindow;
13113            if (contentWindow && contentWindow.requestAnimationFrame) {
13114                requestAnimationFrameImplementation =
13115                    contentWindow.requestAnimationFrame;
13116            }
13117            document.head.removeChild(sandbox);
13118        }
13119        catch (e) {
13120        }
13121    }
13122    return (cachedRequestAnimationFrameImplementation =
13123        requestAnimationFrameImplementation.bind(window));
13124}
13125function onRequestAnimationFrame(...rest) {
13126    return getRequestAnimationFrameImplementation()(...rest);
13127}
13128
13129var CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {
13130  CanvasContext2[CanvasContext2["2D"] = 0] = "2D";
13131  CanvasContext2[CanvasContext2["WebGL"] = 1] = "WebGL";
13132  CanvasContext2[CanvasContext2["WebGL2"] = 2] = "WebGL2";
13133  return CanvasContext2;
13134})(CanvasContext || {});
13135
13136let errorHandler;
13137function registerErrorHandler(handler) {
13138    errorHandler = handler;
13139}
13140const callbackWrapper = (cb) => {
13141    if (!errorHandler) {
13142        return cb;
13143    }
13144    const rrwebWrapped = ((...rest) => {
13145        try {
13146            return cb(...rest);
13147        }
13148        catch (error) {
13149            if (errorHandler && errorHandler(error) === true) {
13150                return () => {
13151                };
13152            }
13153            throw error;
13154        }
13155    });
13156    return rrwebWrapped;
13157};
13158
13159/*
13160 * base64-arraybuffer 1.0.1 <https://github.com/niklasvh/base64-arraybuffer>
13161 * Copyright (c) 2021 Niklas von Hertzen <https://hertzen.com>
13162 * Released under MIT License
13163 */
13164var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
13165// Use a lookup table to find the index.
13166var lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
13167for (var i = 0; i < chars.length; i++) {
13168    lookup[chars.charCodeAt(i)] = i;
13169}
13170var encode = function (arraybuffer) {
13171    var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = '';
13172    for (i = 0; i < len; i += 3) {
13173        base64 += chars[bytes[i] >> 2];
13174        base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
13175        base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
13176        base64 += chars[bytes[i + 2] & 63];
13177    }
13178    if (len % 3 === 2) {
13179        base64 = base64.substring(0, base64.length - 1) + '=';
13180    }
13181    else if (len % 3 === 1) {
13182        base64 = base64.substring(0, base64.length - 2) + '==';
13183    }
13184    return base64;
13185};
13186
13187const canvasVarMap = new Map();
13188function variableListFor(ctx, ctor) {
13189    let contextMap = canvasVarMap.get(ctx);
13190    if (!contextMap) {
13191        contextMap = new Map();
13192        canvasVarMap.set(ctx, contextMap);
13193    }
13194    if (!contextMap.has(ctor)) {
13195        contextMap.set(ctor, []);
13196    }
13197    return contextMap.get(ctor);
13198}
13199const saveWebGLVar = (value, win, ctx) => {
13200    if (!value ||
13201        !(isInstanceOfWebGLObject(value, win) || typeof value === 'object'))
13202        return;
13203    const name = value.constructor.name;
13204    const list = variableListFor(ctx, name);
13205    let index = list.indexOf(value);
13206    if (index === -1) {
13207        index = list.length;
13208        list.push(value);
13209    }
13210    return index;
13211};
13212function serializeArg(value, win, ctx) {
13213    if (value instanceof Array) {
13214        return value.map((arg) => serializeArg(arg, win, ctx));
13215    }
13216    else if (value === null) {
13217        return value;
13218    }
13219    else if (value instanceof Float32Array ||
13220        value instanceof Float64Array ||
13221        value instanceof Int32Array ||
13222        value instanceof Uint32Array ||
13223        value instanceof Uint8Array ||
13224        value instanceof Uint16Array ||
13225        value instanceof Int16Array ||
13226        value instanceof Int8Array ||
13227        value instanceof Uint8ClampedArray) {
13228        const name = value.constructor.name;
13229        return {
13230            rr_type: name,
13231            args: [Object.values(value)],
13232        };
13233    }
13234    else if (value instanceof ArrayBuffer) {
13235        const name = value.constructor.name;
13236        const base64 = encode(value);
13237        return {
13238            rr_type: name,
13239            base64,
13240        };
13241    }
13242    else if (value instanceof DataView) {
13243        const name = value.constructor.name;
13244        return {
13245            rr_type: name,
13246            args: [
13247                serializeArg(value.buffer, win, ctx),
13248                value.byteOffset,
13249                value.byteLength,
13250            ],
13251        };
13252    }
13253    else if (value instanceof HTMLImageElement) {
13254        const name = value.constructor.name;
13255        const { src } = value;
13256        return {
13257            rr_type: name,
13258            src,
13259        };
13260    }
13261    else if (value instanceof HTMLCanvasElement) {
13262        const name = 'HTMLImageElement';
13263        const src = value.toDataURL();
13264        return {
13265            rr_type: name,
13266            src,
13267        };
13268    }
13269    else if (value instanceof ImageData) {
13270        const name = value.constructor.name;
13271        return {
13272            rr_type: name,
13273            args: [serializeArg(value.data, win, ctx), value.width, value.height],
13274        };
13275    }
13276    else if (isInstanceOfWebGLObject(value, win) || typeof value === 'object') {
13277        const name = value.constructor.name;
13278        const index = saveWebGLVar(value, win, ctx);
13279        return {
13280            rr_type: name,
13281            index: index,
13282        };
13283    }
13284    return value;
13285}
13286const serializeArgs = (args, win, ctx) => {
13287    return args.map((arg) => serializeArg(arg, win, ctx));
13288};
13289const isInstanceOfWebGLObject = (value, win) => {
13290    const webGLConstructorNames = [
13291        'WebGLActiveInfo',
13292        'WebGLBuffer',
13293        'WebGLFramebuffer',
13294        'WebGLProgram',
13295        'WebGLRenderbuffer',
13296        'WebGLShader',
13297        'WebGLShaderPrecisionFormat',
13298        'WebGLTexture',
13299        'WebGLUniformLocation',
13300        'WebGLVertexArrayObject',
13301        'WebGLVertexArrayObjectOES',
13302    ];
13303    const supportedWebGLConstructorNames = webGLConstructorNames.filter((name) => typeof win[name] === 'function');
13304    return Boolean(supportedWebGLConstructorNames.find((name) => value instanceof win[name]));
13305};
13306
13307function initCanvas2DMutationObserver(cb, win, blockClass, blockSelector, unblockSelector) {
13308    const handlers = [];
13309    const props2D = Object.getOwnPropertyNames(win.CanvasRenderingContext2D.prototype);
13310    for (const prop of props2D) {
13311        try {
13312            if (typeof win.CanvasRenderingContext2D.prototype[prop] !== 'function') {
13313                continue;
13314            }
13315            const restoreHandler = patch(win.CanvasRenderingContext2D.prototype, prop, function (original) {
13316                return function (...args) {
13317                    if (!isBlocked(this.canvas, blockClass, blockSelector, unblockSelector, true)) {
13318                        setTimeout(() => {
13319                            const recordArgs = serializeArgs(args, win, this);
13320                            cb(this.canvas, {
13321                                type: CanvasContext['2D'],
13322                                property: prop,
13323                                args: recordArgs,
13324                            });
13325                        }, 0);
13326                    }
13327                    return original.apply(this, args);
13328                };
13329            });
13330            handlers.push(restoreHandler);
13331        }
13332        catch (e) {
13333            const hookHandler = hookSetter(win.CanvasRenderingContext2D.prototype, prop, {
13334                set(v) {
13335                    cb(this.canvas, {
13336                        type: CanvasContext['2D'],
13337                        property: prop,
13338                        args: [v],
13339                        setter: true,
13340                    });
13341                },
13342            });
13343            handlers.push(hookHandler);
13344        }
13345    }
13346    return () => {
13347        handlers.forEach((h) => h());
13348    };
13349}
13350
13351function getNormalizedContextName(contextType) {
13352    return contextType === 'experimental-webgl' ? 'webgl' : contextType;
13353}
13354function initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, setPreserveDrawingBufferToTrue) {
13355    const handlers = [];
13356    try {
13357        const restoreHandler = patch(win.HTMLCanvasElement.prototype, 'getContext', function (original) {
13358            return function (contextType, ...args) {
13359                if (!isBlocked(this, blockClass, blockSelector, unblockSelector, true)) {
13360                    const ctxName = getNormalizedContextName(contextType);
13361                    if (!('__context' in this))
13362                        this.__context = ctxName;
13363                    if (setPreserveDrawingBufferToTrue &&
13364                        ['webgl', 'webgl2'].includes(ctxName)) {
13365                        if (args[0] && typeof args[0] === 'object') {
13366                            const contextAttributes = args[0];
13367                            if (!contextAttributes.preserveDrawingBuffer) {
13368                                contextAttributes.preserveDrawingBuffer = true;
13369                            }
13370                        }
13371                        else {
13372                            args.splice(0, 1, {
13373                                preserveDrawingBuffer: true,
13374                            });
13375                        }
13376                    }
13377                }
13378                return original.apply(this, [contextType, ...args]);
13379            };
13380        });
13381        handlers.push(restoreHandler);
13382    }
13383    catch (e) {
13384        console.error('failed to patch HTMLCanvasElement.prototype.getContext');
13385    }
13386    return () => {
13387        handlers.forEach((h) => h());
13388    };
13389}
13390
13391function patchGLPrototype(prototype, type, cb, blockClass, blockSelector, unblockSelector, mirror, win) {
13392    const handlers = [];
13393    const props = Object.getOwnPropertyNames(prototype);
13394    for (const prop of props) {
13395        if ([
13396            'isContextLost',
13397            'canvas',
13398            'drawingBufferWidth',
13399            'drawingBufferHeight',
13400        ].includes(prop)) {
13401            continue;
13402        }
13403        try {
13404            if (typeof prototype[prop] !== 'function') {
13405                continue;
13406            }
13407            const restoreHandler = patch(prototype, prop, function (original) {
13408                return function (...args) {
13409                    const result = original.apply(this, args);
13410                    saveWebGLVar(result, win, this);
13411                    if ('tagName' in this.canvas &&
13412                        !isBlocked(this.canvas, blockClass, blockSelector, unblockSelector, true)) {
13413                        const recordArgs = serializeArgs(args, win, this);
13414                        const mutation = {
13415                            type,
13416                            property: prop,
13417                            args: recordArgs,
13418                        };
13419                        cb(this.canvas, mutation);
13420                    }
13421                    return result;
13422                };
13423            });
13424            handlers.push(restoreHandler);
13425        }
13426        catch (e) {
13427            const hookHandler = hookSetter(prototype, prop, {
13428                set(v) {
13429                    cb(this.canvas, {
13430                        type,
13431                        property: prop,
13432                        args: [v],
13433                        setter: true,
13434                    });
13435                },
13436            });
13437            handlers.push(hookHandler);
13438        }
13439    }
13440    return handlers;
13441}
13442function initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector, unblockSelector, mirror) {
13443    const handlers = [];
13444    handlers.push(...patchGLPrototype(win.WebGLRenderingContext.prototype, CanvasContext.WebGL, cb, blockClass, blockSelector, unblockSelector, mirror, win));
13445    if (typeof win.WebGL2RenderingContext !== 'undefined') {
13446        handlers.push(...patchGLPrototype(win.WebGL2RenderingContext.prototype, CanvasContext.WebGL2, cb, blockClass, blockSelector, unblockSelector, mirror, win));
13447    }
13448    return () => {
13449        handlers.forEach((h) => h());
13450    };
13451}
13452
13453var r = `for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",e="undefined"==typeof Uint8Array?[]:new Uint8Array(256),n=0;n<64;n++)e[t.charCodeAt(n)]=n;var a=function(e){var n,a=new Uint8Array(e),s=a.length,r="";for(n=0;n<s;n+=3)r+=t[a[n]>>2],r+=t[(3&a[n])<<4|a[n+1]>>4],r+=t[(15&a[n+1])<<2|a[n+2]>>6],r+=t[63&a[n+2]];return s%3==2?r=r.substring(0,r.length-1)+"=":s%3==1&&(r=r.substring(0,r.length-2)+"=="),r};const s=new Map,r=new Map;const i=self;i.onmessage=async function(t){if(!("OffscreenCanvas"in globalThis))return i.postMessage({id:t.data.id});{const{id:e,bitmap:n,width:o,height:f,dataURLOptions:c}=t.data,g=async function(t,e,n){const s=t+"-"+e;if("OffscreenCanvas"in globalThis){if(r.has(s))return r.get(s);const i=new OffscreenCanvas(t,e);i.getContext("2d");const o=await i.convertToBlob(n),f=await o.arrayBuffer(),c=a(f);return r.set(s,c),c}return""}(o,f,c),d=new OffscreenCanvas(o,f);d.getContext("2d").drawImage(n,0,0),n.close();const u=await d.convertToBlob(c),h=u.type,w=await u.arrayBuffer(),l=a(w);if(!s.has(e)&&await g===l)return s.set(e,l),i.postMessage({id:e});if(s.get(e)===l)return i.postMessage({id:e});i.postMessage({id:e,type:h,base64:l,width:o,height:f}),s.set(e,l)}};`;
13454
13455function t(){const t=new Blob([r]);return URL.createObjectURL(t)}
13456
13457class CanvasManager {
13458    reset() {
13459        this.pendingCanvasMutations.clear();
13460        this.resetObservers && this.resetObservers();
13461    }
13462    freeze() {
13463        this.frozen = true;
13464    }
13465    unfreeze() {
13466        this.frozen = false;
13467    }
13468    lock() {
13469        this.locked = true;
13470    }
13471    unlock() {
13472        this.locked = false;
13473    }
13474    constructor(options) {
13475        this.pendingCanvasMutations = new Map();
13476        this.rafStamps = { latestId: 0, invokeId: null };
13477        this.frozen = false;
13478        this.locked = false;
13479        this.processMutation = (target, mutation) => {
13480            const newFrame = this.rafStamps.invokeId &&
13481                this.rafStamps.latestId !== this.rafStamps.invokeId;
13482            if (newFrame || !this.rafStamps.invokeId)
13483                this.rafStamps.invokeId = this.rafStamps.latestId;
13484            if (!this.pendingCanvasMutations.has(target)) {
13485                this.pendingCanvasMutations.set(target, []);
13486            }
13487            this.pendingCanvasMutations.get(target).push(mutation);
13488        };
13489        const { sampling = 'all', win, blockClass, blockSelector, unblockSelector, recordCanvas, dataURLOptions, errorHandler, } = options;
13490        this.mutationCb = options.mutationCb;
13491        this.mirror = options.mirror;
13492        this.options = options;
13493        if (errorHandler) {
13494            registerErrorHandler(errorHandler);
13495        }
13496        if (options.enableManualSnapshot) {
13497            return;
13498        }
13499        callbackWrapper(() => {
13500            if (recordCanvas && sampling === 'all')
13501                this.initCanvasMutationObserver(win, blockClass, blockSelector, unblockSelector);
13502            if (recordCanvas && typeof sampling === 'number')
13503                this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, unblockSelector, {
13504                    dataURLOptions,
13505                });
13506        })();
13507    }
13508    initCanvasFPSObserver(fps, win, blockClass, blockSelector, unblockSelector, options) {
13509        const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, true);
13510        const rafId = this.takeSnapshot(false, fps, win, blockClass, blockSelector, unblockSelector, options.dataURLOptions);
13511        this.resetObservers = () => {
13512            canvasContextReset();
13513            cancelAnimationFrame(rafId);
13514        };
13515    }
13516    initCanvasMutationObserver(win, blockClass, blockSelector, unblockSelector) {
13517        this.startRAFTimestamping();
13518        this.startPendingCanvasMutationFlusher();
13519        const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, false);
13520        const canvas2DReset = initCanvas2DMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector);
13521        const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector, this.mirror);
13522        this.resetObservers = () => {
13523            canvasContextReset();
13524            canvas2DReset();
13525            canvasWebGL1and2Reset();
13526        };
13527    }
13528    snapshot(canvasElement) {
13529        const { options } = this;
13530        const rafId = this.takeSnapshot(true, options.sampling === 'all' ? 2 : options.sampling || 2, options.win, options.blockClass, options.blockSelector, options.unblockSelector, options.dataURLOptions, canvasElement);
13531        this.resetObservers = () => {
13532            cancelAnimationFrame(rafId);
13533        };
13534    }
13535    takeSnapshot(isManualSnapshot, fps, win, blockClass, blockSelector, unblockSelector, dataURLOptions, canvasElement) {
13536        const snapshotInProgressMap = new Map();
13537        const worker = new Worker(t());
13538        worker.onmessage = (e) => {
13539            const data = e.data;
13540            const { id } = data;
13541            snapshotInProgressMap.set(id, false);
13542            if (!('base64' in data))
13543                return;
13544            const { base64, type, width, height } = data;
13545            this.mutationCb({
13546                id,
13547                type: CanvasContext['2D'],
13548                commands: [
13549                    {
13550                        property: 'clearRect',
13551                        args: [0, 0, width, height],
13552                    },
13553                    {
13554                        property: 'drawImage',
13555                        args: [
13556                            {
13557                                rr_type: 'ImageBitmap',
13558                                args: [
13559                                    {
13560                                        rr_type: 'Blob',
13561                                        data: [{ rr_type: 'ArrayBuffer', base64 }],
13562                                        type,
13563                                    },
13564                                ],
13565                            },
13566                            0,
13567                            0,
13568                        ],
13569                    },
13570                ],
13571            });
13572        };
13573        const timeBetweenSnapshots = 1000 / fps;
13574        let lastSnapshotTime = 0;
13575        let rafId;
13576        const getCanvas = (canvasElement) => {
13577            if (canvasElement) {
13578                return [canvasElement];
13579            }
13580            const matchedCanvas = [];
13581            win.document.querySelectorAll('canvas').forEach((canvas) => {
13582                if (!isBlocked(canvas, blockClass, blockSelector, unblockSelector, true)) {
13583                    matchedCanvas.push(canvas);
13584                }
13585            });
13586            return matchedCanvas;
13587        };
13588        const takeCanvasSnapshots = (timestamp) => {
13589            if (lastSnapshotTime &&
13590                timestamp - lastSnapshotTime < timeBetweenSnapshots) {
13591                rafId = onRequestAnimationFrame(takeCanvasSnapshots);
13592                return;
13593            }
13594            lastSnapshotTime = timestamp;
13595            getCanvas(canvasElement).forEach((canvas) => {
13596                const id = this.mirror.getId(canvas);
13597                if (snapshotInProgressMap.get(id))
13598                    return;
13599                snapshotInProgressMap.set(id, true);
13600                if (!isManualSnapshot &&
13601                    ['webgl', 'webgl2'].includes(canvas.__context)) {
13602                    const context = canvas.getContext(canvas.__context);
13603                    if (_optionalChain([context, 'optionalAccess', _ => _.getContextAttributes, 'call', _2 => _2(), 'optionalAccess', _3 => _3.preserveDrawingBuffer]) === false) {
13604                        context.clear(context.COLOR_BUFFER_BIT);
13605                    }
13606                }
13607                createImageBitmap(canvas)
13608                    .then((bitmap) => {
13609                    worker.postMessage({
13610                        id,
13611                        bitmap,
13612                        width: canvas.width,
13613                        height: canvas.height,
13614                        dataURLOptions,
13615                    }, [bitmap]);
13616                })
13617                    .catch((error) => {
13618                    callbackWrapper(() => {
13619                        throw error;
13620                    })();
13621                });
13622            });
13623            rafId = onRequestAnimationFrame(takeCanvasSnapshots);
13624        };
13625        rafId = onRequestAnimationFrame(takeCanvasSnapshots);
13626        return rafId;
13627    }
13628    startPendingCanvasMutationFlusher() {
13629        onRequestAnimationFrame(() => this.flushPendingCanvasMutations());
13630    }
13631    startRAFTimestamping() {
13632        const setLatestRAFTimestamp = (timestamp) => {
13633            this.rafStamps.latestId = timestamp;
13634            onRequestAnimationFrame(setLatestRAFTimestamp);
13635        };
13636        onRequestAnimationFrame(setLatestRAFTimestamp);
13637    }
13638    flushPendingCanvasMutations() {
13639        this.pendingCanvasMutations.forEach((values, canvas) => {
13640            const id = this.mirror.getId(canvas);
13641            this.flushPendingCanvasMutationFor(canvas, id);
13642        });
13643        onRequestAnimationFrame(() => this.flushPendingCanvasMutations());
13644    }
13645    flushPendingCanvasMutationFor(canvas, id) {
13646        if (this.frozen || this.locked) {
13647            return;
13648        }
13649        const valuesWithType = this.pendingCanvasMutations.get(canvas);
13650        if (!valuesWithType || id === -1)
13651            return;
13652        const values = valuesWithType.map((value) => {
13653            const { type, ...rest } = value;
13654            return rest;
13655        });
13656        const { type } = valuesWithType[0];
13657        this.mutationCb({ id, type, commands: values });
13658        this.pendingCanvasMutations.delete(canvas);
13659    }
13660}
13661
13662const CANVAS_QUALITY = {
13663  low: {
13664    sampling: {
13665      canvas: 1,
13666    },
13667    dataURLOptions: {
13668      type: 'image/webp',
13669      quality: 0.25,
13670    },
13671  },
13672  medium: {
13673    sampling: {
13674      canvas: 2,
13675    },
13676    dataURLOptions: {
13677      type: 'image/webp',
13678      quality: 0.4,
13679    },
13680  },
13681  high: {
13682    sampling: {
13683      canvas: 4,
13684    },
13685    dataURLOptions: {
13686      type: 'image/webp',
13687      quality: 0.5,
13688    },
13689  },
13690};
13691
13692const INTEGRATION_NAME = 'ReplayCanvas';
13693
13694/** Exported only for type safe tests. */
13695const _replayCanvasIntegration = ((options = {}) => {
13696  const _canvasOptions = {
13697    quality: options.quality || 'medium',
13698    enableManualSnapshot: options.enableManualSnapshot,
13699  };
13700
13701  let canvasManagerResolve;
13702  const _canvasManager = new Promise(resolve => (canvasManagerResolve = resolve));
13703
13704  return {
13705    name: INTEGRATION_NAME,
13706    // eslint-disable-next-line @typescript-eslint/no-empty-function
13707    setupOnce() {},
13708    getOptions() {
13709      const { quality, enableManualSnapshot } = _canvasOptions;
13710
13711      return {
13712        enableManualSnapshot,
13713        recordCanvas: true,
13714        getCanvasManager: (options) => {
13715          const manager = new CanvasManager({
13716            ...options,
13717            enableManualSnapshot,
13718            errorHandler: (err) => {
13719              try {
13720                if (typeof err === 'object') {
13721                  (err ).__rrweb__ = true;
13722                }
13723              } catch (error) {
13724                // ignore errors here
13725                // this can happen if the error is frozen or does not allow mutation for other reasons
13726              }
13727            },
13728          });
13729          canvasManagerResolve(manager);
13730          return manager;
13731        },
13732        ...(CANVAS_QUALITY[quality || 'medium'] || CANVAS_QUALITY.medium),
13733      };
13734    },
13735    async snapshot(canvasElement) {
13736      const canvasManager = await _canvasManager;
13737      canvasManager.snapshot(canvasElement);
13738    },
13739  };
13740}) ;
13741
13742/**
13743 * Add this in addition to `replayIntegration()` to enable canvas recording.
13744 */
13745const replayCanvasIntegration = core.defineIntegration(_replayCanvasIntegration);
13746
13747/**
13748 * @deprecated Use `replayCanvasIntegration()` instead
13749 */
13750// eslint-disable-next-line deprecation/deprecation
13751const ReplayCanvas = core.convertIntegrationFnToClass(INTEGRATION_NAME, replayCanvasIntegration)
13752
13753;
13754
13755exports.ReplayCanvas = ReplayCanvas;
13756exports.replayCanvasIntegration = replayCanvasIntegration;
13757
13758
13759},{"@sentry/core":250,"@sentry/utils":319}],184:[function(require,module,exports){
13760Object.defineProperty(exports, '__esModule', { value: true });
13761
13762const core = require('@sentry/core');
13763const utils = require('@sentry/utils');
13764const debugBuild = require('../common/debug-build.js');
13765const types = require('./types.js');
13766
13767/**
13768 * Add a listener that cancels and finishes a transaction when the global
13769 * document is hidden.
13770 */
13771function registerBackgroundTabDetection() {
13772  if (types.WINDOW && types.WINDOW.document) {
13773    types.WINDOW.document.addEventListener('visibilitychange', () => {
13774      // eslint-disable-next-line deprecation/deprecation
13775      const activeTransaction = core.getActiveTransaction() ;
13776      if (types.WINDOW.document.hidden && activeTransaction) {
13777        const statusType = 'cancelled';
13778
13779        const { op, status } = core.spanToJSON(activeTransaction);
13780
13781        debugBuild.DEBUG_BUILD &&
13782          utils.logger.log(`[Tracing] Transaction: ${statusType} -> since tab moved to the background, op: ${op}`);
13783        // We should not set status if it is already set, this prevent important statuses like
13784        // error or data loss from being overwritten on transaction.
13785        if (!status) {
13786          activeTransaction.setStatus(statusType);
13787        }
13788        // TODO: Can we rewrite this to an attribute?
13789        // eslint-disable-next-line deprecation/deprecation
13790        activeTransaction.setTag('visibilitychange', 'document.hidden');
13791        activeTransaction.end();
13792      }
13793    });
13794  } else {
13795    debugBuild.DEBUG_BUILD && utils.logger.warn('[Tracing] Could not set up background tab detection due to lack of global document');
13796  }
13797}
13798
13799exports.registerBackgroundTabDetection = registerBackgroundTabDetection;
13800
13801
13802},{"../common/debug-build.js":206,"./types.js":192,"@sentry/core":250,"@sentry/utils":319}],185:[function(require,module,exports){
13803Object.defineProperty(exports, '__esModule', { value: true });
13804
13805const core = require('@sentry/core');
13806const utils = require('@sentry/utils');
13807const debugBuild = require('../common/debug-build.js');
13808const backgroundtab = require('./backgroundtab.js');
13809const instrument = require('./instrument.js');
13810const index = require('./metrics/index.js');
13811const request = require('./request.js');
13812const types = require('./types.js');
13813
13814const BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';
13815
13816/** Options for Browser Tracing integration */
13817
13818const DEFAULT_BROWSER_TRACING_OPTIONS = {
13819  ...core.TRACING_DEFAULTS,
13820  instrumentNavigation: true,
13821  instrumentPageLoad: true,
13822  markBackgroundSpan: true,
13823  enableLongTask: true,
13824  enableInp: false,
13825  _experiments: {},
13826  ...request.defaultRequestInstrumentationOptions,
13827};
13828
13829/**
13830 * The Browser Tracing integration automatically instruments browser pageload/navigation
13831 * actions as transactions, and captures requests, metrics and errors as spans.
13832 *
13833 * The integration can be configured with a variety of options, and can be extended to use
13834 * any routing library. This integration uses {@see IdleTransaction} to create transactions.
13835 *
13836 * We explicitly export the proper type here, as this has to be extended in some cases.
13837 */
13838const browserTracingIntegration = ((_options = {}) => {
13839  const _hasSetTracePropagationTargets = debugBuild.DEBUG_BUILD
13840    ? !!(
13841        // eslint-disable-next-line deprecation/deprecation
13842        (_options.tracePropagationTargets || _options.tracingOrigins)
13843      )
13844    : false;
13845
13846  core.addTracingExtensions();
13847
13848  // TODO (v8): remove this block after tracingOrigins is removed
13849  // Set tracePropagationTargets to tracingOrigins if specified by the user
13850  // In case both are specified, tracePropagationTargets takes precedence
13851  // eslint-disable-next-line deprecation/deprecation
13852  if (!_options.tracePropagationTargets && _options.tracingOrigins) {
13853    // eslint-disable-next-line deprecation/deprecation
13854    _options.tracePropagationTargets = _options.tracingOrigins;
13855  }
13856
13857  const options = {
13858    ...DEFAULT_BROWSER_TRACING_OPTIONS,
13859    ..._options,
13860  };
13861
13862  const _collectWebVitals = index.startTrackingWebVitals();
13863
13864  /** Stores a mapping of interactionIds from PerformanceEventTimings to the origin interaction path */
13865  const interactionIdtoRouteNameMapping = {};
13866  if (options.enableInp) {
13867    index.startTrackingINP(interactionIdtoRouteNameMapping);
13868  }
13869
13870  if (options.enableLongTask) {
13871    index.startTrackingLongTasks();
13872  }
13873  if (options._experiments.enableInteractions) {
13874    index.startTrackingInteractions();
13875  }
13876
13877  const latestRoute
13878
13879 = {
13880    name: undefined,
13881    context: undefined,
13882  };
13883
13884  /** Create routing idle transaction. */
13885  function _createRouteTransaction(context) {
13886    // eslint-disable-next-line deprecation/deprecation
13887    const hub = core.getCurrentHub();
13888
13889    const { beforeStartSpan, idleTimeout, finalTimeout, heartbeatInterval } = options;
13890
13891    const isPageloadTransaction = context.op === 'pageload';
13892
13893    let expandedContext;
13894    if (isPageloadTransaction) {
13895      const sentryTrace = isPageloadTransaction ? getMetaContent('sentry-trace') : '';
13896      const baggage = isPageloadTransaction ? getMetaContent('baggage') : undefined;
13897      const { traceId, dsc, parentSpanId, sampled } = utils.propagationContextFromHeaders(sentryTrace, baggage);
13898      expandedContext = {
13899        traceId,
13900        parentSpanId,
13901        parentSampled: sampled,
13902        ...context,
13903        metadata: {
13904          // eslint-disable-next-line deprecation/deprecation
13905          ...context.metadata,
13906          dynamicSamplingContext: dsc,
13907        },
13908        trimEnd: true,
13909      };
13910    } else {
13911      expandedContext = {
13912        trimEnd: true,
13913        ...context,
13914      };
13915    }
13916
13917    const finalContext = beforeStartSpan ? beforeStartSpan(expandedContext) : expandedContext;
13918
13919    // If `beforeStartSpan` set a custom name, record that fact
13920    // eslint-disable-next-line deprecation/deprecation
13921    finalContext.metadata =
13922      finalContext.name !== expandedContext.name
13923        ? // eslint-disable-next-line deprecation/deprecation
13924          { ...finalContext.metadata, source: 'custom' }
13925        : // eslint-disable-next-line deprecation/deprecation
13926          finalContext.metadata;
13927
13928    latestRoute.name = finalContext.name;
13929    latestRoute.context = finalContext;
13930
13931    if (finalContext.sampled === false) {
13932      debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Will not send ${finalContext.op} transaction because of beforeNavigate.`);
13933    }
13934
13935    debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Starting ${finalContext.op} transaction on scope`);
13936
13937    const { location } = types.WINDOW;
13938
13939    const idleTransaction = core.startIdleTransaction(
13940      hub,
13941      finalContext,
13942      idleTimeout,
13943      finalTimeout,
13944      true,
13945      { location }, // for use in the tracesSampler
13946      heartbeatInterval,
13947      isPageloadTransaction, // should wait for finish signal if it's a pageload transaction
13948    );
13949
13950    if (isPageloadTransaction && types.WINDOW.document) {
13951      types.WINDOW.document.addEventListener('readystatechange', () => {
13952        if (['interactive', 'complete'].includes(types.WINDOW.document.readyState)) {
13953          idleTransaction.sendAutoFinishSignal();
13954        }
13955      });
13956
13957      if (['interactive', 'complete'].includes(types.WINDOW.document.readyState)) {
13958        idleTransaction.sendAutoFinishSignal();
13959      }
13960    }
13961
13962    idleTransaction.registerBeforeFinishCallback(transaction => {
13963      _collectWebVitals();
13964      index.addPerformanceEntries(transaction);
13965    });
13966
13967    return idleTransaction ;
13968  }
13969
13970  return {
13971    name: BROWSER_TRACING_INTEGRATION_ID,
13972    // eslint-disable-next-line @typescript-eslint/no-empty-function
13973    setupOnce: () => {},
13974    afterAllSetup(client) {
13975      const clientOptions = client.getOptions();
13976
13977      const { markBackgroundSpan, traceFetch, traceXHR, shouldCreateSpanForRequest, enableHTTPTimings, _experiments } =
13978        options;
13979
13980      const clientOptionsTracePropagationTargets = clientOptions && clientOptions.tracePropagationTargets;
13981      // There are three ways to configure tracePropagationTargets:
13982      // 1. via top level client option `tracePropagationTargets`
13983      // 2. via BrowserTracing option `tracePropagationTargets`
13984      // 3. via BrowserTracing option `tracingOrigins` (deprecated)
13985      //
13986      // To avoid confusion, favour top level client option `tracePropagationTargets`, and fallback to
13987      // BrowserTracing option `tracePropagationTargets` and then `tracingOrigins` (deprecated).
13988      // This is done as it minimizes bundle size (we don't have to have undefined checks).
13989      //
13990      // If both 1 and either one of 2 or 3 are set (from above), we log out a warning.
13991      // eslint-disable-next-line deprecation/deprecation
13992      const tracePropagationTargets = clientOptionsTracePropagationTargets || options.tracePropagationTargets;
13993      if (debugBuild.DEBUG_BUILD && _hasSetTracePropagationTargets && clientOptionsTracePropagationTargets) {
13994        utils.logger.warn(
13995          '[Tracing] The `tracePropagationTargets` option was set in the BrowserTracing integration and top level `Sentry.init`. The top level `Sentry.init` value is being used.',
13996        );
13997      }
13998
13999      let activeSpan;
14000      let startingUrl = types.WINDOW.location && types.WINDOW.location.href;
14001
14002      if (client.on) {
14003        client.on('startNavigationSpan', (context) => {
14004          if (activeSpan) {
14005            debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Finishing current transaction with op: ${core.spanToJSON(activeSpan).op}`);
14006            // If there's an open transaction on the scope, we need to finish it before creating an new one.
14007            activeSpan.end();
14008          }
14009          activeSpan = _createRouteTransaction({
14010            op: 'navigation',
14011            ...context,
14012          });
14013        });
14014
14015        client.on('startPageLoadSpan', (context) => {
14016          if (activeSpan) {
14017            debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Finishing current transaction with op: ${core.spanToJSON(activeSpan).op}`);
14018            // If there's an open transaction on the scope, we need to finish it before creating an new one.
14019            activeSpan.end();
14020          }
14021          activeSpan = _createRouteTransaction({
14022            op: 'pageload',
14023            ...context,
14024          });
14025        });
14026      }
14027
14028      if (options.instrumentPageLoad && client.emit && types.WINDOW.location) {
14029        const context = {
14030          name: types.WINDOW.location.pathname,
14031          // pageload should always start at timeOrigin (and needs to be in s, not ms)
14032          startTimestamp: utils.browserPerformanceTimeOrigin ? utils.browserPerformanceTimeOrigin / 1000 : undefined,
14033          origin: 'auto.pageload.browser',
14034          attributes: {
14035            [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
14036          },
14037        };
14038        startBrowserTracingPageLoadSpan(client, context);
14039      }
14040
14041      if (options.instrumentNavigation && client.emit && types.WINDOW.location) {
14042        utils.addHistoryInstrumentationHandler(({ to, from }) => {
14043          /**
14044           * This early return is there to account for some cases where a navigation transaction starts right after
14045           * long-running pageload. We make sure that if `from` is undefined and a valid `startingURL` exists, we don't
14046           * create an uneccessary navigation transaction.
14047           *
14048           * This was hard to duplicate, but this behavior stopped as soon as this fix was applied. This issue might also
14049           * only be caused in certain development environments where the usage of a hot module reloader is causing
14050           * errors.
14051           */
14052          if (from === undefined && startingUrl && startingUrl.indexOf(to) !== -1) {
14053            startingUrl = undefined;
14054            return;
14055          }
14056
14057          if (from !== to) {
14058            startingUrl = undefined;
14059            const context = {
14060              name: types.WINDOW.location.pathname,
14061              origin: 'auto.navigation.browser',
14062              attributes: {
14063                [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
14064              },
14065            };
14066
14067            startBrowserTracingNavigationSpan(client, context);
14068          }
14069        });
14070      }
14071
14072      if (markBackgroundSpan) {
14073        backgroundtab.registerBackgroundTabDetection();
14074      }
14075
14076      if (_experiments.enableInteractions) {
14077        registerInteractionListener(options, latestRoute);
14078      }
14079
14080      if (options.enableInp) {
14081        registerInpInteractionListener(interactionIdtoRouteNameMapping, latestRoute);
14082      }
14083
14084      request.instrumentOutgoingRequests({
14085        traceFetch,
14086        traceXHR,
14087        tracePropagationTargets,
14088        shouldCreateSpanForRequest,
14089        enableHTTPTimings,
14090      });
14091    },
14092    // TODO v8: Remove this again
14093    // This is private API that we use to fix converted BrowserTracing integrations in Next.js & SvelteKit
14094    options,
14095  };
14096}) ;
14097
14098/**
14099 * Manually start a page load span.
14100 * This will only do something if the BrowserTracing integration has been setup.
14101 */
14102function startBrowserTracingPageLoadSpan(client, spanOptions) {
14103  if (!client.emit) {
14104    return;
14105  }
14106
14107  client.emit('startPageLoadSpan', spanOptions);
14108
14109  const span = core.getActiveSpan();
14110  const op = span && core.spanToJSON(span).op;
14111  return op === 'pageload' ? span : undefined;
14112}
14113
14114/**
14115 * Manually start a navigation span.
14116 * This will only do something if the BrowserTracing integration has been setup.
14117 */
14118function startBrowserTracingNavigationSpan(client, spanOptions) {
14119  if (!client.emit) {
14120    return;
14121  }
14122
14123  client.emit('startNavigationSpan', spanOptions);
14124
14125  const span = core.getActiveSpan();
14126  const op = span && core.spanToJSON(span).op;
14127  return op === 'navigation' ? span : undefined;
14128}
14129
14130/** Returns the value of a meta tag */
14131function getMetaContent(metaName) {
14132  // Can't specify generic to `getDomElement` because tracing can be used
14133  // in a variety of environments, have to disable `no-unsafe-member-access`
14134  // as a result.
14135  const metaTag = utils.getDomElement(`meta[name=${metaName}]`);
14136  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
14137  return metaTag ? metaTag.getAttribute('content') : undefined;
14138}
14139
14140/** Start listener for interaction transactions */
14141function registerInteractionListener(
14142  options,
14143  latestRoute
14144
14145,
14146) {
14147  let inflightInteractionTransaction;
14148  const registerInteractionTransaction = () => {
14149    const { idleTimeout, finalTimeout, heartbeatInterval } = options;
14150    const op = 'ui.action.click';
14151
14152    // eslint-disable-next-line deprecation/deprecation
14153    const currentTransaction = core.getActiveTransaction();
14154    if (currentTransaction && currentTransaction.op && ['navigation', 'pageload'].includes(currentTransaction.op)) {
14155      debugBuild.DEBUG_BUILD &&
14156        utils.logger.warn(
14157          `[Tracing] Did not create ${op} transaction because a pageload or navigation transaction is in progress.`,
14158        );
14159      return undefined;
14160    }
14161
14162    if (inflightInteractionTransaction) {
14163      inflightInteractionTransaction.setFinishReason('interactionInterrupted');
14164      inflightInteractionTransaction.end();
14165      inflightInteractionTransaction = undefined;
14166    }
14167
14168    if (!latestRoute.name) {
14169      debugBuild.DEBUG_BUILD && utils.logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`);
14170      return undefined;
14171    }
14172
14173    const { location } = types.WINDOW;
14174
14175    const context = {
14176      name: latestRoute.name,
14177      op,
14178      trimEnd: true,
14179      data: {
14180        [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: latestRoute.context ? getSource(latestRoute.context) : 'url',
14181      },
14182    };
14183
14184    inflightInteractionTransaction = core.startIdleTransaction(
14185      // eslint-disable-next-line deprecation/deprecation
14186      core.getCurrentHub(),
14187      context,
14188      idleTimeout,
14189      finalTimeout,
14190      true,
14191      { location }, // for use in the tracesSampler
14192      heartbeatInterval,
14193    );
14194  };
14195
14196  ['click'].forEach(type => {
14197    addEventListener(type, registerInteractionTransaction, { once: false, capture: true });
14198  });
14199}
14200
14201function isPerformanceEventTiming(entry) {
14202  return 'duration' in entry;
14203}
14204
14205/** We store up to 10 interaction candidates max to cap memory usage. This is the same cap as getINP from web-vitals */
14206const MAX_INTERACTIONS = 10;
14207
14208/** Creates a listener on interaction entries, and maps interactionIds to the origin path of the interaction */
14209function registerInpInteractionListener(
14210  interactionIdtoRouteNameMapping,
14211  latestRoute
14212
14213,
14214) {
14215  instrument.addPerformanceInstrumentationHandler('event', ({ entries }) => {
14216    const client = core.getClient();
14217    // We need to get the replay, user, and activeTransaction from the current scope
14218    // so that we can associate replay id, profile id, and a user display to the span
14219    const replay =
14220      client !== undefined && client.getIntegrationByName !== undefined
14221        ? (client.getIntegrationByName('Replay') )
14222        : undefined;
14223    const replayId = replay !== undefined ? replay.getReplayId() : undefined;
14224    // eslint-disable-next-line deprecation/deprecation
14225    const activeTransaction = core.getActiveTransaction();
14226    const currentScope = core.getCurrentScope();
14227    const user = currentScope !== undefined ? currentScope.getUser() : undefined;
14228    for (const entry of entries) {
14229      if (isPerformanceEventTiming(entry)) {
14230        const duration = entry.duration;
14231        const keys = Object.keys(interactionIdtoRouteNameMapping);
14232        const minInteractionId =
14233          keys.length > 0
14234            ? keys.reduce((a, b) => {
14235                return interactionIdtoRouteNameMapping[a].duration < interactionIdtoRouteNameMapping[b].duration
14236                  ? a
14237                  : b;
14238              })
14239            : undefined;
14240        if (minInteractionId === undefined || duration > interactionIdtoRouteNameMapping[minInteractionId].duration) {
14241          const interactionId = entry.interactionId;
14242          const routeName = latestRoute.name;
14243          const parentContext = latestRoute.context;
14244          if (interactionId && routeName && parentContext) {
14245            if (minInteractionId && Object.keys(interactionIdtoRouteNameMapping).length >= MAX_INTERACTIONS) {
14246              // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
14247              delete interactionIdtoRouteNameMapping[minInteractionId];
14248            }
14249            interactionIdtoRouteNameMapping[interactionId] = {
14250              routeName,
14251              duration,
14252              parentContext,
14253              user,
14254              activeTransaction,
14255              replayId,
14256            };
14257          }
14258        }
14259      }
14260    }
14261  });
14262}
14263
14264function getSource(context) {
14265  const sourceFromAttributes = context.attributes && context.attributes[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
14266  // eslint-disable-next-line deprecation/deprecation
14267  const sourceFromData = context.data && context.data[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
14268  // eslint-disable-next-line deprecation/deprecation
14269  const sourceFromMetadata = context.metadata && context.metadata.source;
14270
14271  return sourceFromAttributes || sourceFromData || sourceFromMetadata;
14272}
14273
14274exports.BROWSER_TRACING_INTEGRATION_ID = BROWSER_TRACING_INTEGRATION_ID;
14275exports.browserTracingIntegration = browserTracingIntegration;
14276exports.getMetaContent = getMetaContent;
14277exports.startBrowserTracingNavigationSpan = startBrowserTracingNavigationSpan;
14278exports.startBrowserTracingPageLoadSpan = startBrowserTracingPageLoadSpan;
14279
14280
14281},{"../common/debug-build.js":206,"./backgroundtab.js":184,"./instrument.js":187,"./metrics/index.js":188,"./request.js":190,"./types.js":192,"@sentry/core":250,"@sentry/utils":319}],186:[function(require,module,exports){
14282Object.defineProperty(exports, '__esModule', { value: true });
14283
14284const core = require('@sentry/core');
14285const utils = require('@sentry/utils');
14286const debugBuild = require('../common/debug-build.js');
14287const backgroundtab = require('./backgroundtab.js');
14288const instrument = require('./instrument.js');
14289const index = require('./metrics/index.js');
14290const request = require('./request.js');
14291const router = require('./router.js');
14292const types = require('./types.js');
14293
14294const BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';
14295
14296/** Options for Browser Tracing integration */
14297
14298const DEFAULT_BROWSER_TRACING_OPTIONS = {
14299  ...core.TRACING_DEFAULTS,
14300  markBackgroundTransactions: true,
14301  routingInstrumentation: router.instrumentRoutingWithDefaults,
14302  startTransactionOnLocationChange: true,
14303  startTransactionOnPageLoad: true,
14304  enableLongTask: true,
14305  enableInp: false,
14306  _experiments: {},
14307  ...request.defaultRequestInstrumentationOptions,
14308};
14309
14310/** We store up to 10 interaction candidates max to cap memory usage. This is the same cap as getINP from web-vitals */
14311const MAX_INTERACTIONS = 10;
14312
14313/**
14314 * The Browser Tracing integration automatically instruments browser pageload/navigation
14315 * actions as transactions, and captures requests, metrics and errors as spans.
14316 *
14317 * The integration can be configured with a variety of options, and can be extended to use
14318 * any routing library. This integration uses {@see IdleTransaction} to create transactions.
14319 *
14320 * @deprecated Use `browserTracingIntegration()` instead.
14321 */
14322class BrowserTracing  {
14323  // This class currently doesn't have a static `id` field like the other integration classes, because it prevented
14324  // @sentry/tracing from being treeshaken. Tree shakers do not like static fields, because they behave like side effects.
14325  // TODO: Come up with a better plan, than using static fields on integration classes, and use that plan on all
14326  // integrations.
14327
14328  /** Browser Tracing integration options */
14329
14330  /**
14331   * @inheritDoc
14332   */
14333
14334   constructor(_options) {
14335    this.name = BROWSER_TRACING_INTEGRATION_ID;
14336    this._hasSetTracePropagationTargets = false;
14337
14338    core.addTracingExtensions();
14339
14340    if (debugBuild.DEBUG_BUILD) {
14341      this._hasSetTracePropagationTargets = !!(
14342        _options &&
14343        // eslint-disable-next-line deprecation/deprecation
14344        (_options.tracePropagationTargets || _options.tracingOrigins)
14345      );
14346    }
14347
14348    this.options = {
14349      ...DEFAULT_BROWSER_TRACING_OPTIONS,
14350      ..._options,
14351    };
14352
14353    // Special case: enableLongTask can be set in _experiments
14354    // TODO (v8): Remove this in v8
14355    if (this.options._experiments.enableLongTask !== undefined) {
14356      this.options.enableLongTask = this.options._experiments.enableLongTask;
14357    }
14358
14359    // TODO (v8): remove this block after tracingOrigins is removed
14360    // Set tracePropagationTargets to tracingOrigins if specified by the user
14361    // In case both are specified, tracePropagationTargets takes precedence
14362    // eslint-disable-next-line deprecation/deprecation
14363    if (_options && !_options.tracePropagationTargets && _options.tracingOrigins) {
14364      // eslint-disable-next-line deprecation/deprecation
14365      this.options.tracePropagationTargets = _options.tracingOrigins;
14366    }
14367
14368    this._collectWebVitals = index.startTrackingWebVitals();
14369    /** Stores a mapping of interactionIds from PerformanceEventTimings to the origin interaction path */
14370    this._interactionIdtoRouteNameMapping = {};
14371
14372    if (this.options.enableInp) {
14373      index.startTrackingINP(this._interactionIdtoRouteNameMapping);
14374    }
14375    if (this.options.enableLongTask) {
14376      index.startTrackingLongTasks();
14377    }
14378    if (this.options._experiments.enableInteractions) {
14379      index.startTrackingInteractions();
14380    }
14381
14382    this._latestRoute = {
14383      name: undefined,
14384      context: undefined,
14385    };
14386  }
14387
14388  /**
14389   * @inheritDoc
14390   */
14391   setupOnce(_, getCurrentHub) {
14392    this._getCurrentHub = getCurrentHub;
14393    const hub = getCurrentHub();
14394    // eslint-disable-next-line deprecation/deprecation
14395    const client = hub.getClient();
14396    const clientOptions = client && client.getOptions();
14397
14398    const {
14399      routingInstrumentation: instrumentRouting,
14400      startTransactionOnLocationChange,
14401      startTransactionOnPageLoad,
14402      markBackgroundTransactions,
14403      traceFetch,
14404      traceXHR,
14405      shouldCreateSpanForRequest,
14406      enableHTTPTimings,
14407      _experiments,
14408    } = this.options;
14409
14410    const clientOptionsTracePropagationTargets = clientOptions && clientOptions.tracePropagationTargets;
14411    // There are three ways to configure tracePropagationTargets:
14412    // 1. via top level client option `tracePropagationTargets`
14413    // 2. via BrowserTracing option `tracePropagationTargets`
14414    // 3. via BrowserTracing option `tracingOrigins` (deprecated)
14415    //
14416    // To avoid confusion, favour top level client option `tracePropagationTargets`, and fallback to
14417    // BrowserTracing option `tracePropagationTargets` and then `tracingOrigins` (deprecated).
14418    // This is done as it minimizes bundle size (we don't have to have undefined checks).
14419    //
14420    // If both 1 and either one of 2 or 3 are set (from above), we log out a warning.
14421    // eslint-disable-next-line deprecation/deprecation
14422    const tracePropagationTargets = clientOptionsTracePropagationTargets || this.options.tracePropagationTargets;
14423    if (debugBuild.DEBUG_BUILD && this._hasSetTracePropagationTargets && clientOptionsTracePropagationTargets) {
14424      utils.logger.warn(
14425        '[Tracing] The `tracePropagationTargets` option was set in the BrowserTracing integration and top level `Sentry.init`. The top level `Sentry.init` value is being used.',
14426      );
14427    }
14428
14429    instrumentRouting(
14430      (context) => {
14431        const transaction = this._createRouteTransaction(context);
14432
14433        this.options._experiments.onStartRouteTransaction &&
14434          this.options._experiments.onStartRouteTransaction(transaction, context, getCurrentHub);
14435
14436        return transaction;
14437      },
14438      startTransactionOnPageLoad,
14439      startTransactionOnLocationChange,
14440    );
14441
14442    if (markBackgroundTransactions) {
14443      backgroundtab.registerBackgroundTabDetection();
14444    }
14445
14446    if (_experiments.enableInteractions) {
14447      this._registerInteractionListener();
14448    }
14449
14450    if (this.options.enableInp) {
14451      this._registerInpInteractionListener();
14452    }
14453
14454    request.instrumentOutgoingRequests({
14455      traceFetch,
14456      traceXHR,
14457      tracePropagationTargets,
14458      shouldCreateSpanForRequest,
14459      enableHTTPTimings,
14460    });
14461  }
14462
14463  /** Create routing idle transaction. */
14464   _createRouteTransaction(context) {
14465    if (!this._getCurrentHub) {
14466      debugBuild.DEBUG_BUILD &&
14467        utils.logger.warn(`[Tracing] Did not create ${context.op} transaction because _getCurrentHub is invalid.`);
14468      return undefined;
14469    }
14470
14471    const hub = this._getCurrentHub();
14472
14473    const { beforeNavigate, idleTimeout, finalTimeout, heartbeatInterval } = this.options;
14474
14475    const isPageloadTransaction = context.op === 'pageload';
14476
14477    let expandedContext;
14478    if (isPageloadTransaction) {
14479      const sentryTrace = isPageloadTransaction ? getMetaContent('sentry-trace') : '';
14480      const baggage = isPageloadTransaction ? getMetaContent('baggage') : undefined;
14481      const { traceId, dsc, parentSpanId, sampled } = utils.propagationContextFromHeaders(sentryTrace, baggage);
14482      expandedContext = {
14483        traceId,
14484        parentSpanId,
14485        parentSampled: sampled,
14486        ...context,
14487        metadata: {
14488          // eslint-disable-next-line deprecation/deprecation
14489          ...context.metadata,
14490          dynamicSamplingContext: dsc,
14491        },
14492        trimEnd: true,
14493      };
14494    } else {
14495      expandedContext = {
14496        trimEnd: true,
14497        ...context,
14498      };
14499    }
14500
14501    const modifiedContext = typeof beforeNavigate === 'function' ? beforeNavigate(expandedContext) : expandedContext;
14502
14503    // For backwards compatibility reasons, beforeNavigate can return undefined to "drop" the transaction (prevent it
14504    // from being sent to Sentry).
14505    const finalContext = modifiedContext === undefined ? { ...expandedContext, sampled: false } : modifiedContext;
14506
14507    // If `beforeNavigate` set a custom name, record that fact
14508    // eslint-disable-next-line deprecation/deprecation
14509    finalContext.metadata =
14510      finalContext.name !== expandedContext.name
14511        ? // eslint-disable-next-line deprecation/deprecation
14512          { ...finalContext.metadata, source: 'custom' }
14513        : // eslint-disable-next-line deprecation/deprecation
14514          finalContext.metadata;
14515
14516    this._latestRoute.name = finalContext.name;
14517    this._latestRoute.context = finalContext;
14518
14519    // eslint-disable-next-line deprecation/deprecation
14520    if (finalContext.sampled === false) {
14521      debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Will not send ${finalContext.op} transaction because of beforeNavigate.`);
14522    }
14523
14524    debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Starting ${finalContext.op} transaction on scope`);
14525
14526    const { location } = types.WINDOW;
14527
14528    const idleTransaction = core.startIdleTransaction(
14529      hub,
14530      finalContext,
14531      idleTimeout,
14532      finalTimeout,
14533      true,
14534      { location }, // for use in the tracesSampler
14535      heartbeatInterval,
14536      isPageloadTransaction, // should wait for finish signal if it's a pageload transaction
14537    );
14538
14539    if (isPageloadTransaction) {
14540      types.WINDOW.document.addEventListener('readystatechange', () => {
14541        if (['interactive', 'complete'].includes(types.WINDOW.document.readyState)) {
14542          idleTransaction.sendAutoFinishSignal();
14543        }
14544      });
14545
14546      if (['interactive', 'complete'].includes(types.WINDOW.document.readyState)) {
14547        idleTransaction.sendAutoFinishSignal();
14548      }
14549    }
14550
14551    idleTransaction.registerBeforeFinishCallback(transaction => {
14552      this._collectWebVitals();
14553      index.addPerformanceEntries(transaction);
14554    });
14555
14556    return idleTransaction ;
14557  }
14558
14559  /** Start listener for interaction transactions */
14560   _registerInteractionListener() {
14561    let inflightInteractionTransaction;
14562    const registerInteractionTransaction = () => {
14563      const { idleTimeout, finalTimeout, heartbeatInterval } = this.options;
14564      const op = 'ui.action.click';
14565
14566      // eslint-disable-next-line deprecation/deprecation
14567      const currentTransaction = core.getActiveTransaction();
14568      if (currentTransaction && currentTransaction.op && ['navigation', 'pageload'].includes(currentTransaction.op)) {
14569        debugBuild.DEBUG_BUILD &&
14570          utils.logger.warn(
14571            `[Tracing] Did not create ${op} transaction because a pageload or navigation transaction is in progress.`,
14572          );
14573        return undefined;
14574      }
14575
14576      if (inflightInteractionTransaction) {
14577        inflightInteractionTransaction.setFinishReason('interactionInterrupted');
14578        inflightInteractionTransaction.end();
14579        inflightInteractionTransaction = undefined;
14580      }
14581
14582      if (!this._getCurrentHub) {
14583        debugBuild.DEBUG_BUILD && utils.logger.warn(`[Tracing] Did not create ${op}
14583 transaction because _getCurrentHub is invalid.`);
14584        return undefined;
14585      }
14586
14587      if (!this._latestRoute.name) {
14588        debugBuild.DEBUG_BUILD && utils.logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`);
14589        return undefined;
14590      }
14591
14592      const hub = this._getCurrentHub();
14593      const { location } = types.WINDOW;
14594
14595      const context = {
14596        name: this._latestRoute.name,
14597        op,
14598        trimEnd: true,
14599        data: {
14600          [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: this._latestRoute.context
14601            ? getSource(this._latestRoute.context)
14602            : 'url',
14603        },
14604      };
14605
14606      inflightInteractionTransaction = core.startIdleTransaction(
14607        hub,
14608        context,
14609        idleTimeout,
14610        finalTimeout,
14611        true,
14612        { location }, // for use in the tracesSampler
14613        heartbeatInterval,
14614      );
14615    };
14616
14617    ['click'].forEach(type => {
14618      addEventListener(type, registerInteractionTransaction, { once: false, capture: true });
14619    });
14620  }
14621
14622  /** Creates a listener on interaction entries, and maps interactionIds to the origin path of the interaction */
14623   _registerInpInteractionListener() {
14624    instrument.addPerformanceInstrumentationHandler('event', ({ entries }) => {
14625      const client = core.getClient();
14626      // We need to get the replay, user, and activeTransaction from the current scope
14627      // so that we can associate replay id, profile id, and a user display to the span
14628      const replay =
14629        client !== undefined && client.getIntegrationByName !== undefined
14630          ? (client.getIntegrationByName('Replay') )
14631          : undefined;
14632      const replayId = replay !== undefined ? replay.getReplayId() : undefined;
14633      // eslint-disable-next-line deprecation/deprecation
14634      const activeTransaction = core.getActiveTransaction();
14635      const currentScope = core.getCurrentScope();
14636      const user = currentScope !== undefined ? currentScope.getUser() : undefined;
14637      for (const entry of entries) {
14638        if (isPerformanceEventTiming(entry)) {
14639          const duration = entry.duration;
14640          const keys = Object.keys(this._interactionIdtoRouteNameMapping);
14641          const minInteractionId =
14642            keys.length > 0
14643              ? keys.reduce((a, b) => {
14644                  return this._interactionIdtoRouteNameMapping[a].duration <
14645                    this._interactionIdtoRouteNameMapping[b].duration
14646                    ? a
14647                    : b;
14648                })
14649              : undefined;
14650          if (
14651            minInteractionId === undefined ||
14652            duration > this._interactionIdtoRouteNameMapping[minInteractionId].duration
14653          ) {
14654            const interactionId = entry.interactionId;
14655            const routeName = this._latestRoute.name;
14656            const parentContext = this._latestRoute.context;
14657            if (interactionId && routeName && parentContext) {
14658              if (minInteractionId && Object.keys(this._interactionIdtoRouteNameMapping).length >= MAX_INTERACTIONS) {
14659                // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
14660                delete this._interactionIdtoRouteNameMapping[minInteractionId];
14661              }
14662              this._interactionIdtoRouteNameMapping[interactionId] = {
14663                routeName,
14664                duration,
14665                parentContext,
14666                user,
14667                activeTransaction,
14668                replayId,
14669              };
14670            }
14671          }
14672        }
14673      }
14674    });
14675  }
14676}
14677
14678/** Returns the value of a meta tag */
14679function getMetaContent(metaName) {
14680  // Can't specify generic to `getDomElement` because tracing can be used
14681  // in a variety of environments, have to disable `no-unsafe-member-access`
14682  // as a result.
14683  const metaTag = utils.getDomElement(`meta[name=${metaName}]`);
14684  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
14685  return metaTag ? metaTag.getAttribute('content') : undefined;
14686}
14687
14688function getSource(context) {
14689  const sourceFromAttributes = context.attributes && context.attributes[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
14690  // eslint-disable-next-line deprecation/deprecation
14691  const sourceFromData = context.data && context.data[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
14692  // eslint-disable-next-line deprecation/deprecation
14693  const sourceFromMetadata = context.metadata && context.metadata.source;
14694
14695  return sourceFromAttributes || sourceFromData || sourceFromMetadata;
14696}
14697
14698function isPerformanceEventTiming(entry) {
14699  return 'duration' in entry;
14700}
14701
14702exports.BROWSER_TRACING_INTEGRATION_ID = BROWSER_TRACING_INTEGRATION_ID;
14703exports.BrowserTracing = BrowserTracing;
14704exports.getMetaContent = getMetaContent;
14705
14706
14707},{"../common/debug-build.js":206,"./backgroundtab.js":184,"./instrument.js":187,"./metrics/index.js":188,"./request.js":190,"./router.js":191,"./types.js":192,"@sentry/core":250,"@sentry/utils":319}],187:[function(require,module,exports){
14708Object.defineProperty(exports, '__esModule', { value: true });
14709
14710const utils = require('@sentry/utils');
14711const debugBuild = require('../common/debug-build.js');
14712const getCLS = require('./web-vitals/getCLS.js');
14713const getFID = require('./web-vitals/getFID.js');
14714const getINP = require('./web-vitals/getINP.js');
14715const getLCP = require('./web-vitals/getLCP.js');
14716const observe = require('./web-vitals/lib/observe.js');
14717
14718const handlers = {};
14719const instrumented = {};
14720
14721let _previousCls;
14722let _previousFid;
14723let _previousLcp;
14724let _previousInp;
14725
14726/**
14727 * Add a callback that will be triggered when a CLS metric is available.
14728 * Returns a cleanup callback which can be called to remove the instrumentation handler.
14729 *
14730 * Pass `stopOnCallback = true` to stop listening for CLS when the cleanup callback is called.
14731 * This will lead to the CLS being finalized and frozen.
14732 */
14733function addClsInstrumentationHandler(
14734  callback,
14735  stopOnCallback = false,
14736) {
14737  return addMetricObserver('cls', callback, instrumentCls, _previousCls, stopOnCallback);
14738}
14739
14740/**
14741 * Add a callback that will be triggered when a LCP metric is available.
14742 * Returns a cleanup callback which can be called to remove the instrumentation handler.
14743 *
14744 * Pass `stopOnCallback = true` to stop listening for LCP when the cleanup callback is called.
14745 * This will lead to the LCP being finalized and frozen.
14746 */
14747function addLcpInstrumentationHandler(
14748  callback,
14749  stopOnCallback = false,
14750) {
14751  return addMetricObserver('lcp', callback, instrumentLcp, _previousLcp, stopOnCallback);
14752}
14753
14754/**
14755 * Add a callback that will be triggered when a FID metric is available.
14756 * Returns a cleanup callback which can be called to remove the instrumentation handler.
14757 */
14758function addFidInstrumentationHandler(callback) {
14759  return addMetricObserver('fid', callback, instrumentFid, _previousFid);
14760}
14761
14762/**
14763 * Add a callback that will be triggered when a INP metric is available.
14764 * Returns a cleanup callback which can be called to remove the instrumentation handler.
14765 */
14766function addInpInstrumentationHandler(
14767  callback,
14768) {
14769  return addMetricObserver('inp', callback, instrumentInp, _previousInp);
14770}
14771
14772/**
14773 * Add a callback that will be triggered when a performance observer is triggered,
14774 * and receives the entries of the observer.
14775 * Returns a cleanup callback which can be called to remove the instrumentation handler.
14776 */
14777function addPerformanceInstrumentationHandler(
14778  type,
14779  callback,
14780) {
14781  addHandler(type, callback);
14782
14783  if (!instrumented[type]) {
14784    instrumentPerformanceObserver(type);
14785    instrumented[type] = true;
14786  }
14787
14788  return getCleanupCallback(type, callback);
14789}
14790
14791/** Trigger all handlers of a given type. */
14792function triggerHandlers(type, data) {
14793  const typeHandlers = handlers[type];
14794
14795  if (!typeHandlers || !typeHandlers.length) {
14796    return;
14797  }
14798
14799  for (const handler of typeHandlers) {
14800    try {
14801      handler(data);
14802    } catch (e) {
14803      debugBuild.DEBUG_BUILD &&
14804        utils.logger.error(
14805          `Error while triggering instrumentation handler.\nType: ${type}\nName: ${utils.getFunctionName(handler)}\nError:`,
14806          e,
14807        );
14808    }
14809  }
14810}
14811
14812function instrumentCls() {
14813  return getCLS.onCLS(metric => {
14814    triggerHandlers('cls', {
14815      metric,
14816    });
14817    _previousCls = metric;
14818  });
14819}
14820
14821function instrumentFid() {
14822  return getFID.onFID(metric => {
14823    triggerHandlers('fid', {
14824      metric,
14825    });
14826    _previousFid = metric;
14827  });
14828}
14829
14830function instrumentLcp() {
14831  return getLCP.onLCP(metric => {
14832    triggerHandlers('lcp', {
14833      metric,
14834    });
14835    _previousLcp = metric;
14836  });
14837}
14838
14839function instrumentInp() {
14840  return getINP.onINP(metric => {
14841    triggerHandlers('inp', {
14842      metric,
14843    });
14844    _previousInp = metric;
14845  });
14846}
14847
14848function addMetricObserver(
14849  type,
14850  callback,
14851  instrumentFn,
14852  previousValue,
14853  stopOnCallback = false,
14854) {
14855  addHandler(type, callback);
14856
14857  let stopListening;
14858
14859  if (!instrumented[type]) {
14860    stopListening = instrumentFn();
14861    instrumented[type] = true;
14862  }
14863
14864  if (previousValue) {
14865    callback({ metric: previousValue });
14866  }
14867
14868  return getCleanupCallback(type, callback, stopOnCallback ? stopListening : undefined);
14869}
14870
14871function instrumentPerformanceObserver(type) {
14872  const options = {};
14873
14874  // Special per-type options we want to use
14875  if (type === 'event') {
14876    options.durationThreshold = 0;
14877  }
14878
14879  observe.observe(
14880    type,
14881    entries => {
14882      triggerHandlers(type, { entries });
14883    },
14884    options,
14885  );
14886}
14887
14888function addHandler(type, handler) {
14889  handlers[type] = handlers[type] || [];
14890  (handlers[type] ).push(handler);
14891}
14892
14893// Get a callback which can be called to remove the instrumentation handler
14894function getCleanupCallback(
14895  type,
14896  callback,
14897  stopListening,
14898) {
14899  return () => {
14900    if (stopListening) {
14901      stopListening();
14902    }
14903
14904    const typeHandlers = handlers[type];
14905
14906    if (!typeHandlers) {
14907      return;
14908    }
14909
14910    const index = typeHandlers.indexOf(callback);
14911    if (index !== -1) {
14912      typeHandlers.splice(index, 1);
14913    }
14914  };
14915}
14916
14917exports.addClsInstrumentationHandler = addClsInstrumentationHandler;
14918exports.addFidInstrumentationHandler = addFidInstrumentationHandler;
14919exports.addInpInstrumentationHandler = addInpInstrumentationHandler;
14920exports.addLcpInstrumentationHandler = addLcpInstrumentationHandler;
14921exports.addPerformanceInstrumentationHandler = addPerformanceInstrumentationHandler;
14922
14923
14924},{"../common/debug-build.js":206,"./web-vitals/getCLS.js":193,"./web-vitals/getFID.js":194,"./web-vitals/getINP.js":195,"./web-vitals/getLCP.js":196,"./web-vitals/lib/observe.js":203,"@sentry/utils":319}],188:[function(require,module,exports){
14925Object.defineProperty(exports, '__esModule', { value: true });
14926
14927const core = require('@sentry/core');
14928const utils = require('@sentry/utils');
14929const debugBuild = require('../../common/debug-build.js');
14930const instrument = require('../instrument.js');
14931const types = require('../types.js');
14932const getVisibilityWatcher = require('../web-vitals/lib/getVisibilityWatcher.js');
14933const utils$1 = require('./utils.js');
14934
14935const MAX_INT_AS_BYTES = 2147483647;
14936
14937/**
14938 * Converts from milliseconds to seconds
14939 * @param time time in ms
14940 */
14941function msToSec(time) {
14942  return time / 1000;
14943}
14944
14945function getBrowserPerformanceAPI() {
14946  // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are
14947  return types.WINDOW && types.WINDOW.addEventListener && types.WINDOW.performance;
14948}
14949
14950let _performanceCursor = 0;
14951
14952let _measurements = {};
14953let _lcpEntry;
14954let _clsEntry;
14955
14956/**
14957 * Start tracking web vitals.
14958 * The callback returned by this function can be used to stop tracking & ensure all measurements are final & captured.
14959 *
14960 * @returns A function that forces web vitals collection
14961 */
14962function startTrackingWebVitals() {
14963  const performance = getBrowserPerformanceAPI();
14964  if (performance && utils.browserPerformanceTimeOrigin) {
14965    // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are
14966    if (performance.mark) {
14967      types.WINDOW.performance.mark('sentry-tracing-init');
14968    }
14969    const fidCallback = _trackFID();
14970    const clsCallback = _trackCLS();
14971    const lcpCallback = _trackLCP();
14972
14973    return () => {
14974      fidCallback();
14975      clsCallback();
14976      lcpCallback();
14977    };
14978  }
14979
14980  return () => undefined;
14981}
14982
14983/**
14984 * Start tracking long tasks.
14985 */
14986function startTrackingLongTasks() {
14987  instrument.addPerformanceInstrumentationHandler('longtask', ({ entries }) => {
14988    for (const entry of entries) {
14989      // eslint-disable-next-line deprecation/deprecation
14990      const transaction = core.getActiveTransaction() ;
14991      if (!transaction) {
14992        return;
14993      }
14994      const startTime = msToSec((utils.browserPerformanceTimeOrigin ) + entry.startTime);
14995      const duration = msToSec(entry.duration);
14996
14997      // eslint-disable-next-line deprecation/deprecation
14998      transaction.startChild({
14999        description: 'Main UI thread blocked',
15000        op: 'ui.long-task',
15001        origin: 'auto.ui.browser.metrics',
15002        startTimestamp: startTime,
15003        endTimestamp: startTime + duration,
15004      });
15005    }
15006  });
15007}
15008
15009/**
15010 * Start tracking interaction events.
15011 */
15012function startTrackingInteractions() {
15013  instrument.addPerformanceInstrumentationHandler('event', ({ entries }) => {
15014    for (const entry of entries) {
15015      // eslint-disable-next-line deprecation/deprecation
15016      const transaction = core.getActiveTransaction() ;
15017      if (!transaction) {
15018        return;
15019      }
15020
15021      if (entry.name === 'click') {
15022        const startTime = msToSec((utils.browserPerformanceTimeOrigin ) + entry.startTime);
15023        const duration = msToSec(entry.duration);
15024
15025        const span = {
15026          description: utils.htmlTreeAsString(entry.target),
15027          op: `ui.interaction.${entry.name}`,
15028          origin: 'auto.ui.browser.metrics',
15029          startTimestamp: startTime,
15030          endTimestamp: startTime + duration,
15031        };
15032
15033        const componentName = utils.getComponentName(entry.target);
15034        if (componentName) {
15035          span.attributes = { 'ui.component_name': componentName };
15036        }
15037
15038        // eslint-disable-next-line deprecation/deprecation
15039        transaction.startChild(span);
15040      }
15041    }
15042  });
15043}
15044
15045/**
15046 * Start tracking INP webvital events.
15047 */
15048function startTrackingINP(interactionIdtoRouteNameMapping) {
15049  const performance = getBrowserPerformanceAPI();
15050  if (performance && utils.browserPerformanceTimeOrigin) {
15051    const inpCallback = _trackINP(interactionIdtoRouteNameMapping);
15052
15053    return () => {
15054      inpCallback();
15055    };
15056  }
15057
15058  return () => undefined;
15059}
15060
15061/** Starts tracking the Cumulative Layout Shift on the current page. */
15062function _trackCLS() {
15063  return instrument.addClsInstrumentationHandler(({ metric }) => {
15064    const entry = metric.entries[metric.entries.length - 1];
15065    if (!entry) {
15066      return;
15067    }
15068
15069    debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding CLS');
15070    _measurements['cls'] = { value: metric.value, unit: '' };
15071    _clsEntry = entry ;
15072  }, true);
15073}
15074
15075/** Starts tracking the Largest Contentful Paint on the current page. */
15076function _trackLCP() {
15077  return instrument.addLcpInstrumentationHandler(({ metric }) => {
15078    const entry = metric.entries[metric.entries.length - 1];
15079    if (!entry) {
15080      return;
15081    }
15082
15083    debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding LCP');
15084    _measurements['lcp'] = { value: metric.value, unit: 'millisecond' };
15085    _lcpEntry = entry ;
15086  }, true);
15087}
15088
15089/** Starts tracking the First Input Delay on the current page. */
15090function _trackFID() {
15091  return instrument.addFidInstrumentationHandler(({ metric }) => {
15092    const entry = metric.entries[metric.entries.length - 1];
15093    if (!entry) {
15094      return;
15095    }
15096
15097    const timeOrigin = msToSec(utils.browserPerformanceTimeOrigin );
15098    const startTime = msToSec(entry.startTime);
15099    debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding FID');
15100    _measurements['fid'] = { value: metric.value, unit: 'millisecond' };
15101    _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' };
15102  });
15103}
15104
15105/** Starts tracking the Interaction to Next Paint on the current page. */
15106function _trackINP(interactionIdtoRouteNameMapping) {
15107  return instrument.addInpInstrumentationHandler(({ metric }) => {
15108    const entry = metric.entries.find(e => e.name === 'click' || e.name === 'pointerdown');
15109    const client = core.getClient();
15110    if (!entry || !client) {
15111      return;
15112    }
15113    const options = client.getOptions();
15114    /** Build the INP span, create an envelope from the span, and then send the envelope */
15115    const startTime = msToSec((utils.browserPerformanceTimeOrigin ) + entry.startTime);
15116    const duration = msToSec(metric.value);
15117    const { routeName, parentContext, activeTransaction, user, replayId } =
15118      entry.interactionId !== undefined
15119        ? interactionIdtoRouteNameMapping[entry.interactionId]
15120        : {
15121            routeName: undefined,
15122            parentContext: undefined,
15123            activeTransaction: undefined,
15124            user: undefined,
15125            replayId: undefined,
15126          };
15127    const userDisplay = user !== undefined ? user.email || user.id || user.ip_address : undefined;
15128    // eslint-disable-next-line deprecation/deprecation
15129    const profileId = activeTransaction !== undefined ? activeTransaction.getProfileId() : undefined;
15130    const span = new core.Span({
15131      startTimestamp: startTime,
15132      endTimestamp: startTime + duration,
15133      op: 'ui.interaction.click',
15134      name: utils.htmlTreeAsString(entry.target),
15135      attributes: {
15136        release: options.release,
15137        environment: options.environment,
15138        transaction: routeName,
15139        ...(userDisplay !== undefined && userDisplay !== '' ? { user: userDisplay } : {}),
15140        ...(profileId !== undefined ? { profile_id: profileId } : {}),
15141        ...(replayId !== undefined ? { replay_id: replayId } : {}),
15142      },
15143      exclusiveTime: metric.value,
15144      measurements: {
15145        inp: { value: metric.value, unit: 'millisecond' },
15146      },
15147    });
15148
15149    /** Check to see if the span should be sampled */
15150    const sampleRate = getSampleRate(parentContext, options);
15151    if (!sampleRate) {
15152      return;
15153    }
15154
15155    if (Math.random() < (sampleRate )) {
15156      const envelope = span ? core.createSpanEnvelope([span], client.getDsn()) : undefined;
15157      const transport = client && client.getTransport();
15158      if (transport && envelope) {
15159        transport.send(envelope).then(null, reason => {
15160          debugBuild.DEBUG_BUILD && utils.logger.error('Error while sending interaction:', reason);
15161        });
15162      }
15163      return;
15164    }
15165  });
15166}
15167
15168/** Add performance related spans to a transaction */
15169function addPerformanceEntries(transaction) {
15170  const performance = getBrowserPerformanceAPI();
15171  if (!performance || !types.WINDOW.performance.getEntries || !utils.browserPerformanceTimeOrigin) {
15172    // Gatekeeper if performance API not available
15173    return;
15174  }
15175
15176  debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] Adding & adjusting spans using Performance API');
15177  const timeOrigin = msToSec(utils.browserPerformanceTimeOrigin);
15178
15179  const performanceEntries = performance.getEntries();
15180
15181  let responseStartTimestamp;
15182  let requestStartTimestamp;
15183
15184  const { op, start_timestamp: transactionStartTime } = core.spanToJSON(transaction);
15185
15186  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15187  performanceEntries.slice(_performanceCursor).forEach((entry) => {
15188    const startTime = msToSec(entry.startTime);
15189    const duration = msToSec(entry.duration);
15190
15191    // eslint-disable-next-line deprecation/deprecation
15192    if (transaction.op === 'navigation' && transactionStartTime && timeOrigin + startTime < transactionStartTime) {
15193      return;
15194    }
15195
15196    switch (entry.entryType) {
15197      case 'navigation': {
15198        _addNavigationSpans(transaction, entry, timeOrigin);
15199        responseStartTimestamp = timeOrigin + msToSec(entry.responseStart);
15200        requestStartTimestamp = timeOrigin + msToSec(entry.requestStart);
15201        break;
15202      }
15203      case 'mark':
15204      case 'paint':
15205      case 'measure': {
15206        _addMeasureSpans(transaction, entry, startTime, duration, timeOrigin);
15207
15208        // capture web vitals
15209        const firstHidden = getVisibilityWatcher.getVisibilityWatcher();
15210        // Only report if the page wasn't hidden prior to the web vital.
15211        const shouldRecord = entry.startTime < firstHidden.firstHiddenTime;
15212
15213        if (entry.name === 'first-paint' && shouldRecord) {
15214          debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding FP');
15215          _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' };
15216        }
15217        if (entry.name === 'first-contentful-paint' && shouldRecord) {
15218          debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding FCP');
15219          _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' };
15220        }
15221        break;
15222      }
15223      case 'resource': {
15224        _addResourceSpans(transaction, entry, entry.name , startTime, duration, timeOrigin);
15225        break;
15226      }
15227      // Ignore other entry types.
15228    }
15229  });
15230
15231  _performanceCursor = Math.max(performanceEntries.length - 1, 0);
15232
15233  _trackNavigator(transaction);
15234
15235  // Measurements are only available for pageload transactions
15236  if (op === 'pageload') {
15237    _addTtfbToMeasurements(_measurements, responseStartTimestamp, requestStartTimestamp, transactionStartTime);
15238
15239    ['fcp', 'fp', 'lcp'].forEach(name => {
15240      if (!_measurements[name] || !transactionStartTime || timeOrigin >= transactionStartTime) {
15241        return;
15242      }
15243      // The web vitals, fcp, fp, lcp, and ttfb, all measure relative to timeOrigin.
15244      // Unfortunately, timeOrigin is not captured within the transaction span data, so these web vitals will need
15245      // to be adjusted to be relative to transaction.startTimestamp.
15246      const oldValue = _measurements[name].value;
15247      const measurementTimestamp = timeOrigin + msToSec(oldValue);
15248
15249      // normalizedValue should be in milliseconds
15250      const normalizedValue = Math.abs((measurementTimestamp - transactionStartTime) * 1000);
15251      const delta = normalizedValue - oldValue;
15252
15253      debugBuild.DEBUG_BUILD && utils.logger.log(`[Measurements] Normalized ${name} from ${oldValue} to ${normalizedValue} (${delta})`);
15254      _measurements[name].value = normalizedValue;
15255    });
15256
15257    const fidMark = _measurements['mark.fid'];
15258    if (fidMark && _measurements['fid']) {
15259      // create span for FID
15260      utils$1._startChild(transaction, {
15261        description: 'first input delay',
15262        endTimestamp: fidMark.value + msToSec(_measurements['fid'].value),
15263        op: 'ui.action',
15264        origin: 'auto.ui.browser.metrics',
15265        startTimestamp: fidMark.value,
15266      });
15267
15268      // Delete mark.fid as we don't want it to be part of final payload
15269      delete _measurements['mark.fid'];
15270    }
15271
15272    // If FCP is not recorded we should not record the cls value
15273    // according to the new definition of CLS.
15274    if (!('fcp' in _measurements)) {
15275      delete _measurements.cls;
15276    }
15277
15278    Object.keys(_measurements).forEach(measurementName => {
15279      core.setMeasurement(measurementName, _measurements[measurementName].value, _measurements[measurementName].unit);
15280    });
15281
15282    _tagMetricInfo(transaction);
15283  }
15284
15285  _lcpEntry = undefined;
15286  _clsEntry = undefined;
15287  _measurements = {};
15288}
15289
15290/** Create measure related spans */
15291function _addMeasureSpans(
15292  transaction,
15293  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15294  entry,
15295  startTime,
15296  duration,
15297  timeOrigin,
15298) {
15299  const measureStartTimestamp = timeOrigin + startTime;
15300  const measureEndTimestamp = measureStartTimestamp + duration;
15301
15302  utils$1._startChild(transaction, {
15303    description: entry.name ,
15304    endTimestamp: measureEndTimestamp,
15305    op: entry.entryType ,
15306    origin: 'auto.resource.browser.metrics',
15307    startTimestamp: measureStartTimestamp,
15308  });
15309
15310  return measureStartTimestamp;
15311}
15312
15313/** Instrument navigation entries */
15314// eslint-disable-next-line @typescript-eslint/no-explicit-any
15315function _addNavigationSpans(transaction, entry, timeOrigin) {
15316  ['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'].forEach(event => {
15317    _addPerformanceNavigationTiming(transaction, entry, event, timeOrigin);
15318  });
15319  _addPerformanceNavigationTiming(transaction, entry, 'secureConnection', timeOrigin, 'TLS/SSL', 'connectEnd');
15320  _addPerformanceNavigationTiming(transaction, entry, 'fetch', timeOrigin, 'cache', 'domainLookupStart');
15321  _addPerformanceNavigationTiming(transaction, entry, 'domainLookup', timeOrigin, 'DNS');
15322  _addRequest(transaction, entry, timeOrigin);
15323}
15324
15325/** Create performance navigation related spans */
15326function _addPerformanceNavigationTiming(
15327  transaction,
15328  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15329  entry,
15330  event,
15331  timeOrigin,
15332  description,
15333  eventEnd,
15334) {
15335  const end = eventEnd ? (entry[eventEnd] ) : (entry[`${event}End`] );
15336  const start = entry[`${event}Start`] ;
15337  if (!start || !end) {
15338    return;
15339  }
15340  utils$1._startChild(transaction, {
15341    op: 'browser',
15342    origin: 'auto.browser.browser.metrics',
15343    description: description || event,
15344    startTimestamp: timeOrigin + msToSec(start),
15345    endTimestamp: timeOrigin + msToSec(end),
15346  });
15347}
15348
15349/** Create request and response related spans */
15350// eslint-disable-next-line @typescript-eslint/no-explicit-any
15351function _addRequest(transaction, entry, timeOrigin) {
15352  if (entry.responseEnd) {
15353    // 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.
15354    // In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.
15355    // In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect
15356    // these spans when the responseEnd value is available. The backend (Relay) would drop the entire transaction if it contained faulty spans.
15357    utils$1._startChild(transaction, {
15358      op: 'browser',
15359      origin: 'auto.browser.browser.metrics',
15360      description: 'request',
15361      startTimestamp: timeOrigin + msToSec(entry.requestStart ),
15362      endTimestamp: timeOrigin + msToSec(entry.responseEnd ),
15363    });
15364
15365    utils$1._startChild(transaction, {
15366      op: 'browser',
15367      origin: 'auto.browser.browser.metrics',
15368      description: 'response',
15369      startTimestamp: timeOrigin + msToSec(entry.responseStart ),
15370      endTimestamp: timeOrigin + msToSec(entry.responseEnd ),
15371    });
15372  }
15373}
15374
15375/** Create resource-related spans */
15376function _addResourceSpans(
15377  transaction,
15378  entry,
15379  resourceUrl,
15380  startTime,
15381  duration,
15382  timeOrigin,
15383) {
15384  // we already instrument based on fetch and xhr, so we don't need to
15385  // duplicate spans here.
15386  if (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') {
15387    return;
15388  }
15389
15390  const parsedUrl = utils.parseUrl(resourceUrl);
15391
15392  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15393  const data = {};
15394  setResourceEntrySizeData(data, entry, 'transferSize', 'http.response_transfer_size');
15395  setResourceEntrySizeData(data, entry, 'encodedBodySize', 'http.response_content_length');
15396  setResourceEntrySizeData(data, entry, 'decodedBodySize', 'http.decoded_response_content_length');
15397
15398  if ('renderBlockingStatus' in entry) {
15399    data['resource.render_blocking_status'] = entry.renderBlockingStatus;
15400  }
15401  if (parsedUrl.protocol) {
15402    data['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.
15403  }
15404
15405  if (parsedUrl.host) {
15406    data['server.address'] = parsedUrl.host;
15407  }
15408
15409  data['url.same_origin'] = resourceUrl.includes(types.WINDOW.location.origin);
15410
15411  const startTimestamp = timeOrigin + startTime;
15412  const endTimestamp = startTimestamp + duration;
15413
15414  utils$1._startChild(transaction, {
15415    description: resourceUrl.replace(types.WINDOW.location.origin, ''),
15416    endTimestamp,
15417    op: entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other',
15418    origin: 'auto.resource.browser.metrics',
15419    startTimestamp,
15420    data,
15421  });
15422}
15423
15424/**
15425 * Capture the information of the user agent.
15426 */
15427function _trackNavigator(transaction) {
15428  const navigator = types.WINDOW.navigator ;
15429  if (!navigator) {
15430    return;
15431  }
15432
15433  // track network connectivity
15434  const connection = navigator.connection;
15435  if (connection) {
15436    if (connection.effectiveType) {
15437      // TODO: Can we rewrite this to an attribute?
15438      // eslint-disable-next-line deprecation/deprecation
15439      transaction.setTag('effectiveConnectionType', connection.effectiveType);
15440    }
15441
15442    if (connection.type) {
15443      // TODO: Can we rewrite this to an attribute?
15444      // eslint-disable-next-line deprecation/deprecation
15445      transaction.setTag('connectionType', connection.type);
15446    }
15447
15448    if (utils$1.isMeasurementValue(connection.rtt)) {
15449      _measurements['connection.rtt'] = { value: connection.rtt, unit: 'millisecond' };
15450    }
15451  }
15452
15453  if (utils$1.isMeasurementValue(navigator.deviceMemory)) {
15454    // TODO: Can we rewrite this to an attribute?
15455    // eslint-disable-next-line deprecation/deprecation
15456    transaction.setTag('deviceMemory', `${navigator.deviceMemory} GB`);
15457  }
15458
15459  if (utils$1.isMeasurementValue(navigator.hardwareConcurrency)) {
15460    // TODO: Can we rewrite this to an attribute?
15461    // eslint-disable-next-line deprecation/deprecation
15462    transaction.setTag('hardwareConcurrency', String(navigator.hardwareConcurrency));
15463  }
15464}
15465
15466/** Add LCP / CLS data to transaction to allow debugging */
15467function _tagMetricInfo(transaction) {
15468  if (_lcpEntry) {
15469    debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding LCP Data');
15470
15471    // Capture Properties of the LCP element that contributes to the LCP.
15472
15473    if (_lcpEntry.element) {
15474      // TODO: Can we rewrite this to an attribute?
15475      // eslint-disable-next-line deprecation/deprecation
15476      transaction.setTag('lcp.element', utils.htmlTreeAsString(_lcpEntry.element));
15477    }
15478
15479    if (_lcpEntry.id) {
15480      // TODO: Can we rewrite this to an attribute?
15481      // eslint-disable-next-line deprecation/deprecation
15482      transaction.setTag('lcp.id', _lcpEntry.id);
15483    }
15484
15485    if (_lcpEntry.url) {
15486      // Trim URL to the first 200 characters.
15487      // TODO: Can we rewrite this to an attribute?
15488      // eslint-disable-next-line deprecation/deprecation
15489      transaction.setTag('lcp.url', _lcpEntry.url.trim().slice(0, 200));
15490    }
15491
15492    // TODO: Can we rewrite this to an attribute?
15493    // eslint-disable-next-line deprecation/deprecation
15494    transaction.setTag('lcp.size', _lcpEntry.size);
15495  }
15496
15497  // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift
15498  if (_clsEntry && _clsEntry.sources) {
15499    debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding CLS Data');
15500    _clsEntry.sources.forEach((source, index) =>
15501      // TODO: Can we rewrite this to an attribute?
15502      // eslint-disable-next-line deprecation/deprecation
15503      transaction.setTag(`cls.source.${index + 1}`, utils.htmlTreeAsString(source.node)),
15504    );
15505  }
15506}
15507
15508function setResourceEntrySizeData(
15509  data,
15510  entry,
15511  key,
15512  dataKey,
15513) {
15514  const entryVal = entry[key];
15515  if (entryVal != null && entryVal < MAX_INT_AS_BYTES) {
15516    data[dataKey] = entryVal;
15517  }
15518}
15519
15520/**
15521 * Add ttfb information to measurements
15522 *
15523 * Exported for tests
15524 */
15525function _addTtfbToMeasurements(
15526  _measurements,
15527  responseStartTimestamp,
15528  requestStartTimestamp,
15529  transactionStartTime,
15530) {
15531  // Generate TTFB (Time to First Byte), which measured as the time between the beginning of the transaction and the
15532  // start of the response in milliseconds
15533  if (typeof responseStartTimestamp === 'number' && transactionStartTime) {
15534    debugBuild.DEBUG_BUILD && utils.logger.log('[Measurements] Adding TTFB');
15535    _measurements['ttfb'] = {
15536      // As per https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/responseStart,
15537      // responseStart can be 0 if the request is coming straight from the cache.
15538      // This might lead us to calculate a negative ttfb if we don't use Math.max here.
15539      //
15540      // This logic is the same as what is in the web-vitals library to calculate ttfb
15541      // https://github.com/GoogleChrome/web-vitals/blob/2301de5015e82b09925238a228a0893635854587/src/onTTFB.ts#L92
15542      // TODO(abhi): We should use the web-vitals library instead of this custom calculation.
15543      value: Math.max(responseStartTimestamp - transactionStartTime, 0) * 1000,
15544      unit: 'millisecond',
15545    };
15546
15547    if (typeof requestStartTimestamp === 'number' && requestStartTimestamp <= responseStartTimestamp) {
15548      // Capture the time spent making the request and receiving the first byte of the response.
15549      // This is the time between the start of the request and the start of the response in milliseconds.
15550      _measurements['ttfb.requestTime'] = {
15551        value: (responseStartTimestamp - requestStartTimestamp) * 1000,
15552        unit: 'millisecond',
15553      };
15554    }
15555  }
15556}
15557
15558/** Taken from @sentry/core sampling.ts */
15559function getSampleRate(transactionContext, options) {
15560  if (!core.hasTracingEnabled(options)) {
15561    return false;
15562  }
15563  let sampleRate;
15564  if (transactionContext !== undefined && typeof options.tracesSampler === 'function') {
15565    sampleRate = options.tracesSampler({
15566      transactionContext,
15567      name: transactionContext.name,
15568      parentSampled: transactionContext.parentSampled,
15569      attributes: {
15570        // eslint-disable-next-line deprecation/deprecation
15571        ...transactionContext.data,
15572        ...transactionContext.attributes,
15573      },
15574      location: types.WINDOW.location,
15575    });
15576  } else if (transactionContext !== undefined && transactionContext.sampled !== undefined) {
15577    sampleRate = transactionContext.sampled;
15578  } else if (typeof options.tracesSampleRate !== 'undefined') {
15579    sampleRate = options.tracesSampleRate;
15580  } else {
15581    sampleRate = 1;
15582  }
15583  if (!core.isValidSampleRate(sampleRate)) {
15584    debugBuild.DEBUG_BUILD && utils.logger.warn('[Tracing] Discarding transaction because of invalid sample rate.');
15585    return false;
15586  }
15587  return sampleRate;
15588}
15589
15590exports._addMeasureSpans = _addMeasureSpans;
15591exports._addResourceSpans = _addResourceSpans;
15592exports._addTtfbToMeasurements = _addTtfbToMeasurements;
15593exports.addPerformanceEntries = addPerformanceEntries;
15594exports.startTrackingINP = startTrackingINP;
15595exports.startTrackingInteractions = startTrackingInteractions;
15596exports.startTrackingLongTasks = startTrackingLongTasks;
15597exports.startTrackingWebVitals = startTrackingWebVitals;
15598
15599
15600},{"../../common/debug-build.js":206,"../instrument.js":187,"../types.js":192,"../web-vitals/lib/getVisibilityWatcher.js":201,"./utils.js":189,"@sentry/core":250,"@sentry/utils":319}],189:[function(require,module,exports){
15601Object.defineProperty(exports, '__esModule', { value: true });
15602
15603/**
15604 * Checks if a given value is a valid measurement value.
15605 */
15606function isMeasurementValue(value) {
15607  return typeof value === 'number' && isFinite(value);
15608}
15609
15610/**
15611 * Helper function to start child on transactions. This function will make sure that the transaction will
15612 * use the start timestamp of the created child span if it is earlier than the transactions actual
15613 * start timestamp.
15614 *
15615 * Note: this will not be possible anymore in v8,
15616 * unless we do some special handling for browser here...
15617 */
15618function _startChild(transaction, { startTimestamp, ...ctx }) {
15619  // eslint-disable-next-line deprecation/deprecation
15620  if (startTimestamp && transaction.startTimestamp > startTimestamp) {
15621    // eslint-disable-next-line deprecation/deprecation
15622    transaction.startTimestamp = startTimestamp;
15623  }
15624
15625  // eslint-disable-next-line deprecation/deprecation
15626  return transaction.startChild({
15627    startTimestamp,
15628    ...ctx,
15629  });
15630}
15631
15632exports._startChild = _startChild;
15633exports.isMeasurementValue = isMeasurementValue;
15634
15635
15636},{}],190:[function(require,module,exports){
15637Object.defineProperty(exports, '__esModule', { value: true });
15638
15639const core = require('@sentry/core');
15640const utils = require('@sentry/utils');
15641const fetch = require('../common/fetch.js');
15642const instrument = require('./instrument.js');
15643
15644/* eslint-disable max-lines */
15645
15646const DEFAULT_TRACE_PROPAGATION_TARGETS = ['localhost', /^\/(?!\/)/];
15647
15648/** Options for Request Instrumentation */
15649
15650const defaultRequestInstrumentationOptions = {
15651  traceFetch: true,
15652  traceXHR: true,
15653  enableHTTPTimings: true,
15654  // TODO (v8): Remove this property
15655  tracingOrigins: DEFAULT_TRACE_PROPAGATION_TARGETS,
15656  tracePropagationTargets: DEFAULT_TRACE_PROPAGATION_TARGETS,
15657};
15658
15659/** Registers span creators for xhr and fetch requests  */
15660function instrumentOutgoingRequests(_options) {
15661  const {
15662    traceFetch,
15663    traceXHR,
15664    // eslint-disable-next-line deprecation/deprecation
15665    tracePropagationTargets,
15666    // eslint-disable-next-line deprecation/deprecation
15667    tracingOrigins,
15668    shouldCreateSpanForRequest,
15669    enableHTTPTimings,
15670  } = {
15671    traceFetch: defaultRequestInstrumentationOptions.traceFetch,
15672    traceXHR: defaultRequestInstrumentationOptions.traceXHR,
15673    ..._options,
15674  };
15675
15676  const shouldCreateSpan =
15677    typeof shouldCreateSpanForRequest === 'function' ? shouldCreateSpanForRequest : (_) => true;
15678
15679  // TODO(v8) Remove tracingOrigins here
15680  // The only reason we're passing it in here is because this instrumentOutgoingRequests function is publicly exported
15681  // and we don't want to break the API. We can remove it in v8.
15682  const shouldAttachHeadersWithTargets = (url) =>
15683    shouldAttachHeaders(url, tracePropagationTargets || tracingOrigins);
15684
15685  const spans = {};
15686
15687  if (traceFetch) {
15688    utils.addFetchInstrumentationHandler(handlerData => {
15689      const createdSpan = fetch.instrumentFetchRequest(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans);
15690      if (enableHTTPTimings && createdSpan) {
15691        addHTTPTimings(createdSpan);
15692      }
15693    });
15694  }
15695
15696  if (traceXHR) {
15697    utils.addXhrInstrumentationHandler(handlerData => {
15698      const createdSpan = xhrCallback(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans);
15699      if (enableHTTPTimings && createdSpan) {
15700        addHTTPTimings(createdSpan);
15701      }
15702    });
15703  }
15704}
15705
15706function isPerformanceResourceTiming(entry) {
15707  return (
15708    entry.entryType === 'resource' &&
15709    'initiatorType' in entry &&
15710    typeof (entry ).nextHopProtocol === 'string' &&
15711    (entry.initiatorType === 'fetch' || entry.initiatorType === 'xmlhttprequest')
15712  );
15713}
15714
15715/**
15716 * Creates a temporary observer to listen to the next fetch/xhr resourcing timings,
15717 * so that when timings hit their per-browser limit they don't need to be removed.
15718 *
15719 * @param span A span that has yet to be finished, must contain `url` on data.
15720 */
15721function addHTTPTimings(span) {
15722  const { url } = core.spanToJSON(span).data || {};
15723
15724  if (!url || typeof url !== 'string') {
15725    return;
15726  }
15727
15728  const cleanup = instrument.addPerformanceInstrumentationHandler('resource', ({ entries }) => {
15729    entries.forEach(entry => {
15730      if (isPerformanceResourceTiming(entry) && entry.name.endsWith(url)) {
15731        const spanData = resourceTimingEntryToSpanData(entry);
15732        spanData.forEach(data => span.setAttribute(...data));
15733        // In the next tick, clean this handler up
15734        // We have to wait here because otherwise this cleans itself up before it is fully done
15735        setTimeout(cleanup);
15736      }
15737    });
15738  });
15739}
15740
15741/**
15742 * Converts ALPN protocol ids to name and version.
15743 *
15744 * (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)
15745 * @param nextHopProtocol PerformanceResourceTiming.nextHopProtocol
15746 */
15747function extractNetworkProtocol(nextHopProtocol) {
15748  let name = 'unknown';
15749  let version = 'unknown';
15750  let _name = '';
15751  for (const char of nextHopProtocol) {
15752    // http/1.1 etc.
15753    if (char === '/') {
15754      [name, version] = nextHopProtocol.split('/');
15755      break;
15756    }
15757    // h2, h3 etc.
15758    if (!isNaN(Number(char))) {
15759      name = _name === 'h' ? 'http' : _name;
15760      version = nextHopProtocol.split(_name)[1];
15761      break;
15762    }
15763    _name += char;
15764  }
15765  if (_name === nextHopProtocol) {
15766    // webrtc, ftp, etc.
15767    name = _name;
15768  }
15769  return { name, version };
15770}
15771
15772function getAbsoluteTime(time = 0) {
15773  return ((utils.browserPerformanceTimeOrigin || performance.timeOrigin) + time) / 1000;
15774}
15775
15776function resourceTimingEntryToSpanData(resourceTiming) {
15777  const { name, version } = extractNetworkProtocol(resourceTiming.nextHopProtocol);
15778
15779  const timingSpanData = [];
15780
15781  timingSpanData.push(['network.protocol.version', version], ['network.protocol.name', name]);
15782
15783  if (!utils.browserPerformanceTimeOrigin) {
15784    return timingSpanData;
15785  }
15786  return [
15787    ...timingSpanData,
15788    ['http.request.redirect_start', getAbsoluteTime(resourceTiming.redirectStart)],
15789    ['http.request.fetch_start', getAbsoluteTime(resourceTiming.fetchStart)],
15790    ['http.request.domain_lookup_start', getAbsoluteTime(resourceTiming.domainLookupStart)],
15791    ['http.request.domain_lookup_end', getAbsoluteTime(resourceTiming.domainLookupEnd)],
15792    ['http.request.connect_start', getAbsoluteTime(resourceTiming.connectStart)],
15793    ['http.request.secure_connection_start', getAbsoluteTime(resourceTiming.secureConnectionStart)],
15794    ['http.request.connection_end', getAbsoluteTime(resourceTiming.connectEnd)],
15795    ['http.request.request_start', getAbsoluteTime(resourceTiming.requestStart)],
15796    ['http.request.response_start', getAbsoluteTime(resourceTiming.responseStart)],
15797    ['http.request.response_end', getAbsoluteTime(resourceTiming.responseEnd)],
15798  ];
15799}
15800
15801/**
15802 * A function that determines whether to attach tracing headers to a request.
15803 * This was extracted from `instrumentOutgoingRequests` to make it easier to test shouldAttachHeaders.
15804 * We only export this fuction for testing purposes.
15805 */
15806function shouldAttachHeaders(url, tracePropagationTargets) {
15807  return utils.stringMatchesSomePattern(url, tracePropagationTargets || DEFAULT_TRACE_PROPAGATION_TARGETS);
15808}
15809
15810/**
15811 * Create and track xhr request spans
15812 *
15813 * @returns Span if a span was created, otherwise void.
15814 */
15815// eslint-disable-next-line complexity
15816function xhrCallback(
15817  handlerData,
15818  shouldCreateSpan,
15819  shouldAttachHeaders,
15820  spans,
15821) {
15822  const xhr = handlerData.xhr;
15823  const sentryXhrData = xhr && xhr[utils.SENTRY_XHR_DATA_KEY];
15824
15825  if (!core.hasTracingEnabled() || !xhr || xhr.__sentry_own_request__ || !sentryXhrData) {
15826    return undefined;
15827  }
15828
15829  const shouldCreateSpanResult = shouldCreateSpan(sentryXhrData.url);
15830
15831  // check first if the request has finished and is tracked by an existing span which should now end
15832  if (handlerData.endTimestamp && shouldCreateSpanResult) {
15833    const spanId = xhr.__sentry_xhr_span_id__;
15834    if (!spanId) return;
15835
15836    const span = spans[spanId];
15837    if (span && sentryXhrData.status_code !== undefined) {
15838      core.setHttpStatus(span, sentryXhrData.status_code);
15839      span.end();
15840
15841      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
15842      delete spans[spanId];
15843    }
15844    return undefined;
15845  }
15846
15847  const scope = core.getCurrentScope();
15848  const isolationScope = core.getIsolationScope();
15849
15850  const span = shouldCreateSpanResult
15851    ? core.startInactiveSpan({
15852        name: `${sentryXhrData.method} ${sentryXhrData.url}`,
15853        onlyIfParent: true,
15854        attributes: {
15855          type: 'xhr',
15856          'http.method': sentryXhrData.method,
15857          url: sentryXhrData.url,
15858          [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser',
15859        },
15860        op: 'http.client',
15861      })
15862    : undefined;
15863
15864  if (span) {
15865    xhr.__sentry_xhr_span_id__ = span.spanContext().spanId;
15866    spans[xhr.__sentry_xhr_span_id__] = span;
15867  }
15868
15869  const client = core.getClient();
15870
15871  if (xhr.setRequestHeader && shouldAttachHeaders(sentryXhrData.url) && client) {
15872    const { traceId, spanId, sampled, dsc } = {
15873      ...isolationScope.getPropagationContext(),
15874      ...scope.getPropagationContext(),
15875    };
15876
15877    const sentryTraceHeader = span ? core.spanToTraceHeader(span) : utils.generateSentryTraceHeader(traceId, spanId, sampled);
15878
15879    const sentryBaggageHeader = utils.dynamicSamplingContextToSentryBaggageHeader(
15880      dsc ||
15881        (span ? core.getDynamicSamplingContextFromSpan(span) : core.getDynamicSamplingContextFromClient(traceId, client, scope)),
15882    );
15883
15884    setHeaderOnXhr(xhr, sentryTraceHeader, sentryBaggageHeader);
15885  }
15886
15887  return span;
15888}
15889
15890function setHeaderOnXhr(
15891  xhr,
15892  sentryTraceHeader,
15893  sentryBaggageHeader,
15894) {
15895  try {
15896    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
15897    xhr.setRequestHeader('sentry-trace', sentryTraceHeader);
15898    if (sentryBaggageHeader) {
15899      // From MDN: "If this method is called several times with the same header, the values are merged into one single request header."
15900      // We can therefore simply set a baggage header without checking what was there before
15901      // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader
15902      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
15903      xhr.setRequestHeader(utils.BAGGAGE_HEADER_NAME, sentryBaggageHeader);
15904    }
15905  } catch (_) {
15906    // Error: InvalidStateError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.
15907  }
15908}
15909
15910exports.DEFAULT_TRACE_PROPAGATION_TARGETS = DEFAULT_TRACE_PROPAGATION_TARGETS;
15911exports.defaultRequestInstrumentationOptions = defaultRequestInstrumentationOptions;
15912exports.extractNetworkProtocol = extractNetworkProtocol;
15913exports.instrumentOutgoingRequests = instrumentOutgoingRequests;
15914exports.shouldAttachHeaders = shouldAttachHeaders;
15915exports.xhrCallback = xhrCallback;
15916
15917
15918},{"../common/fetch.js":207,"./instrument.js":187,"@sentry/core":250,"@sentry/utils":319}],191:[function(require,module,exports){
15919Object.defineProperty(exports, '__esModule', { value: true });
15920
15921const utils = require('@sentry/utils');
15922const debugBuild = require('../common/debug-build.js');
15923const types = require('./types.js');
15924
15925/**
15926 * Default function implementing pageload and navigation transactions
15927 */
15928function instrumentRoutingWithDefaults(
15929  customStartTransaction,
15930  startTransactionOnPageLoad = true,
15931  startTransactionOnLocationChange = true,
15932) {
15933  if (!types.WINDOW || !types.WINDOW.location) {
15934    debugBuild.DEBUG_BUILD && utils.logger.warn('Could not initialize routing instrumentation due to invalid location');
15935    return;
15936  }
15937
15938  let startingUrl = types.WINDOW.location.href;
15939
15940  let activeTransaction;
15941  if (startTransactionOnPageLoad) {
15942    activeTransaction = customStartTransaction({
15943      name: types.WINDOW.location.pathname,
15944      // pageload should always start at timeOrigin (and needs to be in s, not ms)
15945      startTimestamp: utils.browserPerformanceTimeOrigin ? utils.browserPerformanceTimeOrigin / 1000 : undefined,
15946      op: 'pageload',
15947      origin: 'auto.pageload.browser',
15948      metadata: { source: 'url' },
15949    });
15950  }
15951
15952  if (startTransactionOnLocationChange) {
15953    utils.addHistoryInstrumentationHandler(({ to, from }) => {
15954      /**
15955       * This early return is there to account for some cases where a navigation transaction starts right after
15956       * long-running pageload. We make sure that if `from` is undefined and a valid `startingURL` exists, we don't
15957       * create an uneccessary navigation transaction.
15958       *
15959       * This was hard to duplicate, but this behavior stopped as soon as this fix was applied. This issue might also
15960       * only be caused in certain development environments where the usage of a hot module reloader is causing
15961       * errors.
15962       */
15963      if (from === undefined && startingUrl && startingUrl.indexOf(to) !== -1) {
15964        startingUrl = undefined;
15965        return;
15966      }
15967
15968      if (from !== to) {
15969        startingUrl = undefined;
15970        if (activeTransaction) {
15971          debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Finishing current transaction with op: ${activeTransaction.op}`);
15972          // If there's an open transaction on the scope, we need to finish it before creating an new one.
15973          activeTransaction.end();
15974        }
15975        activeTransaction = customStartTransaction({
15976          name: types.WINDOW.location.pathname,
15977          op: 'navigation',
15978          origin: 'auto.navigation.browser',
15979          metadata: { source: 'url' },
15980        });
15981      }
15982    });
15983  }
15984}
15985
15986exports.instrumentRoutingWithDefaults = instrumentRoutingWithDefaults;
15987
15988
15989},{"../common/debug-build.js":206,"./types.js":192,"@sentry/utils":319}],192:[function(require,module,exports){
15990Object.defineProperty(exports, '__esModule', { value: true });
15991
15992const utils = require('@sentry/utils');
15993
15994const WINDOW = utils.GLOBAL_OBJ ;
15995
15996exports.WINDOW = WINDOW;
15997
15998
15999},{"@sentry/utils":319}],193:[function(require,module,exports){
16000Object.defineProperty(exports, '__esModule', { value: true });
16001
16002const bindReporter = require('./lib/bindReporter.js');
16003const initMetric = require('./lib/initMetric.js');
16004const observe = require('./lib/observe.js');
16005const onHidden = require('./lib/onHidden.js');
16006
16007/*
16008 * Copyright 2020 Google LLC
16009 *
16010 * Licensed under the Apache License, Version 2.0 (the "License");
16011 * you may not use this file except in compliance with the License.
16012 * You may obtain a copy of the License at
16013 *
16014 *     https://www.apache.org/licenses/LICENSE-2.0
16015 *
16016 * Unless required by applicable law or agreed to in writing, software
16017 * distributed under the License is distributed on an "AS IS" BASIS,
16018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16019 * See the License for the specific language governing permissions and
16020 * limitations under the License.
16021 */
16022
16023/**
16024 * Calculates the [CLS](https://web.dev/cls/) value for the current page and
16025 * calls the `callback` function once the value is ready to be reported, along
16026 * with all `layout-shift` performance entries that were used in the metric
16027 * value calculation. The reported value is a `double` (corresponding to a
16028 * [layout shift score](https://web.dev/cls/#layout-shift-score)).
16029 *
16030 * If the `reportAllChanges` configuration option is set to `true`, the
16031 * `callback` function will be called as soon as the value is initially
16032 * determined as well as any time the value changes throughout the page
16033 * lifespan.
16034 *
16035 * _**Important:** CLS should be continually monitored for changes throughout
16036 * the entire lifespan of a page—including if the user returns to the page after
16037 * it's been hidden/backgrounded. However, since browsers often [will not fire
16038 * additional callbacks once the user has backgrounded a
16039 * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
16040 * `callback` is always called when the page's visibility state changes to
16041 * hidden. As a result, the `callback` function might be called multiple times
16042 * during the same page load._
16043 */
16044const onCLS = (onReport) => {
16045  const metric = initMetric.initMetric('CLS', 0);
16046  let report;
16047
16048  let sessionValue = 0;
16049  let sessionEntries = [];
16050
16051  // const handleEntries = (entries: Metric['entries']) => {
16052  const handleEntries = (entries) => {
16053    entries.forEach(entry => {
16054      // Only count layout shifts without recent user input.
16055      if (!entry.hadRecentInput) {
16056        const firstSessionEntry = sessionEntries[0];
16057        const lastSessionEntry = sessionEntries[sessionEntries.length - 1];
16058
16059        // If the entry occurred less than 1 second after the previous entry and
16060        // less than 5 seconds after the first entry in the session, include the
16061        // entry in the current session. Otherwise, start a new session.
16062        if (
16063          sessionValue &&
16064          sessionEntries.length !== 0 &&
16065          entry.startTime - lastSessionEntry.startTime < 1000 &&
16066          entry.startTime - firstSessionEntry.startTime < 5000
16067        ) {
16068          sessionValue += entry.value;
16069          sessionEntries.push(entry);
16070        } else {
16071          sessionValue = entry.value;
16072          sessionEntries = [entry];
16073        }
16074
16075        // If the current session value is larger than the current CLS value,
16076        // update CLS and the entries contributing to it.
16077        if (sessionValue > metric.value) {
16078          metric.value = sessionValue;
16079          metric.entries = sessionEntries;
16080          if (report) {
16081            report();
16082          }
16083        }
16084      }
16085    });
16086  };
16087
16088  const po = observe.observe('layout-shift', handleEntries);
16089  if (po) {
16090    report = bindReporter.bindReporter(onReport, metric);
16091
16092    const stopListening = () => {
16093      handleEntries(po.takeRecords() );
16094      report(true);
16095    };
16096
16097    onHidden.onHidden(stopListening);
16098
16099    return stopListening;
16100  }
16101
16102  return;
16103};
16104
16105exports.onCLS = onCLS;
16106
16107
16108},{"./lib/bindReporter.js":197,"./lib/initMetric.js":202,"./lib/observe.js":203,"./lib/onHidden.js":204}],194:[function(require,module,exports){
16109Object.defineProperty(exports, '__esModule', { value: true });
16110
16111const bindReporter = require('./lib/bindReporter.js');
16112const getVisibilityWatcher = require('./lib/getVisibilityWatcher.js');
16113const initMetric = require('./lib/initMetric.js');
16114const observe = require('./lib/observe.js');
16115const onHidden = require('./lib/onHidden.js');
16116
16117/*
16118 * Copyright 2020 Google LLC
16119 *
16120 * Licensed under the Apache License, Version 2.0 (the "License");
16121 * you may not use this file except in compliance with the License.
16122 * You may obtain a copy of the License at
16123 *
16124 *     https://www.apache.org/licenses/LICENSE-2.0
16125 *
16126 * Unless required by applicable law or agreed to in writing, software
16127 * distributed under the License is distributed on an "AS IS" BASIS,
16128 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16129 * See the License for the specific language governing permissions and
16130 * limitations under the License.
16131 */
16132
16133/**
16134 * Calculates the [FID](https://web.dev/fid/) value for the current page and
16135 * calls the `callback` function once the value is ready, along with the
16136 * relevant `first-input` performance entry used to determine the value. The
16137 * reported value is a `DOMHighResTimeStamp`.
16138 *
16139 * _**Important:** since FID is only reported after the user interacts with the
16140 * page, it's possible that it will not be reported for some page loads._
16141 */
16142const onFID = (onReport) => {
16143  const visibilityWatcher = getVisibilityWatcher.getVisibilityWatcher();
16144  const metric = initMetric.initMetric('FID');
16145  // eslint-disable-next-line prefer-const
16146  let report;
16147
16148  const handleEntry = (entry) => {
16149    // Only report if the page wasn't hidden prior to the first input.
16150    if (entry.startTime < visibilityWatcher.firstHiddenTime) {
16151      metric.value = entry.processingStart - entry.startTime;
16152      metric.entries.push(entry);
16153      report(true);
16154    }
16155  };
16156
16157  const handleEntries = (entries) => {
16158    (entries ).forEach(handleEntry);
16159  };
16160
16161  const po = observe.observe('first-input', handleEntries);
16162  report = bindReporter.bindReporter(onReport, metric);
16163
16164  if (po) {
16165    onHidden.onHidden(() => {
16166      handleEntries(po.takeRecords() );
16167      po.disconnect();
16168    }, true);
16169  }
16170};
16171
16172exports.onFID = onFID;
16173
16174
16175},{"./lib/bindReporter.js":197,"./lib/getVisibilityWatcher.js":201,"./lib/initMetric.js":202,"./lib/observe.js":203,"./lib/onHidden.js":204}],195:[function(require,module,exports){
16176Object.defineProperty(exports, '__esModule', { value: true });
16177
16178const bindReporter = require('./lib/bindReporter.js');
16179const initMetric = require('./lib/initMetric.js');
16180const observe = require('./lib/observe.js');
16181const onHidden = require('./lib/onHidden.js');
16182const interactionCountPolyfill = require('./lib/polyfills/interactionCountPolyfill.js');
16183
16184/*
16185 * Copyright 2022 Google LLC
16186 *
16187 * Licensed under the Apache License, Version 2.0 (the "License");
16188 * you may not use this file except in compliance with the License.
16189 * You may obtain a copy of the License at
16190 *
16191 *     https://www.apache.org/licenses/LICENSE-2.0
16192 *
16193 * Unless required by applicable law or agreed to in writing, software
16194 * distributed under the License is distributed on an "AS IS" BASIS,
16195 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16196 * See the License for the specific language governing permissions and
16197 * limitations under the License.
16198 */
16199
16200/**
16201 * Returns the interaction count since the last bfcache restore (or for the
16202 * full page lifecycle if there were no bfcache restores).
16203 */
16204const getInteractionCountForNavigation = () => {
16205  return interactionCountPolyfill.getInteractionCount();
16206};
16207
16208// To prevent unnecessary memory usage on pages with lots of interactions,
16209// store at most 10 of the longest interactions to consider as INP candidates.
16210const MAX_INTERACTIONS_TO_CONSIDER = 10;
16211
16212// A list of longest interactions on the page (by latency) sorted so the
16213// longest one is first. The list is as most MAX_INTERACTIONS_TO_CONSIDER long.
16214const longestInteractionList = [];
16215
16216// A mapping of longest interactions by their interaction ID.
16217// This is used for faster lookup.
16218const longestInteractionMap = {};
16219
16220/**
16221 * Takes a performance entry and adds it to the list of worst interactions
16222 * if its duration is long enough to make it among the worst. If the
16223 * entry is part of an existing interaction, it is merged and the latency
16224 * and entries list is updated as needed.
16225 */
16226const processEntry = (entry) => {
16227  // The least-long of the 10 longest interactions.
16228  const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1];
16229
16230  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16231  const existingInteraction = longestInteractionMap[entry.interactionId];
16232
16233  // Only process the entry if it's possibly one of the ten longest,
16234  // or if it's part of an existing interaction.
16235  if (
16236    existingInteraction ||
16237    longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||
16238    entry.duration > minLongestInteraction.latency
16239  ) {
16240    // If the interaction already exists, update it. Otherwise create one.
16241    if (existingInteraction) {
16242      existingInteraction.entries.push(entry);
16243      existingInteraction.latency = Math.max(existingInteraction.latency, entry.duration);
16244    } else {
16245      const interaction = {
16246        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
16247        id: entry.interactionId,
16248        latency: entry.duration,
16249        entries: [entry],
16250      };
16251      longestInteractionMap[interaction.id] = interaction;
16252      longestInteractionList.push(interaction);
16253    }
16254
16255    // Sort the entries by latency (descending) and keep only the top ten.
16256    longestInteractionList.sort((a, b) => b.latency - a.latency);
16257    longestInteractionList.splice(MAX_INTERACTIONS_TO_CONSIDER).forEach(i => {
16258      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
16259      delete longestInteractionMap[i.id];
16260    });
16261  }
16262};
16263
16264/**
16265 * Returns the estimated p98 longest interaction based on the stored
16266 * interaction candidates and the interaction count for the current page.
16267 */
16268const estimateP98LongestInteraction = () => {
16269  const candidateInteractionIndex = Math.min(
16270    longestInteractionList.length - 1,
16271    Math.floor(getInteractionCountForNavigation() / 50),
16272  );
16273
16274  return longestInteractionList[candidateInteractionIndex];
16275};
16276
16277/**
16278 * Calculates the [INP](https://web.dev/responsiveness/) value for the current
16279 * page and calls the `callback` function once the value is ready, along with
16280 * the `event` performance entries reported for that interaction. The reported
16281 * value is a `DOMHighResTimeStamp`.
16282 *
16283 * A custom `durationThreshold` configuration option can optionally be passed to
16284 * control what `event-timing` entries are considered for INP reporting. The
16285 * default threshold is `40`, which means INP scores of less than 40 are
16286 * reported as 0. Note that this will not affect your 75th percentile INP value
16287 * unless that value is also less than 40 (well below the recommended
16288 * [good](https://web.dev/inp/#what-is-a-good-inp-score) threshold).
16289 *
16290 * If the `reportAllChanges` configuration option is set to `true`, the
16291 * `callback` function will be called as soon as the value is initially
16292 * determined as well as any time the value changes throughout the page
16293 * lifespan.
16294 *
16295 * _**Important:** INP should be continually monitored for changes throughout
16296 * the entire lifespan of a page—including if the user returns to the page after
16297 * it's been hidden/backgrounded. However, since browsers often [will not fire
16298 * additional callbacks once the user has backgrounded a
16299 * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
16300 * `callback` is always called when the page's visibility state changes to
16301 * hidden. As a result, the `callback` function might be called multiple times
16302 * during the same page load._
16303 */
16304const onINP = (onReport, opts) => {
16305  // Set defaults
16306  // eslint-disable-next-line no-param-reassign
16307  opts = opts || {};
16308
16309  // https://web.dev/inp/#what's-a-%22good%22-inp-value
16310  // const thresholds = [200, 500];
16311
16312  // TODO(philipwalton): remove once the polyfill is no longer needed.
16313  interactionCountPolyfill.initInteractionCountPolyfill();
16314
16315  const metric = initMetric.initMetric('INP');
16316  // eslint-disable-next-line prefer-const
16317  let report;
16318
16319  const handleEntries = (entries) => {
16320    entries.forEach(entry => {
16321      if (entry.interactionId) {
16322        processEntry(entry);
16323      }
16324
16325      // Entries of type `first-input` don't currently have an `interactionId`,
16326      // so to consider them in INP we have to first check that an existing
16327      // entry doesn't match the `duration` and `startTime`.
16328      // Note that this logic assumes that `event` entries are dispatched
16329      // before `first-input` entries. This is true in Chrome but it is not
16330      // true in Firefox; however, Firefox doesn't support interactionId, so
16331      // it's not an issue at the moment.
16332      // TODO(philipwalton): remove once crbug.com/1325826 is fixed.
16333      if (entry.entryType === 'first-input') {
16334        const noMatchingEntry = !longestInteractionList.some(interaction => {
16335          return interaction.entries.some(prevEntry => {
16336            return entry.duration === prevEntry.duration && entry.startTime === prevEntry.startTime;
16337          });
16338        });
16339        if (noMatchingEntry) {
16340          processEntry(entry);
16341        }
16342      }
16343    });
16344
16345    const inp = estimateP98LongestInteraction();
16346
16347    if (inp && inp.latency !== metric.value) {
16348      metric.value = inp.latency;
16349      metric.entries = inp.entries;
16350      report();
16351    }
16352  };
16353
16354  const po = observe.observe('event', handleEntries, {
16355    // Event Timing entries have their durations rounded to the nearest 8ms,
16356    // so a duration of 40ms would be any event that spans 2.5 or more frames
16357    // at 60Hz. This threshold is chosen to strike a balance between usefulness
16358    // and performance. Running this callback for any interaction that spans
16359    // just one or two frames is likely not worth the insight that could be
16360    // gained.
16361    durationThreshold: opts.durationThreshold || 40,
16362  } );
16363
16364  report = bindReporter.bindReporter(onReport, metric, opts.reportAllChanges);
16365
16366  if (po) {
16367    // Also observe entries of type `first-input`. This is useful in cases
16368    // where the first interaction is less than the `durationThreshold`.
16369    po.observe({ type: 'first-input', buffered: true });
16370
16371    onHidden.onHidden(() => {
16372      handleEntries(po.takeRecords() );
16373
16374      // If the interaction count shows that there were interactions but
16375      // none were captured by the PerformanceObserver, report a latency of 0.
16376      if (metric.value < 0 && getInteractionCountForNavigation() > 0) {
16377        metric.value = 0;
16378        metric.entries = [];
16379      }
16380
16381      report(true);
16382    });
16383  }
16384};
16385
16386exports.onINP = onINP;
16387
16388
16389},{"./lib/bindReporter.js":197,"./lib/initMetric.js":202,"./lib/observe.js":203,"./lib/onHidden.js":204,"./lib/polyfills/interactionCountPolyfill.js":205}],196:[function(require,module,exports){
16390Object.defineProperty(exports, '__esModule', { value: true });
16391
16392const bindReporter = require('./lib/bindReporter.js');
16393const getActivationStart = require('./lib/getActivationStart.js');
16394const getVisibilityWatcher = require('./lib/getVisibilityWatcher.js');
16395const initMetric = require('./lib/initMetric.js');
16396const observe = require('./lib/observe.js');
16397const onHidden = require('./lib/onHidden.js');
16398
16399/*
16400 * Copyright 2020 Google LLC
16401 *
16402 * Licensed under the Apache License, Version 2.0 (the "License");
16403 * you may not use this file except in compliance with the License.
16404 * You may obtain a copy of the License at
16405 *
16406 *     https://www.apache.org/licenses/LICENSE-2.0
16407 *
16408 * Unless required by applicable law or agreed to in writing, software
16409 * distributed under the License is distributed on an "AS IS" BASIS,
16410 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16411 * See the License for the specific language governing permissions and
16412 * limitations under the License.
16413 */
16414
16415const reportedMetricIDs = {};
16416
16417/**
16418 * Calculates the [LCP](https://web.dev/lcp/) value for the current page and
16419 * calls the `callback` function once the value is ready (along with the
16420 * relevant `largest-contentful-paint` performance entry used to determine the
16421 * value). The reported value is a `DOMHighResTimeStamp`.
16422 */
16423const onLCP = (onReport) => {
16424  const visibilityWatcher = getVisibilityWatcher.getVisibilityWatcher();
16425  const metric = initMetric.initMetric('LCP');
16426  let report;
16427
16428  const handleEntries = (entries) => {
16429    const lastEntry = entries[entries.length - 1] ;
16430    if (lastEntry) {
16431      // The startTime attribute returns the value of the renderTime if it is
16432      // not 0, and the value of the loadTime otherwise. The activationStart
16433      // reference is used because LCP should be relative to page activation
16434      // rather than navigation start if the page was prerendered.
16435      const value = Math.max(lastEntry.startTime - getActivationStart.getActivationStart(), 0);
16436
16437      // Only report if the page wasn't hidden prior to LCP.
16438      if (value < visibilityWatcher.firstHiddenTime) {
16439        metric.value = value;
16440        metric.entries = [lastEntry];
16441        report();
16442      }
16443    }
16444  };
16445
16446  const po = observe.observe('largest-contentful-paint', handleEntries);
16447
16448  if (po) {
16449    report = bindReporter.bindReporter(onReport, metric);
16450
16451    const stopListening = () => {
16452      if (!reportedMetricIDs[metric.id]) {
16453        handleEntries(po.takeRecords() );
16454        po.disconnect();
16455        reportedMetricIDs[metric.id] = true;
16456        report(true);
16457      }
16458    };
16459
16460    // Stop listening after input. Note: while scrolling is an input that
16461    // stop LCP observation, it's unreliable since it can be programmatically
16462    // generated. See: https://github.com/GoogleChrome/web-vitals/issues/75
16463    ['keydown', 'click'].forEach(type => {
16464      addEventListener(type, stopListening, { once: true, capture: true });
16465    });
16466
16467    onHidden.onHidden(stopListening, true);
16468
16469    return stopListening;
16470  }
16471
16472  return;
16473};
16474
16475exports.onLCP = onLCP;
16476
16477
16478},{"./lib/bindReporter.js":197,"./lib/getActivationStart.js":199,"./lib/getVisibilityWatcher.js":201,"./lib/initMetric.js":202,"./lib/observe.js":203,"./lib/onHidden.js":204}],197:[function(require,module,exports){
16479Object.defineProperty(exports, '__esModule', { value: true });
16480
16481const bindReporter = (
16482  callback,
16483  metric,
16484  reportAllChanges,
16485) => {
16486  let prevValue;
16487  let delta;
16488  return (forceReport) => {
16489    if (metric.value >= 0) {
16490      if (forceReport || reportAllChanges) {
16491        delta = metric.value - (prevValue || 0);
16492
16493        // Report the metric if there's a non-zero delta or if no previous
16494        // value exists (which can happen in the case of the document becoming
16495        // hidden when the metric value is 0).
16496        // See: https://github.com/GoogleChrome/web-vitals/issues/14
16497        if (delta || prevValue === undefined) {
16498          prevValue = metric.value;
16499          metric.delta = delta;
16500          callback(metric);
16501        }
16502      }
16503    }
16504  };
16505};
16506
16507exports.bindReporter = bindReporter;
16508
16509
16510},{}],198:[function(require,module,exports){
16511Object.defineProperty(exports, '__esModule', { value: true });
16512
16513/*
16514 * Copyright 2020 Google LLC
16515 *
16516 * Licensed under the Apache License, Version 2.0 (the "License");
16517 * you may not use this file except in compliance with the License.
16518 * You may obtain a copy of the License at
16519 *
16520 *     https://www.apache.org/licenses/LICENSE-2.0
16521 *
16522 * Unless required by applicable law or agreed to in writing, software
16523 * distributed under the License is distributed on an "AS IS" BASIS,
16524 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16525 * See the License for the specific language governing permissions and
16526 * limitations under the License.
16527 */
16528
16529/**
16530 * Performantly generate a unique, 30-char string by combining a version
16531 * number, the current timestamp with a 13-digit number integer.
16532 * @return {string}
16533 */
16534const generateUniqueID = () => {
16535  return `v3-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`;
16536};
16537
16538exports.generateUniqueID = generateUniqueID;
16539
16540
16541},{}],199:[function(require,module,exports){
16542Object.defineProperty(exports, '__esModule', { value: true });
16543
16544const getNavigationEntry = require('./getNavigationEntry.js');
16545
16546/*
16547 * Copyright 2022 Google LLC
16548 *
16549 * Licensed under the Apache License, Version 2.0 (the "License");
16550 * you may not use this file except in compliance with the License.
16551 * You may obtain a copy of the License at
16552 *
16553 *     https://www.apache.org/licenses/LICENSE-2.0
16554 *
16555 * Unless required by applicable law or agreed to in writing, software
16556 * distributed under the License is distributed on an "AS IS" BASIS,
16557 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16558 * See the License for the specific language governing permissions and
16559 * limitations under the License.
16560 */
16561
16562const getActivationStart = () => {
16563  const navEntry = getNavigationEntry.getNavigationEntry();
16564  return (navEntry && navEntry.activationStart) || 0;
16565};
16566
16567exports.getActivationStart = getActivationStart;
16568
16569
16570},{"./getNavigationEntry.js":200}],200:[function(require,module,exports){
16571Object.defineProperty(exports, '__esModule', { value: true });
16572
16573const types = require('../../types.js');
16574
16575/*
16576 * Copyright 2022 Google LLC
16577 *
16578 * Licensed under the Apache License, Version 2.0 (the "License");
16579 * you may not use this file except in compliance with the License.
16580 * You may obtain a copy of the License at
16581 *
16582 *     https://www.apache.org/licenses/LICENSE-2.0
16583 *
16584 * Unless required by applicable law or agreed to in writing, software
16585 * distributed under the License is distributed on an "AS IS" BASIS,
16586 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16587 * See the License for the specific language governing permissions and
16588 * limitations under the License.
16589 */
16590
16591const getNavigationEntryFromPerformanceTiming = () => {
16592  // eslint-disable-next-line deprecation/deprecation
16593  const timing = types.WINDOW.performance.timing;
16594  // eslint-disable-next-line deprecation/deprecation
16595  const type = types.WINDOW.performance.navigation.type;
16596
16597  const navigationEntry = {
16598    entryType: 'navigation',
16599    startTime: 0,
16600    type: type == 2 ? 'back_forward' : type === 1 ? 'reload' : 'navigate',
16601  };
16602
16603  for (const key in timing) {
16604    if (key !== 'navigationStart' && key !== 'toJSON') {
16605      // eslint-disable-next-line deprecation/deprecation
16606      navigationEntry[key] = Math.max((timing[key ] ) - timing.navigationStart, 0);
16607    }
16608  }
16609  return navigationEntry ;
16610};
16611
16612const getNavigationEntry = () => {
16613  if (types.WINDOW.__WEB_VITALS_POLYFILL__) {
16614    return (
16615      types.WINDOW.performance &&
16616      ((performance.getEntriesByType && performance.getEntriesByType('navigation')[0]) ||
16617        getNavigationEntryFromPerformanceTiming())
16618    );
16619  } else {
16620    return types.WINDOW.performance && performance.getEntriesByType && performance.getEntriesByType('navigation')[0];
16621  }
16622};
16623
16624exports.getNavigationEntry = getNavigationEntry;
16625
16626
16627},{"../../types.js":192}],201:[function(require,module,exports){
16628Object.defineProperty(exports, '__esModule', { value: true });
16629
16630const types = require('../../types.js');
16631const onHidden = require('./onHidden.js');
16632
16633/*
16634 * Copyright 2020 Google LLC
16635 *
16636 * Licensed under the Apache License, Version 2.0 (the "License");
16637 * you may not use this file except in compliance with the License.
16638 * You may obtain a copy of the License at
16639 *
16640 *     https://www.apache.org/licenses/LICENSE-2.0
16641 *
16642 * Unless required by applicable law or agreed to in writing, software
16643 * distributed under the License is distributed on an "AS IS" BASIS,
16644 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16645 * See the License for the specific language governing permissions and
16646 * limitations under the License.
16647 */
16648
16649let firstHiddenTime = -1;
16650
16651const initHiddenTime = () => {
16652  // If the document is hidden and not prerendering, assume it was always
16653  // hidden and the page was loaded in the background.
16654  return types.WINDOW.document.visibilityState === 'hidden' && !types.WINDOW.document.prerendering ? 0 : Infinity;
16655};
16656
16657const trackChanges = () => {
16658  // Update the time if/when the document becomes hidden.
16659  onHidden.onHidden(({ timeStamp }) => {
16660    firstHiddenTime = timeStamp;
16661  }, true);
16662};
16663
16664const getVisibilityWatcher = (
16665
16666) => {
16667  if (firstHiddenTime < 0) {
16668    // If the document is hidden when this code runs, assume it was hidden
16669    // since navigation start. This isn't a perfect heuristic, but it's the
16670    // best we can do until an API is available to support querying past
16671    // visibilityState.
16672    firstHiddenTime = initHiddenTime();
16673    trackChanges();
16674  }
16675  return {
16676    get firstHiddenTime() {
16677      return firstHiddenTime;
16678    },
16679  };
16680};
16681
16682exports.getVisibilityWatcher = getVisibilityWatcher;
16683
16684
16685},{"../../types.js":192,"./onHidden.js":204}],202:[function(require,module,exports){
16686Object.defineProperty(exports, '__esModule', { value: true });
16687
16688const types = require('../../types.js');
16689const generateUniqueID = require('./generateUniqueID.js');
16690const getActivationStart = require('./getActivationStart.js');
16691const getNavigationEntry = require('./getNavigationEntry.js');
16692
16693/*
16694 * Copyright 2020 Google LLC
16695 *
16696 * Licensed under the Apache License, Version 2.0 (the "License");
16697 * you may not use this file except in compliance with the License.
16698 * You may obtain a copy of the License at
16699 *
16700 *     https://www.apache.org/licenses/LICENSE-2.0
16701 *
16702 * Unless required by applicable law or agreed to in writing, software
16703 * distributed under the License is distributed on an "AS IS" BASIS,
16704 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16705 * See the License for the specific language governing permissions and
16706 * limitations under the License.
16707 */
16708
16709const initMetric = (name, value) => {
16710  const navEntry = getNavigationEntry.getNavigationEntry();
16711  let navigationType = 'navigate';
16712
16713  if (navEntry) {
16714    if (types.WINDOW.document.prerendering || getActivationStart.getActivationStart() > 0) {
16715      navigationType = 'prerender';
16716    } else {
16717      navigationType = navEntry.type.replace(/_/g, '-') ;
16718    }
16719  }
16720
16721  return {
16722    name,
16723    value: typeof value === 'undefined' ? -1 : value,
16724    rating: 'good', // Will be updated if the value changes.
16725    delta: 0,
16726    entries: [],
16727    id: generateUniqueID.generateUniqueID(),
16728    navigationType,
16729  };
16730};
16731
16732exports.initMetric = initMetric;
16733
16734
16735},{"../../types.js":192,"./generateUniqueID.js":198,"./getActivationStart.js":199,"./getNavigationEntry.js":200}],203:[function(require,module,exports){
16736Object.defineProperty(exports, '__esModule', { value: true });
16737
16738/**
16739 * Takes a performance entry type and a callback function, and creates a
16740 * `PerformanceObserver` instance that will observe the specified entry type
16741 * with buffering enabled and call the callback _for each entry_.
16742 *
16743 * This function also feature-detects entry support and wraps the logic in a
16744 * try/catch to avoid errors in unsupporting browsers.
16745 */
16746const observe = (
16747  type,
16748  callback,
16749  opts,
16750) => {
16751  try {
16752    if (PerformanceObserver.supportedEntryTypes.includes(type)) {
16753      const po = new PerformanceObserver(list => {
16754        callback(list.getEntries() );
16755      });
16756      po.observe(
16757        Object.assign(
16758          {
16759            type,
16760            buffered: true,
16761          },
16762          opts || {},
16763        ) ,
16764      );
16765      return po;
16766    }
16767  } catch (e) {
16768    // Do nothing.
16769  }
16770  return;
16771};
16772
16773exports.observe = observe;
16774
16775
16776},{}],204:[function(require,module,exports){
16777Object.defineProperty(exports, '__esModule', { value: true });
16778
16779const types = require('../../types.js');
16780
16781/*
16782 * Copyright 2020 Google LLC
16783 *
16784 * Licensed under the Apache License, Version 2.0 (the "License");
16785 * you may not use this file except in compliance with the License.
16786 * You may obtain a copy of the License at
16787 *
16788 *     https://www.apache.org/licenses/LICENSE-2.0
16789 *
16790 * Unless required by applicable law or agreed to in writing, software
16791 * distributed under the License is distributed on an "AS IS" BASIS,
16792 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16793 * See the License for the specific language governing permissions and
16794 * limitations under the License.
16795 */
16796
16797const onHidden = (cb, once) => {
16798  const onHiddenOrPageHide = (event) => {
16799    if (event.type === 'pagehide' || types.WINDOW.document.visibilityState === 'hidden') {
16800      cb(event);
16801      if (once) {
16802        removeEventListener('visibilitychange', onHiddenOrPageHide, true);
16803        removeEventListener('pagehide', onHiddenOrPageHide, true);
16804      }
16805    }
16806  };
16807  addEventListener('visibilitychange', onHiddenOrPageHide, true);
16808  // Some browsers have buggy implementations of visibilitychange,
16809  // so we use pagehide in addition, just to be safe.
16810  addEventListener('pagehide', onHiddenOrPageHide, true);
16811};
16812
16813exports.onHidden = onHidden;
16814
16815
16816},{"../../types.js":192}],205:[function(require,module,exports){
16817Object.defineProperty(exports, '__esModule', { value: true });
16818
16819const observe = require('../observe.js');
16820
16821let interactionCountEstimate = 0;
16822let minKnownInteractionId = Infinity;
16823let maxKnownInteractionId = 0;
16824
16825const updateEstimate = (entries) => {
16826  (entries ).forEach(e => {
16827    if (e.interactionId) {
16828      minKnownInteractionId = Math.min(minKnownInteractionId, e.interactionId);
16829      maxKnownInteractionId = Math.max(maxKnownInteractionId, e.interactionId);
16830
16831      interactionCountEstimate = maxKnownInteractionId ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1 : 0;
16832    }
16833  });
16834};
16835
16836let po;
16837
16838/**
16839 * Returns the `interactionCount` value using the native API (if available)
16840 * or the polyfill estimate in this module.
16841 */
16842const getInteractionCount = () => {
16843  return po ? interactionCountEstimate : performance.interactionCount || 0;
16844};
16845
16846/**
16847 * Feature detects native support or initializes the polyfill if needed.
16848 */
16849const initInteractionCountPolyfill = () => {
16850  if ('interactionCount' in performance || po) return;
16851
16852  po = observe.observe('event', updateEstimate, {
16853    type: 'event',
16854    buffered: true,
16855    durationThreshold: 0,
16856  } );
16857};
16858
16859exports.getInteractionCount = getInteractionCount;
16860exports.initInteractionCountPolyfill = initInteractionCountPolyfill;
16861
16862
16863},{"../observe.js":203}],206:[function(require,module,exports){
16864Object.defineProperty(exports, '__esModule', { value: true });
16865
16866/**
16867 * 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.
16868 *
16869 * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
16870 */
16871const DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);
16872
16873exports.DEBUG_BUILD = DEBUG_BUILD;
16874
16875
16876},{}],207:[function(require,module,exports){
16877Object.defineProperty(exports, '__esModule', { value: true });
16878
16879const core = require('@sentry/core');
16880const utils = require('@sentry/utils');
16881
16882/**
16883 * Create and track fetch request spans for usage in combination with `addInstrumentationHandler`.
16884 *
16885 * @returns Span if a span was created, otherwise void.
16886 */
16887function instrumentFetchRequest(
16888  handlerData,
16889  shouldCreateSpan,
16890  shouldAttachHeaders,
16891  spans,
16892  spanOrigin = 'auto.http.browser',
16893) {
16894  if (!core.hasTracingEnabled() || !handlerData.fetchData) {
16895    return undefined;
16896  }
16897
16898  const shouldCreateSpanResult = shouldCreateSpan(handlerData.fetchData.url);
16899
16900  if (handlerData.endTimestamp && shouldCreateSpanResult) {
16901    const spanId = handlerData.fetchData.__span;
16902    if (!spanId) return;
16903
16904    const span = spans[spanId];
16905    if (span) {
16906      if (handlerData.response) {
16907        core.setHttpStatus(span, handlerData.response.status);
16908
16909        const contentLength =
16910          handlerData.response && handlerData.response.headers && handlerData.response.headers.get('content-length');
16911
16912        if (contentLength) {
16913          const contentLengthNum = parseInt(contentLength);
16914          if (contentLengthNum > 0) {
16915            span.setAttribute('http.response_content_length', contentLengthNum);
16916          }
16917        }
16918      } else if (handlerData.error) {
16919        span.setStatus('internal_error');
16920      }
16921      span.end();
16922
16923      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
16924      delete spans[spanId];
16925    }
16926    return undefined;
16927  }
16928
16929  const scope = core.getCurrentScope();
16930  const client = core.getClient();
16931
16932  const { method, url } = handlerData.fetchData;
16933
16934  const span = shouldCreateSpanResult
16935    ? core.startInactiveSpan({
16936        name: `${method} ${url}`,
16937        onlyIfParent: true,
16938        attributes: {
16939          url,
16940          type: 'fetch',
16941          'http.method': method,
16942          [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanOrigin,
16943        },
16944        op: 'http.client',
16945      })
16946    : undefined;
16947
16948  if (span) {
16949    handlerData.fetchData.__span = span.spanContext().spanId;
16950    spans[span.spanContext().spanId] = span;
16951  }
16952
16953  if (shouldAttachHeaders(handlerData.fetchData.url) && client) {
16954    const request = handlerData.args[0];
16955
16956    // In case the user hasn't set the second argument of a fetch call we default it to `{}`.
16957    handlerData.args[1] = handlerData.args[1] || {};
16958
16959    // eslint-disable-next-line @typescript-eslint/no-explicit-any
16960    const options = handlerData.args[1];
16961
16962    // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
16963    options.headers = addTracingHeadersToFetchRequest(request, client, scope, options, span);
16964  }
16965
16966  return span;
16967}
16968
16969/**
16970 * Adds sentry-trace and baggage headers to the various forms of fetch headers
16971 */
16972function addTracingHeadersToFetchRequest(
16973  request, // unknown is actually type Request but we can't export DOM types from this package,
16974  client,
16975  scope,
16976  options
16977
16978,
16979  requestSpan,
16980) {
16981  // eslint-disable-next-line deprecation/deprecation
16982  const span = requestSpan || scope.getSpan();
16983
16984  const isolationScope = core.getIsolationScope();
16985
16986  const { traceId, spanId, sampled, dsc } = {
16987    ...isolationScope.getPropagationContext(),
16988    ...scope.getPropagationContext(),
16989  };
16990
16991  const sentryTraceHeader = span ? core.spanToTraceHeader(span) : utils.generateSentryTraceHeader(traceId, spanId, sampled);
16992
16993  const sentryBaggageHeader = utils.dynamicSamplingContextToSentryBaggageHeader(
16994    dsc ||
16995      (span ? core.getDynamicSamplingContextFromSpan(span) : core.getDynamicSamplingContextFromClient(traceId, client, scope)),
16996  );
16997
16998  const headers =
16999    options.headers ||
17000    (typeof Request !== 'undefined' && utils.isInstanceOf(request, Request) ? (request ).headers : undefined);
17001
17002  if (!headers) {
17003    return { 'sentry-trace': sentryTraceHeader, baggage: sentryBaggageHeader };
17004  } else if (typeof Headers !== 'undefined' && utils.isInstanceOf(headers, Headers)) {
17005    const newHeaders = new Headers(headers );
17006
17007    newHeaders.append('sentry-trace', sentryTraceHeader);
17008
17009    if (sentryBaggageHeader) {
17010      // If the same header is appended multiple times the browser will merge the values into a single request header.
17011      // Its therefore safe to simply push a "baggage" entry, even though there might already be another baggage header.
17012      newHeaders.append(utils.BAGGAGE_HEADER_NAME, sentryBaggageHeader);
17013    }
17014
17015    return newHeaders ;
17016  } else if (Array.isArray(headers)) {
17017    const newHeaders = [...headers, ['sentry-trace', sentryTraceHeader]];
17018
17019    if (sentryBaggageHeader) {
17020      // If there are multiple entries with the same key, the browser will merge the values into a single request header.
17021      // Its therefore safe to simply push a "baggage" entry, even though there might already be another baggage header.
17022      newHeaders.push([utils.BAGGAGE_HEADER_NAME, sentryBaggageHeader]);
17023    }
17024
17025    return newHeaders ;
17026  } else {
17027    const existingBaggageHeader = 'baggage' in headers ? headers.baggage : undefined;
17028    const newBaggageHeaders = [];
17029
17030    if (Array.isArray(existingBaggageHeader)) {
17031      newBaggageHeaders.push(...existingBaggageHeader);
17032    } else if (existingBaggageHeader) {
17033      newBaggageHeaders.push(existingBaggageHeader);
17034    }
17035
17036    if (sentryBaggageHeader) {
17037      newBaggageHeaders.push(sentryBaggageHeader);
17038    }
17039
17040    return {
17041      ...(headers ),
17042      'sentry-trace': sentryTraceHeader,
17043      baggage: newBaggageHeaders.length > 0 ? newBaggageHeaders.join(',') : undefined,
17044    };
17045  }
17046}
17047
17048exports.addTracingHeadersToFetchRequest = addTracingHeadersToFetchRequest;
17049exports.instrumentFetchRequest = instrumentFetchRequest;
17050
17051
17052},{"@sentry/core":250,"@sentry/utils":319}],208:[function(require,module,exports){
17053Object.defineProperty(exports, '__esModule', { value: true });
17054
17055const core = require('@sentry/core');
17056const utils = require('@sentry/utils');
17057
17058/**
17059 * @private
17060 */
17061function _autoloadDatabaseIntegrations() {
17062  const carrier = core.getMainCarrier();
17063  if (!carrier.__SENTRY__) {
17064    return;
17065  }
17066
17067  const packageToIntegrationMapping = {
17068    mongodb() {
17069      const integration = utils.dynamicRequire(module, './node/integrations/mongo')
17070
17071;
17072      return new integration.Mongo();
17073    },
17074    mongoose() {
17075      const integration = utils.dynamicRequire(module, './node/integrations/mongo')
17076
17077;
17078      return new integration.Mongo();
17079    },
17080    mysql() {
17081      const integration = utils.dynamicRequire(module, './node/integrations/mysql')
17082
17083;
17084      return new integration.Mysql();
17085    },
17086    pg() {
17087      const integration = utils.dynamicRequire(module, './node/integrations/postgres')
17088
17089;
17090      return new integration.Postgres();
17091    },
17092  };
17093
17094  const mappedPackages = Object.keys(packageToIntegrationMapping)
17095    .filter(moduleName =>
17095 !!utils.loadModule(moduleName))
17096    .map(pkg => {
17097      try {
17098        return packageToIntegrationMapping[pkg]();
17099      } catch (e) {
17100        return undefined;
17101      }
17102    })
17103    .filter(p => p) ;
17104
17105  if (mappedPackages.length > 0) {
17106    carrier.__SENTRY__.integrations = [...(carrier.__SENTRY__.integrations || []), ...mappedPackages];
17107  }
17108}
17109
17110/**
17111 * This patches the global object and injects the Tracing extensions methods
17112 */
17113function addExtensionMethods() {
17114  core.addTracingExtensions();
17115
17116  // Detect and automatically load specified integrations.
17117  if (utils.isNodeEnv()) {
17118    _autoloadDatabaseIntegrations();
17119  }
17120}
17121
17122exports.addExtensionMethods = addExtensionMethods;
17123
17124
17125},{"@sentry/core":250,"@sentry/utils":319}],209:[function(require,module,exports){
17126Object.defineProperty(exports, '__esModule', { value: true });
17127
17128const core = require('@sentry/core');
17129const utils = require('@sentry/utils');
17130const express = require('./node/integrations/express.js');
17131const postgres = require('./node/integrations/postgres.js');
17132const mysql = require('./node/integrations/mysql.js');
17133const mongo = require('./node/integrations/mongo.js');
17134const prisma = require('./node/integrations/prisma.js');
17135const graphql = require('./node/integrations/graphql.js');
17136const apollo = require('./node/integrations/apollo.js');
17137const lazy = require('./node/integrations/lazy.js');
17138const browsertracing = require('./browser/browsertracing.js');
17139const browserTracingIntegration = require('./browser/browserTracingIntegration.js');
17140const request = require('./browser/request.js');
17141const instrument = require('./browser/instrument.js');
17142const fetch = require('./common/fetch.js');
17143const extensions = require('./extensions.js');
17144
17145
17146
17147exports.IdleTransaction = core.IdleTransaction;
17148exports.Span = core.Span;
17149exports.SpanStatus = core.SpanStatus;
17150exports.Transaction = core.Transaction;
17151exports.extractTraceparentData = core.extractTraceparentData;
17152exports.getActiveTransaction = core.getActiveTransaction;
17153exports.hasTracingEnabled = core.hasTracingEnabled;
17154exports.spanStatusfromHttpCode = core.spanStatusfromHttpCode;
17155exports.startIdleTransaction = core.startIdleTransaction;
17156exports.TRACEPARENT_REGEXP = utils.TRACEPARENT_REGEXP;
17157exports.stripUrlQueryAndFragment = utils.stripUrlQueryAndFragment;
17158exports.Express = express.Express;
17159exports.Postgres = postgres.Postgres;
17160exports.Mysql = mysql.Mysql;
17161exports.Mongo = mongo.Mongo;
17162exports.Prisma = prisma.Prisma;
17163exports.GraphQL = graphql.GraphQL;
17164exports.Apollo = apollo.Apollo;
17165exports.lazyLoadedNodePerformanceMonitoringIntegrations = lazy.lazyLoadedNodePerformanceMonitoringIntegrations;
17166exports.BROWSER_TRACING_INTEGRATION_ID = browsertracing.BROWSER_TRACING_INTEGRATION_ID;
17167exports.BrowserTracing = browsertracing.BrowserTracing;
17168exports.browserTracingIntegration = browserTracingIntegration.browserTracingIntegration;
17169exports.startBrowserTracingNavigationSpan = browserTracingIntegration.startBrowserTracingNavigationSpan;
17170exports.startBrowserTracingPageLoadSpan = browserTracingIntegration.startBrowserTracingPageLoadSpan;
17171exports.defaultRequestInstrumentationOptions = request.defaultRequestInstrumentationOptions;
17172exports.instrumentOutgoingRequests = request.instrumentOutgoingRequests;
17173exports.addClsInstrumentationHandler = instrument.addClsInstrumentationHandler;
17174exports.addFidInstrumentationHandler = instrument.addFidInstrumentationHandler;
17175exports.addLcpInstrumentationHandler = instrument.addLcpInstrumentationHandler;
17176exports.addPerformanceInstrumentationHandler = instrument.addPerformanceInstrumentationHandler;
17177exports.addTracingHeadersToFetchRequest = fetch.addTracingHeadersToFetchRequest;
17178exports.instrumentFetchRequest = fetch.instrumentFetchRequest;
17179exports.addExtensionMethods = extensions.addExtensionMethods;
17180
17181
17182},{"./browser/browserTracingIntegration.js":185,"./browser/browsertracing.js":186,"./browser/instrument.js":187,"./browser/request.js":190,"./common/fetch.js":207,"./extensions.js":208,"./node/integrations/apollo.js":210,"./node/integrations/express.js":211,"./node/integrations/graphql.js":212,"./node/integrations/lazy.js":213,"./node/integrations/mongo.js":214,"./node/integrations/mysql.js":215,"./node/integrations/postgres.js":216,"./node/integrations/prisma.js":217,"@sentry/core":250,"@sentry/utils":319}],210:[function(require,module,exports){
17183var {
17184  _optionalChain
17185} = require('@sentry/utils');
17186
17187Object.defineProperty(exports, '__esModule', { value: true });
17188
17189const utils = require('@sentry/utils');
17190const debugBuild = require('../../common/debug-build.js');
17191const nodeUtils = require('./utils/node-utils.js');
17192
17193/** Tracing integration for Apollo */
17194class Apollo  {
17195  /**
17196   * @inheritDoc
17197   */
17198   static __initStatic() {this.id = 'Apollo';}
17199
17200  /**
17201   * @inheritDoc
17202   */
17203
17204  /**
17205   * @inheritDoc
17206   */
17207   constructor(
17208    options = {
17209      useNestjs: false,
17210    },
17211  ) {
17212    this.name = Apollo.id;
17213    this._useNest = !!options.useNestjs;
17214  }
17215
17216  /** @inheritdoc */
17217   loadDependency() {
17218    if (this._useNest) {
17219      this._module = this._module || utils.loadModule('@nestjs/graphql');
17220    } else {
17221      this._module = this._module || utils.loadModule('apollo-server-core');
17222    }
17223
17224    return this._module;
17225  }
17226
17227  /**
17228   * @inheritDoc
17229   */
17230   setupOnce(_, getCurrentHub) {
17231    if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) {
17232      debugBuild.DEBUG_BUILD && utils.logger.log('Apollo Integration is skipped because of instrumenter configuration.');
17233      return;
17234    }
17235
17236    if (this._useNest) {
17237      const pkg = this.loadDependency();
17238
17239      if (!pkg) {
17240        debugBuild.DEBUG_BUILD && utils.logger.error('Apollo-NestJS Integration was unable to require @nestjs/graphql package.');
17241        return;
17242      }
17243
17244      /**
17245       * Iterate over resolvers of NestJS ResolversExplorerService before schemas are constructed.
17246       */
17247      utils.fill(
17248        pkg.GraphQLFactory.prototype,
17249        'mergeWithSchema',
17250        function (orig) {
17251          return function (
17252
17253            ...args
17254          ) {
17255            utils.fill(this.resolversExplorerService, 'explore', function (orig) {
17256              return function () {
17257                const resolvers = utils.arrayify(orig.call(this));
17258
17259                const instrumentedResolvers = instrumentResolvers(resolvers, getCurrentHub);
17260
17261                return instrumentedResolvers;
17262              };
17263            });
17264
17265            return orig.call(this, ...args);
17266          };
17267        },
17268      );
17269    } else {
17270      const pkg = this.loadDependency();
17271
17272      if (!pkg) {
17273        debugBuild.DEBUG_BUILD && utils.logger.error('Apollo Integration was unable to require apollo-server-core package.');
17274        return;
17275      }
17276
17277      /**
17278       * Iterate over resolvers of the ApolloServer instance before schemas are constructed.
17279       */
17280      utils.fill(pkg.ApolloServerBase.prototype, 'constructSchema', function (orig) {
17281        return function (
17282
17283) {
17284          if (!this.config.resolvers) {
17285            if (debugBuild.DEBUG_BUILD) {
17286              if (this.config.schema) {
17287                utils.logger.warn(
17288                  'Apollo integration is not able to trace `ApolloServer` instances constructed via `schema` property.' +
17289                    'If you are using NestJS with Apollo, please use `Sentry.Integrations.Apollo({ useNestjs: true })` instead.',
17290                );
17291                utils.logger.warn();
17292              } else if (this.config.modules) {
17293                utils.logger.warn(
17294                  'Apollo integration is not able to trace `ApolloServer` instances constructed via `modules` property.',
17295                );
17296              }
17297
17298              utils.logger.error('Skipping tracing as no resolvers found on the `ApolloServer` instance.');
17299            }
17300
17301            return orig.call(this);
17302          }
17303
17304          const resolvers = utils.arrayify(this.config.resolvers);
17305
17306          this.config.resolvers = instrumentResolvers(resolvers, getCurrentHub);
17307
17308          return orig.call(this);
17309        };
17310      });
17311    }
17312  }
17313}Apollo.__initStatic();
17314
17315function instrumentResolvers(resolvers, getCurrentHub) {
17316  return resolvers.map(model => {
17317    Object.keys(model).forEach(resolverGroupName => {
17318      Object.keys(model[resolverGroupName]).forEach(resolverName => {
17319        if (typeof model[resolverGroupName][resolverName] !== 'function') {
17320          return;
17321        }
17322
17323        wrapResolver(model, resolverGroupName, resolverName, getCurrentHub);
17324      });
17325    });
17326
17327    return model;
17328  });
17329}
17330
17331/**
17332 * Wrap a single resolver which can be a parent of other resolvers and/or db operations.
17333 */
17334function wrapResolver(
17335  model,
17336  resolverGroupName,
17337  resolverName,
17338  getCurrentHub,
17339) {
17340  utils.fill(model[resolverGroupName], resolverName, function (orig) {
17341    return function ( ...args) {
17342      // eslint-disable-next-line deprecation/deprecation
17343      const scope = getCurrentHub().getScope();
17344      // eslint-disable-next-line deprecation/deprecation
17345      const parentSpan = scope.getSpan();
17346      // eslint-disable-next-line deprecation/deprecation
17347      const span = _optionalChain([parentSpan, 'optionalAccess', _2 => _2.startChild, 'call', _3 => _3({
17348        description: `${resolverGroupName}.${resolverName}`,
17349        op: 'graphql.resolve',
17350        origin: 'auto.graphql.apollo',
17351      })]);
17352
17353      const rv = orig.call(this, ...args);
17354
17355      if (utils.isThenable(rv)) {
17356        return rv.then((res) => {
17357          _optionalChain([span, 'optionalAccess', _4 => _4.end, 'call', _5 => _5()]);
17358          return res;
17359        });
17360      }
17361
17362      _optionalChain([span, 'optionalAccess', _6 => _6.end, 'call', _7 => _7()]);
17363
17364      return rv;
17365    };
17366  });
17367}
17368
17369exports.Apollo = Apollo;
17370
17371
17372}
17372,{"../../common/debug-build.js":206,"./utils/node-utils.js":218,"@sentry/utils":319}],211:[function(require,module,exports){
17373var {
17374  _optionalChain
17375} = require('@sentry/utils');
17376
17377Object.defineProperty(exports, '__esModule', { value: true });
17378
17379const core = require('@sentry/core');
17380const utils = require('@sentry/utils');
17381const debugBuild = require('../../common/debug-build.js');
17382const nodeUtils = require('./utils/node-utils.js');
17383
17384/* eslint-disable max-lines */
17385
17386/**
17387 * Express integration
17388 *
17389 * Provides an request and error handler for Express framework as well as tracing capabilities
17390 */
17391class Express  {
17392  /**
17393   * @inheritDoc
17394   */
17395   static __initStatic() {this.id = 'Express';}
17396
17397  /**
17398   * @inheritDoc
17399   */
17400
17401  /**
17402   * Express App instance
17403   */
17404
17405  /**
17406   * @inheritDoc
17407   */
17408   constructor(options = {}) {
17409    this.name = Express.id;
17410    this._router = options.router || options.app;
17411    this._methods = (Array.isArray(options.methods) ? options.methods : []).concat('use');
17412  }
17413
17414  /**
17415   * @inheritDoc
17416   */
17417   setupOnce(_, getCurrentHub) {
17418    if (!this._router) {
17419      debugBuild.DEBUG_BUILD && utils.logger.error('ExpressIntegration is missing an Express instance');
17420      return;
17421    }
17422
17423    if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) {
17424      debugBuild.DEBUG_BUILD && utils.logger.log('Express Integration is skipped because of instrumenter configuration.');
17425      return;
17426    }
17427
17428    instrumentMiddlewares(this._router, this._methods);
17429    instrumentRouter(this._router );
17430  }
17431}Express.__initStatic();
17432
17433/**
17434 * Wraps original middleware function in a tracing call, which stores the info about the call as a span,
17435 * and finishes it once the middleware is done invoking.
17436 *
17437 * Express middlewares have 3 various forms, thus we have to take care of all of them:
17438 * // sync
17439 * app.use(function (req, res) { ... })
17440 * // async
17441 * app.use(function (req, res, next) { ... })
17442 * // error handler
17443 * app.use(function (err, req, res, next) { ... })
17444 *
17445 * They all internally delegate to the `router[method]` of the given application instance.
17446 */
17447// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any
17448function wrap(fn, method) {
17449  const arity = fn.length;
17450
17451  switch (arity) {
17452    case 2: {
17453      return function ( req, res) {
17454        const transaction = res.__sentry_transaction;
17455        if (transaction) {
17456          // eslint-disable-next-line deprecation/deprecation
17457          const span = transaction.startChild({
17458            description: fn.name,
17459            op: `middleware.express.${method}`,
17460            origin: 'auto.middleware.express',
17461          });
17462          res.once('finish', () => {
17463            span.end();
17464          });
17465        }
17466        return fn.call(this, req, res);
17467      };
17468    }
17469    case 3: {
17470      return function (
17471
17472        req,
17473        res,
17474        next,
17475      ) {
17476        const transaction = res.__sentry_transaction;
17477        // eslint-disable-next-line deprecation/deprecation
17478        const span = _optionalChain([transaction, 'optionalAccess', _2 => _2.startChild, 'call', _3 => _3({
17479          description: fn.name,
17480          op: `middleware.express.${method}`,
17481          origin: 'auto.middleware.express',
17482        })]);
17483        fn.call(this, req, res, function ( ...args) {
17484          _optionalChain([span, 'optionalAccess', _4 => _4.end, 'call', _5 => _5()]);
17485          next.call(this, ...args);
17486        });
17487      };
17488    }
17489    case 4: {
17490      return function (
17491
17492        err,
17493        req,
17494        res,
17495        next,
17496      ) {
17497        const transaction = res.__sentry_transaction;
17498        // eslint-disable-next-line deprecation/deprecation
17499        const span = _optionalChain([transaction, 'optionalAccess', _6 => _6.startChild, 'call', _7 => _7({
17500          description: fn.name,
17501          op: `middleware.express.${method}`,
17502          origin: 'auto.middleware.express',
17503        })]);
17504        fn.call(this, err, req, res, function ( ...args) {
17505          _optionalChain([span, 'optionalAccess', _8 => _8.end, 'call', _9 => _9()]);
17506          next.call(this, ...args);
17507        });
17508      };
17509    }
17510    default: {
17511      throw new Error(`Express middleware takes 2-4 arguments. Got: ${arity}`);
17512    }
17513  }
17514}
17515
17516/**
17517 * Takes all the function arguments passed to the original `app` or `router` method, eg. `app.use` or `router.use`
17518 * and wraps every function, as well as array of functions with a call to our `wrap` method.
17519 * We have to take care of the arrays as well as iterate over all of the arguments,
17520 * as `app.use` can accept middlewares in few various forms.
17521 *
17522 * app.use([<path>], <fn>)
17523 * app.use([<path>], <fn>, ...<fn>)
17524 * app.use([<path>], ...<fn>[])
17525 */
17526function wrapMiddlewareArgs(args, method) {
17527  return args.map((arg) => {
17528    if (typeof arg === 'function') {
17529      return wrap(arg, method);
17530    }
17531
17532    if (Array.isArray(arg)) {
17533      return arg.map((a) => {
17534        if (typeof a === 'function') {
17535          return wrap(a, method);
17536        }
17537        return a;
17538      });
17539    }
17540
17541    return arg;
17542  });
17543}
17544
17545/**
17546 * Patches original router to utilize our tracing functionality
17547 */
17548function patchMiddleware(router, method) {
17549  const originalCallback = router[method];
17550
17551  router[method] = function (...args) {
17552    return originalCallback.call(this, ...wrapMiddlewareArgs(args, method));
17553  };
17554
17555  return router;
17556}
17557
17558/**
17559 * Patches original router methods
17560 */
17561function instrumentMiddlewares(router, methods = []) {
17562  methods.forEach((method) => patchMiddleware(router, method));
17563}
17564
17565/**
17566 * Patches the prototype of Express.Router to accumulate the resolved route
17567 * if a layer instance's `match` function was called and it returned a successful match.
17568 *
17569 * @see https://github.com/expressjs/express/blob/master/lib/router/index.js
17570 *
17571 * @param appOrRouter the router instance which can either be an app (i.e. top-level) or a (nested) router.
17572 */
17573function instrumentRouter(appOrRouter) {
17574  // This is how we can distinguish between app and routers
17575  const isApp = 'settings' in appOrRouter;
17576
17577  // In case the app's top-level router hasn't been initialized yet, we have to do it now
17578  if (isApp && appOrRouter._router === undefined && appOrRouter.lazyrouter) {
17579    appOrRouter.lazyrouter();
17580  }
17581
17582  const router = isApp ? appOrRouter._router : appOrRouter;
17583
17584  if (!router) {
17585    /*
17586    If we end up here, this means likely that this integration is used with Express 3 or Express 5.
17587    For now, we don't support these versions (3 is very old and 5 is still in beta). To support Express 5,
17588    we'd need to make more changes to the routing instrumentation because the router is no longer part of
17589    the Express core package but maintained in its own package. The new router has different function
17590    signatures and works slightly differently, demanding more changes than just taking the router from
17591    `app.router` instead of `app._router`.
17592    @see https://github.com/pillarjs/router
17593
17594    TODO: Proper Express 5 support
17595    */
17596    debugBuild.DEBUG_BUILD && utils.logger.debug('Cannot instrument router for URL Parameterization (did not find a valid router).');
17597    debugBuild.DEBUG_BUILD && utils.logger.debug('Routing instrumentation is currently only supported in Express 4.');
17598    return;
17599  }
17600
17601  const routerProto = Object.getPrototypeOf(router) ;
17602
17603  const originalProcessParams = routerProto.process_params;
17604  routerProto.process_params = function process_params(
17605    layer,
17606    called,
17607    req,
17608    res,
17609    done,
17610  ) {
17611    // Base case: We're in the first part of the URL (thus we start with the root '/')
17612    if (!req._reconstructedRoute) {
17613      req._reconstructedRoute = '';
17614    }
17615
17616    // If the layer's partial route has params, is a regex or an array, the route is stored in layer.route.
17617    const { layerRoutePath, isRegex, isArray, numExtraSegments } = getLayerRoutePathInfo(layer);
17618
17619    if (layerRoutePath || isRegex || isArray) {
17620      req._hasParameters = true;
17621    }
17622
17623    // Otherwise, the hardcoded path (i.e. a partial route without params) is stored in layer.path
17624    let partialRoute;
17625
17626    if (layerRoutePath) {
17627      partialRoute = layerRoutePath;
17628    } else {
17629      /**
17630       * prevent duplicate segment in _reconstructedRoute param if router match multiple routes before final path
17631       * example:
17632       * original url: /api/v1/1234
17633       * prevent: /api/api/v1/:userId
17634       * router structure
17635       * /api -> middleware
17636       * /api/v1 -> middleware
17637       * /1234 -> endpoint with param :userId
17638       * final _reconstructedRoute is /api/v1/:userId
17639       */
17640      partialRoute = preventDuplicateSegments(req.originalUrl, req._reconstructedRoute, layer.path) || '';
17641    }
17642
17643    // Normalize the partial route so that it doesn't contain leading or trailing slashes
17644    // and exclude empty or '*' wildcard routes.
17645    // The exclusion of '*' routes is our best effort to not "pollute" the transaction name
17646    // with interim handlers (e.g. ones that check authentication or do other middleware stuff).
17647    // We want to end up with the parameterized URL of the incoming request without any extraneous path segments.
17648    const finalPartialRoute = partialRoute
17649      .split('/')
17650      .filter(segment => segment.length > 0 && (isRegex || isArray || !segment.includes('*')))
17651      .join('/');
17652
17653    // If we found a valid partial URL, we append it to the reconstructed route
17654    if (finalPartialRoute && finalPartialRoute.length > 0) {
17655      // If the partial route is from a regex route, we append a '/' to close the regex
17656      req._reconstructedRoute += `/${finalPartialRoute}${isRegex ? '/' : ''}`;
17657    }
17658
17659    // Now we check if we are in the "last" part of the route. We determine this by comparing the
17660    // number of URL segments from the original URL to that of our reconstructed parameterized URL.
17661    // If we've reached our final destination, we update the transaction name.
17662    const urlLength = utils.getNumberOfUrlSegments(utils.stripUrlQueryAndFragment(req.originalUrl || '')) + numExtraSegments;
17663    const routeLength = utils.getNumberOfUrlSegments(req._reconstructedRoute);
17664
17665    if (urlLength === routeLength) {
17666      if (!req._hasParameters) {
17667        if (req._reconstructedRoute !== req.originalUrl) {
17668          req._reconstructedRoute = req.originalUrl ? utils.stripUrlQueryAndFragment(req.originalUrl) : req.originalUrl;
17669        }
17670      }
17671
17672      const transaction = res.__sentry_transaction;
17673      const attributes = (transaction && core.spanToJSON(transaction).data) || {};
17674      if (transaction && attributes[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] !== 'custom') {
17675        // If the request URL is '/' or empty, the reconstructed route will be empty.
17676        // Therefore, we fall back to setting the final route to '/' in this case.
17677        const finalRoute = req._reconstructedRoute || '/';
17678
17679        const [name, source] = utils.extractPathForTransaction(req, { path: true, method: true, customRoute: finalRoute });
17680        transaction.updateName(name);
17681        transaction.setAttribute(core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source);
17682      }
17683    }
17684
17685    return originalProcessParams.call(this, layer, called, req, res, done);
17686  };
17687}
17688
17689/**
17690 * Recreate layer.route.path from layer.regexp and layer.keys.
17691 * Works until express.js used package [email protected]
17692 * or until layer.keys contain offset attribute
17693 *
17694 * @param layer the layer to extract the stringified route from
17695 *
17696 * @returns string in layer.route.path structure 'router/:pathParam' or undefined
17697 */
17698const extractOriginalRoute = (
17699  path,
17700  regexp,
17701  keys,
17702) => {
17703  if (!path || !regexp || !keys || Object.keys(keys).length === 0 || !_optionalChain([
vendor: 2,216 bytes, lines 17703-17773
17703keys, 'access', _10 => _10[0], 'optionalAccess', _11 => _11.offset])) {
17704    return undefined;
17705  }
17706
17707  const orderedKeys = keys.sort((a, b) => a.offset - b.offset);
17708
17709  // add d flag for getting indices from regexp result
17710  // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- regexp comes from express.js
17711  const pathRegex = new RegExp(regexp, `${regexp.flags}d`);
17712  /**
17713   * use custom type cause of TS error with missing indices in RegExpExecArray
17714   */
17715  const execResult = pathRegex.exec(path) ;
17716
17717  if (!execResult || !execResult.indices) {
17718    return undefined;
17719  }
17720  /**
17721   * remove first match from regex cause contain whole layer.path
17722   */
17723  const [, ...paramIndices] = execResult.indices;
17724
17725  if (paramIndices.length !== orderedKeys.length) {
17726    return undefined;
17727  }
17728  let resultPath = path;
17729  let indexShift = 0;
17730
17731  /**
17732   * iterate param matches from regexp.exec
17733   */
17734  paramIndices.forEach((item, index) => {
17735    /** check if offsets is define because in some cases regex d flag returns undefined */
17736    if (item) {
17737      const [startOffset, endOffset] = item;
17738      /**
17739       * isolate part before param
17740       */
17741      const substr1 = resultPath.substring(0, startOffset - indexShift);
17742      /**
17743       * define paramName as replacement in format :pathParam
17744       */
17745      const replacement = `:${orderedKeys[index].name}`;
17746
17747      /**
17748       * isolate part after param
17749       */
17750      const substr2 = resultPath.substring(endOffset - indexShift);
17751
17752      /**
17753       * recreate original path but with param replacement
17754       */
17755      resultPath = substr1 + replacement + substr2;
17756
17757      /**
17758       * calculate new index shift after resultPath was modified
17759       */
17760      indexShift = indexShift + (endOffset - startOffset - replacement.length);
17761    }
17762  });
17763
17764  return resultPath;
17765};
17766
17767/**
17768 * Extracts and stringifies the layer's route which can either be a string with parameters (`users/:id`),
17769 * a RegEx (`/test/`) or an array of strings and regexes (`['/path1', /\/path[2-5]/, /path/:id]`). Additionally
17770 * returns extra information about the route, such as if the route is defined as regex or as an array.
17771 *
17772 * @param layer the layer to extract the stringified route from
17773 *
17774 * @returns an object containing the stringified route, a flag determining if the route was a regex
17775 *          and the number of extra segments to the matched path that are additionally in the route,
17776 *          if the route was an array (defaults to 0).
17777 */
17778function getLayerRoutePathInfo(layer) {
17779  let lrp = _optionalChain([layer, 'access', _12 => _12.route, 'optionalAccess', _13 => _13.path]);
17780
17781  const isRegex = utils.isRegExp(lrp);
17782  const isArray = Array.isArray(lrp);
17783
17784  if (!lrp) {
17785    // parse node.js major version
17786    // Next.js will complain if we directly use `proces.versions` here because of edge runtime.
17787    const [major] = (utils.GLOBAL_OBJ ).process.versions.node.split('.').map(Number);
17788
17789    // allow call extractOriginalRoute only if node version support Regex d flag, node 16+
17790    if (major >= 16) {
17791      /**
17792       * If lrp does not exist try to recreate original layer path from route regexp
17793       */
17794      lrp = extractOriginalRoute(layer.path, layer.regexp, layer.keys);
17795    }
17796  }
17797
17798  if (!lrp) {
17799    return { isRegex, isArray, numExtraSegments: 0 };
17800  }
17801
17802  const numExtraSegments = isArray
17803    ? Math.max(getNumberOfArrayUrlSegments(lrp ) - utils.getNumberOfUrlSegments(layer.path || ''), 0)
17804    : 0;
17805
17806  const layerRoutePath = getLayerRoutePathString(isArray, lrp);
17807
17808  return { layerRoutePath, isRegex, isArray, numExtraSegments };
17809}
17810
17811/**
17812 * Returns the number of URL segments in an array of routes
17813 *
17814 * Example: ['/api/test', /\/api\/post[0-9]/, '/users/:id/details`] -> 7
17815 */
17816function getNumberOfArrayUrlSegments(routesArray) {
17817  return routesArray.reduce((accNumSegments, currentRoute) => {
17818    // array members can be a RegEx -> convert them toString
17819    return accNumSegments + utils.getNumberOfUrlSegments(currentRoute.toString());
17820  }, 0);
17821}
17822
17823/**
17824 * Extracts and returns the stringified version of the layers route path
17825 * Handles route arrays (by joining the paths together) as well as RegExp and normal
17826 * string values (in the latter case the toString conversion is technically unnecessary but
17827 * it doesn't hurt us either).
17828 */
17829function getLayerRoutePathString(isArray, lrp) {
17830  if (isArray) {
17831    return (lrp ).map(r => r.toString()).join(',');
17832  }
17833  return lrp && lrp.toString();
17834}
17835
17836/**
17837 * remove duplicate segment contain in layerPath against reconstructedRoute,
17838 * and return only unique segment that can be added into reconstructedRoute
17839 */
17840function preventDuplicateSegments(
17841  originalUrl,
17842  reconstructedRoute,
17843  layerPath,
17844) {
17845  // filter query params
17846  const normalizeURL = utils.stripUrlQueryAndFragment(originalUrl || '');
17847  const originalUrlSplit = _optionalChain([normalizeURL, 'optionalAccess', _14 => _14.split, 'call', _15 => _15('/'), 'access', _16 => _16.filter, 'call', _17 => _17(v => !!v)]);
17848  let tempCounter = 0;
17849  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;
17850  const result = _optionalChain([layerPath
17851, 'optionalAccess', _23 => _23.split, 'call', _24 => _24('/')
17852, 'access', _25 => _25.filter, 'call', _26 => _26(segment => {
17853      if (_optionalChain([originalUrlSplit, 'optionalAccess', _27 => _27[currentOffset + tempCounter]]) === segment) {
17854        tempCounter += 1;
17855        return true;
17856      }
17857      return false;
17858    })
17859, 'access', _28 => _28.join, 'call', _29 => _29('/')]);
17860  return result;
17861}
17862
17863exports.Express = Express;
17864exports.extractOriginalRoute = extractOriginalRoute;
17865exports.preventDuplicateSegments = preventDuplicateSegments;
17866
17867
17868},{"../../common/debug-build.js":206,"./utils/node-utils.js":218,"@sentry/core":250,"@sentry/utils":319}],212:[function(require,module,exports){
17869var {
17870  _optionalChain
17871} = require('@sentry/utils');
17872
17873Object.defineProperty(exports, '__esModule', { value: true });
17874
17875const utils = require('@sentry/utils');
17876const debugBuild = require('../../common/debug-build.js');
17877const nodeUtils = require('./utils/node-utils.js');
17878
17879/** Tracing integration for graphql package */
17880class GraphQL  {
17881  /**
17882   * @inheritDoc
17883   */
17884   static __initStatic() {this.id = 'GraphQL';}
17885
17886  /**
17887   * @inheritDoc
17888   */
17889
17890   constructor() {
17891    this.name = GraphQL.id;
17892  }
17893
17894  /** @inheritdoc */
17895   loadDependency() {
17896    return (this._module = this._module || utils.loadModule('graphql/execution/execute.js'));
17897  }
17898
17899  /**
17900   * @inheritDoc
17901   */
17902   setupOnce(_, getCurrentHub) {
17903    if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) {
17904      debugBuild.DEBUG_BUILD && utils.logger.log('GraphQL Integration is skipped because of instrumenter configuration.');
17905      return;
17906    }
17907
17908    const pkg = this.loadDependency();
17909
17910    if (!pkg) {
17911      debugBuild.DEBUG_BUILD && utils.logger.error('GraphQL Integration was unable to require graphql/execution package.');
17912      return;
17913    }
17914
17915    utils.fill(pkg, 'execute', function (orig) {
17916      return function ( ...args) {
17917        // eslint-disable-next-line deprecation/deprecation
17918        const scope = getCurrentHub().getScope();
17919        // eslint-disable-next-line deprecation/deprecation
17920        const parentSpan = scope.getSpan();
17921
17922        // eslint-disable-next-line deprecation/deprecation
17923        const span = _optionalChain([parentSpan, 'optionalAccess', _2 => _2.startChild, 'call', _3 => _3({
17924          description: 'execute',
17925          op: 'graphql.execute',
17926          origin: 'auto.graphql.graphql',
17927        })]);
17928
17929        // eslint-disable-next-line deprecation/deprecation
17930        _optionalChain([scope, 'optionalAccess', _4 => _4.setSpan, 'call', _5 => _5(span)]);
17931
17932        const rv = orig.call(this, ...args);
17933
17934        if (utils.isThenable(rv)) {
17935          return rv.then((res) => {
17936            _optionalChain([span, 'optionalAccess', _6 => _6.end, 'call', _7 => _7()]);
17937            // eslint-disable-next-line deprecation/deprecation
17938            _optionalChain([scope, 'optionalAccess', _8 => _8.setSpan, 'call', _9 => _9(parentSpan)]);
17939
17940            return res;
17941          });
17942        }
17943
17944        _optionalChain([span, 'optionalAccess', _10 => _10.end, 'call', _11 => _11()]);
17945        // eslint-disable-next-line deprecation/deprecation
17946        _optionalChain([scope, 'optionalAccess', _12 => _12.setSpan, 'call', _13 => _13(parentSpan)]);
17947        return rv;
17948      };
17949    });
17950  }
17951}GraphQL.__initStatic();
17952
17953exports.GraphQL = GraphQL;
17954
17955
17956},{"../../common/debug-build.js":206,"./utils/node-utils.js":218,"@sentry/utils":319}],213:[function(require,module,exports){
17957Object.defineProperty(exports, '__esModule', { value: true });
17958
17959const utils = require('@sentry/utils');
17960
17961const lazyLoadedNodePerformanceMonitoringIntegrations = [
17962  () => {
17963    const integration = utils.dynamicRequire(module, './apollo')
17964
17965;
17966    return new integration.Apollo();
17967  },
17968  () => {
17969    const integration = utils.dynamicRequire(module, './apollo')
17970
17971;
17972    return new integration.Apollo({ useNestjs: true });
17973  },
17974  () => {
17975    const integration = utils.dynamicRequire(module, './graphql')
17976
17977;
17978    return new integration.GraphQL();
17979  },
17980  () => {
17981    const integration = utils.dynamicRequire(module, './mongo')
17982
17983;
17984    return new integration.Mongo();
17985  },
17986  () => {
17987    const integration = utils.dynamicRequire(module, './mongo')
17988
17989;
17990    return new integration.Mongo({ mongoose: true });
17991  },
17992  () => {
17993    const integration = utils.dynamicRequire(module, './mysql')
17994
17995;
17996    return new integration.Mysql();
17997  },
17998  () => {
17999    const integration = utils.dynamicRequire(module, './postgres')
18000
18001;
18002    return new integration.Postgres();
18003  },
18004];
18005
18006exports.lazyLoadedNodePerformanceMonitoringIntegrations = lazyLoadedNodePerformanceMonitoringIntegrations;
18007
18008
18009},{"@sentry/utils":319}],214:[function(require,module,exports){
18010var {
18011  _optionalChain
18012} = require('@sentry/utils');
18013
18014Object.defineProperty(exports, '__esModule', { value: true });
18015
18016const utils = require('@sentry/utils');
18017const debugBuild = require('../../common/debug-build.js');
vendor: 4,128 bytes, lines 18018-18118
18018const nodeUtils = require('./utils/node-utils.js');
18019
18020// This allows us to use the same array for both defaults options and the type itself.
18021// (note `as const` at the end to make it a union of string literal types (i.e. "a" | "b" | ... )
18022// and not just a string[])
18023
18024const OPERATIONS = [
18025  'aggregate', // aggregate(pipeline, options, callback)
18026  'bulkWrite', // bulkWrite(operations, options, callback)
18027  'countDocuments', // countDocuments(query, options, callback)
18028  'createIndex', // createIndex(fieldOrSpec, options, callback)
18029  'createIndexes', // createIndexes(indexSpecs, options, callback)
18030  'deleteMany', // deleteMany(filter, options, callback)
18031  'deleteOne', // deleteOne(filter, options, callback)
18032  'distinct', // distinct(key, query, options, callback)
18033  'drop', // drop(options, callback)
18034  'dropIndex', // dropIndex(indexName, options, callback)
18035  'dropIndexes', // dropIndexes(options, callback)
18036  'estimatedDocumentCount', // estimatedDocumentCount(options, callback)
18037  'find', // find(query, options, callback)
18038  'findOne', // findOne(query, options, callback)
18039  'findOneAndDelete', // findOneAndDelete(filter, options, callback)
18040  'findOneAndReplace', // findOneAndReplace(filter, replacement, options, callback)
18041  'findOneAndUpdate', // findOneAndUpdate(filter, update, options, callback)
18042  'indexes', // indexes(options, callback)
18043  'indexExists', // indexExists(indexes, options, callback)
18044  'indexInformation', // indexInformation(options, callback)
18045  'initializeOrderedBulkOp', // initializeOrderedBulkOp(options, callback)
18046  'insertMany', // insertMany(docs, options, callback)
18047  'insertOne', // insertOne(doc, options, callback)
18048  'isCapped', // isCapped(options, callback)
18049  'mapReduce', // mapReduce(map, reduce, options, callback)
18050  'options', // options(options, callback)
18051  'parallelCollectionScan', // parallelCollectionScan(options, callback)
18052  'rename', // rename(newName, options, callback)
18053  'replaceOne', // replaceOne(filter, doc, options, callback)
18054  'stats', // stats(options, callback)
18055  'updateMany', // updateMany(filter, update, options, callback)
18056  'updateOne', // updateOne(filter, update, options, callback)
18057] ;
18058
18059// All of the operations above take `options` and `callback` as their final parameters, but some of them
18060// take additional parameters as well. For those operations, this is a map of
18061// { <operation name>:  [<names of additional parameters>] }, as a way to know what to call the operation's
18062// positional arguments when we add them to the span's `data` object later
18063const OPERATION_SIGNATURES
18064
18065 = {
18066  // aggregate intentionally not included because `pipeline` arguments are too complex to serialize well
18067  // see https://github.com/getsentry/sentry-javascript/pull/3102
18068  bulkWrite: ['operations'],
18069  countDocuments: ['query'],
18070  createIndex: ['fieldOrSpec'],
18071  createIndexes: ['indexSpecs'],
18072  deleteMany: ['filter'],
18073  deleteOne: ['filter'],
18074  distinct: ['key', 'query'],
18075  dropIndex: ['indexName'],
18076  find: ['query'],
18077  findOne: ['query'],
18078  findOneAndDelete: ['filter'],
18079  findOneAndReplace: ['filter', 'replacement'],
18080  findOneAndUpdate: ['filter', 'update'],
18081  indexExists: ['indexes'],
18082  insertMany: ['docs'],
18083  insertOne: ['doc'],
18084  mapReduce: ['map', 'reduce'],
18085  rename: ['newName'],
18086  replaceOne: ['filter', 'doc'],
18087  updateMany: ['filter', 'update'],
18088  updateOne: ['filter', 'update'],
18089};
18090
18091function isCursor(maybeCursor) {
18092  return maybeCursor && typeof maybeCursor === 'object' && maybeCursor.once && typeof maybeCursor.once === 'function';
18093}
18094
18095/** Tracing integration for mongo package */
18096class Mongo  {
18097  /**
18098   * @inheritDoc
18099   */
18100   static __initStatic() {this.id = 'Mongo';}
18101
18102  /**
18103   * @inheritDoc
18104   */
18105
18106  /**
18107   * @inheritDoc
18108   */
18109   constructor(options = {}) {
18110    this.name = Mongo.id;
18111    this._operations = Array.isArray(options.operations) ? options.operations : (OPERATIONS );
18112    this._describeOperations = 'describeOperations' in options ? options.describeOperations : true;
18113    this._useMongoose = !!options.useMongoose;
18114  }
18115
18116  /** @inheritdoc */
18117   loadDependency() {
18118    const moduleName = this._useMongoose ? 'mongoose' : 'mongodb';
18119    return (this._module = this._module || utils.loadModule(moduleName));
18120  }
18121
18122  /**
18123   * @inheritDoc
18124   */
18125   setupOnce(_, getCurrentHub) {
18126    if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) {
18127      debugBuild.DEBUG_BUILD && utils.logger.log('Mongo Integration is skipped because of instrumenter configuration.');
18128      return;
18129    }
18130
18131    const pkg = this.loadDependency();
18132
18133    if (!pkg) {
18134      const moduleName = this._useMongoose ? 'mongoose' : 'mongodb';
18135      debugBuild.DEBUG_BUILD && utils.logger.error(`Mongo Integration was unable to require \`${moduleName}\` package.`);
18136      return;
18137    }
18138
18139    this._instrumentOperations(pkg.Collection, this._operations, getCurrentHub);
18140  }
18141
18142  /**
18143   * Patches original collection methods
18144   */
18145   _instrumentOperations(collection, operations, getCurrentHub) {
18146    operations.forEach((operation) => this._patchOperation(collection, operation, getCurrentHub));
18147  }
18148
18149  /**
18150   * Patches original collection to utilize our tracing functionality
18151   */
18152   _patchOperation(collection, operation, getCurrentHub) {
18153    if (!(operation in collection.prototype)) return;
18154
18155    const getSpanContext = this._getSpanContextFromOperationArguments.bind(this);
18156
18157    utils.fill(collection.prototype, operation, function (orig) {
18158      return function ( ...args) {
18159        const lastArg = args[args.length - 1];
18160        // eslint-disable-next-line deprecation/deprecation
18161        const hub = getCurrentHub();
18162        // eslint-disable-next-line deprecation/deprecation
18163        const scope = hub.getScope();
18164        // eslint-disable-next-line deprecation/deprecation
18165        const client = hub.getClient();
18166        // eslint-disable-next-line deprecation/deprecation
18167        const parentSpan = scope.getSpan();
18168
18169        const sendDefaultPii = _optionalChain([client, 'optionalAccess', _2 => _2.getOptions, 'call', _3 => _3(), 'access', _4 => _4.sendDefaultPii]);
18170
18171        // Check if the operation was passed a callback. (mapReduce requires a different check, as
18172        // its (non-callback) arguments can also be functions.)
18173        if (typeof lastArg !== 'function' || (operation === 'mapReduce' && args.length === 2)) {
18174          // eslint-disable-next-line deprecation/deprecation
18175          const span = _optionalChain([parentSpan, 'optionalAccess', _5 => _5.startChild, 'call', _6 => _6(getSpanContext(this, operation, args, sendDefaultPii))]);
18176          const maybePromiseOrCursor = orig.call(this, ...args);
18177
18178          if (utils.isThenable(maybePromiseOrCursor)) {
18179            return maybePromiseOrCursor.then((res) => {
18180              _optionalChain([span, 'optionalAccess', _7 => _7.end, 'call', _8 => _8()]);
18181              return res;
18182            });
18183          }
18184          // If the operation returns a Cursor
18185          // we need to attach a listener to it to finish the span when the cursor is closed.
18186          else if (isCursor(maybePromiseOrCursor)) {
18187            const cursor = maybePromiseOrCursor ;
18188
18189            try {
18190              cursor.once('close', () => {
18191                _optionalChain([span, 'optionalAccess', _9 => _9.end, 'call', _10 => _10()]);
18192              });
18193            } catch (e) {
18194              // If the cursor is already closed, `once` will throw an error. In that case, we can
18195              // finish the span immediately.
18196              _optionalChain([span, 'optionalAccess', _11 => _11.end, 'call', _12 => _12()]);
18197            }
18198
18199            return cursor;
18200          } else {
18201            _optionalChain([span, 'optionalAccess', _13 => _13.end, 'call', _14 => _14()]);
18202            return maybePromiseOrCursor;
18203          }
18204        }
18205
18206        // eslint-disable-next-line deprecation/deprecation
18207        const span = _optionalChain([parentSpan, 'optionalAccess', _15 => _15.startChild, 'call', _16 => _16(getSpanContext(this, operation, args.slice(0, -1)))]);
18208
18209        return orig.call(this, ...args.slice(0, -1), function (err, result) {
18210          _optionalChain([span, 'optionalAccess', _17 => _17.end, 'call', _18 => _18()]);
18211          lastArg(err, result);
18212        });
18213      };
18214    });
18215  }
18216
18217  /**
18218   * Form a SpanContext based on the user input to a given operation.
18219   */
18220   _getSpanContextFromOperationArguments(
18221    collection,
18222    operation,
18223    args,
18224    sendDefaultPii = false,
18225  ) {
18226    const data = {
18227      'db.system': 'mongodb',
18228      'db.name': collection.dbName,
18229      'db.operation': operation,
18230      'db.mongodb.collection': collection.collectionName,
18231    };
18232    const spanContext = {
18233      op: 'db',
18234      // TODO v8: Use `${collection.collectionName}.${operation}`
18235      origin: 'auto.db.mongo',
18236      description: operation,
18237      data,
18238    };
18239
18240    // If the operation takes no arguments besides `options` and `callback`, or if argument
18241    // collection is disabled for this operation, just return early.
18242    const signature = OPERATION_SIGNATURES[operation];
18243    const shouldDescribe = Array.isArray(this._describeOperations)
18244      ? this._describeOperations.includes(operation)
18245      : this._describeOperations;
18246
18247    if (!signature || !shouldDescribe || !sendDefaultPii) {
18248      return spanContext;
18249    }
18250
18251    try {
18252      // Special case for `mapReduce`, as the only one accepting functions as arguments.
18253      if (operation === 'mapReduce') {
18254        const [map, reduce] = args ;
18255        data[signature[0]] = typeof map === 'string' ? map : map.name || '<anonymous>';
18256        data[signature[1]] = typeof reduce === 'string' ? reduce : reduce.name || '<anonymous>';
18257      } else {
18258        for (let i = 0; i < signature.length; i++) {
18259          data[`db.mongodb.${signature[i]}`] = JSON.stringify(args[i]);
18260        }
18261      }
18262    } catch (_oO) {
18263      // no-empty
18264    }
18265
18266    return spanContext;
18267  }
18268}Mongo.__initStatic();
18269
18270exports.Mongo = Mongo;
18271
18272
18273},{"../../common/debug-build.js":206,"./utils/node-utils.js":218,"@sentry/utils":319}],215:[function(require,module,exports){
18274var {
18275  _optionalChain
18276} = require('@sentry/utils');
18277
18278Object.defineProperty(exports, '__esModule', { value: true });
18279
18280const utils = require('@sentry/utils');
18281const debugBuild = require('../../common/debug-build.js');
18282const nodeUtils = require('./utils/node-utils.js');
18283
18284/** Tracing integration for node-mysql package */
18285class Mysql  {
18286  /**
18287   * @inheritDoc
18288   */
18289   static __initStatic() {this.id = 'Mysql';}
18290
18291  /**
18292   * @inheritDoc
18293   */
18294
18295   constructor() {
18296    this.name = Mysql.id;
18297  }
18298
18299  /** @inheritdoc */
18300   loadDependency() {
18301    return (this._module = this._module || utils.loadModule('mysql/lib/Connection.js'));
18302  }
18303
18304  /**
18305   * @inheritDoc
18306   */
18307   setupOnce(_, getCurrentHub) {
18308    if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) {
18309      debugBuild.DEBUG_BUILD && utils.logger.log('Mysql Integration is skipped because of instrumenter configuration.');
18310      return;
18311    }
18312
18313    const pkg = this.loadDependency();
18314
18315    if (!pkg) {
18316      debugBuild.DEBUG_BUILD && utils.logger.error('Mysql Integration was unable to require `mysql` package.');
18317      return;
18318    }
18319
18320    let mySqlConfig = undefined;
18321
18322    try {
18323      pkg.prototype.connect = new Proxy(pkg.prototype.connect, {
18324        apply(wrappingTarget, thisArg, args) {
18325          if (!mySqlConfig) {
18326            mySqlConfig = thisArg.config;
18327          }
18328          return wrappingTarget.apply(thisArg, args);
18329        },
18330      });
18331    } catch (e) {
18332      debugBuild.DEBUG_BUILD && utils.logger.error('Mysql Integration was unable to instrument `mysql` config.');
18333    }
18334
18335    function spanDataFromConfig() {
18336      if (!mySqlConfig) {
18337        return {};
18338      }
18339      return {
18340        'server.address': mySqlConfig.host,
18341        'server.port': mySqlConfig.port,
18342        'db.user': mySqlConfig.user,
18343      };
18344    }
18345
18346    function finishSpan(span) {
18347      if (!span) {
18348        return;
18349      }
18350
18351      const data = spanDataFromConfig();
18352      Object.keys(data).forEach(key => {
18353        span.setAttribute(key, data[key]);
18354      });
18355
18356      span.end();
18357    }
18358
18359    // The original function will have one of these signatures:
18360    //    function (callback) => void
18361    //    function (options, callback) => void
18362    //    function (options, values, callback) => void
18363    utils.fill(pkg, 'createQuery', function (orig) {
18364      return function ( options, values, callback) {
18365        // eslint-disable-next-line deprecation/deprecation
18366        const scope = getCurrentHub().getScope();
18367        // eslint-disable-next-line deprecation/deprecation
18368        const parentSpan = scope.getSpan();
18369
18370        // eslint-disable-next-line deprecation/deprecation
18371        const span = _optionalChain([parentSpan, 'optionalAccess', _2 => _2.startChild, 'call', _3 => _3({
18372          description: typeof options === 'string' ? options : (options ).sql,
18373          op: 'db',
18374          origin: 'auto.db.mysql',
18375          data: {
18376            'db.system': 'mysql',
18377          },
18378        })]);
18379
18380        if (typeof callback === 'function') {
18381          return orig.call(this, options, values, function (err, result, fields) {
18382            finishSpan(span);
18383            callback(err, result, fields);
18384          });
18385        }
18386
18387        if (typeof values === 'function') {
18388          return orig.call(this, options, function (err, result, fields) {
18389            finishSpan(span);
18390            values(err, result, fields);
18391          });
18392        }
18393
18394        // streaming, no callback!
18395        const query = orig.call(this, options, values) ;
18396
18397        query.on('end', () => {
18398          finishSpan(span);
18399        });
18400
18401        return query;
18402      };
18403    });
18404  }
18405}Mysql.__initStatic();
18406
18407exports.Mysql = Mysql;
18408
18409
18410}
18410,{"../../common/debug-build.js":206,"./utils/node-utils.js":218,"@sentry/utils":319}],216:[function(require,module,exports){
18411var {
18412  _optionalChain
18413} = require('@sentry/utils');
18414
18415Object.defineProperty(exports, '__esModule', { value: true });
18416
18417const utils = require('@sentry/utils');
18418const debugBuild = require('../../common/debug-build.js');
18419const nodeUtils = require('./utils/node-utils.js');
18420
18421/** Tracing integration for node-postgres package */
18422class Postgres  {
18423  /**
18424   * @inheritDoc
18425   */
18426   static __initStatic() {this.id = 'Postgres';}
18427
18428  /**
18429   * @inheritDoc
18430   */
18431
18432   constructor(options = {}) {
18433    this.name = Postgres.id;
18434    this._usePgNative = !!options.usePgNative;
18435    this._module = options.module;
18436  }
18437
18438  /** @inheritdoc */
18439   loadDependency() {
18440    return (this._module = this._module || utils.loadModule('pg'));
18441  }
18442
18443  /**
18444   * @inheritDoc
18445   */
18446   setupOnce(_, getCurrentHub) {
18447    if (nodeUtils.shouldDisableAutoInstrumentation(getCurrentHub)) {
18448      debugBuild.DEBUG_BUILD && utils.logger.log('Postgres Integration is skipped because of instrumenter configuration.');
18449      return;
18450    }
18451
18452    const pkg = this.loadDependency();
18453
18454    if (!pkg) {
18455      debugBuild.DEBUG_BUILD && utils.logger.error('Postgres Integration was unable to require `pg` package.');
18456      return;
18457    }
18458
18459    const Client = this._usePgNative ? _optionalChain([pkg, 'access', _2 => _2.native, 'optionalAccess', _3 => _3.Client]) : pkg.Client;
18460
18461    if (!Client) {
18462      debugBuild.DEBUG_BUILD && utils.logger.error("Postgres Integration was unable to access 'pg-native' bindings.");
18463      return;
18464    }
18465
18466    /**
18467     * function (query, callback) => void
18468     * function (query, params, callback) => void
18469     * function (query) => Promise
18470     * function (query, params) => Promise
18471     * function (pg.Cursor) => pg.Cursor
18472     */
18473    utils.fill(Client.prototype, 'query', function (orig) {
18474      return function ( config, values, callback) {
18475        // eslint-disable-next-line deprecation/deprecation
18476        const scope = getCurrentHub().getScope();
18477        // eslint-disable-next-line deprecation/deprecation
18478        const parentSpan = scope.getSpan();
18479
18480        const data = {
18481          'db.system': 'postgresql',
18482        };
18483
18484        try {
18485          if (this.database) {
18486            data['db.name'] = this.database;
18487          }
18488          if (this.host) {
18489            data['server.address'] = this.host;
18490          }
18491          if (this.port) {
18492            data['server.port'] = this.port;
18493          }
18494          if (this.user) {
18495            data['db.user'] = this.user;
18496          }
18497        } catch (e) {
18498          // ignore
18499        }
18500
18501        // eslint-disable-next-line deprecation/deprecation
18502        const span = _optionalChain([parentSpan, 'optionalAccess', _4 => _4.startChild, 'call', _5 => _5({
18503          description: typeof config === 'string' ? config : (config ).text,
18504          op: 'db',
18505          origin: 'auto.db.postgres',
18506          data,
18507        })]);
18508
18509        if (typeof callback === 'function') {
18510          return orig.call(this, config, values, function (err, result) {
18511            _optionalChain([span, 'optionalAccess', _6 => _6.end, 'call', _7 => _7()]);
18512            callback(err, result);
18513          });
18514        }
18515
18516        if (typeof values === 'function') {
18517          return orig.call(this, config, function (err, result) {
18518            _optionalChain([span, 'optionalAccess', _8 => _8.end, 'call', _9 => _9()]);
18519            values(err, result);
18520          });
18521        }
18522
18523        const rv = typeof values !== 'undefined' ? orig.call(this, config, values) : orig.call(this, config);
18524
18525        if (utils.isThenable(rv)) {
18526          return rv.then((res) => {
18527            _optionalChain([span, 'optionalAccess', _10 => _10.end, 'call', _11 => _11()]);
18528            return res;
18529          });
18530        }
18531
18532        _optionalChain([span, 'optionalAccess', _12 => _12.end, 'call', _13 => _13()]);
18533        return rv;
18534      };
18535    });
18536  }
18537}Postgres.__initStatic();
18538
18539exports.Postgres = Postgres;
18540
18541
18542},{"../../common/debug-build.js":206,"./utils/node-utils.js":218,"@sentry/utils":319}],217:[function(require,module,exports){
18543Object.defineProperty(exports, '__esModule', { value: true });
18544
18545const core = require('@sentry/core');
18546const utils = require('@sentry/utils');
18547const debugBuild = require('../../common/debug-build.js');
18548const nodeUtils = require('./utils/node-utils.js');
18549
18550function isValidPrismaClient(possibleClient) {
18551  return !!possibleClient && !!(possibleClient )['$use'];
18552}
18553
18554/** Tracing integration for @prisma/client package */
18555class Prisma  {
18556  /**
18557   * @inheritDoc
18558   */
18559   static __initStatic() {this.id = 'Prisma';}
18560
18561  /**
18562   * @inheritDoc
18563   */
18564
18565  /**
18566   * @inheritDoc
18567   */
18568   constructor(options = {}) {
18569    this.name = Prisma.id;
18570
18571    // We instrument the PrismaClient inside the constructor and not inside `setupOnce` because in some cases of server-side
18572    // bundling (Next.js) multiple Prisma clients can be instantiated, even though users don't intend to. When instrumenting
18573    // in setupOnce we can only ever instrument one client.
18574    // https://github.com/getsentry/sentry-javascript/issues/7216#issuecomment-1602375012
18575    // In the future we might explore providing a dedicated PrismaClient middleware instead of this hack.
18576    if (isValidPrismaClient(options.client) && !options.client._sentryInstrumented) {
18577      // eslint-disable-next-line @typescript-eslint/no-explicit-any
18578      utils.addNonEnumerableProperty(options.client , '_sentryInstrumented', true);
18579
18580      const clientData = {};
18581      try {
18582        const engineConfig = (options.client )._engineConfig;
18583        if (engineConfig) {
18584          const { activeProvider, clientVersion } = engineConfig;
18585          if (activeProvider) {
18586            clientData['db.system'] = activeProvider;
18587          }
18588          if (clientVersion) {
18589            clientData['db.prisma.version'] = clientVersion;
18590          }
18591        }
18592      } catch (e) {
18593        // ignore
18594      }
18595
18596      options.client.$use((params, next) => {
18597        // eslint-disable-next-line deprecation/deprecation
18598        if (nodeUtils.shouldDisableAutoInstrumentation(core.getCurrentHub)) {
18599          return next(params);
18600        }
18601
18602        const action = params.action;
18603        const model = params.model;
18604
18605        return core.startSpan(
18606          {
18607            name: model ? `${model} ${action}` : action,
18608            onlyIfParent: true,
18609            op: 'db.prisma',
18610            attributes: {
18611              [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.prisma',
18612            },
18613            data: { ...clientData, 'db.operation': action },
18614          },
18615          () => next(params),
18616        );
18617      });
18618    } else {
18619      debugBuild.DEBUG_BUILD &&
18620        utils.logger.warn('Unsupported Prisma client provided to PrismaIntegration. Provided client:', options.client);
18621    }
18622  }
18623
18624  /**
18625   * @inheritDoc
18626   */
18627   setupOnce() {
18628    // Noop - here for backwards compatibility
18629  }
18630} Prisma.__initStatic();
18631
18632exports.Prisma = Prisma;
18633
18634
18635},{"../../common/debug-build.js":206,"./utils/node-utils.js":218,"@sentry/core":250,"@sentry/utils":319}],218:[function(require,module,exports){
18636var {
18637 _optionalChain
18638} = require('@sentry/utils');
18639
18640Object.defineProperty(exports, '__esModule', { value: true });
18641
18642/**
18643 * Check if Sentry auto-instrumentation should be disabled.
18644 *
18645 * @param getCurrentHub A method to fetch the current hub
18646 * @returns boolean
18647 */
18648function shouldDisableAutoInstrumentation(getCurrentHub) {
18649  // eslint-disable-next-line deprecation/deprecation
18650  const clientOptions = _optionalChain([getCurrentHub, 'call', _ => _(), 'access', _2 => _2.getClient, 'call', _3 => _3(), 'optionalAccess', _4 => _4.getOptions, 'call', _5 => _5()]);
18651  const instrumenter = _optionalChain([clientOptions, 'optionalAccess', _6 => _6.instrumenter]) || 'sentry';
18652
18653  return instrumenter !== 'sentry';
18654}
18655
18656exports.shouldDisableAutoInstrumentation = shouldDisableAutoInstrumentation;
18657
18658
18659},{"@sentry/utils":319}],219:[function(require,module,exports){
18660Object.defineProperty(exports, '__esModule', { value: true });
18661
18662const core = require('@sentry/core');
18663const utils = require('@sentry/utils');
18664const debugBuild = require('./debug-build.js');
18665const eventbuilder = require('./eventbuilder.js');
18666const helpers = require('./helpers.js');
18667const userfeedback = require('./userfeedback.js');
18668
18669/**
18670 * Configuration options for the Sentry Browser SDK.
18671 * @see @sentry/types Options for more information.
18672 */
18673
18674/**
18675 * The Sentry Browser SDK Client.
18676 *
18677 * @see BrowserOptions for documentation on configuration options.
18678 * @see SentryClient for usage documentation.
18679 */
18680class BrowserClient extends core.BaseClient {
18681  /**
18682   * Creates a new Browser SDK instance.
18683   *
18684   * @param options Configuration options for this SDK.
18685   */
18686   constructor(options) {
18687    const sdkSource = helpers.WINDOW.SENTRY_SDK_SOURCE || utils.getSDKSource();
18688    core.applySdkMetadata(options, 'browser', ['browser'], sdkSource);
18689
18690    super(options);
18691
18692    if (options.sendClientReports && helpers.WINDOW.document) {
18693      helpers.WINDOW.document.addEventListener('visibilitychange', () => {
18694        if (helpers.WINDOW.document.visibilityState === 'hidden') {
18695          this._flushOutcomes();
18696        }
18697      });
18698    }
18699  }
18700
18701  /**
18702   * @inheritDoc
18703   */
18704   eventFromException(exception, hint) {
18705    return eventbuilder.eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);
18706  }
18707
18708  /**
18709   * @inheritDoc
18710   */
18711   eventFromMessage(
18712    message,
18713    // eslint-disable-next-line deprecation/deprecation
18714    level = 'info',
18715    hint,
18716  ) {
18717    return eventbuilder.eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);
18718  }
18719
18720  /**
18721   * Sends user feedback to Sentry.
18722   */
18723   captureUserFeedback(feedback) {
18724    if (!this._isEnabled()) {
18725      debugBuild.DEBUG_BUILD && utils.logger.warn('SDK not enabled, will not capture user feedback.');
18726      return;
18727    }
18728
18729    const envelope = userfeedback.createUserFeedbackEnvelope(feedback, {
18730      metadata: this.getSdkMetadata(),
18731      dsn: this.getDsn(),
18732      tunnel: this.getOptions().tunnel,
18733    });
18734
18735    // _sendEnvelope should not throw
18736    // eslint-disable-next-line @typescript-eslint/no-floating-promises
18737    this._sendEnvelope(envelope);
18738  }
18739
18740  /**
18741   * @inheritDoc
18742   */
18743   _prepareEvent(event, hint, scope) {
18744    event.platform = event.platform || 'javascript';
18745    return super._prepareEvent(event, hint, scope);
18746  }
18747
18748  /**
18749   * Sends client reports as an envelope.
18750   */
18751   _flushOutcomes() {
18752    const outcomes = this._clearOutcomes();
18753
18754    if (outcomes.length === 0) {
18755      debugBuild.DEBUG_BUILD && utils.logger.log('No outcomes to send');
18756      return;
18757    }
18758
18759    // This is really the only place where we want to check for a DSN and only send outcomes then
18760    if (!this._dsn) {
18761      debugBuild.DEBUG_BUILD && utils.logger.log('No dsn provided, will not send outcomes');
18762      return;
18763    }
18764
18765    debugBuild.DEBUG_BUILD && utils.logger.log('Sending outcomes:', outcomes);
18766
18767    const envelope = utils.createClientReportEnvelope(outcomes, this._options.tunnel && utils.dsnToString(this._dsn));
18768
18769    // _sendEnvelope should not throw
18770    // eslint-disable-next-line @typescript-eslint/no-floating-promises
18771    this._sendEnvelope(envelope);
18772  }
18773}
18774
18775exports.BrowserClient = BrowserClient;
18776
18777
18778},{"./debug-build.js":220,"./eventbuilder.js":221,"./helpers.js":222,"./userfeedback.js":240,"@sentry/core":250,"@sentry/utils":319}],220:[function(require,module,exports){
18779arguments[4][206][0].apply(exports,arguments)
18780},{"dup":206}],221:[function(require,module,exports){
18781Object.defineProperty(exports, '__esModule', { value: true });
18782
18783const core = require('@sentry/core');
18784const utils = require('@sentry/utils');
18785
18786/**
18787 * This function creates an exception from a JavaScript Error
18788 */
18789function exceptionFromError(stackParser, ex) {
18790  // Get the frames first since Opera can lose the stack if we touch anything else first
18791  const frames = parseStackFrames(stackParser, ex);
18792
18793  const exception = {
18794    type: ex && ex.name,
18795    value: extractMessage(ex),
18796  };
18797
18798  if (frames.length) {
18799    exception.stacktrace = { frames };
18800  }
18801
18802  if (exception.type === undefined && exception.value === '') {
18803    exception.value = 'Unrecoverable error caught';
18804  }
18805
18806  return exception;
18807}
18808
18809/**
18810 * @hidden
18811 */
18812function eventFromPlainObject(
18813  stackParser,
18814  exception,
18815  syntheticException,
18816  isUnhandledRejection,
18817) {
18818  const client = core.getClient();
18819  const normalizeDepth = client && client.getOptions().normalizeDepth;
18820
18821  const event = {
18822    exception: {
18823      values: [
18824        {
18825          type: utils.isEvent(exception) ? exception.constructor.name : isUnhandledRejection ? 'UnhandledRejection' : 'Error',
18826          value: getNonErrorObjectExceptionValue(exception, { isUnhandledRejection }),
18827        },
18828      ],
18829    },
18830    extra: {
18831      __serialized__: utils.normalizeToSize(exception, normalizeDepth),
18832    },
18833  };
18834
18835  if (syntheticException) {
18836    const frames = parseStackFrames(stackParser, syntheticException);
18837    if (frames.length) {
18838      // event.exception.values[0] has been set above
18839      (event.exception ).values[0].stacktrace = { frames };
18840    }
18841  }
18842
18843  return event;
18844}
18845
18846/**
18847 * @hidden
18848 */
18849function eventFromError(stackParser, ex) {
18850  return {
18851    exception: {
18852      values: [exceptionFromError(stackParser, ex)],
18853    },
18854  };
18855}
18856
18857/** Parses stack frames from an error */
18858function parseStackFrames(
18859  stackParser,
18860  ex,
18861) {
18862  // Access and store the stacktrace property before doing ANYTHING
18863  // else to it because Opera is not very good at providing it
18864  // reliably in other circumstances.
18865  const stacktrace = ex.stacktrace || ex.stack || '';
18866
18867  const popSize = getPopSize(ex);
18868
18869  try {
18870    return stackParser(stacktrace, popSize);
18871  } catch (e) {
18872    // no-empty
18873  }
18874
18875  return [];
18876}
18877
18878// Based on our own mapping pattern - https://github.com/getsentry/sentry/blob/9f08305e09866c8bd6d0c24f5b0aabdd7dd6c59c/src/sentry/lang/javascript/errormapping.py#L83-L108
18879const reactMinifiedRegexp = /Minified React error #\d+;/i;
18880
18881function getPopSize(ex) {
18882  if (ex) {
18883    if (typeof ex.framesToPop === 'number') {
18884      return ex.framesToPop;
18885    }
18886
18887    if (reactMinifiedRegexp.test(ex.message)) {
18888      return 1;
18889    }
18890  }
18891
18892  return 0;
18893}
18894
18895/**
18896 * There are cases where stacktrace.message is an Event object
18897 * https://github.com/getsentry/sentry-javascript/issues/1949
18898 * In this specific case we try to extract stacktrace.message.error.message
18899 */
18900function extractMessage(ex) {
18901  const message = ex && ex.message;
18902  if (!message) {
18903    return 'No error message';
18904  }
18905  if (message.error && typeof message.error.message === 'string') {
18906    return message.error.message;
18907  }
18908  return message;
18909}
18910
18911/**
18912 * Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`.
18913 * @hidden
18914 */
18915function eventFromException(
18916  stackParser,
18917  exception,
18918  hint,
18919  attachStacktrace,
18920) {
18921  const syntheticException = (hint && hint.syntheticException) || undefined;
18922  const event = eventFromUnknownInput(stackParser, exception, syntheticException, attachStacktrace);
18923  utils.addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }
18924  event.level = 'error';
18925  if (hint && hint.event_id) {
18926    event.event_id = hint.event_id;
18927  }
18928  return utils.resolvedSyncPromise(event);
18929}
18930
18931/**
18932 * Builds and Event from a Message
18933 * @hidden
18934 */
18935function eventFromMessage(
18936  stackParser,
18937  message,
18938  // eslint-disable-next-line deprecation/deprecation
18939  level = 'info',
18940  hint,
18941  attachStacktrace,
18942) {
18943  const syntheticException = (hint && hint.syntheticException) || undefined;
18944  const event = eventFromString(stackParser, message, syntheticException, attachStacktrace);
18945  event.level = level;
18946  if (hint && hint.event_id) {
18947    event.event_id = hint.event_id;
18948  }
18949  return utils.resolvedSyncPromise(event);
18950}
18951
18952/**
18953 * @hidden
18954 */
18955function eventFromUnknownInput(
18956  stackParser,
18957  exception,
18958  syntheticException,
18959  attachStacktrace,
18960  isUnhandledRejection,
18961) {
18962  let event;
18963
18964  if (utils.isErrorEvent(exception ) && (exception ).error) {
18965    // If it is an ErrorEvent with `error` property, extract it to get actual Error
18966    const errorEvent = exception ;
18967    return eventFromError(stackParser, errorEvent.error );
18968  }
18969
18970  // If it is a `DOMError` (which is a legacy API, but still supported in some browsers) then we just extract the name
18971  // and message, as it doesn't provide anything else. According to the spec, all `DOMExceptions` should also be
18972  // `Error`s, but that's not the case in IE11, so in that case we treat it the same as we do a `DOMError`.
18973  //
18974  // https://developer.mozilla.org/en-US/docs/Web/API/DOMError
18975  // https://developer.mozilla.org/en-US/docs/Web/API/DOMException
18976  // https://webidl.spec.whatwg.org/#es-DOMException-specialness
18977  if (utils.isDOMError(exception) || utils.isDOMException(exception )) {
18978    const domException = exception ;
18979
18980    if ('stack' in (exception )) {
18981      event = eventFromError(stackParser, exception );
18982    } else {
18983      const name = domException.name || (utils.isDOMError(domException) ? 'DOMError' : 'DOMException');
18984      const message = domException.message ? `${name}: ${domException.message}` : name;
18985      event = eventFromString(stackParser, message, syntheticException, attachStacktrace);
18986      utils.addExceptionTypeValue(event, message);
18987    }
18988    if ('code' in domException) {
18989      // eslint-disable-next-line deprecation/deprecation
18990      event.tags = { ...event.tags, 'DOMException.code': `${domException.code}` };
18991    }
18992
18993    return event;
18994  }
18995  if (utils.isError(exception)) {
18996    // we have a real Error object, do nothing
18997    return eventFromError(stackParser, exception);
18998  }
18999  if (utils.isPlainObject(exception) || utils.isEvent(exception)) {
19000    // If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize
19001    // it manually. This will allow us to group events based on top-level keys which is much better than creating a new
19002    // group on any key/value change.
19003    const objectException = exception ;
19004    event = eventFromPlainObject(stackParser, objectException, syntheticException, isUnhandledRejection);
19005    utils.addExceptionMechanism(event, {
19006      synthetic: true,
19007    });
19008    return event;
19009  }
19010
19011  // If none of previous checks were valid, then it means that it's not:
19012  // - an instance of DOMError
19013  // - an instance of DOMException
19014  // - an instance of Event
19015  // - an instance of Error
19016  // - a valid ErrorEvent (one with an error property)
19017  // - a plain Object
19018  //
19019  // So bail out and capture it as a simple message:
19020  event = eventFromString(stackParser, exception , syntheticException, attachStacktrace);
19021  utils.addExceptionTypeValue(event, `${exception}`, undefined);
19022  utils.addExceptionMechanism(event, {
19023    synthetic: true,
19024  });
19025
19026  return event;
19027}
19028
19029/**
19030 * @hidden
19031 */
19032function eventFromString(
19033  stackParser,
19034  message,
19035  syntheticException,
19036  attachStacktrace,
19037) {
19038  const event = {};
19039
19040  if (attachStacktrace && syntheticException) {
19041    const frames = parseStackFrames(stackParser, syntheticException);
19042    if (frames.length) {
19043      event.exception = {
19044        values: [{ value: message, stacktrace: { frames } }],
19045      };
19046    }
19047  }
19048
19049  if (utils.isParameterizedString(message)) {
19050    const { __sentry_template_string__, __sentry_template_values__ } = message;
19051
19052    event.logentry = {
19053      message: __sentry_template_string__,
19054      params: __sentry_template_values__,
19055    };
19056    return event;
19057  }
19058
19059  event.message = message;
19060  return event;
19061}
19062
19063function getNonErrorObjectExceptionValue(
19064  exception,
19065  { isUnhandledRejection },
19066) {
19067  const keys = utils.extractExceptionKeysForMessage(exception);
19068  const captureType = isUnhandledRejection ? 'promise rejection' : 'exception';
19069
19070  // Some ErrorEvent instances do not have an `error` property, which is why they are not handled before
19071  // We still want to try to get a decent message for these cases
19072  if (utils.isErrorEvent(exception)) {
19073    return `Event \`ErrorEvent\` captured as ${captureType} with message \`${exception.message}\``;
19074  }
19075
19076  if (utils.isEvent(exception)) {
19077    const className = getObjectClassName(exception);
19078    return `Event \`${className}\` (type=${exception.type}) captured as ${captureType}`;
19079  }
19080
19081  return `Object captured as ${captureType} with keys: ${keys}`;
19082}
19083
19084function getObjectClassName(obj) {
19085  try {
19086    const prototype = Object.getPrototypeOf(obj);
19087    return prototype ? prototype.constructor.name : undefined;
19088  } catch (e) {
19089    // ignore errors here
19090  }
19091}
19092
19093exports.eventFromError = eventFromError;
19094exports.eventFromException = eventFromException;
19095exports.eventFromMessage = eventFromMessage;
19096exports.eventFromPlainObject = eventFromPlainObject;
19097exports.eventFromString = eventFromString;
19098exports.eventFromUnknownInput = eventFromUnknownInput;
19099exports.exceptionFromError = exceptionFromError;
19100exports.parseStackFrames = parseStackFrames;
19101
19102
19103},{"@sentry/core":250,"@sentry/utils":319}],222:[function(require,module,exports){
19104Object.defineProperty(exports, '__esModule', { value: true });
19105
19106require('@sentry-internal/tracing');
19107const core = require('@sentry/core');
19108const utils = require('@sentry/utils');
19109
19110const WINDOW = utils.GLOBAL_OBJ ;
19111
19112let ignoreOnError = 0;
19113
19114/**
19115 * @hidden
19116 */
19117function shouldIgnoreOnError() {
19118  return ignoreOnError > 0;
19119}
19120
19121/**
19122 * @hidden
19123 */
19124function ignoreNextOnError() {
19125  // onerror should trigger before setTimeout
19126  ignoreOnError++;
19127  setTimeout(() => {
19128    ignoreOnError--;
19129  });
19130}
19131
19132/**
19133 * Instruments the given function and sends an event to Sentry every time the
19134 * function throws an exception.
19135 *
19136 * @param fn A function to wrap. It is generally safe to pass an unbound function, because the returned wrapper always
19137 * has a correct `this` context.
19138 * @returns The wrapped function.
19139 * @hidden
19140 */
19141function wrap(
19142  fn,
19143  options
19144
19145 = {},
19146  before,
19147  // eslint-disable-next-line @typescript-eslint/no-explicit-any
19148) {
19149  // for future readers what this does is wrap a function and then create
19150  // a bi-directional wrapping between them.
19151  //
19152  // example: wrapped = wrap(original);
19153  //  original.__sentry_wrapped__ -> wrapped
19154  //  wrapped.__sentry_original__ -> original
19155
19156  if (typeof fn !== 'function') {
19157    return fn;
19158  }
19159
19160  try {
19161    // if we're dealing with a function that was previously wrapped, return
19162    // the original wrapper.
19163    const wrapper = fn.__sentry_wrapped__;
19164    if (wrapper) {
19165      return wrapper;
19166    }
19167
19168    // We don't wanna wrap it twice
19169    if (utils.getOriginalFunction(fn)) {
19170      return fn;
19171    }
19172  } catch (e) {
19173    // Just accessing custom props in some Selenium environments
19174    // can cause a "Permission denied" exception (see raven-js#495).
19175    // Bail on wrapping and return the function as-is (defers to window.onerror).
19176    return fn;
19177  }
19178
19179  /* eslint-disable prefer-rest-params */
19180  // It is important that `sentryWrapped` is not an arrow function to preserve the context of `this`
19181  const sentryWrapped = function () {
19182    const args = Array.prototype.slice.call(arguments);
19183
19184    try {
19185      if (before && typeof before === 'function') {
19186        before.apply(this, arguments);
19187      }
19188
19189      // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
19190      const wrappedArguments = args.map((arg) => wrap(arg, options));
19191
19192      // Attempt to invoke user-land function
19193      // NOTE: If you are a Sentry user, and you are seeing this stack frame, it
19194      //       means the sentry.javascript SDK caught an error invoking your application code. This
19195      //       is expected behavior and NOT indicative of a bug with sentry.javascript.
19196      return fn.apply(this, wrappedArguments);
19197    } catch (ex) {
19198      ignoreNextOnError();
19199
19200      core.withScope(scope => {
19201        scope.addEventProcessor(event => {
19202          if (options.mechanism) {
19203            utils.addExceptionTypeValue(event, undefined, undefined);
19204            utils.addExceptionMechanism(event, options.mechanism);
19205          }
19206
19207          event.extra = {
19208            ...event.extra,
19209            arguments: args,
19210          };
19211
19212          return event;
19213        });
19214
19215        core.captureException(ex);
19216      });
19217
19218      throw ex;
19219    }
19220  };
19221  /* eslint-enable prefer-rest-params */
19222
19223  // Accessing some objects may throw
19224  // ref: https://github.com/getsentry/sentry-javascript/issues/1168
19225  try {
19226    for (const property in fn) {
19227      if (Object.prototype.hasOwnProperty.call(fn, property)) {
19228        sentryWrapped[property] = fn[property];
19229      }
19230    }
19231  } catch (_oO) {} // eslint-disable-line no-empty
19232
19233  // Signal that this function has been wrapped/filled already
19234  // for both debugging and to prevent it to being wrapped/filled twice
19235  utils.markFunctionWrapped(sentryWrapped, fn);
19236
19237  utils.addNonEnumerableProperty(fn, '__sentry_wrapped__', sentryWrapped);
19238
19239  // Restore original function name (not all browsers allow that)
19240  try {
19241    const descriptor = Object.getOwnPropertyDescriptor(sentryWrapped, 'name') ;
19242    if (descriptor.configurable) {
19243      Object.defineProperty(sentryWrapped, 'name', {
19244        get() {
19245          return fn.name;
19246        },
19247      });
19248    }
19249    // eslint-disable-next-line no-empty
19250  } catch (_oO) {}
19251
19252  return sentryWrapped;
19253}
19254
19255exports.WINDOW = WINDOW;
19256exports.ignoreNextOnError = ignoreNextOnError;
19257exports.shouldIgnoreOnError = shouldIgnoreOnError;
19258exports.wrap = wrap;
19259
19260
19261},{"@sentry-internal/tracing":209,"@sentry/core":250,"@sentry/utils":319}],223:[function(require,module,exports){
19262Object.defineProperty(exports, '__esModule', { value: true });
19263
19264const core = require('@sentry/core');
19265const helpers = require('./helpers.js');
19266const client = require('./client.js');
19267const fetch = require('./transports/fetch.js');
19268const xhr = require('./transports/xhr.js');
19269const stackParsers = require('./stack-parsers.js');
19270const eventbuilder = require('./eventbuilder.js');
19271const userfeedback = require('./userfeedback.js');
19272const sdk = require('./sdk.js');
19273const breadcrumbs = require('./integrations/breadcrumbs.js');
19274const dedupe = require('./integrations/dedupe.js');
19275const globalhandlers = require('./integrations/globalhandlers.js');
19276const httpcontext = require('./integrations/httpcontext.js');
19277const linkederrors = require('./integrations/linkederrors.js');
19278const trycatch = require('./integrations/trycatch.js');
19279const index = require('./integrations/index.js');
19280const replay = require('@sentry/replay');
19281const replayCanvas = require('@sentry-internal/replay-canvas');
19282const feedback = require('@sentry-internal/feedback');
19283const tracing = require('@sentry-internal/tracing');
19284const offline = require('./transports/offline.js');
19285const hubextensions = require('./profiling/hubextensions.js');
19286const integration = require('./profiling/integration.js');
19287
19288let windowIntegrations = {};
19289
19290// This block is needed to add compatibility with the integrations packages when used with a C
19290DN
19291if (helpers.WINDOW.Sentry && helpers.WINDOW.Sentry.Integrations) {
19292  windowIntegrations = helpers.WINDOW.Sentry.Integrations;
19293}
19294
19295/** @deprecated Import the integration function directly, e.g. `inboundFiltersIntegration()` instead of `new Integrations.InboundFilter(). */
19296const INTEGRATIONS = {
19297  ...windowIntegrations,
19298  // eslint-disable-next-line deprecation/deprecation
19299  ...core.Integrations,
19300  ...index,
19301};
19302
19303exports.FunctionToString = core.FunctionToString;
19304exports.Hub = core.Hub;
19305exports.InboundFilters = core.InboundFilters;
19306exports.ModuleMetadata = core.ModuleMetadata;
19307exports.SDK_VERSION = core.SDK_VERSION;
19308exports.SEMANTIC_ATTRIBUTE_SENTRY_OP = core.SEMANTIC_ATTRIBUTE_SENTRY_OP;
19309exports.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN;
19310exports.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = core.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE;
19311exports.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE;
19312exports.Scope = core.Scope;
19313exports.addBreadcrumb = core.addBreadcrumb;
19314exports.addEventProcessor = core.addEventProcessor;
19315exports.addGlobalEventProcessor = core.addGlobalEventProcessor;
19316exports.addIntegration = core.addIntegration;
19317exports.addTracingExtensions = core.addTracingExtensions;
19318exports.captureEvent = core.captureEvent;
19319exports.captureException = core.captureException;
19320exports.captureMessage = core.captureMessage;
19321exports.captureSession = core.captureSession;
19322exports.close = core.close;
19323exports.configureScope = core.configureScope;
19324exports.continueTrace = core.continueTrace;
19325exports.createTransport = core.createTransport;
19326exports.endSession = core.endSession;
19327exports.extractTraceparentData = core.extractTraceparentData;
19328exports.flush = core.flush;
19329exports.functionToStringIntegration = core.functionToStringIntegration;
19330exports.getActiveSpan = core.getActiveSpan;
19331exports.getActiveTransaction = core.getActiveTransaction;
19332exports.getClient = core.getClient;
19333exports.getCurrentHub = core.getCurrentHub;
19334exports.getCurrentScope = core.getCurrentScope;
19335exports.getHubFromCarrier = core.getHubFromCarrier;
19336exports.getSpanStatusFromHttpCode = core.getSpanStatusFromHttpCode;
19337exports.inboundFiltersIntegration = core.inboundFiltersIntegration;
19338exports.isInitialized = core.isInitialized;
19339exports.lastEventId = core.lastEventId;
19340exports.makeMain = core.makeMain;
19341exports.makeMultiplexedTransport = core.makeMultiplexedTransport;
19342exports.metrics = core.metrics;
19343exports.moduleMetadataIntegration = core.moduleMetadataIntegration;
19344exports.parameterize = core.parameterize;
19345exports.setContext = core.setContext;
19346exports.setCurrentClient = core.setCurrentClient;
19347exports.setExtra = core.setExtra;
19348exports.setExtras = core.setExtras;
19349exports.setHttpStatus = core.setHttpStatus;
19350exports.setMeasurement = core.setMeasurement;
19351exports.setTag = core.setTag;
19352exports.setTags = core.setTags;
19353exports.setUser = core.setUser;
19354exports.spanStatusfromHttpCode = core.spanStatusfromHttpCode;
19355exports.startInactiveSpan = core.startInactiveSpan;
19356exports.startSession = core.startSession;
19357exports.startSpan = core.startSpan;
19358exports.startSpanManual = core.startSpanManual;
19359exports.startTransaction = core.startTransaction;
19360exports.trace = core.trace;
19361exports.withActiveSpan = core.withActiveSpan;
19362exports.withIsolationScope = core.withIsolationScope;
19363exports.withScope = core.withScope;
19364exports.WINDOW = helpers.WINDOW;
19365exports.BrowserClient = client.BrowserClient;
19366exports.makeFetchTransport = fetch.makeFetchTransport;
19367exports.makeXHRTransport = xhr.makeXHRTransport;
19368exports.chromeStackLineParser = stackParsers.chromeStackLineParser;
19369exports.defaultStackLineParsers = stackParsers.defaultStackLineParsers;
19370exports.defaultStackParser = stackParsers.defaultStackParser;
19371exports.geckoStackLineParser = stackParsers.geckoStackLineParser;
19372exports.opera10StackLineParser = stackParsers.opera10StackLineParser;
19373exports.opera11StackLineParser = stackParsers.opera11StackLineParser;
19374exports.winjsStackLineParser = stackParsers.winjsStackLineParser;
19375exports.eventFromException = eventbuilder.eventFromException;
19376exports.eventFromMessage = eventbuilder.eventFromMessage;
19377exports.exceptionFromError = eventbuilder.exceptionFromError;
19378exports.createUserFeedbackEnvelope = userfeedback.createUserFeedbackEnvelope;
19379exports.captureUserFeedback = sdk.captureUserFeedback;
19380exports.defaultIntegrations = sdk.defaultIntegrations;
19381exports.forceLoad = sdk.forceLoad;
19382exports.getDefaultIntegrations = sdk.getDefaultIntegrations;
19383exports.init = sdk.init;
19384exports.onLoad = sdk.onLoad;
19385exports.showReportDialog = sdk.showReportDialog;
19386exports.wrap = sdk.wrap;
19387exports.Breadcrumbs = breadcrumbs.Breadcrumbs;
19388exports.breadcrumbsIntegration = breadcrumbs.breadcrumbsIntegration;
19389exports.Dedupe = dedupe.Dedupe;
19390exports.dedupeIntegration = dedupe.dedupeIntegration;
19391exports.GlobalHandlers = globalhandlers.GlobalHandlers;
19392exports.globalHandlersIntegration = globalhandlers.globalHandlersIntegration;
19393exports.HttpContext = httpcontext.HttpContext;
19394exports.httpContextIntegration = httpcontext.httpContextIntegration;
19395exports.LinkedErrors = linkederrors.LinkedErrors;
19396exports.linkedErrorsIntegration = linkederrors.linkedErrorsIntegration;
19397exports.TryCatch = trycatch.TryCatch;
19398exports.browserApiErrorsIntegration = trycatch.browserApiErrorsIntegration;
19399exports.Replay = replay.Replay;
19400exports.getReplay = replay.getReplay;
19401exports.replayIntegration = replay.replayIntegration;
19402exports.ReplayCanvas = replayCanvas.ReplayCanvas;
19403exports.replayCanvasIntegration = replayCanvas.replayCanvasIntegration;
19404exports.Feedback = feedback.Feedback;
19405exports.feedbackIntegration = feedback.feedbackIntegration;
19406exports.sendFeedback = feedback.sendFeedback;
19407exports.BrowserTracing = tracing.BrowserTracing;
19408exports.browserTracingIntegration = tracing.browserTracingIntegration;
19409exports.defaultRequestInstrumentationOptions = tracing.defaultRequestInstrumentationOptions;
19410exports.instrumentOutgoingRequests = tracing.instrumentOutgoingRequests;
19411exports.startBrowserTracingNavigationSpan = tracing.startBrowserTracingNavigationSpan;
19412exports.startBrowserTracingPageLoadSpan = tracing.startBrowserTracingPageLoadSpan;
19413exports.makeBrowserOfflineTransport = offline.makeBrowserOfflineTransport;
19414exports.onProfilingStartRouteTransaction = hubextensions.onProfilingStartRouteTransaction;
19415exports.BrowserProfilingIntegration = integration.BrowserProfilingIntegration;
19416exports.browserProfilingIntegration = integration.browserProfilingIntegration;
19417exports.Integrations = INTEGRATIONS;
19418
19419
19420},{"./client.js":219,"./eventbuilder.js":221,"./helpers.js":222,"./integrations/breadcrumbs.js":224,"./integrations/dedupe.js":225,"./integrations/globalhandlers.js":226,"./integrations/httpcontext.js":227,"./integrations/index.js":228,"./integrations/linkederrors.js":229,"./integrations/trycatch.js":230,"./profiling/hubextensions.js":231,"./profiling/integration.js":232,"./sdk.js":234,"./stack-parsers.js":235,"./transports/fetch.js":236,"./transports/offline.js":237,"./transports/xhr.js":239,"./userfeedback.js":240,"@sentry-internal/feedback":182,"@sentry-internal/replay-canvas":183,"@sentry-internal/tracing":209,"@sentry/core":250,"@sentry/replay":299}],224:[function(require,module,exports){
19421Object.defineProperty(exports, '__esModule', { value: true });
19422
19423const core = require('@sentry/core');
19424const utils = require('@sentry/utils');
19425const debugBuild = require('../debug-build.js');
19426const helpers = require('../helpers.js');
19427
19428/* eslint-disable max-lines */
19429
19430/** maxStringLength gets capped to prevent 100 breadcrumbs exceeding 1MB event payload size */
19431const MAX_ALLOWED_STRING_LENGTH = 1024;
19432
19433const INTEGRATION_NAME = 'Breadcrumbs';
19434
19435const _breadcrumbsIntegration = ((options = {}) => {
19436  const _options = {
19437    console: true,
19438    dom: true,
19439    fetch: true,
19440    history: true,
19441    sentry: true,
19442    xhr: true,
19443    ...options,
19444  };
19445
19446  return {
19447    name: INTEGRATION_NAME,
19448    // TODO v8: Remove this
19449    setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
19450    setup(client) {
19451      if (_options.console) {
19452        utils.addConsoleInstrumentationHandler(_getConsoleBreadcrumbHandler(client));
19453      }
19454      if (_options.dom) {
19455        utils.addClickKeypressInstrumentationHandler(_getDomBreadcrumbHandler(client, _options.dom));
19456      }
19457      if (_options.xhr) {
19458        utils.addXhrInstrumentationHandler(_getXhrBreadcrumbHandler(client));
19459      }
19460      if (_options.fetch) {
19461        utils.addFetchInstrumentationHandler(_getFetchBreadcrumbHandler(client));
19462      }
19463      if (_options.history) {
19464        utils.addHistoryInstrumentationHandler(_getHistoryBreadcrumbHandler(client));
19465      }
19466      if (_options.sentry && client.on) {
19467        client.on('beforeSendEvent', _getSentryBreadcrumbHandler(client));
19468      }
19469    },
19470  };
19471}) ;
19472
19473const breadcrumbsIntegration = core.defineIntegration(_breadcrumbsIntegration);
19474
19475/**
19476 * Default Breadcrumbs instrumentations
19477 *
19478 * @deprecated Use `breadcrumbsIntegration()` instead.
19479 */
19480// eslint-disable-next-line deprecation/deprecation
19481const Breadcrumbs = core.convertIntegrationFnToClass(INTEGRATION_NAME, breadcrumbsIntegration)
19482
19483;
19484
19485/**
19486 * Adds a breadcrumb for Sentry events or transactions if this option is enabled.
19487 */
19488function _getSentryBreadcrumbHandler(client) {
19489  return function addSentryBreadcrumb(event) {
19490    if (core.getClient() !== client) {
19491      return;
19492    }
19493
19494    core.addBreadcrumb(
19495      {
19496        category: `sentry.${event.type === 'transaction' ? 'transaction' : 'event'}`,
19497        event_id: event.event_id,
19498        level: event.level,
19499        message: utils.getEventDescription(event),
19500      },
19501      {
19502        event,
19503      },
19504    );
19505  };
19506}
19507
19508/**
19509 * A HOC that creaes a function that creates breadcrumbs from DOM API calls.
19510 * This is a HOC so that we get access to dom options in the closure.
19511 */
19512function _getDomBreadcrumbHandler(
19513  client,
19514  dom,
19515) {
19516  return function _innerDomBreadcrumb(handlerData) {
19517    if (core.getClient() !== client) {
19518      return;
19519    }
19520
19521    let target;
19522    let componentName;
19523    let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined;
19524
19525    let maxStringLength =
19526      typeof dom === 'object' && typeof dom.maxStringLength === 'number' ? dom.maxStringLength : undefined;
19527    if (maxStringLength && maxStringLength > MAX_ALLOWED_STRING_LENGTH) {
19528      debugBuild.DEBUG_BUILD &&
19529        utils.logger.warn(
19530          `\`dom.maxStringLength\` cannot exceed ${MAX_ALLOWED_STRING_LENGTH}, but a value of ${maxStringLength} was configured. Sentry will use ${MAX_ALLOWED_STRING_LENGTH} instead.`,
19531        );
19532      maxStringLength = MAX_ALLOWED_STRING_LENGTH;
19533    }
19534
19535    if (typeof keyAttrs === 'string') {
19536      keyAttrs = [keyAttrs];
19537    }
19538
19539    // Accessing event.target can throw (see getsentry/raven-js#838, #768)
19540    try {
19541      const event = handlerData.event ;
19542      const element = _isEvent(event) ? event.target : event;
19543
19544      target = utils.htmlTreeAsString(element, { keyAttrs, maxStringLength });
19545      componentName = utils.getComponentName(element);
19546    } catch (e) {
19547      target = '<unknown>';
19548    }
19549
19550    if (target.length === 0) {
19551      return;
19552    }
19553
19554    const breadcrumb = {
19555      category: `ui.${handlerData.name}`,
19556      message: target,
19557    };
19558
19559    if (componentName) {
19560      breadcrumb.data = { 'ui.component_name': componentName };
19561    }
19562
19563    core.addBreadcrumb(breadcrumb, {
19564      event: handlerData.event,
19565      name: handlerData.name,
19566      global: handlerData.global,
19567    });
19568  };
19569}
19570
19571/**
19572 * Creates breadcrumbs from console API calls
19573 */
19574function _getConsoleBreadcrumbHandler(client) {
19575  return function _consoleBreadcrumb(handlerData) {
19576    if (core.getClient() !== client) {
19577      return;
19578    }
19579
19580    const breadcrumb = {
19581      category: 'console',
19582      data: {
19583        arguments: handlerData.args,
19584        logger: 'console',
19585      },
19586      level: utils.severityLevelFromString(handlerData.level),
19587      message: utils.safeJoin(handlerData.args, ' '),
19588    };
19589
19590    if (handlerData.level === 'assert') {
19591      if (handlerData.args[0] === false) {
19592        breadcrumb.message = `Assertion failed: ${utils.safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
19593        breadcrumb.data.arguments = handlerData.args.slice(1);
19594      } else {
19595        // Don't capture a breadcrumb for passed assertions
19596        return;
19597      }
19598    }
19599
19600    core.addBreadcrumb(breadcrumb, {
19601      input: handlerData.args,
19602      level: handlerData.level,
19603    });
19604  };
19605}
19606
19607/**
19608 * Creates breadcrumbs from XHR API calls
19609 */
19610function _getXhrBreadcrumbHandler(client) {
19611  return function _xhrBreadcrumb(handlerData) {
19612    if (core.getClient() !== client) {
19613      return;
19614    }
19615
19616    const { startTimestamp, endTimestamp } = handlerData;
19617
19618    const sentryXhrData = handlerData.xhr[utils.SENTRY_XHR_DATA_KEY];
19619
19620    // We only capture complete, non-sentry requests
19621    if (!startTimestamp || !endTimestamp || !sentryXhrData) {
19622      return;
19623    }
19624
19625    const { method, url, status_code, body } = sentryXhrData;
19626
19627    const data = {
19628      method,
19629      url,
19630      status_code,
19631    };
19632
19633    const hint = {
19634      xhr: handlerData.xhr,
19635      input: body,
19636      startTimestamp,
19637      endTimestamp,
19638    };
19639
19640    core.addBreadcrumb(
19641      {
19642        category: 'xhr',
19643        data,
19644        type: 'http',
19645      },
19646      hint,
19647    );
19648  };
19649}
19650
19651/**
19652 * Creates breadcrumbs from fetch API calls
19653 */
19654function _getFetchBreadcrumbHandler(client) {
19655  return function _fetchBreadcrumb(handlerData) {
19656    if (core.getClient() !== client) {
19657      return;
19658    }
19659
19660    const { startTimestamp, endTimestamp } = handlerData;
19661
19662    // We only capture complete fetch requests
19663    if (!endTimestamp) {
19664      return;
19665    }
19666
19667    if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
19668      // We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
19669      return;
19670    }
19671
19672    if (handlerData.error) {
19673      const data = handlerData.fetchData;
19674      const hint = {
19675        data: handlerData.error,
19676        input: handlerData.args,
19677        startTimestamp,
19678        endTimestamp,
19679      };
19680
19681      core.addBreadcrumb(
19682        {
19683          category: 'fetch',
19684          data,
19685          level: 'error',
19686          type: 'http',
19687        },
19688        hint,
19689      );
19690    } else {
19691      const response = handlerData.response ;
19692      const data = {
19693        ...handlerData.fetchData,
19694        status_code: response && response.status,
19695      };
19696      const hint = {
19697        input: handlerData.args,
19698        response,
19699        startTimestamp,
19700        endTimestamp,
19701      };
19702      core.addBreadcrumb(
19703        {
19704          category: 'fetch',
19705          data,
19706          type: 'http',
19707        },
19708        hint,
19709      );
19710    }
19711  };
19712}
19713
19714/**
19715 * Creates breadcrumbs from history API calls
19716 */
19717function _getHistoryBreadcrumbHandler(client) {
19718  return function _historyBreadcrumb(handlerData) {
19719    if (core.getClient() !== client) {
19720      return;
19721    }
19722
19723    let from = handlerData.from;
19724    let to = handlerData.to;
19725    const parsedLoc = utils.parseUrl(helpers.WINDOW.location.href);
19726    let parsedFrom = from ? utils.parseUrl(from) : undefined;
19727    const parsedTo = utils.parseUrl(to);
19728
19729    // Initial pushState doesn't provide `from` information
19730    if (!parsedFrom || !parsedFrom.path) {
19731      parsedFrom = parsedLoc;
19732    }
19733
19734    // Use only the path component of the URL if the URL matches the current
19735    // document (almost all the time when using pushState)
19736    if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {
19737      to = parsedTo.relative;
19738    }
19739    if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {
19740      from = parsedFrom.relative;
19741    }
19742
19743    core.addBreadcrumb({
19744      category: 'navigation',
19745      data: {
19746        from,
19747        to,
19748      },
19749    });
19750  };
19751}
19752
19753function _isEvent(event) {
19754  return !!event && !!(event ).target;
19755}
19756
19757exports.Breadcrumbs = Breadcrumbs;
19758exports.breadcrumbsIntegration = breadcrumbsIntegration;
19759
19760
19761},{"../debug-build.js":220,"../helpers.js":222,"@sentry/core":250,"@sentry/utils":319}],225:[function(require,module,exports){
19762Object.defineProperty(exports, '__esModule', { value: true });
19763
19764const core = require('@sentry/core');
19765const utils = require('@sentry/utils');
19766const debugBuild = require('../debug-build.js');
19767
19768const INTEGRATION_NAME = 'Dedupe';
19769
19770const _dedupeIntegration = (() => {
19771  let previousEvent;
19772
19773  return {
19774    name: INTEGRATION_NAME,
19775    // TODO v8: Remove this
19776    setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
19777    processEvent(currentEvent) {
19778      // We want to ignore any non-error type events, e.g. transactions or replays
19779      // These should never be deduped, and also not be compared against as _previousEvent.
19780      if (currentEvent.type) {
19781        return currentEvent;
19782      }
19783
19784      // Juuust in case something goes wrong
vendor: 4,137 bytes, lines 19785-19937
19785      try {
19786        if (_shouldDropEvent(currentEvent, previousEvent)) {
19787          debugBuild.DEBUG_BUILD && utils.logger.warn('Event dropped due to being a duplicate of previously captured event.');
19788          return null;
19789        }
19790      } catch (_oO) {} // eslint-disable-line no-empty
19791
19792      return (previousEvent = currentEvent);
19793    },
19794  };
19795}) ;
19796
19797const dedupeIntegration = core.defineIntegration(_dedupeIntegration);
19798
19799/**
19800 * Deduplication filter.
19801 * @deprecated Use `dedupeIntegration()` instead.
19802 */
19803// eslint-disable-next-line deprecation/deprecation
19804const Dedupe = core.convertIntegrationFnToClass(INTEGRATION_NAME, dedupeIntegration)
19805
19806;
19807
19808function _shouldDropEvent(currentEvent, previousEvent) {
19809  if (!previousEvent) {
19810    return false;
19811  }
19812
19813  if (_isSameMessageEvent(currentEvent, previousEvent)) {
19814    return true;
19815  }
19816
19817  if (_isSameExceptionEvent(currentEvent, previousEvent)) {
19818    return true;
19819  }
19820
19821  return false;
19822}
19823
19824function _isSameMessageEvent(currentEvent, previousEvent) {
19825  const currentMessage = currentEvent.message;
19826  const previousMessage = previousEvent.message;
19827
19828  // If neither event has a message property, they were both exceptions, so bail out
19829  if (!currentMessage && !previousMessage) {
19830    return false;
19831  }
19832
19833  // If only one event has a stacktrace, but not the other one, they are not the same
19834  if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
19835    return false;
19836  }
19837
19838  if (currentMessage !== previousMessage) {
19839    return false;
19840  }
19841
19842  if (!_isSameFingerprint(currentEvent, previousEvent)) {
19843    return false;
19844  }
19845
19846  if (!_isSameStacktrace(currentEvent, previousEvent)) {
19847    return false;
19848  }
19849
19850  return true;
19851}
19852
19853function _isSameExceptionEvent(currentEvent, previousEvent) {
19854  const previousException = _getExceptionFromEvent(previousEvent);
19855  const currentException = _getExceptionFromEvent(currentEvent);
19856
19857  if (!previousException || !currentException) {
19858    return false;
19859  }
19860
19861  if (previousException.type !== currentException.type || previousException.value !== currentException.value) {
19862    return false;
19863  }
19864
19865  if (!_isSameFingerprint(currentEvent, previousEvent)) {
19866    return false;
19867  }
19868
19869  if (!_isSameStacktrace(currentEvent, previousEvent)) {
19870    return false;
19871  }
19872
19873  return true;
19874}
19875
19876function _isSameStacktrace(currentEvent, previousEvent) {
19877  let currentFrames = _getFramesFromEvent(currentEvent);
19878  let previousFrames = _getFramesFromEvent(previousEvent);
19879
19880  // If neither event has a stacktrace, they are assumed to be the same
19881  if (!currentFrames && !previousFrames) {
19882    return true;
19883  }
19884
19885  // If only one event has a stacktrace, but not the other one, they are not the same
19886  if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) {
19887    return false;
19888  }
19889
19890  currentFrames = currentFrames ;
19891  previousFrames = previousFrames ;
19892
19893  // If number of frames differ, they are not the same
19894  if (previousFrames.length !== currentFrames.length) {
19895    return false;
19896  }
19897
19898  // Otherwise, compare the two
19899  for (let i = 0; i < previousFrames.length; i++) {
19900    const frameA = previousFrames[i];
19901    const frameB = currentFrames[i];
19902
19903    if (
19904      frameA.filename !== frameB.filename ||
19905      frameA.lineno !== frameB.lineno ||
19906      frameA.colno !== frameB.colno ||
19907      frameA.function !== frameB.function
19908    ) {
19909      return false;
19910    }
19911  }
19912
19913  return true;
19914}
19915
19916function _isSameFingerprint(currentEvent, previousEvent) {
19917  let currentFingerprint = currentEvent.fingerprint;
19918  let previousFingerprint = previousEvent.fingerprint;
19919
19920  // If neither event has a fingerprint, they are assumed to be the same
19921  if (!currentFingerprint && !previousFingerprint) {
19922    return true;
19923  }
19924
19925  // If only one event has a fingerprint, but not the other one, they are not the same
19926  if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) {
19927    return false;
19928  }
19929
19930  currentFingerprint = currentFingerprint ;
19931  previousFingerprint = previousFingerprint ;
19932
19933  // Otherwise, compare the two
19934  try {
19935    return !!(currentFingerprint.join('') === previousFingerprint.join(''));
19936  } catch (_oO) {
19937    return false;
19938  }
19939}
19940
19941function _getExceptionFromEvent(event) {
19942  return event.exception && event.exception.values && event.exception.values[0];
19943}
19944
19945function _getFramesFromEvent(event) {
19946  const exception = event.exception;
19947
19948  if (exception) {
19949    try {
19950      // @ts-expect-error Object could be undefined
19951      return exception.values[0].stacktrace.frames;
19952    } catch (_oO) {
19953      return undefined;
19954    }
19955  }
19956  return undefined;
19957}
19958
19959exports.Dedupe = Dedupe;
19960exports.dedupeIntegration = dedupeIntegration;
19961
19962
19963},{"../debug-build.js":220,"@sentry/core":250,"@sentry/utils":319}],226:[function(require,module,exports){
19964Object.defineProperty(exports, '__esModule', { value: true });
19965
19966const core = require('@sentry/core');
19967const utils = require('@sentry/utils');
19968const debugBuild = require('../debug-build.js');
19969const eventbuilder = require('../eventbuilder.js');
19970const helpers = require('../helpers.js');
19971
19972/* eslint-disable @typescript-eslint/no-unsafe-member-access */
19973
19974const INTEGRATION_NAME = 'GlobalHandlers';
19975
19976const _globalHandlersIntegration = ((options = {}) => {
19977  const _options = {
19978    onerror: true,
19979    onunhandledrejection: true,
19980    ...options,
19981  };
19982
19983  return {
19984    name: INTEGRATION_NAME,
19985    setupOnce() {
19986      Error.stackTraceLimit = 50;
19987    },
19988    setup(client) {
19989      if (_options.onerror) {
19990        _installGlobalOnErrorHandler(client);
19991        globalHandlerLog('onerror');
19992      }
19993      if (_options.onunhandledrejection) {
19994        _installGlobalOnUnhandledRejectionHandler(client);
19995        globalHandlerLog('onunhandledrejection');
19996      }
19997    },
19998  };
19999}) ;
20000
20001const globalHandlersIntegration = core.defineIntegration(_globalHandlersIntegration);
20002
20003/**
20004 * Global handlers.
20005 * @deprecated Use `globalHandlersIntegration()` instead.
20006 */
20007// eslint-disable-next-line deprecation/deprecation
20008const GlobalHandlers = core.convertIntegrationFnToClass(
20009  INTEGRATION_NAME,
20010  globalHandlersIntegration,
20011)
20012
20013;
20014
20015function _installGlobalOnErrorHandler(client) {
20016  utils.addGlobalErrorInstrumentationHandler(data => {
20017    const { stackParser, attachStacktrace } = getOptions();
20018
20019    if (core.getClient() !== client || helpers.shouldIgnoreOnError()) {
20020      return;
20021    }
20022
20023    const { msg, url, line, column, error } = data;
20024
20025    const event =
20026      error === undefined && utils.isString(msg)
20027        ? _eventFromIncompleteOnError(msg, url, line, column)
20028        : _enhanceEventWithInitialFrame(
20029            eventbuilder.eventFromUnknownInput(stackParser, error || msg, undefined, attachStacktrace, false),
20030            url,
20031            line,
20032            column,
20033          );
20034
20035    event.level = 'error';
20036
20037    core.captureEvent(event, {
20038      originalException: error,
20039      mechanism: {
20040        handled: false,
20041        type: 'onerror',
20042      },
20043    });
20044  });
20045}
20046
20047function _installGlobalOnUnhandledRejectionHandler(client) {
20048  utils.addGlobalUnhandledRejectionInstrumentationHandler(e => {
20049    const { stackParser, attachStacktrace } = getOptions();
20050
20051    if (core.getClient() !== client || helpers.shouldIgnoreOnError()) {
20052      return;
20053    }
20054
20055    const error = _getUnhandledRejectionError(e );
20056
20057    const event = utils.isPrimitive(error)
20058      ? _eventFromRejectionWithPrimitive(error)
20059      : eventbuilder.eventFromUnknownInput(stackParser, error, undefined, attachStacktrace, true);
20060
20061    event.level = 'error';
20062
20063    core.captureEvent(event, {
20064      originalException: error,
20065      mechanism: {
20066        handled: false,
20067        type: 'onunhandledrejection',
20068      },
20069    });
20070  });
20071}
20072
20073function _getUnhandledRejectionError(error) {
20074  if (utils.isPrimitive(error)) {
20075    return error;
20076  }
20077
20078  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20079  const e = error ;
20080
20081  // dig the object of the rejection out of known event types
20082  try {
20083    // PromiseRejectionEvents store the object of the rejection under 'reason'
20084    // see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
20085    if ('reason' in e) {
20086      return e.reason;
20087    }
20088
20089    // something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents
20090    // to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
20091    // the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
20092    // see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
20093    // https://github.com/getsentry/sentry-javascript/issues/2380
20094    else if ('detail' in e && 'reason' in e.detail) {
20095      return e.detail.reason;
20096    }
20097  } catch (e2) {} // eslint-disable-line no-empty
20098
20099  return error;
20100}
20101
20102/**
20103 * Create an event from a promise rejection where the `reason` is a primitive.
20104 *
20105 * @param reason: The `reason` property of the promise rejection
20106 * @returns An Event object with an appropriate `exception` value
20107 */
20108function _eventFromRejectionWithPrimitive(reason) {
20109  return {
20110    exception: {
20111      values: [
20112        {
20113          type: 'UnhandledRejection',
20114          // String() is needed because the Primitive type includes symbols (which can't be automatically stringified)
20115          value: `Non-Error promise rejection captured with value: ${String(reason)}`,
20116        },
20117      ],
20118    },
20119  };
20120}
20121
20122/**
20123 * This function creates a stack from an old, error-less onerror handler.
20124 */
20125// eslint-disable-next-line @typescript-eslint/no-explicit-any
20126function _eventFromIncompleteOnError(msg, url, line, column) {
20127  const ERROR_TYPES_RE =
20128    /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
20129
20130  // If 'message' is ErrorEvent, get real message from inside
20131  let message = utils.isErrorEvent(msg) ? msg.message : msg;
20132  let name = 'Error';
20133
20134  const groups = message.match(ERROR_TYPES_RE);
20135  if (groups) {
20136    name = groups[1];
20137    message = groups[2];
20138  }
20139
20140  const event = {
20141    exception: {
20142      values: [
20143        {
20144          type: name,
20145          value: message,
20146        },
20147      ],
20148    },
20149  };
20150
20151  return _enhanceEventWithInitialFrame(event, url, line, column);
20152}
20153
20154// eslint-disable-next-line @typescript-eslint/no-explicit-any
20155function _enhanceEventWithInitialFrame(event, url, line, column) {
20156  // event.exception
20157  const e = (event.exception = event.exception || {});
20158  // event.exception.values
20159  const ev = (e.values = e.values || []);
20160  // event.exception.values[0]
20161  const ev0 = (ev[0] = ev[0] || {});
20162  // event.exception.values[0].stacktrace
20163  const ev0s = (ev0.stacktrace = ev0.stacktrace || {});
20164  // event.exception.values[0].stacktrace.frames
20165  const ev0sf = (ev0s.frames = ev0s.frames || []);
20166
20167  const colno = isNaN(parseInt(column, 10)) ? undefined : column;
20168  const lineno = isNaN(parseInt(line, 10)) ? undefined : line;
20169  const filename = utils.isString(url) && url.length > 0 ? url : utils.getLocationHref();
20170
20171  // event.exception.values[0].stacktrace.frames
20172  if (ev0sf.length === 0) {
20173    ev0sf.push({
20174      colno,
20175      filename,
20176      function: '?',
20177      in_app: true,
20178      lineno,
20179    });
20180  }
20181
20182  return event;
20183}
20184
20185function globalHandlerLog(type) {
20186  debugBuild.DEBUG_BUILD && utils.logger.log(`Global Handler attached: ${type}`);
20187}
20188
20189function getOptions() {
20190  const client = core.getClient();
20191  const options = (client && client.getOptions()) || {
20192    stackParser: () => [],
20193    attachStacktrace: false,
20194  };
20195  return options;
20196}
20197
20198exports.GlobalHandlers = GlobalHandlers;
20199exports.globalHandlersIntegration = globalHandlersIntegration;
20200
20201
20202},{"../debug-build.js":220,"../eventbuilder.js":221,"../helpers.js":222,"@sentry/core":250,"@sentry/utils":319}],227:[function(require,module,exports){
20203Object.defineProperty(exports, '__esModule', { value: true });
20204
20205const core = require('@sentry/core');
20206const helpers = require('../helpers.js');
20207
20208const INTEGRATION_NAME = 'HttpContext';
20209
20210const _httpContextIntegration = (() => {
20211  return {
20212    name: INTEGRATION_NAME,
20213    // TODO v8: Remove this
20214    setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
20215    preprocessEvent(event) {
20216      // if none of the information we want exists, don't bother
20217      if (!helpers.WINDOW.navigator && !helpers.WINDOW.location && !helpers.WINDOW.document) {
20218        return;
20219      }
20220
20221      // grab as much info as exists and add it to the event
20222      const url = (event.request && event.request.url) || (helpers.WINDOW.location && helpers.WINDOW.location.href);
20223      const { referrer } = helpers.WINDOW.document || {};
20224      const { userAgent } = helpers.WINDOW.navigator || {};
20225
20226      const headers = {
20227        ...(event.request && event.request.headers),
20228        ...(referrer && { Referer: referrer }),
20229        ...(userAgent && { 'User-Agent': userAgent }),
20230      };
20231      const request = { ...event.request, ...(url && { url }), headers };
20232
20233      event.request = request;
20234    },
20235  };
20236}) ;
20237
20238const httpContextIntegration = core.defineIntegration(_httpContextIntegration);
20239
20240/**
20241 * HttpContext integration collects information about HTTP request headers.
20242 * @deprecated Use `httpContextIntegration()` instead.
20243 */
20244// eslint-disable-next-line deprecation/deprecation
20245const HttpContext = core.convertIntegrationFnToClass(INTEGRATION_NAME, httpContextIntegration)
20246
20247;
20248
20249exports.HttpContext = HttpContext;
20250exports.httpContextIntegration = httpContextIntegration;
20251
20252
20253},{"../helpers.js":222,"@sentry/core":250}],228:[function(require,module,exports){
20254Object.defineProperty(exports, '__esModule', { value: true });
20255
20256const globalhandlers = require('./globalhandlers.js');
20257const trycatch = require('./trycatch.js');
20258const breadcrumbs = require('./breadcrumbs.js');
20259const linkederrors = require('./linkederrors.js');
20260const httpcontext = require('./httpcontext.js');
20261const dedupe = require('./dedupe.js');
20262
20263/* eslint-disable deprecation/deprecation */
20264
20265exports.GlobalHandlers = globalhandlers.GlobalHandlers;
20266exports.TryCatch = trycatch.TryCatch;
20267exports.Breadcrumbs = breadcrumbs.Breadcrumbs;
20268exports.LinkedErrors = linkederrors.LinkedErrors;
20269exports.HttpContext = httpcontext.HttpContext;
20270exports.Dedupe = dedupe.Dedupe;
20271
20272
20273},{"./breadcrumbs.js":224,"./dedupe.js":225,"./globalhandlers.js":226,"./httpcontext.js":227,"./linkederrors.js":229,"./trycatch.js":230}],229:[function(require,module,exports){
20274Object.defineProperty(exports, '__esModule', { value: true });
20275
20276const core = require('@sentry/core');
20277const utils = require('@sentry/utils');
20278const eventbuilder = require('../eventbuilder.js');
20279
20280const DEFAULT_KEY = 'cause';
20281const DEFAULT_LIMIT = 5;
20282
20283const INTEGRATION_NAME = 'LinkedErrors';
20284
20285const _linkedErrorsIntegration = ((options = {}) => {
20286  const limit = options.limit || DEFAULT_LIMIT;
20287  const key = options.key || DEFAULT_KEY;
20288
20289  return {
20290    name: INTEGRATION_NAME,
20291    // TODO v8: Remove this
20292    setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
20293    preprocessEvent(event, hint, client) {
20294      const options = client.getOptions();
20295
20296      utils.applyAggregateErrorsToEvent(
20297        // This differs from the LinkedErrors integration in core by using a different exceptionFromError function
20298        eventbuilder.exceptionFromError,
20299        options.stackParser,
20300        options.maxValueLength,
20301        key,
20302        limit,
20303        event,
20304        hint,
20305      );
20306    },
20307  };
20308}) ;
20309
20310const linkedErrorsIntegration = core.defineIntegration(_linkedErrorsIntegration);
20311
20312/**
20313 * Aggregrate linked errors in an event.
20314 * @deprecated Use `linkedErrorsIntegration()` instead.
20315 */
20316// eslint-disable-next-line deprecation/deprecation
20317const LinkedErrors = core.convertIntegrationFnToClass(INTEGRATION_NAME, linkedErrorsIntegration)
20318
20319;
20320
20321exports.LinkedErrors = LinkedErrors;
20322exports.linkedErrorsIntegration = linkedErrorsIntegration;
20323
20324
20325},{"../eventbuilder.js":221,"@sentry/core":250,"@sentry/utils":319}],230:[function(require,module,exports){
20326Object.defineProperty(exports, '__esModule', { value: true });
20327
20328const core = require('@sentry/core');
20329const utils = require('@sentry/utils');
20330const helpers = require('../helpers.js');
20331
20332const DEFAULT_EVENT_TARGET = [
20333  'EventTarget',
20334  'Window',
20335  'Node',
20336  'ApplicationCache',
20337  'AudioTrackList',
20338  'BroadcastChannel',
20339  'ChannelMergerNode',
20340  'CryptoOperation',
20341  'EventSource',
20342  'FileReader',
20343  'HTMLUnknownElement',
20344  'IDBDatabase',
20345  'IDBRequest',
20346  'IDBTransaction',
20347  'KeyOperation',
20348  'MediaController',
20349  'MessagePort',
20350  'ModalWindow',
20351  'Notification',
20352  'SVGElementInstance',
20353  'Screen',
20354  'SharedWorker',
20355  'TextTrack',
20356  'TextTrackCue',
20357  'TextTrackList',
20358  'WebSocket',
20359  'WebSocketWorker',
20360  'Worker',
20361  'XMLHttpRequest',
20362  'XMLHttpRequestEventTarget',
20363  'XMLHttpRequestUpload',
20364];
20365
20366const INTEGRATION_NAME = 'TryCatch';
20367
20368const _browserApiErrorsIntegration = ((options = {}) => {
20369  const _options = {
20370    XMLHttpRequest: true,
20371    eventTarget: true,
20372    requestAnimationFrame: true,
20373    setInterval: true,
20374    setTimeout: true,
20375    ...options,
20376  };
20377
20378  return {
20379    name: INTEGRATION_NAME,
20380    // TODO: This currently only works for the first client this is setup
20381    // We may want to adjust this to check for client etc.
20382    setupOnce() {
20383      if (_options.setTimeout) {
20384        utils.fill(helpers.WINDOW, 'setTimeout', _wrapTimeFunction);
20385      }
20386
20387      if (_options.setInterval) {
20388        utils.fill(helpers.WINDOW, 'setInterval', _wrapTimeFunction);
20389      }
20390
20391      if (_options.requestAnimationFrame) {
20392        utils.fill(helpers.WINDOW, 'requestAnimationFrame', _wrapRAF);
20393      }
20394
20395      if (_options.XMLHttpRequest && 'XMLHttpRequest' in helpers.WINDOW) {
20396        utils.fill(XMLHttpRequest.prototype, 'send', _wrapXHR);
20397      }
20398
20399      const eventTargetOption = _options.eventTarget;
20400      if (eventTargetOption) {
20401        const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;
20402        eventTarget.forEach(_wrapEventTarget);
20403      }
20404    },
20405  };
20406}) ;
20407
20408const browserApiErrorsIntegration = core.defineIntegration(_browserApiErrorsIntegration);
20409
20410/**
20411 * Wrap timer functions and event targets to catch errors and provide better meta data.
20412 * @deprecated Use `browserApiErrorsIntegration()` instead.
20413 */
20414// eslint-disable-next-line deprecation/deprecation
20415const TryCatch = core.convertIntegrationFnToClass(
20416  INTEGRATION_NAME,
20417  browserApiErrorsIntegration,
20418)
20419
20420;
20421
20422function _wrapTimeFunction(original) {
20423  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20424  return function ( ...args) {
20425    const originalCallback = args[0];
20426    args[0] = helpers.wrap(originalCallback, {
20427      mechanism: {
20428        data: { function: utils.getFunctionName(original) },
20429        handled: false,
20430        type: 'instrument',
20431      },
20432    });
20433    return original.apply(this, args);
20434  };
20435}
20436
20437// eslint-disable-next-line @typescript-eslint/no-explicit-any
20438function _wrapRAF(original) {
20439  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20440  return function ( callback) {
20441    // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
20442    return original.apply(this, [
20443      helpers.wrap(callback, {
20444        mechanism: {
20445          data: {
20446            function: 'requestAnimationFrame',
20447            handler: utils.getFunctionName(original),
20448          },
20449          handled: false,
20450          type: 'instrument',
20451        },
20452      }),
20453    ]);
20454  };
20455}
20456
20457function _wrapXHR(originalSend) {
20458  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20459  return function ( ...args) {
20460    // eslint-disable-next-line @typescript-eslint/no-this-alias
20461    const xhr = this;
20462    const xmlHttpRequestProps = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];
20463
20464    xmlHttpRequestProps.forEach(prop => {
20465      if (prop in xhr && typeof xhr[prop] === 'function') {
20466        // eslint-disable-next-line @typescript-eslint/no-explicit-any
20467        utils.fill(xhr, prop, function (original) {
20468          const wrapOptions = {
20469            mechanism: {
20470              data: {
20471                function: prop,
20472                handler: utils.getFunctionName(original),
20473              },
20474              handled: false,
20475              type: 'instrument',
20476            },
20477          };
20478
20479          // If Instrument integration has been called before TryCatch, get the name of original function
20480          const originalFunction = utils.getOriginalFunction(original);
20481          if (originalFunction) {
20482            wrapOptions.mechanism.data.handler = utils.getFunctionName(originalFunction);
20483          }
20484
20485          // Otherwise wrap directly
20486          return helpers.wrap(original, wrapOptions);
20487        });
20488      }
20489    });
20490
20491    return originalSend.apply(this, args);
20492  };
20493}
20494
20495function _wrapEventTarget(target) {
20496  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20497  const globalObject = helpers.WINDOW ;
20498  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
20499  const proto = globalObject[target] && globalObject[target].prototype;
20500
20501  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
20502  if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
20503    return;
20504  }
20505
20506  utils.fill(proto, 'addEventListener', function (original,)
20507
20508 {
20509    return function (
20510      // eslint-disable-next-line @typescript-eslint/no-explicit-any
20511
20512      eventName,
20513      fn,
20514      options,
20515    ) {
20516      try {
20517        if (typeof fn.handleEvent === 'function') {
20518          // ESlint disable explanation:
20519          //  First, it is generally safe to call `wrap` with an unbound function. Furthermore, using `.bind()` would
20520          //  introduce a bug here, because bind returns a new function that doesn't have our
20521          //  flags(like __sentry_original__) attached. `wrap` checks for those flags to avoid unnecessary wrapping.
20522          //  Without those flags, every call to addEventListener wraps the function again, causing a memory leak.
20523          // eslint-disable-next-line @typescript-eslint/unbound-method
20524          fn.handleEvent = helpers.wrap(fn.handleEvent, {
20525            mechanism: {
20526              data: {
20527                function: 'handleEvent',
20528                handler: utils.getFunctionName(fn),
20529                target,
20530              },
20531              handled: false,
20532              type: 'instrument',
20533            },
20534          });
20535        }
20536      } catch (err) {
20537        // can sometimes get 'Permission denied to access property "handle Event'
20538      }
20539
20540      return original.apply(this, [
20541        eventName,
20542        // eslint-disable-next-line @typescript-eslint/no-explicit-any
20543        helpers.wrap(fn , {
20544          mechanism: {
20545            data: {
20546              function: 'addEventListener',
20547              handler: utils.getFunctionName(fn),
20548              target,
20549            },
20550            handled: false,
20551            type: 'instrument',
20552          },
20553        }),
20554        options,
20555      ]);
20556    };
20557  });
20558
20559  utils.fill(
20560    proto,
20561    'removeEventListener',
20562    function (
20563      originalRemoveEventListener,
20564      // eslint-disable-next-line @typescript-eslint/no-explicit-any
20565    ) {
20566      return function (
20567        // eslint-disable-next-line @typescript-eslint/no-explicit-any
20568
20569        eventName,
20570        fn,
20571        options,
20572      ) {
20573        /**
20574         * There are 2 possible scenarios here:
20575         *
20576         * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
20577         * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
20578         * as a pass-through, and call original `removeEventListener` with it.
20579         *
20580         * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
20581         * our wrapped version of `addEventListener`, which internally calls `wrap` helper.
20582         * This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
20583         * in order for us to make a distinction between wrapped/non-wrapped functions possible.
20584         * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
20585         *
20586         * When someone adds a handler prior to initialization, and then do it again, but after,
20587         * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
20588         * to get rid of the initial handler and it'd stick there forever.
20589         */
20590        const wrappedEventHandler = fn ;
20591        try {
20592          const originalEventHandler = wrappedEventHandler && wrappedEventHandler.__sentry_wrapped__;
20593          if (originalEventHandler) {
20594            originalRemoveEventListener.call(this, eventName, originalEventHandler, options);
20595          }
20596        } catch (e) {
20597          // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
20598        }
20599        return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);
20600      };
20601    },
20602  );
20603}
20604
20605exports.TryCatch = TryCatch;
20606exports.browserApiErrorsIntegration = browserApiErrorsIntegration;
20607
20608
20609},{"../helpers.js":222,"@sentry/core":250,"@sentry/utils":319}],231:[function(require,module,exports){
20610Object.defineProperty(exports, '__esModule', { value: true });
20611
20612const core = require('@sentry/core');
20613const utils = require('@sentry/utils');
20614const debugBuild = require('../debug-build.js');
20615const helpers = require('../helpers.js');
20616const utils$1 = require('./utils.js');
20617
20618/* eslint-disable complexity */
20619
20620/**
20621 * Safety wrapper for startTransaction for the unlikely case that transaction starts before tracing is imported -
20622 * if that happens we want to avoid throwing an error from profiling code.
20623 * see https://github.com/getsentry/sentry-javascript/issues/4731.
20624 *
20625 * @experimental
20626 */
20627function onProfilingStartRouteTransaction(transaction) {
20628  if (!transaction) {
20629    if (debugBuild.DEBUG_BUILD) {
20630      utils.logger.log('[Profiling] Transaction is undefined, skipping profiling');
20631    }
20632    return transaction;
20633  }
20634
20635  if (utils$1.shouldProfileTransaction(transaction)) {
20636    return startProfileForTransaction(transaction);
20637  }
20638
20639  return transaction;
20640}
20641
20642/**
20643 * Wraps startTransaction and stopTransaction with profiling related logic.
20644 * startProfileForTransaction is called after the call to startTransaction in order to avoid our own code from
20645 * being profiled. Because of that same reason, stopProfiling is called before the call to stopTransaction.
20646 */
20647function startProfileForTransaction(transaction) {
20648  // Start the profiler and get the profiler instance.
20649  let startTimestamp;
20650  if (utils$1.isAutomatedPageLoadTransaction(transaction)) {
20651    startTimestamp = utils.timestampInSeconds() * 1000;
20652  }
20653
20654  const profiler = utils$1.startJSSelfProfile();
20655
20656  // We failed to construct the profiler, fallback to original transaction.
20657  // No need to log anything as this has already been logged in startProfile.
20658  if (!profiler) {
20659    return transaction;
20660  }
20661
20662  if (debugBuild.DEBUG_BUILD) {
20663    utils.logger.log(`[Profiling] started profiling transaction: ${core.spanToJSON(transaction).description}`);
20664  }
20665
20666  // We create "unique" transaction names to avoid concurrent transactions with same names
20667  // from being ignored by the profiler. From here on, only this transaction name should be used when
20668  // calling the profiler methods. Note: we log the original name to the user to avoid confusion.
20669  const profileId = utils.uuid4();
20670
20671  /**
20672   * Idempotent handler for profile stop
20673   */
20674  async function onProfileHandler() {
20675    // Check if the profile exists and return it the behavior has to be idempotent as users may call transaction.finish multiple times.
20676    if (!transaction) {
20677      return null;
20678    }
20679    // Satisfy the type checker, but profiler will always be defined here.
20680    if (!profiler) {
20681      return null;
20682    }
20683
20684    return profiler
20685      .stop()
20686      .then((profile) => {
20687        if (maxDurationTimeoutID) {
20688          helpers.WINDOW.clearTimeout(maxDurationTimeoutID);
20689          maxDurationTimeoutID = undefined;
20690        }
20691
20692        if (debugBuild.DEBUG_BUILD) {
20693          utils.logger.log(`[Profiling] stopped profiling of transaction: ${core.spanToJSON(transaction).description}`);
20694        }
20695
20696        // In case of an overlapping transaction, stopProfiling may return null and silently ignore the overlapping profile.
20697        if (!profile) {
20698          if (debugBuild.DEBUG_BUILD) {
20699            utils.logger.log(
20700              `[Profiling] profiler returned null profile for: ${core.spanToJSON(transaction).description}`,
20701              'this may indicate an overlapping transaction or a call to stopProfiling with a profile title that was never started',
20702            );
20703          }
20704          return null;
20705        }
20706
20707        utils$1.addProfileToGlobalCache(profileId, profile);
20708        return null;
20709      })
20710      .catch(error => {
20711        if (debugBuild.DEBUG_BUILD) {
20712          utils.logger.log('[Profiling] error while stopping profiler:', error);
20713        }
20714        return null;
20715      });
20716  }
20717
20718  // Enqueue a timeout to prevent profiles from running over max duration.
20719  let maxDurationTimeoutID = helpers.WINDOW.setTimeout(() => {
20720    if (debugBuild.DEBUG_BUILD) {
20721      utils.logger.log(
20722        '[Profiling] max profile duration elapsed, stopping profiling for:',
20723        core.spanToJSON(transaction).description,
20724      );
20725    }
20726    // If the timeout exceeds, we want to stop profiling, but not finish the transaction
20727    // eslint-disable-next-line @typescript-eslint/no-floating-promises
20728    onProfileHandler();
20729  }, utils$1.MAX_PROFILE_DURATION_MS);
20730
20731  // We need to reference the original end call to avoid creating an infinite loop
20732  const originalEnd = transaction.end.bind(transaction);
20733
20734  /**
20735   * Wraps startTransaction and stopTransaction with profiling related logic.
20736   * startProfiling is called after the call to startTransaction in order to avoid our own code from
20737   * being profiled. Because of that same reason, stopProfiling is called before the call to stopTransaction.
20738   */
20739  function profilingWrappedTransactionEnd() {
20740    if (!transaction) {
20741      return originalEnd();
20742    }
20743    // onProfileHandler should always return the same profile even if this is called multiple times.
20744    // Always call onProfileHandler to ensure stopProfiling is called and the timeout is cleared.
20745    void onProfileHandler().then(
20746      () => {
20747        // TODO: Can we rewrite this to use attributes?
20748        // eslint-disable-next-line deprecation/deprecation
20749        transaction.setContext('profile', { profile_id: profileId, start_timestamp: startTimestamp });
20750        originalEnd();
20751      },
20752      () => {
20753        // If onProfileHandler fails, we still want to call the original finish method.
20754        originalEnd();
20755      },
20756    );
20757
20758    return transaction;
20759  }
20760
20761  transaction.end = profilingWrappedTransactionEnd;
20762  return transaction;
20763}
20764
20765exports.onProfilingStartRouteTransaction = onProfilingStartRouteTransaction;
20766exports.startProfileForTransaction = startProfileForTransaction;
20767
20768
20769}
20769,{"../debug-build.js":220,"../helpers.js":222,"./utils.js":233,"@sentry/core":250,"@sentry/utils":319}],232:[function(require,module,exports){
20770Object.defineProperty(exports, '__esModule', { value: true });
20771
20772const core = require('@sentry/core');
20773const utils$1 = require('@sentry/utils');
20774const debugBuild = require('../debug-build.js');
20775const hubextensions = require('./hubextensions.js');
20776const utils = require('./utils.js');
20777
20778const INTEGRATION_NAME = 'BrowserProfiling';
20779
20780const _browserProfilingIntegration = (() => {
20781  return {
20782    name: INTEGRATION_NAME,
20783    // TODO v8: Remove this
20784    setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
20785    setup(client) {
20786      const scope = core.getCurrentScope();
20787
20788      // eslint-disable-next-line deprecation/deprecation
20789      const transaction = scope.getTransaction();
20790
20791      if (transaction && utils.isAutomatedPageLoadTransaction(transaction)) {
20792        if (utils.shouldProfileTransaction(transaction)) {
20793          hubextensions.startProfileForTransaction(transaction);
20794        }
20795      }
20796
20797      if (typeof client.on !== 'function') {
20798        utils$1.logger.warn('[Profiling] Client does not support hooks, profiling will be disabled');
20799        return;
20800      }
20801
20802      client.on('startTransaction', (transaction) => {
20803        if (utils.shouldProfileTransaction(transaction)) {
20804          hubextensions.startProfileForTransaction(transaction);
20805        }
20806      });
20807
20808      client.on('beforeEnvelope', (envelope) => {
20809        // if not profiles are in queue, there is nothing to add to the envelope.
20810        if (!utils.getActiveProfilesCount()) {
20811          return;
20812        }
20813
20814        const profiledTransactionEvents = utils.findProfiledTransactionsFromEnvelope(envelope);
20815        if (!profiledTransactionEvents.length) {
20816          return;
20817        }
20818
20819        const profilesToAddToEnvelope = [];
20820
20821        for (const profiledTransaction of profiledTransactionEvents) {
20822          const context = profiledTransaction && profiledTransaction.contexts;
20823          const profile_id = context && context['profile'] && context['profile']['profile_id'];
20824          const start_timestamp = context && context['profile'] && context['profile']['start_timestamp'];
20825
20826          if (typeof profile_id !== 'string') {
20827            debugBuild.DEBUG_BUILD && utils$1.logger.log('[Profiling] cannot find profile for a transaction without a profile context');
20828            continue;
20829          }
20830
20831          if (!profile_id) {
20832            debugBuild.DEBUG_BUILD && utils$1.logger.log('[Profiling] cannot find profile for a transaction without a profile context');
20833            continue;
20834          }
20835
20836          // Remove the profile from the transaction context before sending, relay will take care of the rest.
20837          if (context && context['profile']) {
20838            delete context.profile;
20839          }
20840
20841          const profile = utils.takeProfileFromGlobalCache(profile_id);
20842          if (!profile) {
20843            debugBuild.DEBUG_BUILD && utils$1.logger.log(`[Profiling] Could not retrieve profile for transaction: ${profile_id}`);
20844            continue;
20845          }
20846
20847          const profileEvent = utils.createProfilingEvent(
20848            profile_id,
20849            start_timestamp ,
20850            profile,
20851            profiledTransaction ,
20852          );
20853          if (profileEvent) {
20854            profilesToAddToEnvelope.push(profileEvent);
20855          }
20856        }
20857
20858        utils.addProfilesToEnvelope(envelope , profilesToAddToEnvelope);
20859      });
20860    },
20861  };
20862}) ;
20863
20864const browserProfilingIntegration = core.defineIntegration(_browserProfilingIntegration);
20865
20866/**
20867 * Browser profiling integration. Stores any event that has contexts["profile"]["profile_id"]
20868 * This exists because we do not want to await async profiler.stop calls as transaction.finish is called
20869 * in a synchronous context. Instead, we handle sending the profile async from the promise callback and
20870 * rely on being able to pull the event from the cache when we need to construct the envelope. This makes the
20871 * integration less reliable as we might be dropping profiles when the cache is full.
20872 *
20873 * @experimental
20874 * @deprecated Use `browserProfilingIntegration()` instead.
20875 */
20876// eslint-disable-next-line deprecation/deprecation
20877const BrowserProfilingIntegration = core.convertIntegrationFnToClass(
20878  INTEGRATION_NAME,
20879  browserProfilingIntegration,
20880) ;
20881
20882// eslint-disable-next-line deprecation/deprecation
20883
20884exports.BrowserProfilingIntegration = BrowserProfilingIntegration;
20885exports.browserProfilingIntegration = browserProfilingIntegration;
20886
20887
20888},{"../debug-build.js":220,"./hubextensions.js":231,"./utils.js":233,"@sentry/core":250,"@sentry/utils":319}],233:[function(require,module,exports){
20889Object.defineProperty(exports, '__esModule', { value: true });
20890
20891const core = require('@sentry/core');
20892const utils = require('@sentry/utils');
20893const debugBuild = require('../debug-build.js');
20894const helpers = require('../helpers.js');
20895
20896/* eslint-disable max-lines */
20897
20898const MS_TO_NS = 1e6;
20899// Use 0 as main thread id which is identical to threadId in node:worker_threads
20900// where main logs 0 and workers seem to log in increments of 1
20901const THREAD_ID_STRING = String(0);
20902const THREAD_NAME = 'main';
20903
20904// Machine properties (eval only once)
20905let OS_PLATFORM = '';
20906let OS_PLATFORM_VERSION = '';
20907let OS_ARCH = '';
20908let OS_BROWSER = (helpers.WINDOW.navigator && helpers.WINDOW.navigator.userAgent) || '';
20909let OS_MODEL = '';
20910const OS_LOCALE =
20911  (helpers.WINDOW.navigator && helpers.WINDOW.navigator.language) ||
20912  (helpers.WINDOW.navigator && helpers.WINDOW.navigator.languages && helpers.WINDOW.navigator.languages[0]) ||
20913  '';
20914
20915function isUserAgentData(data) {
20916  return typeof data === 'object' && data !== null && 'getHighEntropyValues' in data;
20917}
20918
20919// @ts-expect-error userAgentData is not part of the navigator interface yet
20920const userAgentData = helpers.WINDOW.navigator && helpers.WINDOW.navigator.userAgentData;
20921
20922if (isUserAgentData(userAgentData)) {
20923  userAgentData
20924    .getHighEntropyValues(['architecture', 'model', 'platform', 'platformVersion', 'fullVersionList'])
20925    .then((ua) => {
20926      OS_PLATFORM = ua.platform || '';
20927      OS_ARCH = ua.architecture || '';
20928      OS_MODEL = ua.model || '';
20929      OS_PLATFORM_VERSION = ua.platformVersion || '';
20930
20931      if (ua.fullVersionList && ua.fullVersionList.length > 0) {
20932        const firstUa = ua.fullVersionList[ua.fullVersionList.length - 1];
20933        OS_BROWSER = `${firstUa.brand} ${firstUa.version}`;
20934      }
20935    })
20936    .catch(e => void e);
20937}
20938
20939function isProcessedJSSelfProfile(profile) {
20940  return !('thread_metadata' in profile);
20941}
20942
20943// Enriches the profile with threadId of the current thread.
20944// This is done in node as we seem to not be able to get the info from C native code.
20945/**
20946 *
20947 */
20948function enrichWithThreadInformation(profile) {
20949  if (!isProcessedJSSelfProfile(profile)) {
20950    return profile;
20951  }
20952
20953  return convertJSSelfProfileToSampledFormat(profile);
20954}
20955
20956// Profile is marked as optional because it is deleted from the metadata
20957// by the integration before the event is processed by other integrations.
20958
20959function getTraceId(event) {
20960  const traceId = event && event.contexts && event.contexts['trace'] && event.contexts['trace']['trace_id'];
20961  // Log a warning if the profile has an invalid traceId (should be uuidv4).
20962  // All profiles and transactions are rejected if this is the case and we want to
20963  // warn users that this is happening if they enable debug flag
20964  if (typeof traceId === 'string' && traceId.length !== 32) {
20965    if (debugBuild.DEBUG_BUILD) {
20966      utils.logger.log(`[Profiling] Invalid traceId: ${traceId} on profiled event`);
20967    }
20968  }
20969  if (typeof traceId !== 'string') {
20970    return '';
20971  }
20972
20973  return traceId;
20974}
20975/**
20976 * Creates a profiling event envelope from a Sentry event. If profile does not pass
20977 * validation, returns null.
20978 * @param event
20979 * @param dsn
20980 * @param metadata
20981 * @param tunnel
20982 * @returns {EventEnvelope | null}
20983 */
20984
20985/**
20986 * Creates a profiling event envelope from a Sentry event.
20987 */
20988function createProfilePayload(
20989  profile_id,
20990  start_timestamp,
20991  processed_profile,
20992  event,
20993) {
20994  if (event.type !== 'transaction') {
20995    // createProfilingEventEnvelope should only be called for transactions,
20996    // we type guard this behavior with isProfiledTransactionEvent.
20997    throw new TypeError('Profiling events may only be attached to transactions, this should never occur.');
20998  }
20999
21000  if (processed_profile === undefined || processed_profile === null) {
21001    throw new TypeError(
21002      `Cannot construct profiling event envelope without a valid profile. Got ${processed_profile} instead.`,
21003    );
21004  }
21005
21006  const traceId = getTraceId(event);
21007  const enrichedThreadProfile = enrichWithThreadInformation(processed_profile);
21008  const transactionStartMs = start_timestamp
21009    ? start_timestamp
21010    : typeof event.start_timestamp === 'number'
21011      ? event.start_timestamp * 1000
21012      : Date.now();
21013  const transactionEndMs = typeof event.timestamp === 'number' ? event.timestamp * 1000 : Date.now();
21014
21015  const profile = {
21016    event_id: profile_id,
21017    timestamp: new Date(transactionStartMs).toISOString(),
21018    platform: 'javascript',
21019    version: '1',
21020    release: event.release || '',
21021    environment: event.environment || core.DEFAULT_ENVIRONMENT,
21022    runtime: {
21023      name: 'javascript',
21024      version: helpers.WINDOW.navigator.userAgent,
21025    },
21026    os: {
21027      name: OS_PLATFORM,
21028      version: OS_PLATFORM_VERSION,
21029      build_number: OS_BROWSER,
21030    },
21031    device: {
21032      locale: OS_LOCALE,
21033      model: OS_MODEL,
21034      manufacturer: OS_BROWSER,
21035      architecture: OS_ARCH,
21036      is_emulator: false,
21037    },
21038    debug_meta: {
21039      images: applyDebugMetadata(processed_profile.resources),
21040    },
21041    profile: enrichedThreadProfile,
21042    transactions: [
21043      {
21044        name: event.transaction || '',
21045        id: event.event_id || utils.uuid4(),
21046        trace_id: traceId,
21047        active_thread_id: THREAD_ID_STRING,
21048        relative_start_ns: '0',
21049        relative_end_ns: ((transactionEndMs - transactionStartMs) * 1e6).toFixed(0),
21050      },
21051    ],
21052  };
21053
21054  return profile;
21055}
21056
21057/*
21058  See packages/tracing-internal/src/browser/router.ts
21059*/
21060/**
21061 *
21062 */
21063function isAutomatedPageLoadTransaction(transaction) {
21064  return transaction.op === 'pageload';
21065}
21066
21067/**
21068 * Converts a JSSelfProfile to a our sampled format.
21069 * Does not currently perform stack indexing.
21070 */
21071function convertJSSelfProfileToSampledFormat(input) {
21072  let EMPTY_STACK_ID = undefined;
21073  let STACK_ID = 0;
21074
21075  // Initialize the profile that we will fill with data
21076  const profile = {
21077    samples: [],
21078    stacks: [],
21079    frames: [],
21080    thread_metadata: {
21081      [THREAD_ID_STRING]: { name: THREAD_NAME },
21082    },
21083  };
21084
21085  if (!input.samples.length) {
21086    return profile;
21087  }
21088
21089  // We assert samples.length > 0 above and timestamp should always be present
21090  const start = input.samples[0].timestamp;
21091  // The JS SDK might change it's time origin based on some heuristic (see See packages/utils/src/time.ts)
21092  // when that happens, we need to ensure we are correcting the profile timings so the two timelines stay in sync.
21093  // Since JS self profiling time origin is always initialized to performance.timeOrigin, we need to adjust for
21094  // the drift between the SDK selected value and our profile time origin.
21095  const origin =
21096    typeof performance.timeOrigin === 'number' ? performance.timeOrigin : utils.browserPerformanceTimeOrigin || 0;
21097  const adjustForOriginChange = origin - (utils.browserPerformanceTimeOrigin || origin);
21098
21099  for (let i = 0; i < input.samples.length; i++) {
21100    const jsSample = input.samples[i];
21101
21102    // If sample has no stack, add an empty sample
21103    if (jsSample.stackId === undefined) {
21104      if (EMPTY_STACK_ID === undefined) {
21105        EMPTY_STACK_ID = STACK_ID;
21106        profile.stacks[EMPTY_STACK_ID] = [];
21107        STACK_ID++;
21108      }
21109
21110      profile['samples'][i] = {
21111        // convert ms timestamp to ns
21112        elapsed_since_start_ns: ((jsSample.timestamp + adjustForOriginChange - start) * MS_TO_NS).toFixed(0),
21113        stack_id: EMPTY_STACK_ID,
21114        thread_id: THREAD_ID_STRING,
21115      };
21116      continue;
21117    }
21118
21119    let stackTop = input.stacks[jsSample.stackId];
21120
21121    // Functions in top->down order (root is last)
21122    // We follow the stackTop.parentId trail and collect each visited frameId
21123    const stack = [];
21124
21125    while (stackTop) {
21126      stack.push(stackTop.frameId);
21127
21128      const frame = input.frames[stackTop.frameId];
21129
21130      // If our frame has not been indexed yet, index it
21131      if (profile.frames[stackTop.frameId] === undefined) {
21132        profile.frames[stackTop.frameId] = {
21133          function: frame.name,
21134          abs_path: typeof frame.resourceId === 'number' ? input.resources[frame.resourceId] : undefined,
21135          lineno: frame.line,
21136          colno: frame.column,
21137        };
21138      }
21139
21140      stackTop = stackTop.parentId === undefined ? undefined : input.stacks[stackTop.parentId];
21141    }
21142
21143    const sample = {
21144      // convert ms timestamp to ns
21145      elapsed_since_start_ns: ((jsSample.timestamp + adjustForOriginChange - start) * MS_TO_NS).toFixed(0),
21146      stack_id: STACK_ID,
21147      thread_id: THREAD_ID_STRING,
21148    };
21149
21150    profile['stacks'][STACK_ID] = stack;
21151    profile['samples'][i] = sample;
21152    STACK_ID++;
21153  }
21154
21155  return profile;
21156}
21157
21158/**
21159 * Adds items to envelope if they are not already present - mutates the envelope.
21160 * @param envelope
21161 */
21162function addProfilesToEnvelope(envelope, profiles) {
21163  if (!profiles.length) {
21164    return envelope;
21165  }
21166
21167  for (const profile of profiles) {
21168    envelope[1].push([{ type: 'profile' }, profile]);
21169  }
21170  return envelope;
21171}
21172
21173/**
21174 * Finds transactions with profile_id context in the envelope
21175 * @param envelope
21176 * @returns
21177 */
21178function findProfiledTransactionsFromEnvelope(envelope) {
21179  const events = [];
21180
21181  utils.forEachEnvelopeItem(envelope, (item, type) => {
21182    if (type !== 'transaction') {
21183      return;
21184    }
21185
21186    for (let j = 1; j < item.length; j++) {
21187      const event = item[j] ;
21188
21189      if (event && event.contexts && event.contexts['profile'] && event.contexts['profile']['profile_id']) {
21190        events.push(item[j] );
21191      }
21192    }
21193  });
21194
21195  return events;
21196}
21197
21198const debugIdStackParserCache = new WeakMap();
21199/**
21200 * Applies debug meta data to an event from a list of paths to resources (sourcemaps)
21201 */
21202function applyDebugMetadata(resource_paths) {
21203  const debugIdMap = utils.GLOBAL_OBJ._sentryDebugIds;
21204
21205  if (!debugIdMap) {
21206    return [];
21207  }
21208
21209  const client = core.getClient();
21210  const options = client && client.getOptions();
21211  const stackParser = options && options.stackParser;
21212
21213  if (!stackParser) {
21214    return [];
21215  }
21216
21217  let debugIdStackFramesCache;
21218  const cachedDebugIdStackFrameCache = debugIdStackParserCache.get(stackParser);
21219  if (cachedDebugIdStackFrameCache) {
21220    debugIdStackFramesCache = cachedDebugIdStackFrameCache;
21221  } else {
21222    debugIdStackFramesCache = new Map();
21223    debugIdStackParserCache.set(stackParser, debugIdStackFramesCache);
21224  }
21225
21226  // Build a map of filename -> debug_id
21227  const filenameDebugIdMap = Object.keys(debugIdMap).reduce((acc, debugIdStackTrace) => {
21228    let parsedStack;
21229
21230    const cachedParsedStack = debugIdStackFramesCache.get(debugIdStackTrace);
21231    if (cachedParsedStack) {
21232      parsedStack = cachedParsedStack;
21233    } else {
21234      parsedStack = stackParser(debugIdStackTrace);
21235      debugIdStackFramesCache.set(debugIdStackTrace, parsedStack);
21236    }
21237
21238    for (let i = parsedStack.length - 1; i >= 0; i--) {
21239      const stackFrame = parsedStack[i];
21240      const file = stackFrame && stackFrame.filename;
21241
21242      if (stackFrame && file) {
21243        acc[file] = debugIdMap[debugIdStackTrace] ;
21244        break;
21245      }
21246    }
21247    return acc;
21248  }, {});
21249
21250  const images = [];
21251  for (const path of resource_paths) {
21252    if (path && filenameDebugIdMap[path]) {
21253      images.push({
21254        type: 'sourcemap',
21255        code_file: path,
21256        debug_id: filenameDebugIdMap[path] ,
21257      });
21258    }
21259  }
21260
21261  return images;
21262}
21263
21264/**
21265 * Checks the given sample rate to make sure it is valid type and value (a boolean, or a number between 0 and 1).
21266 */
21267function isValidSampleRate(rate) {
21268  // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck
21269  if ((typeof rate !== 'number' && typeof rate !== 'boolean') || (typeof rate === 'number' && isNaN(rate))) {
21270    debugBuild.DEBUG_BUILD &&
21271      utils.logger.warn(
21272        `[Profiling] Invalid sample rate. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify(
21273          rate,
21274        )} of type ${JSON.stringify(typeof rate)}.`,
21275      );
21276    return false;
21277  }
21278
21279  // Boolean sample rates are always valid
21280  if (rate === true || rate === false) {
21281    return true;
21282  }
21283
21284  // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false
21285  if (rate < 0 || rate > 1) {
21286    debugBuild.DEBUG_BUILD && utils.logger.warn(`[Profiling] Invalid sample rate. Sample rate must be between 0 and 1. Got ${rate}.`);
21287    return false;
21288  }
21289  return true;
21290}
21291
21292function isValidProfile(profile) {
21293  if (profile.samples.length < 2) {
21294    if (debugBuild.DEBUG_BUILD) {
21295      // Log a warning if the profile has less than 2 samples so users can know why
21296      // they are not seeing any profiling data and we cant avoid the back and forth
21297      // of asking them to provide us with a dump of the profile data.
21298      utils.logger.log('[Profiling] Discarding profile because it contains less than 2 samples');
21299    }
21300    return false;
21301  }
21302
21303  if (!profile.frames.length) {
21304    if (debugBuild.DEBUG_BUILD) {
21305      utils.logger.log('[Profiling] Discarding profile because it contains no frames');
21306    }
21307    return false;
21308  }
21309
21310  return true;
21311}
21312
21313// Keep a flag value to avoid re-initializing the profiler constructor. If it fails
21314// once, it will always fail and this allows us to early return.
21315let PROFILING_CONSTRUCTOR_FAILED = false;
21316const MAX_PROFILE_DURATION_MS = 30000;
21317
21318/**
21319 * Check if profiler constructor is available.
21320 * @param maybeProfiler
21321 */
21322function isJSProfilerSupported(maybeProfiler) {
21323  return typeof maybeProfiler === 'function';
21324}
21325
21326/**
21327 * Starts the profiler and returns the profiler instance.
21328 */
21329function startJSSelfProfile() {
21330  // Feature support check first
21331  const JSProfilerConstructor = helpers.WINDOW.Profiler;
21332
21333  if (!isJSProfilerSupported(JSProfilerConstructor)) {
21334    if (debugBuild.DEBUG_BUILD) {
21335      utils.logger.log(
21336        '[Profiling] Profiling is not supported by this browser, Profiler interface missing on window object.',
21337      );
21338    }
21339    return;
21340  }
21341
21342  // From initial testing, it seems that the minimum value for sampleInterval is 10ms.
21343  const samplingIntervalMS = 10;
21344  // Start the profiler
21345  const maxSamples = Math.floor(MAX_PROFILE_DURATION_MS / samplingIntervalMS);
21346
21347  // Attempt to initialize the profiler constructor, if it fails, we disable profiling for the current user session.
21348  // This is likely due to a missing 'Document-Policy': 'js-profiling' header. We do not want to throw an error if this happens
21349  // as we risk breaking the user's application, so just disable profiling and log an error.
21350  try {
21351    return new JSProfilerConstructor({ sampleInterval: samplingIntervalMS, maxBufferSize: maxSamples });
21352  } catch (e) {
21353    if (debugBuild.DEBUG_BUILD) {
21354      utils.logger.log(
21355        "[Profiling] Failed to initialize the Profiling constructor, this is likely due to a missing 'Document-Policy': 'js-profiling' header.",
21356      );
21357      utils.logger.log('[Profiling] Disabling profiling for current user session.');
21358    }
21359    PROFILING_CONSTRUCTOR_FAILED = true;
21360  }
21361
21362  return;
21363}
21364
21365/**
21366 * Determine if a profile should be profiled.
21367 */
21368function shouldProfileTransaction(transaction) {
21369  // If constructor failed once, it will always fail, so we can early return.
21370  if (PROFILING_CONSTRUCTOR_FAILED) {
21371    if (debugBuild.DEBUG_BUILD) {
21372      utils.logger.log('[Profiling] Profiling has been disabled for the duration of the current user session.');
21373    }
21374    return false;
21375  }
21376
21377  if (!transaction.isRecording()) {
21378    if (debugBuild.DEBUG_BUILD) {
21379      utils.logger.log('[Profiling] Discarding profile because transaction was not sampled.');
21380    }
21381    return false;
21382  }
21383
21384  const client = core.getClient();
21385  const options = client && client.getOptions();
21386  if (!options) {
21387    debugBuild.DEBUG_BUILD && utils.logger.log('[Profiling] Profiling disabled, no options found.');
21388    return false;
21389  }
21390
21391  // @ts-expect-error profilesSampleRate is not part of the browser options yet
21392  const profilesSampleRate = options.profilesSampleRate;
21393
21394  // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The
21395  // only valid values are booleans or numbers between 0 and 1.)
21396  if (!isValidSampleRate(profilesSampleRate)) {
21397    debugBuild.DEBUG_BUILD && utils.logger.warn('[Profiling] Discarding profile because of invalid sample rate.');
21398    return false;
21399  }
21400
21401  // if the function returned 0 (or false), or if `profileSampleRate` is 0, it's a sign the profile should be dropped
21402  if (!profilesSampleRate) {
21403    debugBuild.DEBUG_BUILD &&
21404      utils.logger.log(
21405        '[Profiling] Discarding profile because a negative sampling decision was inherited or profileSampleRate is set to 0',
21406      );
21407    return false;
21408  }
21409
21410  // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is
21411  // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.
21412  const sampled = profilesSampleRate === true ? true : Math.random() < profilesSampleRate;
21413  // Check if we should sample this profile
21414  if (!sampled) {
21415    debugBuild.DEBUG_BUILD &&
21416      utils.logger.log(
21417        `[Profiling] Discarding profile because it's not included in the random sample (sampling rate = ${Number(
21418          profilesSampleRate,
21419        )})`,
21420      );
21421    return false;
21422  }
21423
21424  return true;
21425}
21426
21427/**
21428 * Creates a profiling envelope item, if the profile does not pass validation, returns null.
21429 * @param event
21430 * @returns {Profile | null}
21431 */
21432function createProfilingEvent(
21433  profile_id,
21434  start_timestamp,
21435  profile,
21436  event,
21437) {
21438  if (!isValidProfile(profile)) {
21439    return null;
21440  }
21441
21442  return createProfilePayload(profile_id, start_timestamp, profile, event);
21443}
21444
21445// TODO (v8): We need to obtain profile ids in @sentry-internal/tracing,
21446// but we don't have access to this map because importing this map would
21447// cause a circular dependancy. We need to resolve this in v8.
21448const PROFILE_MAP = new Map();
21449/**
21450 *
21451 */
21452function getActiveProfilesCount() {
21453  return PROFILE_MAP.size;
21454}
21455
21456/**
21457 * Retrieves profile from global cache and removes it.
21458 */
21459function takeProfileFromGlobalCache(profile_id) {
21460  const profile = PROFILE_MAP.get(profile_id);
21461  if (profile) {
21462    PROFILE_MAP.delete(profile_id);
21463  }
21464  return profile;
21465}
21466/**
21467 * Adds profile to global cache and evicts the oldest profile if the cache is full.
21468 */
21469function addProfileToGlobalCache(profile_id, profile) {
21470  PROFILE_MAP.set(profile_id, profile);
21471
21472  if (PROFILE_MAP.size > 30) {
21473    const last = PROFILE_MAP.keys().next().value;
21474    PROFILE_MAP.delete(last);
21475  }
21476}
21477
21478exports.MAX_PROFILE_DURATION_MS = MAX_PROFILE_DURATION_MS;
21479exports.addProfileToGlobalCache = addProfileToGlobalCache;
21480exports.addProfilesToEnvelope = addProfilesToEnvelope;
21481exports.applyDebugMetadata = applyDebugMetadata;
21482exports.convertJSSelfProfileToSampledFormat = convertJSSelfProfileToSampledFormat;
21483exports.createProfilePayload = createProfilePayload;
21484exports.createProfilingEvent = createProfilingEvent;
21485exports.enrichWithThreadInformation = enrichWithThreadInformation;
21486exports.findProfiledTransactionsFromEnvelope = findProfiledTransactionsFromEnvelope;
21487exports.getActiveProfilesCount = getActiveProfilesCount;
21488exports.isAutomatedPageLoadTransaction = isAutomatedPageLoadTransaction;
21489exports.isValidSampleRate = isValidSampleRate;
21490exports.shouldProfileTransaction = shouldProfileTransaction;
21491exports.startJSSelfProfile = startJSSelfProfile;
21492exports.takeProfileFromGlobalCache = takeProfileFromGlobalCache;
21493
21494
21495},{"../debug-build.js":220,"../helpers.js":222,"@sentry/core":250,"@sentry/utils":319}],234:[function(require,module,exports){
21496Object.defineProperty(exports, '__esModule', { value: true });
21497
21498const core = require('@sentry/core');
21499const utils = require('@sentry/utils');
21500const client = require('./client.js');
21501const debugBuild = require('./debug-build.js');
21502const helpers = require('./helpers.js');
21503const breadcrumbs = require('./integrations/breadcrumbs.js');
21504const dedupe = require('./integrations/dedupe.js');
21505const globalhandlers = require('./integrations/globalhandlers.js');
21506const httpcontext = require('./integrations/httpcontext.js');
21507const linkederrors = require('./integrations/linkederrors.js');
21508const trycatch = require('./integrations/trycatch.js');
21509const stackParsers = require('./stack-parsers.js');
21510const fetch = require('./transports/fetch.js');
21511const xhr = require('./transports/xhr.js');
21512
21513/** @deprecated Use `getDefaultIntegrations(options)` instead. */
21514const defaultIntegrations = [
21515  core.inboundFiltersIntegration(),
21516  core.functionToStringIntegration(),
21517  trycatch.browserApiErrorsIntegration(),
21518  breadcrumbs.breadcrumbsIntegration(),
21519  globalhandlers.globalHandlersIntegration(),
21520  linkederrors.linkedErrorsIntegration(),
21521  dedupe.dedupeIntegration(),
21522  httpcontext.httpContextIntegration(),
21523];
21524
21525/** Get the default integrations for the browser SDK. */
21526function getDefaultIntegrations(_options) {
21527  // We return a copy of the defaultIntegrations here to avoid mutating this
21528  return [
21529    // eslint-disable-next-line deprecation/deprecation
21530    ...defaultIntegrations,
21531  ];
21532}
21533
21534/**
21535 * A magic string that build tooling can leverage in order to inject a release value into the SDK.
21536 */
21537
21538/**
21539 * The Sentry Browser SDK Client.
21540 *
21541 * To use this SDK, call the {@link init} function as early as possible when
21542 * loading the web page. To set context information or send manual events, use
21543 * the provided methods.
21544 *
21545 * @example
21546 *
21547 * ```
21548 *
21549 * import { init } from '@sentry/browser';
21550 *
21551 * init({
21552 *   dsn: '__DSN__',
21553 *   // ...
21554 * });
21555 * ```
21556 *
21557 * @example
21558 * ```
21559 *
21560 * import { configureScope } from '@sentry/browser';
21561 * configureScope((scope: Scope) => {
21562 *   scope.setExtra({ battery: 0.7 });
21563 *   scope.setTag({ user_mode: 'admin' });
21564 *   scope.setUser({ id: '4711' });
21565 * });
21566 * ```
21567 *
21568 * @example
21569 * ```
21570 *
21571 * import { addBreadcrumb } from '@sentry/browser';
21572 * addBreadcrumb({
21573 *   message: 'My Breadcrumb',
21574 *   // ...
21575 * });
21576 * ```
21577 *
21578 * @example
21579 *
21580 * ```
21581 *
21582 * import * as Sentry from '@sentry/browser';
21583 * Sentry.captureMessage('Hello, world!');
21584 * Sentry.captureException(new Error('Good bye'));
21585 * Sentry.captureEvent({
21586 *   message: 'Manual',
21587 *   stacktrace: [
21588 *     // ...
21589 *   ],
21590 * });
21591 * ```
21592 *
21593 * @see {@link BrowserOptions} for documentation on configuration options.
21594 */
21595function init(options = {}) {
21596  if (options.defaultIntegrations === undefined) {
21597    options.defaultIntegrations = getDefaultIntegrations();
21598  }
21599  if (options.release === undefined) {
21600    // This allows build tooling to find-and-replace __SENTRY_RELEASE__ to inject a release value
21601    if (typeof __SENTRY_RELEASE__ === 'string') {
21602      options.release = __SENTRY_RELEASE__;
21603    }
21604
21605    // This supports the variable that sentry-webpack-plugin injects
21606    if (helpers.WINDOW.SENTRY_RELEASE && helpers.WINDOW.SENTRY_RELEASE.id) {
21607      options.release = helpers.WINDOW.SENTRY_RELEASE.id;
21608    }
21609  }
21610  if (options.autoSessionTracking === undefined) {
21611    options.autoSessionTracking = true;
21612  }
21613  if (options.sendClientReports === undefined) {
21614    options.sendClientReports = true;
21615  }
21616
21617  const clientOptions = {
21618    ...options,
21619    stackParser: utils.stackParserFromStackParserOptions(options.stackParser || stackParsers.defaultStackParser),
21620    integrations: core.getIntegrationsToSetup(options),
21621    transport: options.transport || (utils.supportsFetch() ? fetch.makeFetchTransport : xhr.makeXHRTransport),
21622  };
21623
21624  core.initAndBind(client.BrowserClient, clientOptions);
21625
21626  if (options.autoSessionTracking) {
21627    startSessionTracking();
21628  }
21629}
21630
21631const showReportDialog = (
21632  // eslint-disable-next-line deprecation/deprecation
21633  options = {},
21634  // eslint-disable-next-line deprecation/deprecation
21635  hub = core.getCurrentHub(),
21636) => {
21637  // doesn't work without a document (React Native)
21638  if (!helpers.WINDOW.document) {
21639    debugBuild.DEBUG_BUILD && utils.logger.error('Global document not defined in showReportDialog call');
21640    return;
21641  }
21642
21643  // eslint-disable-next-line deprecation/deprecation
21644  const { client, scope } = hub.getStackTop();
21645  const dsn = options.dsn || (client && client.getDsn());
21646  if (!dsn) {
21647    debugBuild.DEBUG_BUILD && utils.logger.error('DSN not configured for showReportDialog call');
21648    return;
21649  }
21650
21651  if (scope) {
21652    options.user = {
21653      ...scope.getUser(),
21654      ...options.user,
21655    };
21656  }
21657
21658  // TODO(v8): Remove this entire if statement. `eventId` will be a required option.
21659  // eslint-disable-next-line deprecation/deprecation
21660  if (!options.eventId) {
21661    // eslint-disable-next-line deprecation/deprecation
21662    options.eventId = hub.lastEventId();
21663  }
21664
21665  const script = helpers.WINDOW.document.createElement('script');
21666  script.async = true;
21667  script.crossOrigin = 'anonymous';
21668  script.src = core.getReportDialogEndpoint(dsn, options);
21669
21670  if (options.onLoad) {
21671    script.onload = options.onLoad;
21672  }
21673
21674  const { onClose } = options;
21675  if (onClose) {
21676    const reportDialogClosedMessageHandler = (event) => {
21677      if (event.data === '__sentry_reportdialog_closed__') {
21678        try {
21679          onClose();
21680        } finally {
21681          helpers.WINDOW.removeEventListener('message', reportDialogClosedMessageHandler);
21682        }
21683      }
21684    };
21685    helpers.WINDOW.addEventListener('message', reportDialogClosedMessageHandler);
21686  }
21687
21688  const injectionPoint = helpers.WINDOW.document.head || helpers.WINDOW.document.body;
21689  if (injectionPoint) {
21690    injectionPoint.appendChild(script);
21691  } else {
21692    debugBuild.DEBUG_BUILD && utils.logger.error('Not injecting report dialog. No injection point found in HTML');
21693  }
21694};
21695
21696/**
21697 * This function is here to be API compatible with the loader.
21698 * @hidden
21699 */
21700function forceLoad() {
21701  // Noop
21702}
21703
21704/**
21705 * This function is here to be API compatible with the loader.
21706 * @hidden
21707 */
21708function onLoad(callback) {
21709  callback();
21710}
21711
21712/**
21713 * Wrap code within a try/catch block so the SDK is able to capture errors.
21714 *
21715 * @deprecated This function will be removed in v8.
21716 * It is not part of Sentry's official API and it's easily replaceable by using a try/catch block
21717 * and calling Sentry.captureException.
21718 *
21719 * @param fn A function to wrap.
21720 *
21721 * @returns The result of wrapped function call.
21722 */
21723// TODO(v8): Remove this function
21724// eslint-disable-next-line @typescript-eslint/no-explicit-any
21725function wrap(fn) {
21726  return helpers.wrap(fn)();
21727}
21728
21729/**
21730 * Enable automatic Session Tracking for the initial page load.
21731 */
21732function startSessionTracking() {
21733  if (typeof helpers.WINDOW.document === 'undefined') {
21734    debugBuild.DEBUG_BUILD && utils.logger.warn('Session tracking in non-browser environment with @sentry/browser is not supported.');
21735    return;
21736  }
21737
21738  // The session duration for browser sessions does not track a meaningful
21739  // concept that can be used as a metric.
21740  // Automatically captured sessions are akin to page views, and thus we
21741  // discard their duration.
21742  core.startSession({ ignoreDuration: true });
21743  core.captureSession();
21744
21745  // We want to create a session for every navigation as well
21746  utils.addHistoryInstrumentationHandler(({ from, to }) => {
21747    // Don't create an additional session for the initial route or if the location did not change
21748    if (from !== undefined && from !== to) {
21749      core.startSession({ ignoreDuration: true });
21750      core.captureSession();
21751    }
21752  });
21753}
21754
21755/**
21756 * Captures user feedback and sends it to Sentry.
21757 */
21758function captureUserFeedback(feedback) {
21759  const client = core.getClient();
21760  if (client) {
21761    client.captureUserFeedback(feedback);
21762  }
21763}
21764
21765exports.captureUserFeedback = captureUserFeedback;
21766exports.defaultIntegrations = defaultIntegrations;
21767exports.forceLoad = forceLoad;
21768exports.getDefaultIntegrations = getDefaultIntegrations;
21769exports.init = init;
21770exports.onLoad = onLoad;
21771exports.showReportDialog = showReportDialog;
21772exports.wrap = wrap;
21773
21774
21775},{"./client.js":219,"./debug-build.js":220,"./helpers.js":222,"./integrations/breadcrumbs.js":224,"./integrations/dedupe.js":225,"./integrations/globalhandlers.js":226,"./integrations/httpcontext.js":227,"./integrations/linkederrors.js":229,"./integrations/trycatch.js":230,"./stack-parsers.js":235,"./transports/fetch.js":236,"./transports/xhr.js":239,"@sentry/core":250,"@sentry/utils":319}],235:[function(require,module,exports){
21776Object.defineProperty(exports, '__esModule', { value: true });
21777
21778const utils = require('@sentry/utils');
21779
21780// global reference to slice
21781const UNKNOWN_FUNCTION = '?';
21782
21783const OPERA10_PRIORITY = 10;
21784const OPERA11_PRIORITY = 20;
21785const CHROME_PRIORITY = 30;
21786const WINJS_PRIORITY = 40;
21787const GECKO_PRIORITY = 50;
21788
21789function createFrame(filename, func, lineno, colno) {
21790  const frame = {
21791    filename,
21792    function: func,
21793    in_app: true, // All browser frames are considered in_app
21794  };
21795
21796  if (lineno !== undefined) {
21797    frame.lineno = lineno;
21798  }
21799
21800  if (colno !== undefined) {
21801    frame.colno = colno;
21802  }
21803
21804  return frame;
21805}
21806
21807// Chromium based browsers: Chrome, Brave, new Opera, new Edge
21808const chromeRegex =
21809  /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
21810const chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
21811
21812// We cannot call this variable `chrome` because it can conflict with global `chrome` variable in certain environments
21813// See: https://github.com/getsentry/sentry-javascript/issues/6880
21814const chromeStackParserFn = line => {
21815  const parts = chromeRegex.exec(line);
21816
21817  if (parts) {
21818    const isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line
21819
21820    if (isEval) {
21821      const subMatch = chromeEvalRegex.exec(parts[2]);
21822
21823      if (subMatch) {
21824        // throw out eval line/column and use top-most line/column number
21825        parts[2] = subMatch[1]; // url
21826        parts[3] = subMatch[2]; // line
21827        parts[4] = subMatch[3]; // column
21828      }
21829    }
21830
21831    // Kamil: One more hack won't hurt us right? Understanding and adding more rules on top of these regexps right now
21832    // would be way too time consuming. (TODO: Rewrite whole RegExp to be more readable)
21833    const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);
21834
21835    return createFrame(filename, func, parts[3] ? +parts[3] : undefined, parts[4] ? +parts[4] : undefined);
21836  }
21837
21838  return;
21839};
21840
21841const chromeStackLineParser = [CHROME_PRIORITY, chromeStackParserFn];
21842
21843// gecko regex: `(?:bundle|\d+\.js)`: `bundle` is for react native, `\d+\.js` also but specifically for ram bundles because it
21844// generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js
21845// We need this specific case for now because we want no other regex to match.
21846const geckoREgex =
21847  /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
21848const geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
21849
21850const gecko = line => {
21851  const parts = geckoREgex.exec(line);
21852
21853  if (parts) {
21854    const isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
21855    if (isEval) {
21856      const subMatch = geckoEvalRegex.exec(parts[3]);
21857
21858      if (subMatch) {
21859        // throw out eval line/column and use top-most line number
21860        parts[1] = parts[1] || 'eval';
21861        parts[3] = subMatch[1];
21862        parts[4] = subMatch[2];
21863        parts[5] = ''; // no column when eval
21864      }
21865    }
21866
21867    let filename = parts[3];
21868    let func = parts[1] || UNKNOWN_FUNCTION;
21869    [func, filename] = extractSafariExtensionDetails(func, filename);
21870
21871    return createFrame(filename, func, parts[4] ? +parts[4] : undefined, parts[5] ? +parts[5] : undefined);
21872  }
21873
21874  return;
21875};
21876
21877const geckoStackLineParser = [GECKO_PRIORITY, gecko];
21878
21879const winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
21880
21881const winjs = line => {
21882  const parts = winjsRegex.exec(line);
21883
21884  return parts
21885    ? createFrame(parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined)
21886    : undefined;
21887};
21888
21889const winjsStackLineParser = [WINJS_PRIORITY, winjs];
21890
21891const opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
21892
21893const opera10 = line => {
21894  const parts = opera10Regex.exec(line);
21895  return parts ? createFrame(parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1]) : undefined;
21896};
21897
21898const opera10StackLineParser = [OPERA10_PRIORITY, opera10];
21899
21900const opera11Regex =
21901  / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\(.*\))? in (.*):\s*$/i;
21902
21903const opera11 = line => {
21904  const parts = opera11Regex.exec(line);
21905  return parts ? createFrame(parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : undefined;
21906};
21907
21908const opera11StackLineParser = [OPERA11_PRIORITY, opera11];
21909
21910const defaultStackLineParsers = [chromeStackLineParser, geckoStackLineParser, winjsStackLineParser];
21911
21912const defaultStackParser = utils.createStackParser(...defaultStackLineParsers);
21913
21914/**
21915 * Safari web extensions, starting version unknown, can produce "frames-only" stacktraces.
21916 * What it means, is that instead of format like:
21917 *
21918 * Error: wat
21919 *   at function@url:row:col
21920 *   at function@url:row:col
21921 *   at function@url:row:col
21922 *
21923 * it produces something like:
21924 *
21925 *   function@url:row:col
21926 *   function@url:row:col
21927 *   function@url:row:col
21928 *
21929 * Because of that, it won't be captured by `chrome` RegExp and will fall into `Gecko` branch.
21930 * This function is extracted so that we can use it in both places without duplicating the logic.
21931 * Unfortunately "just" changing RegExp is too complicated now and making it pass all tests
21932 * and fix this case seems like an impossible, or at least way too time-consuming task.
21933 */
21934const extractSafariExtensionDetails = (func, filename) => {
21935  const isSafariExtension = func.indexOf('safari-extension') !== -1;
21936  const isSafariWebExtension = func.indexOf('safari-web-extension') !== -1;
21937
21938  return isSafariExtension || isSafariWebExtension
21939    ? [
21940        func.indexOf('@') !== -1 ? func.split('@')[0] : UNKNOWN_FUNCTION,
21941        isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`,
21942      ]
21943    : [func, filename];
21944};
21945
21946exports.chromeStackLineParser = chromeStackLineParser;
21947exports.defaultStackLineParsers = defaultStackLineParsers;
21948exports.defaultStackParser = defaultStackParser;
21949exports.geckoStackLineParser = geckoStackLineParser;
21950exports.opera10StackLineParser = opera10StackLineParser;
21951exports.opera11StackLineParser = opera11StackLineParser;
21952exports.winjsStackLineParser = winjsStackLineParser;
21953
21954
21955},{"@sentry/utils":319}],236:[function(require,module,exports){
21956Object.defineProperty(exports, '__esModule', { value: true });
21957
21958const core = require('@sentry/core');
21959const utils$1 = require('@sentry/utils');
21960const utils = require('./utils.js');
21961
21962/**
21963 * Creates a Transport that uses the Fetch API to send events to Sentry.
21964 */
21965function makeFetchTransport(
21966  options,
21967  nativeFetch = utils.getNativeFetchImplementation(),
21968) {
21969  let pendingBodySize = 0;
21970  let pendingCount = 0;
21971
21972  function makeRequest(request) {
21973    const requestSize = request.body.length;
21974    pendingBodySize += requestSize;
21975    pendingCount++;
21976
21977    const requestOptions = {
21978      body: request.body,
21979      method: 'POST',
21980      referrerPolicy: 'origin',
21981      headers: options.headers,
21982      // Outgoing requests are usually cancelled when navigating to a different page, causing a "TypeError: Failed to
21983      // fetch" error and sending a "network_error" client-outcome - in Chrome, the request status shows "(cancelled)".
21984      // The `keepalive` flag keeps outgoing requests alive, even when switching pages. We want this since we're
21985      // frequently sending events right before the user is switching pages (eg. whenfinishing navigation transactions).
21986      // Gotchas:
21987      // - `keepalive` isn't supported by Firefox
21988      // - As per spec (https://fetch.spec.whatwg.org/#http-network-or-cache-fetch):
21989      //   If the sum of contentLength and inflightKeepaliveBytes is greater than 64 kibibytes, then return a network error.
21990      //   We will therefore only activate the flag when we're below that limit.
21991      // There is also a limit of requests that can be open at the same time, so we also limit this to 15
21992      // See https://github.com/getsentry/sentry-javascript/pull/7553 for details
21993      keepalive: pendingBodySize <= 60000 && pendingCount < 15,
21994      ...options.fetchOptions,
21995    };
21996
21997    try {
21998      return nativeFetch(options.url, requestOptions).then(response => {
21999        pendingBodySize -= requestSize;
22000        pendingCount--;
22001        return {
22002          statusCode: response.status,
22003          headers: {
22004            'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),
22005            'retry-after': response.headers.get('Retry-After'),
22006          },
22007        };
22008      });
22009    } catch (e) {
22010      utils.clearCachedFetchImplementation();
22011      pendingBodySize -= requestSize;
22012      pendingCount--;
22013      return utils$1.rejectedSyncPromise(e);
22014    }
22015  }
22016
22017  return core.createTransport(options, makeRequest);
22018}
22019
22020exports.makeFetchTransport = makeFetchTransport;
22021
22022
22023},{"./utils.js":238,"@sentry/core":250,"@sentry/utils":319}],237:[function(require,module,exports){
22024Object.defineProperty(exports, '__esModule', { value: true });
22025
22026const core = require('@sentry/core');
22027const utils = require('@sentry/utils');
22028
22029// 'Store', 'promisifyRequest' and 'createStore' were originally copied from the 'idb-keyval' package before being
22030// modified and simplified: https://github.com/jakearchibald/idb-keyval
22031//
22032// At commit: 0420a704fd6cbb4225429c536b1f61112d012fca
22033// Original licence:
22034
22035// Copyright 2016, Jake Archibald
22036//
22037// Licensed under the Apache License, Version 2.0 (the "License");
22038// you may not use this file except in compliance with the License.
22039// You may obtain a copy of the License at
22040//
22041//   http://www.apache.org/licenses/LICENSE-2.0
22042//
22043// Unless required by applicable law or agreed to in writing, software
22044// distributed under the License is distributed on an "AS IS" BASIS,
22045// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22046// See the License for the specific language governing permissions and
22047// limitations under the License.
22048
22049function promisifyRequest(request) {
22050  return new Promise((resolve, reject) => {
22051    // @ts-expect-error - file size hacks
22052    request.oncomplete = request.onsuccess = () => resolve(request.result);
22053    // @ts-expect-error - file size hacks
22054    request.onabort = request.onerror = () => reject(request.error);
22055  });
22056}
22057
22058/** Create or open an IndexedDb store */
22059function createStore(dbName, storeName) {
22060  const request = indexedDB.open(dbName);
22061  request.onupgradeneeded = () => request.result.createObjectStore(storeName);
22062  const dbp = promisifyRequest(request);
22063
22064  return callback => dbp.then(db => callback(db.transaction(storeName, 'readwrite').objectStore(storeName)));
22065}
22066
22067function keys(store) {
22068  return promisifyRequest(store.getAllKeys() );
22069}
22070
22071/** Insert into the store */
22072function insert(store, value, maxQueueSize) {
22073  return store(store => {
22074    return keys(store).then(keys => {
22075      if (keys.length >= maxQueueSize) {
22076        return;
22077      }
22078
22079      // We insert with an incremented key so that the entries are popped in order
22080      store.put(value, Math.max(...keys, 0) + 1);
22081      return promisifyRequest(store.transaction);
22082    });
22083  });
22084}
22085
22086/** Pop the oldest value from the store */
22087function pop(store) {
22088  return store(store => {
22089    return keys(store).then(keys => {
22090      if (keys.length === 0) {
22091        return undefined;
22092      }
22093
22094      return promisifyRequest(store.get(keys[0])).then(value => {
22095        store.delete(keys[0]);
22096        return promisifyRequest(store.transaction).then(() => value);
22097      });
22098    });
22099  });
22100}
22101
22102function createIndexedDbStore(options) {
22103  let store;
22104
22105  // Lazily create the store only when it's needed
22106  function getStore() {
22107    if (store == undefined) {
22108      store = createStore(options.dbName || 'sentry-offline', options.storeName || 'queue');
22109    }
22110
22111    return store;
22112  }
22113
22114  return {
22115    insert: async (env) => {
22116      try {
22117        const serialized = await utils.serializeEnvelope(env, options.textEncoder);
22118        await insert(getStore(), serialized, options.maxQueueSize || 30);
22119      } catch (_) {
22120        //
22121      }
22122    },
22123    pop: async () => {
22124      try {
22125        const deserialized = await pop(getStore());
22126        if (deserialized) {
22127          return utils.parseEnvelope(
22128            deserialized,
22129            options.textEncoder || new TextEncoder(),
22130            options.textDecoder || new TextDecoder(),
22131          );
22132        }
22133      } catch (_) {
22134        //
22135      }
22136
22137      return undefined;
22138    },
22139  };
22140}
22141
22142function makeIndexedDbOfflineTransport(
22143  createTransport,
22144) {
22145  return options => createTransport({ ...options, createStore: createIndexedDbStore });
22146}
22147
22148/**
22149 * Creates a transport that uses IndexedDb to store events when offline.
22150 */
22151function makeBrowserOfflineTransport(
22152  createTransport,
22153) {
22154  return makeIndexedDbOfflineTransport(core.makeOfflineTransport(createTransport));
22155}
22156
22157exports.createStore = createStore;
22158exports.insert = insert;
22159exports.makeBrowserOfflineTransport = makeBrowserOfflineTransport;
22160exports.pop = pop;
22161
22162
22163},{"@sentry/core":250,"@sentry/utils":319}],238:[function(require,module,exports){
22164Object.defineProperty(exports, '__esModule', { value: true });
22165
22166const utils = require('@sentry/utils');
22167const debugBuild = require('../debug-build.js');
22168const helpers = require('../helpers.js');
22169
22170let cachedFetchImpl = undefined;
22171
22172/**
22173 * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers.
22174 * Whenever someone wraps the Fetch API and returns the wrong promise chain,
22175 * this chain becomes orphaned and there is no possible way to capture it's rejections
22176 * other than allowing it bubble up to this very handler. eg.
22177 *
22178 * const f = window.fetch;
22179 * window.fetch = function () {
22180 *   const p = f.apply(this, arguments);
22181 *
22182 *   p.then(function() {
22183 *     console.log('hi.');
22184 *   });
22185 *
22186 *   return p;
22187 * }
22188 *
22189 * `p.then(function () { ... })` is producing a completely separate promise chain,
22190 * however, what's returned is `p` - the result of original `fetch` call.
22191 *
22192 * This mean, that whenever we use the Fetch API to send our own requests, _and_
22193 * some ad-blocker blocks it, this orphaned chain will _always_ reject,
22194 * effectively causing another event to be captured.
22195 * This makes a whole process become an infinite loop, which we need to somehow
22196 * deal with, and break it in one way or another.
22197 *
22198 * To deal with this issue, we are making sure that we _always_ use the real
22199 * browser Fetch API, instead of relying on what `window.fetch` exposes.
22200 * The only downside to this would be missing our own requests as breadcrumbs,
22201 * but because we are already not doing this, it should be just fine.
22202 *
22203 * Possible failed fetch error messages per-browser:
22204 *
22205 * Chrome:  Failed to fetch
22206 * Edge:    Failed to Fetch
22207 * Firefox: NetworkError when attempting to fetch resource
22208 * Safari:  resource blocked by content blocker
22209 */
22210function getNativeFetchImplementation() {
22211  if (cachedFetchImpl) {
22212    return cachedFetchImpl;
22213  }
22214
22215  /* eslint-disable @typescript-eslint/unbound-method */
22216
22217  // Fast path to avoid DOM I/O
22218  if (utils.isNativeFetch(helpers.WINDOW.fetch)) {
22219    return (cachedFetchImpl = helpers.WINDOW.fetch.bind(helpers.WINDOW));
22220  }
22221
22222  const document = helpers.WINDOW.document;
22223  let fetchImpl = helpers.WINDOW.fetch;
22224  // eslint-disable-next-line deprecation/deprecation
22225  if (document && typeof document.createElement === 'function') {
22226    try {
22227      const sandbox = document.createElement('iframe');
22228      sandbox.hidden = true;
22229      document.head.appendChild(sandbox);
22230      const contentWindow = sandbox.contentWindow;
22231      if (contentWindow && contentWindow.fetch) {
22232        fetchImpl = contentWindow.fetch;
22233      }
22234      document.head.removeChild(sandbox);
22235    } catch (e) {
22236      debugBuild.DEBUG_BUILD && utils.logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e);
22237    }
22238  }
22239
22240  return (cachedFetchImpl = fetchImpl.bind(helpers.WINDOW));
22241  /* eslint-enable @typescript-eslint/unbound-method */
22242}
22243
22244/** Clears cached fetch impl */
22245function clearCachedFetchImplementation() {
22246  cachedFetchImpl = undefined;
22247}
22248
22249exports.clearCachedFetchImplementation = clearCachedFetchImplementation;
22250exports.getNativeFetchImplementation = getNativeFetchImplementation;
22251
22252
22253},{"../debug-build.js":220,"../helpers.js":222,"@sentry/utils":319}],239:[function(require,module,exports){
22254Object.defineProperty(exports, '__esModule', { value: true });
22255
22256const core = require('@sentry/core');
22257const utils = require('@sentry/utils');
22258
22259/**
22260 * The DONE ready state for XmlHttpRequest
22261 *
22262 * Defining it here as a constant b/c XMLHttpRequest.DONE is not always defined
22263 * (e.g. during testing, it is `undefined`)
22264 *
22265 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState}
22266 */
22267const XHR_READYSTATE_DONE = 4;
22268
22269/**
22270 * Creates a Transport that uses the XMLHttpRequest API to send events to Sentry.
22271 */
22272function makeXHRTransport(options) {
22273  function makeRequest(request) {
22274    return new utils.SyncPromise((resolve, reject) => {
22275      const xhr = new XMLHttpRequest();
22276
22277      xhr.onerror = reject;
22278
22279      xhr.onreadystatechange = () => {
22280        if (xhr.readyState === XHR_READYSTATE_DONE) {
22281          resolve({
22282            statusCode: xhr.status,
22283            headers: {
22284              'x-sentry-rate-limits': xhr.getResponseHeader('X-Sentry-Rate-Limits'),
22285              'retry-after': xhr.getResponseHeader('Retry-After'),
22286            },
22287          });
22288        }
22289      };
22290
22291      xhr.open('POST', options.url);
22292
22293      for (const header in options.headers) {
22294        if (Object.prototype.hasOwnProperty.call(options.headers, header)) {
22295          xhr.setRequestHeader(header, options.headers[header]);
22296        }
22297      }
22298
22299      xhr.send(request.body);
22300    });
22301  }
22302
22303  return core.createTransport(options, makeRequest);
22304}
22305
22306exports.makeXHRTransport = makeXHRTransport;
22307
22308
22309},{"@sentry/core":250,"@sentry/utils":319}],240:[function(require,module,exports){
22310Object.defineProperty(exports, '__esModule', { value: true });
22311
22312const utils = require('@sentry/utils');
22313
22314/**
22315 * Creates an envelope from a user feedback.
22316 */
22317function createUserFeedbackEnvelope(
22318  feedback,
22319  {
22320    metadata,
22321    tunnel,
22322    dsn,
22323  }
22324
22325,
22326) {
22327  const headers = {
22328    event_id: feedback.event_id,
22329    sent_at: new Date().toISOString(),
22330    ...(metadata &&
22331      metadata.sdk && {
22332        sdk: {
22333          name: metadata.sdk.name,
22334          version: metadata.sdk.version,
22335        },
22336      }),
22337    ...(!!tunnel && !!dsn && { dsn: utils.dsnToString(dsn) }),
22338  };
22339  const item = createUserFeedbackEnvelopeItem(feedback);
22340
22341  return utils.createEnvelope(headers, [item]);
22342}
22343
22344function createUserFeedbackEnvelopeItem(feedback) {
22345  const feedbackHeaders = {
22346    type: 'user_report',
22347  };
22348  return [feedbackHeaders, feedback];
22349}
22350
22351exports.createUserFeedbackEnvelope = createUserFeedbackEnvelope;
22352
22353
22354},{"@sentry/utils":319}],241:[function(require,module,exports){
22355Object.defineProperty(exports, '__esModule', { value: true });
22356
22357const utils = require('@sentry/utils');
22358
22359const SENTRY_API_VERSION = '7';
22360
22361/** Returns the prefix to construct Sentry ingestion API endpoints. */
22362function getBaseApiEndpoint(dsn) {
22363  const protocol = dsn.protocol ? `${dsn.protocol}:` : '';
22364  const port = dsn.port ? `:${dsn.port}` : '';
22365  return `${protocol}//${dsn.host}${port}${dsn.path ? `/${dsn.path}` : ''}/api/`;
22366}
22367
22368/** Returns the ingest API endpoint for target. */
22369function _getIngestEndpoint(dsn) {
22370  return `${getBaseApiEndpoint(dsn)}${dsn.projectId}/envelope/`;
22371}
22372
22373/** Returns a URL-encoded string with auth config suitable for a query string. */
22374function _encodedAuth(dsn, sdkInfo) {
22375  return utils.urlEncode({
22376    // We send only the minimum set of required information. See
22377    // https://github.com/getsentry/sentry-javascript/issues/2572.
22378    sentry_key: dsn.publicKey,
22379    sentry_version: SENTRY_API_VERSION,
22380    ...(sdkInfo && { sentry_client: `${sdkInfo.name}/${sdkInfo.version}` }),
22381  });
22382}
22383
22384/**
22385 * Returns the envelope endpoint URL with auth in the query string.
22386 *
22387 * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
22388 */
22389function getEnvelopeEndpointWithUrlEncodedAuth(
22390  dsn,
22391  // TODO (v8): Remove `tunnelOrOptions` in favor of `options`, and use the substitute code below
22392  // options: ClientOptions = {} as ClientOptions,
22393  tunnelOrOptions = {} ,
22394) {
22395  // TODO (v8): Use this code instead
22396  // const { tunnel, _metadata = {} } = options;
22397  // return tunnel ? tunnel : `${_getIngestEndpoint(dsn)}?${_encodedAuth(dsn, _metadata.sdk)}`;
22398
22399  const tunnel = typeof tunnelOrOptions === 'string' ? tunnelOrOptions : tunnelOrOptions.tunnel;
22400  const sdkInfo =
22401    typeof tunnelOrOptions === 'string' || !tunnelOrOptions._metadata ? undefined : tunnelOrOptions._metadata.sdk;
22402
22403  return tunnel ? tunnel : `${_getIngestEndpoint(dsn)}?${_encodedAuth(dsn, sdkInfo)}`;
22404}
22405
22406/** Returns the url to the report dialog endpoint. */
22407function getReportDialogEndpoint(
22408  dsnLike,
22409  dialogOptions
22410
22411,
22412) {
22413  const dsn = utils.makeDsn(dsnLike);
22414  if (!dsn) {
22415    return '';
22416  }
22417
22418  const endpoint = `${getBaseApiEndpoint(dsn)}embed/error-page/`;
22419
22420  let encodedOptions = `dsn=${utils.dsnToString(dsn)}`;
22421  for (const key in dialogOptions) {
22422    if (key === 'dsn') {
22423      continue;
22424    }
22425
22426    if (key === 'onClose') {
22427      continue;
22428    }
22429
22430    if (key === 'user') {
22431      const user = dialogOptions.user;
22432      if (!user) {
22433        continue;
22434      }
22435      if (user.name) {
22436        encodedOptions += `&name=${encodeURIComponent(user.name)}
22436`;
22437      }
22438      if (user.email) {
22439        encodedOptions += `&email=${encodeURIComponent(user.email)}`;
22440      }
22441    } else {
22442      encodedOptions += `&${encodeURIComponent(key)}=${encodeURIComponent(dialogOptions[key] )}`;
22443    }
22444  }
22445
22446  return `${endpoint}?${encodedOptions}`;
22447}
22448
22449exports.getEnvelopeEndpointWithUrlEncodedAuth = getEnvelopeEndpointWithUrlEncodedAuth;
22450exports.getReportDialogEndpoint = getReportDialogEndpoint;
22451
22452
22453},{"@sentry/utils":319}],242:[function(require,module,exports){
22454Object.defineProperty(exports, '__esModule', { value: true });
22455
22456const utils = require('@sentry/utils');
22457const api = require('./api.js');
22458const debugBuild = require('./debug-build.js');
22459const envelope = require('./envelope.js');
22460const exports$1 = require('./exports.js');
22461const hub = require('./hub.js');
22462const integration = require('./integration.js');
22463const envelope$1 = require('./metrics/envelope.js');
22464const session = require('./session.js');
22465const dynamicSamplingContext = require('./tracing/dynamicSamplingContext.js');
22466const prepareEvent = require('./utils/prepareEvent.js');
22467
22468const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured.";
22469
22470/**
22471 * Base implementation for all JavaScript SDK clients.
22472 *
22473 * Call the constructor with the corresponding options
22474 * specific to the client subclass. To access these options later, use
22475 * {@link Client.getOptions}.
22476 *
22477 * If a Dsn is specified in the options, it will be parsed and stored. Use
22478 * {@link Client.getDsn} to retrieve the Dsn at any moment. In case the Dsn is
22479 * invalid, the constructor will throw a {@link SentryException}. Note that
22480 * without a valid Dsn, the SDK will not send any events to Sentry.
22481 *
22482 * Before sending an event, it is passed through
22483 * {@link BaseClient._prepareEvent} to add SDK information and scope data
22484 * (breadcrumbs and context). To add more custom information, override this
22485 * method and extend the resulting prepared event.
22486 *
22487 * To issue automatically created events (e.g. via instrumentation), use
22488 * {@link Client.captureEvent}. It will prepare the event and pass it through
22489 * the callback lifecycle. To issue auto-breadcrumbs, use
22490 * {@link Client.addBreadcrumb}.
22491 *
22492 * @example
22493 * class NodeClient extends BaseClient<NodeOptions> {
22494 *   public constructor(options: NodeOptions) {
22495 *     super(options);
22496 *   }
22497 *
22498 *   // ...
22499 * }
22500 */
22501class BaseClient {
22502  /**
22503   * A reference to a metrics aggregator
22504   *
22505   * @experimental Note this is alpha API. It may experience breaking changes in the future.
22506   */
22507
22508  /** Options passed to the SDK. */
22509
22510  /** The client Dsn, if specified in options. Without this Dsn, the SDK will be disabled. */
22511
22512  /** Array of set up integrations. */
22513
22514  /** Indicates whether this client's integrations have been set up. */
22515
22516  /** Number of calls being processed */
22517
22518  /** Holds flushable  */
22519
22520  // eslint-disable-next-line @typescript-eslint/ban-types
22521
22522  /**
22523   * Initializes this client instance.
22524   *
22525   * @param options Options for the client.
22526   */
22527   constructor(options) {
22528    this._options = options;
22529    this._integrations = {};
22530    this._integrationsInitialized = false;
22531    this._numProcessing = 0;
22532    this._outcomes = {};
22533    this._hooks = {};
22534    this._eventProcessors = [];
22535
22536    if (options.dsn) {
22537      this._dsn = utils.makeDsn(options.dsn);
22538    } else {
22539      debugBuild.DEBUG_BUILD && utils.logger.warn('No DSN provided, client will not send events.');
22540    }
22541
22542    if (this._dsn) {
22543      const url = api.getEnvelopeEndpointWithUrlEncodedAuth(this._dsn, options);
22544      this._transport = options.transport({
22545        recordDroppedEvent: this.recordDroppedEvent.bind(this),
22546        ...options.transportOptions,
22547        url,
22548      });
22549    }
22550  }
22551
22552  /**
22553   * @inheritDoc
22554   */
22555  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
22556   captureException(exception, hint, scope) {
22557    // ensure we haven't captured this very object before
22558    if (utils.checkOrSetAlreadyCaught(exception)) {
22559      debugBuild.DEBUG_BUILD && utils.logger.log(ALREADY_SEEN_ERROR);
22560      return;
22561    }
22562
22563    let eventId = hint && hint.event_id;
22564
22565    this._process(
22566      this.eventFromException(exception, hint)
22567        .then(event => this._captureEvent(event, hint, scope))
22568        .then(result => {
22569          eventId = result;
22570        }),
22571    );
22572
22573    return eventId;
22574  }
22575
22576  /**
22577   * @inheritDoc
22578   */
22579   captureMessage(
22580    message,
22581    // eslint-disable-next-line deprecation/deprecation
22582    level,
22583    hint,
22584    scope,
22585  ) {
22586    let eventId = hint && hint.event_id;
22587
22588    const eventMessage = utils.isParameterizedString(message) ? message : 
22588String(message);
22589
22590    const promisedEvent = utils.isPrimitive(message)
22591      ? this.eventFromMessage(eventMessage, level, hint)
22592      : this.eventFromException(message, hint);
22593
22594    this._process(
22595      promisedEvent
22596        .then(event => this._captureEvent(event, hint, scope))
22597        .then(result => {
22598          eventId = result;
22599        }),
22600    );
22601
22602    return eventId;
22603  }
22604
22605  /**
22606   * @inheritDoc
22607   */
22608   captureEvent(event, hint, scope) {
22609    // ensure we haven't captured this very object before
22610    if (hint && hint.originalException && utils.checkOrSetAlreadyCaught(hint.originalException)) {
22611      debugBuild.DEBUG_BUILD && utils.logger.log(ALREADY_SEEN_ERROR);
22612      return;
22613    }
22614
22615    let eventId = hint && hint.event_id;
22616
22617    const sdkProcessingMetadata = event.sdkProcessingMetadata || {};
22618    const capturedSpanScope = sdkProcessingMetadata.capturedSpanScope;
22619
22620    this._process(
22621      this._captureEvent(event, hint, capturedSpanScope || scope).then(result => {
22622        eventId = result;
22623      }),
22624    );
22625
22626    return eventId;
22627  }
22628
22629  /**
22630   * @inheritDoc
22631   */
22632   captureSession(session$1) {
22633    if (!(typeof session$1.release === 'string')) {
22634      debugBuild.DEBUG_BUILD && utils.logger.warn('Discarded session because of missing or non-string release');
22635    } else {
22636      this.sendSession(session$1);
22637      // After sending, we set init false to indicate it's not the first occurrence
22638      session.updateSession(session$1, { init: false });
22639    }
22640  }
22641
22642  /**
22643   * @inheritDoc
22644   */
22645   getDsn() {
22646    return this._dsn;
22647  }
22648
22649  /**
22650   * @inheritDoc
22651   */
22652   getOptions() {
22653    return this._options;
22654  }
22655
22656  /**
22657   * @see SdkMetadata in @sentry/types
22658   *
22659   * @return The metadata of the SDK
22660   */
22661   getSdkMetadata() {
22662    return this._options._metadata;
22663  }
22664
22665  /**
22666   * @inheritDoc
22667   */
22668   getTransport() {
22669    return this._transport;
22670  }
22671
22672  /**
22673   * @inheritDoc
22674   */
22675   flush(timeout) {
22676    const transport = this._transport;
22677    if (transport) {
22678      if (this.metricsAggregator) {
22679        this.metricsAggregator.flush();
22680      }
22681      return this._isClientDoneProcessing(timeout).then(clientFinished => {
22682        return transport.flush(timeout).then(transportFlushed => clientFinished && transportFlushed);
22683      });
22684    } else {
22685      return utils.resolvedSyncPromise(true);
22686    }
22687  }
22688
22689  /**
22690   * @inheritDoc
22691   */
22692   close(timeout) {
22693    return this.flush(timeout).then(result => {
22694      this.getOptions().enabled = false;
22695      if (this.metricsAggregator) {
22696        this.metricsAggregator.close();
22697      }
22698      return result;
22699    });
22700  }
22701
22702  /** Get all installed event processors. */
22703   getEventProcessors() {
22704    return this._eventProcessors;
22705  }
22706
22707  /** @inheritDoc */
22708   addEventProcessor(eventProcessor) {
22709    this._eventProcessors.push(eventProcessor);
22710  }
22711
22712  /**
22713   * This is an internal function to setup all integrations that should run on the client.
22714   * @deprecated Use `client.init()` instead.
22715   */
22716   setupIntegrations(forceInitialize) {
22717    if ((forceInitialize && !this._integrationsInitialized) || (this._isEnabled() && !this._integrationsInitialized)) {
22718      this._setupIntegrations();
22719    }
22720  }
22721
22722  /** @inheritdoc */
22723   init() {
22724    if (this._isEnabled()) {
22725      this._setupIntegrations();
22726    }
22727  }
22728
22729  /**
22730   * Gets an installed integration by its `id`.
22731   *
22732   * @returns The installed integration or `undefined` if no integration with that `id` was installed.
22733   * @deprecated Use `getIntegrationByName()` instead.
22734   */
22735   getIntegrationById(integrationId) {
22736    return this.getIntegrationByName(integrationId);
22737  }
22738
22739  /**
22740   * Gets an installed integration by its name.
22741   *
22742   * @returns The installed integration or `undefined` if no integration with that `name` was installed.
22743   */
22744   getIntegrationByName(integrationName) {
22745    return this._integrations[integrationName] ;
22746  }
22747
22748  /**
22749   * Returns the client's instance of the given integration class, it any.
22750   * @deprecated Use `getIntegrationByName()` instead.
22751   */
22752   getIntegration(integration) {
22753    try {
22754      return (this._integrations[integration.id] ) || null;
22755    } catch (_oO) {
22756      debugBuild.DEBUG_BUILD && utils.logger.warn(`Cannot retrieve integration ${integration.id} from the current Client`);
22757      return null;
22758    }
22759  }
22760
22761  /**
22762   * @inheritDoc
22763   */
22764   addIntegration(integration$1) {
22765    const isAlreadyInstalled = this._integrations[integration$1.name];
22766
22767    // This hook takes care of only installing if not already installed
22768    integration.setupIntegration(this, integration$1, this._integrations);
22769    // Here we need to check manually to make sure to not run this multiple times
22770    if (!isAlreadyInstalled) {
22771      integration.afterSetupIntegrations(this, [integration$1]);
22772    }
22773  }
22774
22775  /**
22776   * @inheritDoc
22777   */
22778   sendEvent(event, hint = {}) {
22779    this.emit('beforeSendEvent', event, hint);
22780
22781    let env = envelope.createEventEnvelope(event, this._dsn, this._options._metadata, this._options.tunnel);
22782
22783    for (const attachment of hint.attachments || []) {
22784      env = utils.addItemToEnvelope(
22785        env,
22786        utils.createAttachmentEnvelopeItem(
22787          attachment,
22788          this._options.transportOptions && this._options.transportOptions.textEncoder,
22789        ),
22790      );
22791    }
22792
22793    const promise = this._sendEnvelope(env);
22794    if (promise) {
22795      promise.then(sendResponse => this.emit('afterSendEvent', event, sendResponse), null);
22796    }
22797  }
22798
22799  /**
22800   * @inheritDoc
22801   */
22802   sendSession(session) {
22803    const env = envelope.createSessionEnvelope(session, this._dsn, this._options._metadata, this._options.tunnel);
22804
22805    // _sendEnvelope should not throw
22806    // eslint-disable-next-line @typescript-eslint/no-floating-promises
22807    this._sendEnvelope(env);
22808  }
22809
22810  /**
22811   * @inheritDoc
22812   */
22813   recordDroppedEvent(reason, category, _event) {
22814    // Note: we use `event` in replay, where we overwrite this hook.
22815
22816    if (this._options.sendClientReports) {
22817      // We want to track each category (error, transaction, session, replay_event) separately
22818      // but still keep the distinction between different type of outcomes.
22819      // We could use nested maps, but it's much easier to read and type this way.
22820      // A correct type for map-based implementation if we want to go that route
22821      // would be `Partial<Record<SentryRequestType, Partial<Record<Outcome, number>>>>`
22822      // With typescript 4.1 we could even use template literal types
22823      const key = `${reason}:${category}`;
22824      debugBuild.DEBUG_BUILD && utils.logger.log(`Adding outcome: "${
22824key}"`);
22825
22826      // The following works because undefined + 1 === NaN and NaN is falsy
22827      this._outcomes[key] = this._outcomes[key] + 1 || 1;
22828    }
22829  }
22830
22831  /**
22832   * @inheritDoc
22833   */
22834   captureAggregateMetrics(metricBucketItems) {
22835    debugBuild.DEBUG_BUILD && utils.logger.log(`Flushing aggregated metrics, number of metrics: ${metricBucketItems.length}`);
22836    const metricsEnvelope = envelope$1.createMetricEnvelope(
22837      metricBucketItems,
22838      this._dsn,
22839      this._options._metadata,
22840      this._options.tunnel,
22841    );
22842
22843    // _sendEnvelope should not throw
22844    // eslint-disable-next-line @typescript-eslint/no-floating-promises
22845    this._sendEnvelope(metricsEnvelope);
22846  }
22847
22848  // Keep on() & emit() signatures in sync with types' client.ts interface
22849  /* eslint-disable @typescript-eslint/unified-signatures */
22850
22851  /** @inheritdoc */
22852
22853  /** @inheritdoc */
22854   on(hook, callback) {
22855    if (!this._hooks[hook]) {
22856      this._hooks[hook] = [];
22857    }
22858
22859    // @ts-expect-error We assue the types are correct
22860    this._hooks[hook].push(callback);
22861  }
22862
22863  /** @inheritdoc */
22864
22865  /** @inheritdoc */
22866   emit(hook, ...rest) {
22867    if (this._hooks[hook]) {
22868      this._hooks[hook].forEach(callback => callback(...rest));
22869    }
22870  }
22871
22872  /* eslint-enable @typescript-eslint/unified-signatures */
22873
22874  /** Setup integrations for this client. */
22875   _setupIntegrations() {
22876    const { integrations } = this._options;
22877    this._integrations = integration.setupIntegrations(this, integrations);
22878    integration.afterSetupIntegrations(this, integrations);
22879
22880    // TODO v8: We don't need this flag anymore
22881    this._integrationsInitialized = true;
22882  }
22883
22884  /** Updates existing session based on the provided event */
22885   _updateSessionFromEvent(session$1, event) {
22886    let crashed = false;
22887    let errored = false;
22888    const exceptions = event.exception && event.exception.values;
22889
22890    if (exceptions) {
22891      errored = true;
22892
22893      for (const ex of exceptions) {
22894        const mechanism = ex.mechanism;
22895        if (mechanism && mechanism.handled === false) {
22896          crashed = true;
22897          break;
22898        }
22899      }
22900    }
22901
22902    // A session is updated and that session update is sent in only one of the two following scenarios:
22903    // 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update
22904    // 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update
22905    const sessionNonTerminal = session$1.status === 'ok';
22906    const shouldUpdateAndSend = (sessionNonTerminal && session$1.errors === 0) || (sessionNonTerminal && crashed);
22907
22908    if (shouldUpdateAndSend) {
22909      session.updateSession(session$1, {
22910        ...(crashed && { status: 'crashed' }),
22911        errors: session$1.errors || Number(errored || crashed),
22912      });
22913      this.captureSession(session$1);
22914    }
22915  }
22916
22917  /**
22918   * Determine if the client is finished processing. Returns a promise because it will wait `timeout` ms before saying
22919   * "no" (resolving to `false`) in order to give the client a chance to potentially finish first.
22920   *
22921   * @param timeout The time, in ms, after which to resolve to `false` if the client is still busy. Passing `0` (or not
22922   * passing anything) will make the promise wait as long as it takes for processing to finish before resolving to
22923   * `true`.
22924   * @returns A promise which will resolve to `true` if processing is already done or finishes before the timeout, and
22925   * `false` otherwise
22926   */
22927   _isClientDoneProcessing(timeout) {
22928    return new utils.SyncPromise(resolve => {
22929      let ticked = 0;
22930      const tick = 1;
22931
22932      const interval = setInterval(() => {
22933        if (this._numProcessing == 0) {
22934          clearInterval(interval);
22935          resolve(true);
22936        } else {
22937          ticked += tick;
22938          if (timeout && ticked >= timeout) {
22939            clearInterval(interval);
22940            resolve(false);
22941          }
22942        }
22943      }, tick);
22944    });
22945  }
22946
22947  /** Determines whether this SDK is enabled and a transport is present. */
22948   _isEnabled() {
22949    return this.getOptions().enabled !== false && this._transport !== undefined;
22950  }
22951
22952  /**
22953   * Adds common information to events.
22954   *
22955   * The information includes release and environment from `options`,
22956   * breadcrumbs and context (extra, tags and user) from the scope.
22957   *
22958   * Information that is already present in the event is never overwritten. For
22959   * nested objects, such as the context, keys are merged.
22960   *
22961   * @param event The original event.
22962   * @param hint May contain additional information about the original exception.
22963   * @param scope A scope containing event metadata.
22964   * @returns A new event with more information.
22965   */
22966   _prepareEvent(
22967    event,
22968    hint,
22969    scope,
22970    isolationScope = hub.getIsolationScope(),
22971  ) {
22972    const options = this.getOptions();
22973    const integrations = Object.keys(this._integrations);
22974    if (!hint.integrations && integrations.length > 0) {
22975      hint.integrations = integrations;
22976    }
22977
22978    this.emit('preprocessEvent', event, hint);
22979
22980    return prepareEvent.prepareEvent(options, event, hint, scope, this, isolationScope).then(evt => {
22981      if (evt === null) {
22982        return evt;
22983      }
22984
22985      const propagationContext = {
22986        ...isolationScope.getPropagationContext(),
22987        ...(scope ? scope.getPropagationContext() : undefined),
22988      };
22989
22990      const trace = evt.contexts && evt.contexts.trace;
22991      if (!trace && propagationContext) {
22992        const { traceId: trace_id, spanId, parentSpanId, dsc } = propagationContext;
22993        evt.contexts = {
22994          trace: {
22995            trace_id,
22996            span_id: spanId,
22997            parent_span_id: parentSpanId,
22998          },
22999          ...evt.contexts,
23000        };
23001
23002        const dynamicSamplingContext$1 = dsc ? dsc : dynamicSamplingContext.getDynamicSamplingContextFromClient(trace_id, this, scope);
23003
23004        evt.sdkProcessingMetadata = {
23005          dynamicSamplingContext: dynamicSamplingContext$1,
23006          ...evt.sdkProcessingMetadata,
23007        };
23008      }
23009      return evt;
23010    });
23011  }
23012
23013  /**
23014   * Processes the event and logs an error in case of rejection
23015   * @param event
23016   * @param hint
23017   * @param scope
23018   */
23019   _captureEvent(event, hint = {}, scope) {
23020    return this._processEvent(event, hint, scope).then(
23021      finalEvent => {
23022        return finalEvent.event_id;
23023      },
23024      reason => {
23025        if (debugBuild.DEBUG_BUILD) {
23026          // If something's gone wrong, log the error as a warning. If it's just us having used a `SentryError` for
23027          // control flow, log just the message (no stack) as a log-level log.
23028          const sentryError = reason ;
23029          if (sentryError.logLevel === 'log') {
23030            utils.logger.log(sentryError.message);
23031          } else {
23032            utils.logger.warn(sentryError);
23033          }
23034        }
23035        return undefined;
23036      },
23037    );
23038  }
23039
23040  /**
23041   * Processes an event (either error or message) and sends it to Sentry.
23042   *
23043   * This also adds breadcrumbs and context information to the event. However,
23044   * platform specific meta data (such as the User's IP address) must be added
23045   * by the SDK implementor.
23046   *
23047   *
23048   * @param event The event to send to Sentry.
23049   * @param hint May contain additional information about the original exception.
23050   * @param scope A scope containing event metadata.
23051   * @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send.
23052   */
23053   _processEvent(event, hint, scope) {
23054    const options = this.getOptions();
23055    const { sampleRate } = options;
23056
23057    const isTransaction = isTransactionEvent(event);
23058    const isError = isErrorEvent(event);
23059    const eventType = event.type || 'error';
23060    const beforeSendLabel = `before send for type \`${eventType}\``;
23061
23062    // 1.0 === 100% events are sent
23063    // 0.0 === 0% events are sent
23064    // Sampling for transaction happens somewhere else
23065    if (isError && typeof sampleRate === 'number' && Math.random() > sampleRate) {
23066      this.recordDroppedEvent('sample_rate', 'error', event);
23067      return utils.rejectedSyncPromise(
23068        new utils.SentryError(
23069          `Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`,
23070          'log',
23071        ),
23072      );
23073    }
23074
23075    const dataCategory = eventType === 'replay_event' ? 'replay' : eventType;
23076
23077    const sdkProcessingMetadata = event.sdkProcessingMetadata || {};
23078    const capturedSpanIsolationScope = sdkProcessingMetadata.capturedSpanIsolationScope;
23079
23080    return this._prepareEvent(event, hint, scope, capturedSpanIsolationScope)
23081      .then(prepared => {
23082        if (prepared === null) {
23083          this.recordDroppedEvent('event_processor', dataCategory, event);
23084          throw new utils.SentryError('An event processor returned `null`, will not send event.', 'log');
23085        }
23086
23087        const isInternalException = hint.data && (hint.data ).__sentry__ === true;
23088        if (isInternalException) {
23089          return prepared;
23090        }
23091
23092        const result = processBeforeSend(options, prepared, hint);
23093        return _validateBeforeSendResult(result, beforeSendLabel);
23094      })
23095      .then(processedEvent => {
23096        if (processedEvent === null) {
23097          this.recordDroppedEvent('before_send', dataCategory, event);
23098          throw new utils.SentryError(`${beforeSendLabel} returned \`null\`, will not send event.`, 'log');
23099        }
23100
23101        const session = scope && scope.getSession();
23102        if (!isTransaction && session) {
23103          this._updateSessionFromEvent(session, processedEvent);
23104        }
23105
23106        // None of the Sentry built event processor will update transaction name,
23107        // so if the transaction name has been changed by an event processor, we know
23108        // it has to come from custom event processor added by a user
23109        const transactionInfo = processedEvent.transaction_info;
23110        if (isTransaction && transactionInfo && processedEvent.transaction !== event.transaction) {
23111          const source = 'custom';
23112          processedEvent.transaction_info = {
23113            ...transactionInfo,
23114            source,
23115          };
23116        }
23117
23118        this.sendEvent(processedEvent, hint);
23119        return processedEvent;
23120      })
23121      .then(null, reason => {
23122        if (reason instanceof utils.SentryError) {
23123          throw reason;
23124        }
23125
23126        this.captureException(reason, {
23127          data: {
23128            __sentry__: true,
23129          },
23130          originalException: reason,
23131        });
23132        throw new utils.SentryError(
23133          `Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\nReason: ${reason}`,
23134        );
23135      });
23136  }
23137
23138  /**
23139   * Occupies the client with processing and event
23140   */
23141   _process(promise) {
23142    this._numProcessing++;
23143    void promise.then(
23144      value => {
23145        this._numProcessing--;
23146        return value;
23147      },
23148      reason => {
23149        this._numProcessing--;
23150        return reason;
23151      },
23152    );
23153  }
23154
23155  /**
23156   * @inheritdoc
23157   */
23158   _sendEnvelope(envelope) {
23159    this.emit('beforeEnvelope', envelope);
23160
23161    if (this._isEnabled() && this._transport) {
23162      return this._transport.send(envelope).then(null, reason => {
23163        debugBuild.DEBUG_BUILD && utils.logger.error('Error while sending event:', reason);
23164      });
23165    } else {
23166      debugBuild.DEBUG_BUILD && utils.logger.error('Transport disabled');
23167    }
23168  }
23169
23170  /**
23171   * Clears outcomes on this client and returns them.
23172   */
23173   _clearOutcomes() {
23174    const outcomes = this._outcomes;
23175    this._outcomes = {};
23176    return Object.keys(outcomes).map(key => {
23177      const [reason, category] = key.split(':') ;
23178      return {
23179        reason,
23180        category,
23181        quantity: outcomes[key],
23182      };
23183    });
23184  }
23185
23186  /**
23187   * @inheritDoc
23188   */
23189  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
23190
23191}
23192
23193/**
23194 * Verifies that return value of configured `beforeSend` or `beforeSendTransaction` is of expected type, and returns the value if so.
23195 */
23196function _validateBeforeSendResult(
23197  beforeSendResult,
23198  beforeSendLabel,
23199) {
23200  const invalidValueError = `${beforeSendLabel} must return \`null\` or a valid event.`;
23201  if (utils.isThenable(beforeSendResult)) {
23202    return beforeSendResult.then(
23203      event => {
23204        if (!utils.isPlainObject(event) && event !== null) {
23205          throw new utils.SentryError(invalidValueError);
23206        }
23207        return event;
23208      },
23209      e => {
23210        throw new utils.SentryError(`${beforeSendLabel} rejected with ${e}`);
23211      },
23212    );
23213  } else if (!utils.isPlainObject(beforeSendResult) && beforeSendResult !== null) {
23214    throw new utils.SentryError(invalidValueError);
23215  }
23216  return beforeSendResult;
23217}
23218
23219/**
23220 * Process the matching `beforeSendXXX` callback.
23221 */
23222function processBeforeSend(
23223  options,
23224  event,
23225  hint,
23226) {
23227  const { beforeSend, beforeSendTransaction } = options;
23228
23229  if (isErrorEvent(event) && beforeSend) {
23230    return beforeSend(event, hint);
23231  }
23232
23233  if (isTransactionEvent(event) && beforeSendTransaction) {
23234    return beforeSendTransaction(event, hint);
23235  }
23236
23237  return event;
23238}
23239
23240function isErrorEvent(event) {
23241  return event.type === undefined;
23242}
23243
23244function isTransactionEvent(event) {
23245  return event.type === 'transaction';
23246}
23247
23248/**
23249 * Add an event processor to the current client.
23250 * This event processor will run for all events processed by this client.
23251 */
23252function addEventProcessor(callback) {
23253  const client = exports$1.getClient();
23254
23255  if (!client || !client.addEventProcessor) {
23256    return;
23257  }
23258
23259  client.addEventProcessor(callback);
23260}
23261
23262exports.BaseClient = BaseClient;
23263exports.addEventProcessor = addEventProcessor;
23264
23265
23266},{"./api.js":241,"./debug-build.js":245,"./envelope.js":246,"./exports.js":248,"./hub.js":249,"./integration.js":251,"./metrics/envelope.js":262,"./session.js":272,"./tracing/dynamicSamplingContext.js":275,"./utils/prepareEvent.js":295,"@sentry/utils":319}],243:[function(require,module,exports){
23267Object.defineProperty(exports, '__esModule', { value: true });
23268
23269const utils = require('@sentry/utils');
23270
23271/**
23272 * Create envelope from check in item.
23273 */
23274function createCheckInEnvelope(
23275  checkIn,
23276  dynamicSamplingContext,
23277  metadata,
23278  tunnel,
23279  dsn,
23280) {
23281  const headers = {
23282    sent_at: new Date().toISOString(),
23283  };
23284
23285  if (metadata && metadata.sdk) {
23286    headers.sdk = {
23287      name: metadata.sdk.name,
23288      version: metadata.sdk.version,
23289    };
23290  }
23291
23292  if (!!tunnel && !!dsn) {
23293    headers.dsn = utils.dsnToString(dsn);
23294  }
23295
23296  if (dynamicSamplingContext) {
23297    headers.trace = utils.dropUndefinedKeys(dynamicSamplingContext) ;
23298  }
23299
23300  const item = createCheckInEnvelopeItem(checkIn);
23301  return utils.createEnvelope(headers, [item]);
23302}
23303
23304function createCheckInEnvelopeItem(checkIn) {
23305  const checkInHeaders = {
23306    type: 'check_in',
23307  };
23308  return [checkInHeaders, checkIn];
23309}
23310
23311exports.createCheckInEnvelope = createCheckInEnvelope;
23312
23313
23314},{"@sentry/utils":319}],244:[function(require,module,exports){
23315Object.defineProperty(exports, '__esModule', { value: true });
23316
23317const DEFAULT_ENVIRONMENT = 'production';
23318
23319exports.DEFAULT_ENVIRONMENT = DEFAULT_ENVIRONMENT;
23320
23321
23322},{}],245:[function(require,module,exports){
23323arguments[4][206][0].apply(exports,arguments)
23324},{"dup":206}],246:[function(require,module,exports){
23325Object.defineProperty(exports, '__esModule', { value: true });
23326
23327const utils = require('@sentry/utils');
23328
23329/**
23330 * Apply SdkInfo (name, version, packages, integrations) to the corresponding event key.
23331 * Merge with existing data if any.
23332 **/
23333function enhanceEventWithSdkInfo(event, sdkInfo) {
23334  if (!sdkInfo) {
23335    return event;
23336  }
23337  event.sdk = event.sdk || {};
23338  event.sdk.name = event.sdk.name || sdkInfo.name;
23339  event.sdk.version = event.sdk.version || sdkInfo.version;
23340  event.sdk.integrations = [...(event.sdk.integrations || []), ...(sdkInfo.integrations || [])];
23341  event.sdk.packages = [...(event.sdk.packages || []), ...(sdkInfo.packages || [])];
23342  return event;
23343}
23344
23345/** Creates an envelope from a Session */
23346function createSessionEnvelope(
23347  session,
23348  dsn,
23349  metadata,
23350  tunnel,
23351) {
23352  const sdkInfo = utils.getSdkMetadataForEnvelopeHeader(metadata);
23353  const envelopeHeaders = {
23354    sent_at: new Date().toISOString(),
23355    ...(sdkInfo && { sdk: sdkInfo }),
23356    ...(!!tunnel && dsn && { dsn: utils.dsnToString(dsn) }),
23357  };
23358
23359  const envelopeItem =
23360    'aggregates' in session ? [{ type: 'sessions' }, session] : [{ type: 'session' }, session.toJSON()];
23361
23362  return utils.createEnvelope(envelopeHeaders, [envelopeItem]);
23363}
23364
23365/**
23366 * Create an Envelope from an event.
23367 */
23368function createEventEnvelope(
23369  event,
23370  dsn,
23371  metadata,
23372  tunnel,
23373) {
23374  const sdkInfo = utils.getSdkMetadataForEnvelopeHeader(metadata);
23375
23376  /*
23377    Note: Due to TS, event.type may be `replay_event`, theoretically.
23378    In practice, we never call `createEventEnvelope` with `replay_event` type,
23379    and we'd have to adjut a looot of types to make this work properly.
23380    We want to avoid casting this around, as that could lead to bugs (e.g. when we add another type)
23381    So the safe choice is to really guard against the replay_event type here.
23382  */
23383  const eventType = event.type && event.type !== 'replay_event' ? event.type : 'event';
23384
23385  enhanceEventWithSdkInfo(event, metadata && metadata.sdk);
23386
23387  const envelopeHeaders = utils.createEventEnvelopeHeaders(event, sdkInfo, tunnel, dsn);
23388
23389  // Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to
23390  // sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may
23391  // 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
23392  // of this `delete`, lest we miss putting it back in the next time the property is in use.)
23393  delete event.sdkProcessingMetadata;
23394
23395  const eventItem = [{ type: eventType }, event];
23396  return utils.createEnvelope(envelopeHeaders, [eventItem]);
23397}
23398
23399exports.createEventEnvelope = createEventEnvelope;
23400exports.createSessionEnvelope = createSessionEnvelope;
23401
23402
23403},{"@sentry/utils":319}],247:[function(require,module,exports){
23404Object.defineProperty(exports, '__esModule', { value: true });
23405
23406const utils = require('@sentry/utils');
23407const debugBuild = require('./debug-build.js');
23408
23409/**
23410 * Returns the global event processors.
23411 * @deprecated Global event processors will be removed in v8.
23412 */
23413function getGlobalEventProcessors() {
23414  return utils.getGlobalSingleton('globalEventProcessors', () => []);
23415}
23416
23417/**
23418 * Add a EventProcessor to be kept globally.
23419 * @deprecated Use `addEventProcessor` instead. Global event processors will be removed in v8.
23420 */
23421function addGlobalEventProcessor(callback) {
23422  // eslint-disable-next-line deprecation/deprecation
23423  getGlobalEventProcessors().push(callback);
23424}
23425
23426/**
23427 * Process an array of event processors, returning the processed event (or `null` if the event was dropped).
23428 */
23429function notifyEventProcessors(
23430  processors,
23431  event,
23432  hint,
23433  index = 0,
23434) {
23435  return new utils.SyncPromise((resolve, reject) => {
23436    const processor = processors[index];
23437    if (event === null || typeof processor !== 'function') {
23438      resolve(event);
23439    } else {
23440      const result = processor({ ...event }, hint) ;
23441
23442      debugBuild.DEBUG_BUILD && processor.id && result === null && utils.logger.log(`Event processor "${processor.id}" dropped event`);
23443
23444      if (utils.isThenable(result)) {
23445        void result
23446          .then(final => notifyEventProcessors(processors, final, hint, index + 1).then(resolve))
23447          .then(null, reject);
23448      } else {
23449        void notifyEventProcessors(processors, result, hint, index + 1)
23450          .then(resolve)
23451          .then(null, reject);
23452      }
23453    }
23454  });
23455}
23456
23457exports.addGlobalEventProcessor = addGlobalEventProcessor;
23458exports.getGlobalEventProcessors = getGlobalEventProcessors;
23459exports.notifyEventProcessors = notifyEventProcessors;
23460
23461
23462},{"./debug-build.js":245,"@sentry/utils":319}],248:[function(require,module,exports){
23463Object.defineProperty(exports, '__esModule', { value: true });
23464
23465const utils = require('@sentry/utils');
23466const constants = require('./constants.js');
23467const debugBuild = require('./debug-build.js');
23468const hub = require('./hub.js');
23469const session = require('./session.js');
23470const prepareEvent = require('./utils/prepareEvent.js');
23471
23472/**
23473 * Captures an exception event and sends it to Sentry.
23474 *
23475 * @param exception The exception to capture.
23476 * @param hint Optional additional data to attach to the Sentry event.
23477 * @returns the id of the captured Sentry event.
23478 */
23479function captureException(
23480  // eslint-disable-next-line @typescript-eslint/no-explicit-any
23481  exception,
23482  hint,
23483) {
23484  // eslint-disable-next-line deprecation/deprecation
23485  return hub.getCurrentHub().captureException(exception, prepareEvent.parseEventHintOrCaptureContext(hint));
23486}
23487
23488/**
23489 * Captures a message event and sends it to Sentry.
23490 *
23491 * @param exception The exception to capture.
23492 * @param captureContext Define the level of the message or pass in additional data to attach to the message.
23493 * @returns the id of the captured message.
23494 */
23495function captureMessage(
23496  message,
23497  // eslint-disable-next-line deprecation/deprecation
23498  captureContext,
23499) {
23500  // This is necessary to provide explicit scopes upgrade, without changing the original
23501  // arity of the `captureMessage(message, level)` method.
23502  const level = typeof captureContext === 'string' ? captureContext : undefined;
23503  const context = typeof captureContext !== 'string' ? { captureContext } : undefined;
23504  // eslint-disable-next-line deprecation/deprecation
23505  return hub.getCurrentHub().captureMessage(message, level, context);
23506}
23507
23508/**
23509 * Captures a manually created event and sends it to Sentry.
23510 *
23511 * @param exception The event to send to Sentry.
23512 * @param hint Optional additional data to attach to the Sentry event.
23513 * @returns the id of the captured event.
23514 */
23515function captureEvent(event, hint) {
23516  // eslint-disable-next-line deprecation/deprecation
23517  return hub.getCurrentHub().captureEvent(event, hint);
23518}
23519
23520/**
23521 * Callback to set context information onto the scope.
23522 * @param callback Callback function that receives Scope.
23523 *
23524 * @deprecated Use getCurrentScope() directly.
23525 */
23526function configureScope(callback) {
23527  // eslint-disable-next-line deprecation/deprecation
23528  hub.getCurrentHub().configureScope(callback);
23529}
23530
23531/**
23532 * Records a new breadcrumb which will be attached to future events.
23533 *
23534 * Breadcrumbs will be added to subsequent events to provide more context on
23535 * user's actions prior to an error or crash.
23536 *
23537 * @param breadcrumb The breadcrumb to record.
23538 */
23539function addBreadcrumb(breadcrumb, hint) {
23540  // eslint-disable-next-line deprecation/deprecation
23541  hub.getCurrentHub().addBreadcrumb(breadcrumb, hint);
23542}
23543
23544/**
23545 * Sets context data with the given name.
23546 * @param name of the context
23547 * @param context Any kind of data. This data will be normalized.
23548 */
23549// eslint-disable-next-line @typescript-eslint/no-explicit-any
23550function setContext(name, context) {
23551  // eslint-disable-next-line deprecation/deprecation
23552  hub.getCurrentHub().setContext(name, context);
23553}
23554
23555/**
23556 * Set an object that will be merged sent as extra data with the event.
23557 * @param extras Extras object to merge into current context.
23558 */
23559function setExtras(extras) {
23560  // eslint-disable-next-line deprecation/deprecation
23561  hub.getCurrentHub().setExtras(extras);
23562}
23563
23564/**
23565 * Set key:value that will be sent as extra data with the event.
23566 * @param key String of extra
23567 * @param extra Any kind of data. This data will be normalized.
23568 */
23569function setExtra(key, extra) {
23570  // eslint-disable-next-line deprecation/deprecation
23571  hub.getCurrentHub().setExtra(key, extra);
23572}
23573
23574/**
23575 * Set an object that will be merged sent as tags data with the event.
23576 * @param tags Tags context object to merge into current context.
23577 */
23578function setTags(tags) {
23579  // eslint-disable-next-line deprecation/deprecation
23580  hub.getCurrentHub().setTags(tags);
23581}
23582
23583/**
23584 * Set key:value that will be sent as tags data with the event.
23585 *
23586 * Can also be used to unset a tag, by passing `undefined`.
23587 *
23588 * @param key String key of tag
23589 * @param value Value of tag
23590 */
23591function setTag(key, value) {
23592  // eslint-disable-next-line deprecation/deprecation
23593  hub.getCurrentHub().setTag(key, value);
23594}
23595
23596/**
23597 * Updates user context information for future events.
23598 *
23599 * @param user User context object to be set in the current context. Pass `null` to unset the user.
23600 */
23601function setUser(user) {
23602  // eslint-disable-next-line deprecation/deprecation
23603  hub.getCurrentHub().setUser(user);
23604}
23605
23606/**
23607 * Creates a new scope with and executes the given operation within.
23608 * The scope is automatically removed once the operation
23609 * finishes or throws.
23610 *
23611 * This is essentially a convenience function for:
23612 *
23613 *     pushScope();
23614 *     callback();
23615 *     popScope();
23616 */
23617
23618/**
23619 * Either creates a new active scope, or sets the given scope as active scope in the given callback.
23620 */
23621function withScope(
23622  ...rest
23623) {
23624  // eslint-disable-next-line deprecation/deprecation
23625  const hub$1 = hub.getCurrentHub();
23626
23627  // If a scope is defined, we want to make this the active scope instead of the default one
23628  if (rest.length === 2) {
23629    const [scope, callback] = rest;
23630    if (!scope) {
23631      // eslint-disable-next-line deprecation/deprecation
23632      return hub$1.withScope(callback);
23633    }
23634
23635    // eslint-disable-next-line deprecation/deprecation
23636    return hub$1.withScope(() => {
23637      // eslint-disable-next-line deprecation/deprecation
23638      hub$1.getStackTop().scope = scope ;
23639      return callback(scope );
23640    });
23641  }
23642
23643  // eslint-disable-next-line deprecation/deprecation
23644  return hub$1.withScope(rest[0]);
23645}
23646
23647/**
23648 * Attempts to fork the current isolation scope and the current scope based on the current async context strategy. If no
23649 * async context strategy is set, the isolation scope and the current scope will not be forked (this is currently the
23650 * case, for example, in the browser).
23651 *
23652 * Usage of this function in environments without async context strategy is discouraged and may lead to unexpected behaviour.
23653 *
23654 * This function is intended for Sentry SDK and SDK integration development. It is not recommended to be used in "normal"
23655 * applications directly because it comes with pitfalls. Use at your own risk!
23656 *
23657 * @param callback The callback in which the passed isolation scope is active. (Note: In environments without async
23658 * context strategy, the currently active isolation scope may change within execution of the callback.)
23659 * @returns The same value that `callback` returns.
23660 */
23661function withIsolationScope(callback) {
23662  return hub.runWithAsyncContext(() => {
23663    return callback(hub.getIsolationScope());
23664  });
23665}
23666
23667/**
23668 * Forks the current scope and sets the provided span as active span in the context of the provided callback.
23669 *
23670 * @param span Spans started in the context of the provided callback will be children of this span.
23671 * @param callback Execution context in which the provided span will be active. Is passed the newly forked scope.
23672 * @returns the value returned from the provided callback function.
23673 */
23674function withActiveSpan(span, callback) {
23675  return withScope(scope => {
23676    // eslint-disable-next-line deprecation/deprecation
23677    scope.setSpan(span);
23678    return callback(scope);
23679  });
23680}
23681
23682/**
23683 * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation.
23684 *
23685 * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a
23686 * new child span within the transaction or any span, call the respective `.startChild()` method.
23687 *
23688 * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded.
23689 *
23690 * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its
23691 * finished child spans will be sent to Sentry.
23692 *
23693 * NOTE: This function should only be used for *manual* instrumentation. Auto-instrumentation should call
23694 * `startTransaction` directly on the hub.
23695 *
23696 * @param context Properties of the new `Transaction`.
23697 * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent
23698 * default values). See {@link Options.tracesSampler}.
23699 *
23700 * @returns The transaction which was just started
23701 *
23702 * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead.
23703 */
23704function startTransaction(
23705  context,
23706  customSamplingContext,
23707) {
23708  // eslint-disable-next-line deprecation/deprecation
23709  return hub.getCurrentHub().startTransaction({ ...context }, customSamplingContext);
23710}
23711
23712/**
23713 * Create a cron monitor check in and send it to Sentry.
23714 *
23715 * @param checkIn An object that describes a check in.
23716 * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want
23717 * to create a monitor automatically when sending a check in.
23718 */
23719function captureCheckIn(checkIn, upsertMonitorConfig) {
23720  const scope = getCurrentScope();
23721  const client = getClient();
23722  if (!client) {
23723    debugBuild.DEBUG_BUILD && utils.logger.warn('Cannot capture check-in. No client defined.');
23724  } else if (!client.captureCheckIn) {
23725    debugBuild.DEBUG_BUILD && utils.logger.warn('Cannot capture check-in. Client does not support sending check-ins.');
23726  } else {
23727    return client.captureCheckIn(checkIn, upsertMonitorConfig, scope);
23728  }
23729
23730  return utils.uuid4();
23731}
23732
23733/**
23734 * Wraps a callback with a cron monitor check in. The check in will be sent to Sentry when the callback finishes.
23735 *
23736 * @param monitorSlug The distinct slug of the monitor.
23737 * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want
23738 * to create a monitor automatically when sending a check in.
23739 */
23740function withMonitor(
23741  monitorSlug,
23742  callback,
23743  upsertMonitorConfig,
23744) {
23745  const checkInId = captureCheckIn({ monitorSlug, status: 'in_progress' }, upsertMonitorConfig);
23746  const now = utils.timestampInSeconds();
23747
23748  function finishCheckIn(status) {
23749    captureCheckIn({ monitorSlug, status, checkInId, duration: utils.timestampInSeconds() - now });
23750  }
23751
23752  let maybePromiseResult;
23753  try {
23754    maybePromiseResult = callback();
23755  } catch (e) {
23756    finishCheckIn('error');
23757    throw e;
23758  }
23759
23760  if (utils.isThenable(maybePromiseResult)) {
23761    Promise.resolve(maybePromiseResult).then(
23762      () => {
23763        finishCheckIn('ok');
23764      },
23765      () => {
23766        finishCheckIn('error');
23767      },
23768    );
23769  } else {
23770    finishCheckIn('ok');
23771  }
23772
23773  return maybePromiseResult;
23774}
23775
23776/**
23777 * Call `flush()` on the current client, if there is one. See {@link Client.flush}.
23778 *
23779 * @param timeout Maximum time in ms the client should wait to flush its event queue. Omitting this parameter will cause
23780 * the client to wait until all events are sent before resolving the promise.
23781 * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it
23782 * doesn't (or if there's no client defined).
23783 */
23784async function flush(timeout) {
23785  const client = getClient();
23786  if (client) {
23787    return client.flush(timeout);
23788  }
23789  debugBuild.DEBUG_BUILD && utils.logger.warn('Cannot flush events. No client defined.');
23790  return Promise.resolve(false);
23791}
23792
23793/**
23794 * Call `close()` on the current client, if there is one. See {@link Client.close}.
23795 *
23796 * @param timeout Maximum time in ms the client should wait to flush its event queue before shutting down. Omitting this
23797 * parameter will cause the client to wait until all events are sent before disabling itself.
23798 * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it
23799 * doesn't (or if there's no client defined).
23800 */
23801async function close(timeout) {
23802  const client = getClient();
23803  if (client) {
23804    return client.close(timeout);
23805  }
23806  debugBuild.DEBUG_BUILD && utils.logger.warn('Cannot flush events and disable SDK. No client defined.');
23807  return Promise.resolve(false);
23808}
23809
23810/**
23811 * This is the getter for lastEventId.
23812 *
23813 * @returns The last event id of a captured event.
23814 * @deprecated This function will be removed in the next major version of the Sentry SDK.
23815 */
23816function lastEventId() {
23817  // eslint-disable-next-line deprecation/deprecation
23818  return hub.getCurrentHub().lastEventId();
23819}
23820
23821/**
23822 * Get the currently active client.
23823 */
23824function getClient() {
23825  // eslint-disable-next-line deprecation/deprecation
23826  return hub.getCurrentHub().getClient();
23827}
23828
23829/**
23830 * Returns true if Sentry has been properly initialized.
23831 */
23832function isInitialized() {
23833  return !!getClient();
23834}
23835
23836/**
23837 * Get the currently active scope.
23838 */
23839function getCurrentScope() {
23840  // eslint-disable-next-line deprecation/deprecation
23841  return hub.getCurrentHub().getScope();
23842}
23843
23844/**
23845 * Start a session on the current isolation scope.
23846 *
23847 * @param context (optional) additional properties to be applied to the returned session object
23848 *
23849 * @returns the new active session
23850 */
23851function startSession(context) {
23852  const client = getClient();
23853  const isolationScope = hub.getIsolationScope();
23854  const currentScope = getCurrentScope();
23855
23856  const { release, environment = constants.DEFAULT_ENVIRONMENT } = (client && client.getOptions()) || {};
23857
23858  // Will fetch userAgent if called from browser sdk
23859  const { userAgent } = utils.GLOBAL_OBJ.navigator || {};
23860
23861  const session$1 = session.makeSession({
23862    release,
23863    environment,
23864    user: currentScope.getUser() || isolationScope.getUser(),
23865    ...(userAgent && { userAgent }),
23866    ...context,
23867  });
23868
23869  // End existing session if there's one
23870  const currentSession = isolationScope.getSession();
23871  if (currentSession && currentSession.status === 'ok') {
23872    session.updateSession(currentSession, { status: 'exited' });
23873  }
23874
23875  endSession();
23876
23877  // Afterwards we set the new session on the scope
23878  isolationScope.setSession(session$1);
23879
23880  // TODO (v8): Remove this and only use the isolation scope(?).
23881  // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession()
23882  currentScope.setSession(session$1);
23883
23884  return session$1;
23885}
23886
23887/**
23888 * End the session on the current isolation scope.
23889 */
23890function endSession() {
23891  const isolationScope = hub.getIsolationScope();
23892  const currentScope = getCurrentScope();
23893
23894  const session$1 = currentScope.getSession() || isolationScope.getSession();
23895  if (session$1) {
23896    session.closeSession(session$1);
23897  }
23898  _sendSessionUpdate();
23899
23900  // the session is over; take it off of the scope
23901  isolationScope.setSession();
23902
23903  // TODO (v8): Remove this and only use the isolation scope(?).
23904  // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession()
23905  currentScope.setSession();
23906}
23907
23908/**
23909 * Sends the current Session on the scope
23910 */
23911function _sendSessionUpdate() {
23912  const isolationScope = hub.getIsolationScope();
23913  const currentScope = getCurrentScope();
23914  const client = getClient();
23915  // TODO (v8): Remove currentScope and only use the isolation scope(?).
23916  // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession()
23917  const session = currentScope.getSession() || isolationScope.getSession();
23918  if (session && client && client.captureSession) {
23919    client.captureSession(session);
23920  }
23921}
23922
23923/**
23924 * Sends the current session on the scope to Sentry
23925 *
23926 * @param end If set the session will be marked as exited and removed from the scope.
23927 *            Defaults to `false`.
23928 */
23929function captureSession(end = false) {
23930  // both send the update and pull the session from the scope
23931  if (end) {
23932    endSession();
23933    return;
23934  }
23935
23936  // only send the update
23937  _sendSessionUpdate();
23938}
23939
23940exports.addBreadcrumb = addBreadcrumb;
23941exports.captureCheckIn = captureCheckIn;
23942exports.captureEvent = captureEvent;
23943exports.captureException = captureException;
23944exports.captureMessage = captureMessage;
23945exports.captureSession = captureSession;
23946exports.close = close;
23947exports.configureScope = configureScope;
23948exports.endSession = endSession;
23949exports.flush = flush;
23950exports.getClient = getClient;
23951exports.getCurrentScope = getCurrentScope;
23952exports.isInitialized = isInitialized;
23953exports.lastEventId = lastEventId;
23954exports.setContext = setContext;
23955exports.setExtra = setExtra;
23956exports.setExtras = setExtras;
23957exports.setTag = setTag;
23958exports.setTags = setTags;
23959exports.setUser = setUser;
23960exports.startSession = startSession;
23961exports.startTransaction = startTransaction;
23962exports.withActiveSpan = withActiveSpan;
23963exports.withIsolationScope = withIsolationScope;
23964exports.withMonitor = withMonitor;
23965exports.withScope = withScope;
23966
23967
23968},{"./constants.js":244,"./debug-build.js":245,"./hub.js":249,"./session.js":272,"./utils/prepareEvent.js":295,"@sentry/utils":319}],249:[function(require,module,exports){
23969Object.defineProperty(exports, '__esModule', { value: true });
23970
23971const utils = require('@sentry/utils');
23972const constants = require('./constants.js');
23973const debugBuild = require('./debug-build.js');
23974const scope = require('./scope.js');
23975const session = require('./session.js');
23976const version = require('./version.js');
23977
23978/**
23979 * API compatibility version of this hub.
23980 *
23981 * WARNING: This number should only be increased when the global interface
23982 * changes and new methods are introduced.
23983 *
23984 * @hidden
23985 */
23986const API_VERSION = parseFloat(version.SDK_VERSION);
23987
23988/**
23989 * Default maximum number of breadcrumbs added to an event. Can be overwritten
23990 * with {@link Options.maxBreadcrumbs}.
23991 */
23992const DEFAULT_BREADCRUMBS = 100;
23993
23994/**
23995 * @inheritDoc
23996 */
23997class Hub  {
23998  /** Is a {@link Layer}[] containing the client and scope */
23999
24000  /** Contains the last event id of a captured event.  */
24001
24002  /**
24003   * Creates a new instance of the hub, will push one {@link Layer} into the
24004   * internal stack on creation.
24005   *
24006   * @param client bound to the hub.
24007   * @param scope bound to the hub.
24008   * @param version number, higher number means higher priority.
24009   *
24010   * @deprecated Instantiation of Hub objects is deprecated and the constructor will be removed in version 8 of the SDK.
24011   *
24012   * If you are currently using the Hub for multi-client use like so:
24013   *
24014   * ```
24015   * // OLD
24016   * const hub = new Hub();
24017   * hub.bindClient(client);
24018   * makeMain(hub)
24019   * ```
24020   *
24021   * instead initialize the client as follows:
24022   *
24023   * ```
24024   * // NEW
24025   * Sentry.withIsolationScope(() => {
24026   *    Sentry.setCurrentClient(client);
24027   *    client.init();
24028   * });
24029   * ```
24030   *
24031   * If you are using the Hub to capture events like so:
24032   *
24033   * ```
24034   * // OLD
24035   * const client = new Client();
24036   * const hub = new Hub(client);
24037   * hub.captureException()
24038   * ```
24039   *
24040   * instead capture isolated events as follows:
24041   *
24042   * ```
24043   * // NEW
24044   * const client = new Client();
24045   * const scope = new Scope();
24046   * scope.setClient(client);
24047   * scope.captureException();
24048   * ```
24049   */
24050   constructor(
24051    client,
24052    scope$1,
24053    isolationScope,
24054      _version = API_VERSION,
24055  ) {this._version = _version;
24056    let assignedScope;
24057    if (!scope$1) {
24058      assignedScope = new scope.Scope();
24059      assignedScope.setClient(client);
24060    } else {
24061      assignedScope = scope$1;
24062    }
24063
24064    let assignedIsolationScope;
24065    if (!isolationScope) {
24066      assignedIsolationScope = new scope.Scope();
24067      assignedIsolationScope.setClient(client);
24068    } else {
24069      assignedIsolationScope = isolationScope;
24070    }
24071
24072    this._stack = [{ scope: assignedScope }];
24073
24074    if (client) {
24075      // eslint-disable-next-line deprecation/deprecation
24076      this.bindClient(client);
24077    }
24078
24079    this._isolationScope = assignedIsolationScope;
24080  }
24081
24082  /**
24083   * Checks if this hub's version is older than the given version.
24084   *
24085   * @param version A version number to compare to.
24086   * @return True if the given version is newer; otherwise false.
24087   *
24088   * @deprecated This will be removed in v8.
24089   */
24090   isOlderThan(version) {
24091    return this._version < version;
24092  }
24093
24094  /**
24095   * This binds the given client to the current scope.
24096   * @param client An SDK client (client) instance.
24097   *
24098   * @deprecated Use `initAndBind()` directly, or `setCurrentClient()` and/or `client.init()` instead.
24099   */
24100   bindClient(client) {
24101    // eslint-disable-next-line deprecation/deprecation
24102    const top = this.getStackTop();
24103    top.client = client;
24104    top.scope.setClient(client);
24105    // eslint-disable-next-line deprecation/deprecation
24106    if (client && client.setupIntegrations) {
24107      // eslint-disable-next-line deprecation/deprecation
24108      client.setupIntegrations();
24109    }
24110  }
24111
24112  /**
24113   * @inheritDoc
24114   *
24115   * @deprecated Use `withScope` instead.
24116   */
24117   pushScope() {
24118    // We want to clone the content of prev scope
24119    // eslint-disable-next-line deprecation/deprecation
24120    const scope = this.getScope().clone();
24121    // eslint-disable-next-line deprecation/deprecation
24122    this.getStack().push({
24123      // eslint-disable-next-line deprecation/deprecation
24124      client: this.getClient(),
24125      scope,
24126    });
24127    return scope;
24128  }
24129
24130  /**
24131   * @inheritDoc
24132   *
24133   * @deprecated Use `withScope` instead.
24134   */
24135   popScope() {
24136    // eslint-disable-next-line deprecation/deprecation
24137    if (this.getStack().length <= 1) return false;
24138    // eslint-disable-next-line deprecation/deprecation
24139    return !!this.getStack().pop();
24140  }
24141
24142  /**
24143   * @inheritDoc
24144   *
24145   * @deprecated Use `Sentry.withScope()` instead.
24146   */
24147   withScope(callback) {
24148    // eslint-disable-next-line deprecation/deprecation
24149    const scope = this.pushScope();
24150
24151    let maybePromiseResult;
24152    try {
24153      maybePromiseResult = callback(scope);
24154    } catch (e) {
24155      // eslint-disable-next-line deprecation/deprecation
24156      this.popScope();
24157      throw e;
24158    }
24159
24160    if (utils.isThenable(maybePromiseResult)) {
24161      // @ts-expect-error - isThenable returns the wrong type
24162      return maybePromiseResult.then(
24163        res => {
24164          // eslint-disable-next-line deprecation/deprecation
24165          this.popScope();
24166          return res;
24167        },
24168        e => {
24169          // eslint-disable-next-line deprecation/deprecation
24170          this.popScope();
24171          throw e;
24172        },
24173      );
24174    }
24175
24176    // eslint-disable-next-line deprecation/deprecation
24177    this.popScope();
24178    return maybePromiseResult;
24179  }
24180
24181  /**
24182   * @inheritDoc
24183   *
24184   * @deprecated Use `Sentry.getClient()` instead.
24185   */
24186   getClient() {
24187    // eslint-disable-next-line deprecation/deprecation
24188    return this.getStackTop().client ;
24189  }
24190
24191  /**
24192   * Returns the scope of the top stack.
24193   *
24194   * @deprecated Use `Sentry.getCurrentScope()` instead.
24195   */
24196   getScope() {
24197    // eslint-disable-next-line deprecation/deprecation
24198    return this.getStackTop().scope;
24199  }
24200
24201  /**
24202   * @deprecated Use `Sentry.getIsolationScope()` instead.
24203   */
24204   getIsolationScope() {
24205    return this._isolationScope;
24206  }
24207
24208  /**
24209   * Returns the scope stack for domains or the process.
24210   * @deprecated This will be removed in v8.
24211   */
24212   getStack() {
24213    return this._stack;
24214  }
24215
24216  /**
24217   * Returns the topmost scope layer in the order domain > local > process.
24218   * @deprecated This will be removed in v8.
24219   */
24220   getStackTop() {
24221    return this._stack[this._stack.length - 1];
24222  }
24223
24224  /**
24225   * @inheritDoc
24226   *
24227   * @deprecated Use `Sentry.captureException()` instead.
24228   */
24229   captureException(exception, hint) {
24230    const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : utils.uuid4());
24231    const syntheticException = new Error('Sentry syntheticException');
24232    // eslint-disable-next-line deprecation/deprecation
24233    this.getScope().captureException(exception, {
24234      originalException: exception,
24235      syntheticException,
24236      ...hint,
24237      event_id: eventId,
24238    });
24239
24240    return eventId;
24241  }
24242
24243  /**
24244   * @inheritDoc
24245   *
24246   * @deprecated Use  `Sentry.captureMessage()` instead.
24247   */
24248   captureMessage(
24249    message,
24250    // eslint-disable-next-line deprecation/deprecation
24251    level,
24252    hint,
24253  ) {
24254    const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : utils.uuid4());
24255    const syntheticException = new Error(message);
24256    // eslint-disable-next-line deprecation/deprecation
24257    this.getScope().captureMessage(message, level, {
24258      originalException: message,
24259      syntheticException,
24260      ...hint,
24261      event_id: eventId,
24262    });
24263
24264    return eventId;
24265  }
24266
24267  /**
24268   * @inheritDoc
24269   *
24270   * @deprecated Use `Sentry.captureEvent()` instead.
24271   */
24272   captureEvent(event, hint) {
24273    const eventId = hint && hint.event_id ? hint.event_id : utils.uuid4();
24274    if (!event.type) {
24275      this._lastEventId = eventId;
24276    }
24277    // eslint-disable-next-line deprecation/deprecation
24278    this.getScope().captureEvent(event, { ...hint, event_id: eventId });
24279    return eventId;
24280  }
24281
24282  /**
24283   * @inheritDoc
24284   *
24285   * @deprecated This will be removed in v8.
24286   */
24287   lastEventId() {
24288    return this._lastEventId;
24289  }
24290
24291  /**
24292   * @inheritDoc
24293   *
24294   * @deprecated Use `Sentry.addBreadcrumb()` instead.
24295   */
24296   addBreadcrumb(breadcrumb, hint) {
24297    // eslint-disable-next-line deprecation/deprecation
24298    const { scope, client }
24298 = this.getStackTop();
24299
24300    if (!client) return;
24301
24302    const { beforeBreadcrumb = null, maxBreadcrumbs = DEFAULT_BREADCRUMBS } =
24303      (client.getOptions && client.getOptions()) || {};
24304
24305    if (maxBreadcrumbs <= 0) return;
24306
24307    const timestamp = utils.dateTimestampInSeconds();
24308    const mergedBreadcrumb = { timestamp, ...breadcrumb };
24309    const finalBreadcrumb = beforeBreadcrumb
24310      ? (utils.consoleSandbox(() => beforeBreadcrumb(mergedBreadcrumb, hint)) )
24311      : mergedBreadcrumb;
24312
24313    if (finalBreadcrumb === null) return;
24314
24315    if (client.emit) {
24316      client.emit('beforeAddBreadcrumb', finalBreadcrumb, hint);
24317    }
24318
24319    // TODO(v8): I know this comment doesn't make much sense because the hub will be deprecated but I still wanted to
24320    // write it down. In theory, we would have to add the breadcrumbs to the isolation scope here, however, that would
24321    // duplicate all of the breadcrumbs. There was the possibility of adding breadcrumbs to both, the isolation scope
24322    // and the normal scope, and deduplicating it down the line in the event processing pipeline. However, that would
24323    // have been very fragile, because the breadcrumb objects would have needed to keep their identity all throughout
24324    // the event processing pipeline.
24325    // In the new implementation, the top level `Sentry.addBreadcrumb()` should ONLY write to the isolation scope.
24326
24327    scope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs);
24328  }
24329
24330  /**
24331   * @inheritDoc
24332   * @deprecated Use `Sentry.setUser()` instead.
24333   */
24334   setUser(user) {
24335    // TODO(v8): The top level `Sentry.setUser()` function should write ONLY to the isolation scope.
24336    // eslint-disable-next-line deprecation/deprecation
24337    this.getScope().setUser(user);
24338    // eslint-disable-next-line deprecation/deprecation
24339    this.getIsolationScope().setUser(user);
24340  }
24341
24342  /**
24343   * @inheritDoc
24344   * @deprecated Use `Sentry.setTags()` instead.
24345   */
24346   setTags(tags) {
24347    // TODO(v8): The top level `Sentry.setTags()` function should write ONLY to the isolation scope.
24348    // eslint-disable-next-line deprecation/deprecation
24349    this.getScope().setTags(tags);
24350    // eslint-disable-next-line deprecation/deprecation
24351    this.getIsolationScope().setTags(tags);
24352  }
24353
24354  /**
24355   * @inheritDoc
24356   * @deprecated Use `Sentry.setExtras()` instead.
24357   */
24358   setExtras(extras) {
24359    // TODO(v8): The top level `Sentry.setExtras()` function should write ONLY to the isolation scope.
24360    // eslint-disable-next-line deprecation/deprecation
24361    this.getScope().setExtras(extras);
24362    // eslint-disable-next-line deprecation/deprecation
24363    this.getIsolationScope().setExtras(extras);
24364  }
24365
24366  /**
24367   * @inheritDoc
24368   * @deprecated Use `Sentry.setTag()` instead.
24369   */
24370   setTag(key, value) {
24371    // TODO(v8): The top level `Sentry.setTag()` function should write ONLY to the isolation scope.
24372    // eslint-disable-next-line deprecation/deprecation
24373    this.getScope().setTag(key, value);
24374    // eslint-disable-next-line deprecation/deprecation
24375    this.getIsolationScope().setTag(key, value);
24376  }
24377
24378  /**
24379   * @inheritDoc
24380   * @deprecated Use `Sentry.setExtra()` instead.
24381   */
24382   setExtra(key, extra) {
24383    // TODO(v8): The top level `Sentry.setExtra()` function should write ONLY to the isolation scope.
24384    // eslint-disable-next-line deprecation/deprecation
24385    this.getScope().setExtra(key, extra);
24386    // eslint-disable-next-line deprecation/deprecation
24387    this.getIsolationScope().setExtra(key, extra);
24388  }
24389
24390  /**
24391   * @inheritDoc
24392   * @deprecated Use `Sentry.setContext()` instead.
24393   */
24394  // eslint-disable-next-line @typescript-eslint/no-explicit-any
24395   setContext(name, context) {
24396    // TODO(v8): The top level `Sentry.setContext()` function should write ONLY to the isolation scope.
24397    // eslint-disable-next-line deprecation/deprecation
24398    this.getScope().setContext(name, context);
24399    // eslint-disable-next-line deprecation/deprecation
24400    this.getIsolationScope().setContext(name, context);
24401  }
24402
24403  /**
24404   * @inheritDoc
24405   *
24406   * @deprecated Use `getScope()` directly.
24407   */
24408   configureScope(callback) {
24409    // eslint-disable-next-line deprecation/deprecation
24410    const { scope, client }
vendor: 9,493 bytes, lines 24410-24708
24410 = this.getStackTop();
24411    if (client) {
24412      callback(scope);
24413    }
24414  }
24415
24416  /**
24417   * @inheritDoc
24418   */
24419   run(callback) {
24420    // eslint-disable-next-line deprecation/deprecation
24421    const oldHub = makeMain(this);
24422    try {
24423      callback(this);
24424    } finally {
24425      // eslint-disable-next-line deprecation/deprecation
24426      makeMain(oldHub);
24427    }
24428  }
24429
24430  /**
24431   * @inheritDoc
24432   * @deprecated Use `Sentry.getClient().getIntegrationByName()` instead.
24433   */
24434   getIntegration(integration) {
24435    // eslint-disable-next-line deprecation/deprecation
24436    const client = this.getClient();
24437    if (!client) return null;
24438    try {
24439      // eslint-disable-next-line deprecation/deprecation
24440      return client.getIntegration(integration);
24441    } catch (_oO) {
24442      debugBuild.DEBUG_BUILD && utils.logger.warn(`Cannot retrieve integration ${integration.id} from the current Hub`);
24443      return null;
24444    }
24445  }
24446
24447  /**
24448   * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation.
24449   *
24450   * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a
24451   * new child span within the transaction or any span, call the respective `.startChild()` method.
24452   *
24453   * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded.
24454   *
24455   * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its
24456   * finished child spans will be sent to Sentry.
24457   *
24458   * @param context Properties of the new `Transaction`.
24459   * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent
24460   * default values). See {@link Options.tracesSampler}.
24461   *
24462   * @returns The transaction which was just started
24463   *
24464   * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead.
24465   */
24466   startTransaction(context, customSamplingContext) {
24467    const result = this._callExtensionMethod('startTransaction', context, customSamplingContext);
24468
24469    if (debugBuild.DEBUG_BUILD && !result) {
24470      // eslint-disable-next-line deprecation/deprecation
24471      const client = this.getClient();
24472      if (!client) {
24473        utils.logger.warn(
24474          "Tracing extension 'startTransaction' is missing. You should 'init' the SDK before calling 'startTransaction'",
24475        );
24476      } else {
24477        utils.logger.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init':
24478Sentry.addTracingExtensions();
24479Sentry.init({...});
24480`);
24481      }
24482    }
24483
24484    return result;
24485  }
24486
24487  /**
24488   * @inheritDoc
24489   * @deprecated Use `spanToTraceHeader()` instead.
24490   */
24491   traceHeaders() {
24492    return this._callExtensionMethod('traceHeaders');
24493  }
24494
24495  /**
24496   * @inheritDoc
24497   *
24498   * @deprecated Use top level `captureSession` instead.
24499   */
24500   captureSession(endSession = false) {
24501    // both send the update and pull the session from the scope
24502    if (endSession) {
24503      // eslint-disable-next-line deprecation/deprecation
24504      return this.endSession();
24505    }
24506
24507    // only send the update
24508    this._sendSessionUpdate();
24509  }
24510
24511  /**
24512   * @inheritDoc
24513   * @deprecated Use top level `endSession` instead.
24514   */
24515   endSession() {
24516    // eslint-disable-next-line deprecation/deprecation
24517    const layer = this.getStackTop();
24518    const scope = layer.scope;
24519    const session$1 = scope.getSession();
24520    if (session$1) {
24521      session.closeSession(session$1);
24522    }
24523    this._sendSessionUpdate();
24524
24525    // the session is over; take it off of the scope
24526    scope.setSession();
24527  }
24528
24529  /**
24530   * @inheritDoc
24531   * @deprecated Use top level `startSession` instead.
24532   */
24533   startSession(context) {
24534    // eslint-disable-next-line deprecation/deprecation
24535    const { scope, client } = this.getStackTop();
24536    const { release, environment = constants.DEFAULT_ENVIRONMENT } = (client && client.getOptions()) || {};
24537
24538    // Will fetch userAgent if called from browser sdk
24539    const { userAgent } = utils.GLOBAL_OBJ.navigator || {};
24540
24541    const session$1 = session.makeSession({
24542      release,
24543      environment,
24544      user: scope.getUser(),
24545      ...(userAgent && { userAgent }),
24546      ...context,
24547    });
24548
24549    // End existing session if there's one
24550    const currentSession = scope.getSession && scope.getSession();
24551    if (currentSession && currentSession.status === 'ok') {
24552      session.updateSession(currentSession, { status: 'exited' });
24553    }
24554    // eslint-disable-next-line deprecation/deprecation
24555    this.endSession();
24556
24557    // Afterwards we set the new session on the scope
24558    scope.setSession(session$1);
24559
24560    return session$1;
24561  }
24562
24563  /**
24564   * Returns if default PII should be sent to Sentry and propagated in ourgoing requests
24565   * when Tracing is used.
24566   *
24567   * @deprecated Use top-level `getClient().getOptions().sendDefaultPii` instead. This function
24568   * only unnecessarily increased API surface but only wrapped accessing the option.
24569   */
24570   shouldSendDefaultPii() {
24571    // eslint-disable-next-line deprecation/deprecation
24572    const client = this.getClient();
24573    const options = client && client.getOptions();
24574    return Boolean(options && options.sendDefaultPii);
24575  }
24576
24577  /**
24578   * Sends the current Session on the scope
24579   */
24580   _sendSessionUpdate() {
24581    // eslint-disable-next-line deprecation/deprecation
24582    const { scope, client } = this.getStackTop();
24583
24584    const session = scope.getSession();
24585    if (session && client && client.captureSession) {
24586      client.captureSession(session);
24587    }
24588  }
24589
24590  /**
24591   * Calls global extension method and binding current instance to the function call
24592   */
24593  // @ts-expect-error Function lacks ending return statement and return type does not include 'undefined'. ts(2366)
24594  // eslint-disable-next-line @typescript-eslint/no-explicit-any
24595   _callExtensionMethod(method, ...args) {
24596    const carrier = getMainCarrier();
24597    const sentry = carrier.__SENTRY__;
24598    if (sentry && sentry.extensions && typeof sentry.extensions[method] === 'function') {
24599      return sentry.extensions[method].apply(this, args);
24600    }
24601    debugBuild.DEBUG_BUILD && utils.logger.warn(`Extension method ${method} couldn't be found, doing nothing.`);
24602  }
24603}
24604
24605/**
24606 * Returns the global shim registry.
24607 *
24608 * FIXME: This function is problematic, because despite always returning a valid Carrier,
24609 * it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check
24610 * at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.
24611 **/
24612function getMainCarrier() {
24613  utils.GLOBAL_OBJ.__SENTRY__ = utils.GLOBAL_OBJ.__SENTRY__ || {
24614    extensions: {},
24615    hub: undefined,
24616  };
24617  return utils.GLOBAL_OBJ;
24618}
24619
24620/**
24621 * Replaces the current main hub with the passed one on the global object
24622 *
24623 * @returns The old replaced hub
24624 *
24625 * @deprecated Use `setCurrentClient()` instead.
24626 */
24627function makeMain(hub) {
24628  const registry = getMainCarrier();
24629  const oldHub = getHubFromCarrier(registry);
24630  setHubOnCarrier(registry, hub);
24631  return oldHub;
24632}
24633
24634/**
24635 * Returns the default hub instance.
24636 *
24637 * If a hub is already registered in the global carrier but this module
24638 * contains a more recent version, it replaces the registered version.
24639 * Otherwise, the currently registered hub will be returned.
24640 *
24641 * @deprecated Use the respective replacement method directly instead.
24642 */
24643function getCurrentHub() {
24644  // Get main carrier (global for every environment)
24645  const registry = getMainCarrier();
24646
24647  if (registry.__SENTRY__ && registry.__SENTRY__.acs) {
24648    const hub = registry.__SENTRY__.acs.getCurrentHub();
24649
24650    if (hub) {
24651      return hub;
24652    }
24653  }
24654
24655  // Return hub that lives on a global object
24656  return getGlobalHub(registry);
24657}
24658
24659/**
24660 * Get the currently active isolation scope.
24661 * The isolation scope is active for the current exection context,
24662 * meaning that it will remain stable for the same Hub.
24663 */
24664function getIsolationScope() {
24665  // eslint-disable-next-line deprecation/deprecation
24666  return getCurrentHub().getIsolationScope();
24667}
24668
24669function getGlobalHub(registry = getMainCarrier()) {
24670  // If there's no hub, or its an old API, assign a new one
24671
24672  if (
24673    !hasHubOnCarrier(registry) ||
24674    // eslint-disable-next-line deprecation/deprecation
24675    getHubFromCarrier(registry).isOlderThan(API_VERSION)
24676  ) {
24677    // eslint-disable-next-line deprecation/deprecation
24678    setHubOnCarrier(registry, new Hub());
24679  }
24680
24681  // Return hub that lives on a global object
24682  return getHubFromCarrier(registry);
24683}
24684
24685/**
24686 * @private Private API with no semver guarantees!
24687 *
24688 * If the carrier does not contain a hub, a new hub is created with the global hub client and scope.
24689 */
24690function ensureHubOnCarrier(carrier, parent = getGlobalHub()) {
24691  // If there's no hub on current domain, or it's an old API, assign a new one
24692  if (
24693    !hasHubOnCarrier(carrier) ||
24694    // eslint-disable-next-line deprecation/deprecation
24695    getHubFromCarrier(carrier).isOlderThan(API_VERSION)
24696  ) {
24697    // eslint-disable-next-line deprecation/deprecation
24698    const client = parent.getClient();
24699    // eslint-disable-next-line deprecation/deprecation
24700    const scope = parent.getScope();
24701    // eslint-disable-next-line deprecation/deprecation
24702    const isolationScope = parent.getIsolationScope();
24703    // eslint-disable-next-line deprecation/deprecation
24704    setHubOnCarrier(carrier, new Hub(client, scope.clone(), isolationScope.clone()));
24705  }
24706}
24707
24708/**
24709 * @private Private API with no semver guarantees!
24710 *
24711 * Sets the global async context strategy
24712 */
24713function setAsyncContextStrategy(strategy) {
24714  // Get main carrier (global for every environment)
24715  const registry = getMainCarrier();
24716  registry.__SENTRY__ = registry.__SENTRY__ || {};
24717  registry.__SENTRY__.acs = strategy;
24718}
24719
24720/**
24721 * Runs the supplied callback in its own async context. Async Context strategies are defined per SDK.
24722 *
24723 * @param callback The callback to run in its own async context
24724 * @param options Options to pass to the async context strategy
24725 * @returns The result of the callback
24726 */
24727function runWithAsyncContext(callback, options = {}) {
24728  const registry = getMainCarrier();
24729
24730  if (registry.__SENTRY__ && registry.__SENTRY__.acs) {
24731    return registry.__SENTRY__.acs.runWithAsyncContext(callback, options);
24732  }
24733
24734  // if there was no strategy, fallback to just calling the callback
24735  return callback();
24736}
24737
24738/**
24739 * This will tell whether a carrier has a hub on it or not
24740 * @param carrier object
24741 */
24742function hasHubOnCarrier(carrier) {
24743  return !!(carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub);
24744}
24745
24746/**
24747 * This will create a new {@link Hub} and add to the passed object on
24748 * __SENTRY__.hub.
24749 * @param carrier object
24750 * @hidden
24751 */
24752function getHubFromCarrier(carrier) {
24753  // eslint-disable-next-line deprecation/deprecation
24754  return utils.getGlobalSingleton('hub', () => new Hub(), carrier);
24755}
24756
24757/**
24758 * This will set passed {@link Hub} on the passed object's __SENTRY__.hub attribute
24759 * @param carrier object
24760 * @param hub Hub
24761 * @returns A boolean indicating success or failure
24762 */
24763function setHubOnCarrier(carrier, hub) {
24764  if (!carrier) return false;
24765  const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {});
24766  __SENTRY__.hub = hub;
24767  return true;
24768}
24769
24770exports.API_VERSION = API_VERSION;
24771exports.Hub = Hub;
24772exports.ensureHubOnCarrier = ensureHubOnCarrier;
24773exports.getCurrentHub = getCurrentHub;
24774exports.getHubFromCarrier = getHubFromCarrier;
24775exports.getIsolationScope = getIsolationScope;
24776exports.getMainCarrier = getMainCarrier;
24777exports.makeMain = makeMain;
24778exports.runWithAsyncContext = runWithAsyncContext;
24779exports.setAsyncContextStrategy = setAsyncContextStrategy;
24780exports.setHubOnCarrier = setHubOnCarrier;
24781
24782
24783},{"./constants.js":244,"./debug-build.js":245,"./scope.js":268,"./session.js":272,"./version.js":298,"@sentry/utils":319}],250:[function(require,module,exports){
24784Object.defineProperty(exports, '__esModule', { value: true });
24785
24786const hubextensions = require('./tracing/hubextensions.js');
24787const idletransaction = require('./tracing/idletransaction.js');
24788const span$1 = require('./tracing/span.js');
24789const transaction = require('./tracing/transaction.js');
24790const utils = require('./tracing/utils.js');
24791const spanstatus = require('./tracing/spanstatus.js');
24792const trace = require('./tracing/trace.js');
24793const dynamicSamplingContext = require('./tracing/dynamicSamplingContext.js');
24794const measurement = require('./tracing/measurement.js');
24795const sampling = require('./tracing/sampling.js');
24796const semanticAttributes = require('./semanticAttributes.js');
24797const envelope = require('./envelope.js');
24798const exports$1 = require('./exports.js');
24799const hub = require('./hub.js');
24800const session = require('./session.js');
24801const sessionflusher = require('./sessionflusher.js');
24802const scope = require('./scope.js');
24803const eventProcessors = require('./eventProcessors.js');
24804const api = require('./api.js');
24805const baseclient = require('./baseclient.js');
24806const serverRuntimeClient = require('./server-runtime-client.js');
24807const sdk = require('./sdk.js');
24808const base = require('./transports/base.js');
24809const offline = require('./transports/offline.js');
24810const multiplexed = require('./transports/multiplexed.js');
24811const version = require('./version.js');
24812const integration = require('./integration.js');
24813const applyScopeDataToEvent = require('./utils/applyScopeDataToEvent.js');
24814const prepareEvent = require('./utils/prepareEvent.js');
24815const checkin = require('./checkin.js');
24816const span = require('./span.js');
24817const hasTracingEnabled = require('./utils/hasTracingEnabled.js');
24818const isSentryRequestUrl = require('./utils/isSentryRequestUrl.js');
24819const handleCallbackErrors = require('./utils/handleCallbackErrors.js');
24820const parameterize = require('./utils/parameterize.js');
24821const spanUtils = require('./utils/spanUtils.js');
24822const getRootSpan = require('./utils/getRootSpan.js');
24823const sdkMetadata = require('./utils/sdkMetadata.js');
24824const constants = require('./constants.js');
24825const metadata = require('./integrations/metadata.js');
24826const requestdata = require('./integrations/requestdata.js');
24827const inboundfilters = require('./integrations/inboundfilters.js');
24828const functiontostring = require('./integrations/functiontostring.js');
24829const linkederrors = require('./integrations/linkederrors.js');
24830const index = require('./integrations/index.js');
24831const exports$2 = require('./metrics/exports.js');
24832
24833/** @deprecated Import the integration function directly, e.g. `inboundFiltersIntegration()` instead of `new Integrations.InboundFilter(). */
24834const Integrations = index;
24835
24836exports.addTracingExtensions = hubextensions.addTracingExtensions;
24837exports.startIdleTransaction = hubextensions.startIdleTransaction;
24838exports.IdleTransaction = idletransaction.IdleTransaction;
24839exports.TRACING_DEFAULTS = idletransaction.TRACING_DEFAULTS;
24840exports.Span = span$1.Span;
24841exports.Transaction = transaction.Transaction;
24842exports.extractTraceparentData = utils.extractTraceparentData;
24843exports.getActiveTransaction = utils.getActiveTransaction;
24844Object.defineProperty(exports, 'SpanStatus', {
24845  enumerable: true,
24846  get: () => spanstatus.SpanStatus
24847});
24848exports.getSpanStatusFromHttpCode = spanstatus.getSpanStatusFromHttpCode;
24849exports.setHttpStatus = spanstatus.setHttpStatus;
24850exports.spanStatusfromHttpCode = spanstatus.spanStatusfromHttpCode;
24851exports.continueTrace = trace.continueTrace;
24852exports.getActiveSpan = trace.getActiveSpan;
24853exports.startActiveSpan = trace.startActiveSpan;
24854exports.startInactiveSpan = trace.startInactiveSpan;
24855exports.startSpan = trace.startSpan;
24856exports.startSpanManual = trace.startSpanManual;
24857exports.trace = trace.trace;
24858exports.getDynamicSamplingContextFromClient = dynamicSamplingContext.getDynamicSamplingContextFromClient;
24859exports.getDynamicSamplingContextFromSpan = dynamicSamplingContext.getDynamicSamplingContextFromSpan;
24860exports.setMeasurement = measurement.setMeasurement;
24861exports.isValidSampleRate = sampling.isValidSampleRate;
24862exports.SEMANTIC_ATTRIBUTE_PROFILE_ID = semanticAttributes.SEMANTIC_ATTRIBUTE_PROFILE_ID;
24863exports.SEMANTIC_ATTRIBUTE_SENTRY_OP = semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP;
24864exports.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN;
24865exports.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE;
24866exports.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE;
24867exports.createEventEnvelope = envelope.createEventEnvelope;
24868exports.createSessionEnvelope = envelope.createSessionEnvelope;
24869exports.addBreadcrumb = exports$1.addBreadcrumb;
24870exports.captureCheckIn = exports$1.captureCheckIn;
24871exports.captureEvent = exports$1.captureEvent;
24872exports.captureException = exports$1.captureException;
24873exports.captureMessage = exports$1.captureMessage;
24874exports.captureSession = exports$1.captureSession;
24875exports.close = exports$1.close;
24876exports.configureScope = exports$1.configureScope;
24877exports.endSession = exports$1.endSession;
24878exports.flush = exports$1.flush;
24879exports.getClient = exports$1.getClient;
24880exports.getCurrentScope = exports$1.getCurrentScope;
24881exports.isInitialized = exports$1.isInitialized;
24882exports.lastEventId = exports$1.lastEventId;
24883exports.setContext = exports$1.setContext;
24884exports.setExtra = exports$1.setExtra;
24885exports.setExtras = exports$1.setExtras;
24886exports.setTag = exports$1.setTag;
24887exports.setTags = exports$1.setTags;
24888exports.setUser = exports$1.setUser;
24889exports.startSession = exports$1.startSession;
24890exports.startTransaction = exports$1.startTransaction;
24891exports.withActiveSpan = exports$1.withActiveSpan;
24892exports.withIsolationScope = exports$1.withIsolationScope;
24893exports.withMonitor = exports$1.withMonitor;
24894exports.withScope = exports$1.withScope;
24895exports.Hub = hub.Hub;
24896exports.ensureHubOnCarrier = hub.ensureHubOnCarrier;
24897exports.getCurrentHub = hub.getCurrentHub;
24898exports.getHubFromCarrier = hub.getHubFromCarrier;
24899exports.getIsolationScope = hub.getIsolationScope;
24900exports.getMainCarrier = hub.getMainCarrier;
24901exports.makeMain = hub.makeMain;
24902exports.runWithAsyncContext = hub.runWithAsyncContext;
24903exports.setAsyncContextStrategy = hub.setAsyncContextStrategy;
24904exports.setHubOnCarrier = hub.setHubOnCarrier;
24905exports.closeSession = session.closeSession;
24906exports.makeSession = session.makeSession;
24907exports.updateSession = session.updateSession;
24908exports.SessionFlusher = sessionflusher.SessionFlusher;
24909exports.Scope = scope.Scope;
24910exports.getGlobalScope = scope.getGlobalScope;
24911exports.setGlobalScope = scope.setGlobalScope;
24912exports.addGlobalEventProcessor = eventProcessors.addGlobalEventProcessor;
24913exports.notifyEventProcessors = eventProcessors.notifyEventProcessors;
24914exports.getEnvelopeEndpointWithUrlEncodedAuth = api.getEnvelopeEndpointWithUrlEncodedAuth;
24915exports.getReportDialogEndpoint = api.getReportDialogEndpoint;
24916exports.BaseClient = baseclient.BaseClient;
24917exports.addEventProcessor = baseclient.addEventProcessor;
24918exports.ServerRuntimeClient = serverRuntimeClient.ServerRuntimeClient;
24919exports.initAndBind = sdk.initAndBind;
24920exports.setCurrentClient = sdk.setCurrentClient;
24921exports.createTransport = base.createTransport;
24922exports.makeOfflineTransport = offline.makeOfflineTransport;
24923exports.makeMultiplexedTransport = multiplexed.makeMultiplexedTransport;
24924exports.SDK_VERSION = version.SDK_VERSION;
24925exports.addIntegration = integration.addIntegration;
24926exports.convertIntegrationFnToClass = integration.convertIntegrationFnToClass;
24927exports.defineIntegration = integration.defineIntegration;
24928exports.getIntegrationsToSetup = integration.getIntegrationsToSetup;
24929exports.applyScopeDataToEvent = applyScopeDataToEvent.applyScopeDataToEvent;
24930exports.mergeScopeData = applyScopeDataToEvent.mergeScopeData;
24931exports.prepareEvent = prepareEvent.prepareEvent;
24932exports.createCheckInEnvelope = checkin.createCheckInEnvelope;
24933exports.createSpanEnvelope = span.createSpanEnvelope;
24934exports.hasTracingEnabled = hasTracingEnabled.hasTracingEnabled;
24935exports.isSentryRequestUrl = isSentryRequestUrl.isSentryRequestUrl;
24936exports.handleCallbackErrors = handleCallbackErrors.handleCallbackErrors;
24937exports.parameterize = parameterize.parameterize;
24938exports.spanIsSampled = spanUtils.spanIsSampled;
24939exports.spanToJSON = spanUtils.spanToJSON;
24940exports.spanToTraceContext = spanUtils.spanToTraceContext;
24941exports.spanToTraceHeader = spanUtils.spanToTraceHeader;
24942exports.getRootSpan = getRootSpan.getRootSpan;
24943exports.applySdkMetadata = sdkMetadata.applySdkMetadata;
24944exports.DEFAULT_ENVIRONMENT = constants.DEFAULT_ENVIRONMENT;
24945exports.ModuleMetadata = metadata.ModuleMetadata;
24946exports.moduleMetadataIntegration = metadata.moduleMetadataIntegration;
24947exports.RequestData = requestdata.RequestData;
24948exports.requestDataIntegration = requestdata.requestDataIntegration;
24949exports.InboundFilters = inboundfilters.InboundFilters;
24950exports.inboundFiltersIntegration = inboundfilters.inboundFiltersIntegration;
24951exports.FunctionToString = functiontostring.FunctionToString;
24952exports.functionToStringIntegration = functiontostring.functionToStringIntegration;
24953exports.LinkedErrors = linkederrors.LinkedErrors;
24954exports.linkedErrorsIntegration = linkederrors.linkedErrorsIntegration;
24955exports.metrics = exports$2.metrics;
24956exports.Integrations = Integrations;
24957
24958
24959},{"./api.js":241,"./baseclient.js":242,"./checkin.js":243,"./constants.js":244,"./envelope.js":246,"./eventProcessors.js":247,"./exports.js":248,"./hub.js":249,"./integration.js":251,"./integrations/functiontostring.js":252,"./integrations/inboundfilters.js":253,"./integrations/index.js":254,"./integrations/linkederrors.js":255,"./integrations/metadata.js":256,"./integrations/requestdata.js":257,"./metrics/exports.js":263,"./scope.js":268,"./sdk.js":269,"./semanticAttributes.js":270,"./server-runtime-client.js":271,"./session.js":272,"./sessionflusher.js":273,"./span.js":274,"./tracing/dynamicSamplingContext.js":275,"./tracing/hubextensions.js":277,"./tracing/idletransaction.js":278,"./tracing/measurement.js":279,"./tracing/sampling.js":280,"./tracing/span.js":281,"./tracing/spanstatus.js":282,"./tracing/trace.js":283,"./tracing/transaction.js":284,"./tracing/utils.js":285,"./transports/base.js":286,"./transports/multiplexed.js":287,"./transports/offline.js":288,"./utils/applyScopeDataToEvent.js":289,"./utils/getRootSpan.js":290,"./utils/handleCallbackErrors.js":291,"./utils/hasTracingEnabled.js":292,"./utils/isSentryRequestUrl.js":293,"./utils/parameterize.js":294,"./ut
24959ils/prepareEvent.js":295,"./utils/sdkMetadata.js":296,"./utils/spanUtils.js":297,"./version.js":298}],251:[function(require,module,exports){
24960Object.defineProperty(exports, '__esModule', { value: true });
24961
24962const utils = require('@sentry/utils');
24963const debugBuild = require('./debug-build.js');
24964const eventProcessors = require('./eventProcessors.js');
24965const exports$1 = require('./exports.js');
24966const hub = require('./hub.js');
24967
24968const installedIntegrations = [];
24969
24970/** Map of integrations assigned to a client */
24971
24972/**
24973 * Remove duplicates from the given array, preferring the last instance of any duplicate. Not guaranteed to
24974 * preseve the order of integrations in the array.
24975 *
24976 * @private
24977 */
24978function filterDuplicates(integrations) {
24979  const integrationsByName = {};
24980
24981  integrations.forEach(currentInstance => {
24982    const { name } = currentInstance;
24983
24984    const existingInstance = integrationsByName[name];
24985
24986    // We want integrations later in the array to overwrite earlier ones of the same type, except that we never want a
24987    // default instance to overwrite an existing user instance
24988    if (existingInstance && !existingInstance.isDefaultInstance && currentInstance.isDefaultInstance) {
24989      return;
24990    }
24991
24992    integrationsByName[name] = currentInstance;
24993  });
24994
24995  return Object.keys(integrationsByName).map(k => integrationsByName[k]);
24996}
24997
24998/** Gets integrations to install */
24999function getIntegrationsToSetup(options) {
25000  const defaultIntegrations = options.defaultIntegrations || [];
25001  const userIntegrations = options.integrations;
25002
25003  // We flag default instances, so that later we can tell them apart from any user-created instances of the same class
25004  defaultIntegrations.forEach(integration => {
25005    integration.isDefaultInstance = true;
25006  });
25007
25008  let integrations;
25009
25010  if (Array.isArray(userIntegrations)) {
25011    integrations = [...defaultIntegrations, ...userIntegrations];
25012  } else if (typeof userIntegrations === 'function') {
25013    integrations = utils.arrayify(userIntegrations(defaultIntegrations));
25014  } else {
25015    integrations = defaultIntegrations;
25016  }
25017
25018  const finalIntegrations = filterDuplicates(integrations);
25019
25020  // The `Debug` integration prints copies of the `event` and `hint` which will be passed to `beforeSend` or
25021  // `beforeSendTransaction`. It therefore has to run after all other integrations, so that the changes of all event
25022  // processors will be reflected in the printed values. For lack of a more elegant way to guarantee that, we therefore
25023  // locate it and, assuming it exists, pop it out of its current spot and shove it onto the end of the array.
25024  const debugIndex = findIndex(finalIntegrations, integration => integration.name === 'Debug');
25025  if (debugIndex !== -1) {
25026    const [debugInstance] = finalIntegrations.splice(debugIndex, 1);
25027    finalIntegrations.push(debugInstance);
25028  }
25029
25030  return finalIntegrations;
25031}
25032
25033/**
25034 * Given a list of integration instances this installs them all. When `withDefaults` is set to `true` then all default
25035 * integrations are added unless they were already provided before.
25036 * @param integrations array of integration instances
25037 * @param withDefault should enable default integrations
25038 */
25039function setupIntegrations(client, integrations) {
25040  const integrationIndex = {};
25041
25042  integrations.forEach(integration => {
25043    // guard against empty provided integrations
25044    if (integration) {
25045      setupIntegration(client, integration, integrationIndex);
25046    }
25047  });
25048
25049  return integrationIndex;
25050}
25051
25052/**
25053 * Execute the `afterAllSetup` hooks of the given integrations.
25054 */
25055function afterSetupIntegrations(client, integrations) {
25056  for (const integration of integrations) {
25057    // guard against empty provided integrations
25058    if (integration && integration.afterAllSetup) {
25059      integration.afterAllSetup(client);
25060    }
25061  }
25062}
25063
25064/** Setup a single integration.  */
25065function setupIntegration(client, integration, integrationIndex) {
25066  if (integrationIndex[integration.name]) {
25067    debugBuild.DEBUG_BUILD && utils.logger.log(`Integration skipped because it was already installed: ${integration.name}`);
25068    return;
25069  }
25070  integrationIndex[integration.name] = integration;
25071
25072  // `setupOnce` is only called the first time
25073  if (installedIntegrations.indexOf(integration.name) === -1) {
25074    // eslint-disable-next-line deprecation/deprecation
25075    integration.setupOnce(eventProcessors.addGlobalEventProcessor, hub.getCurrentHub);
25076    installedIntegrations.push(integration.name);
25077  }
25078
25079  // `setup` is run for each client
25080  if (integration.setup && typeof integration.setup === 'function') {
25081    integration.setup(client);
25082  }
25083
25084  if (client.on && typeof integration.preprocessEvent === 'function') {
25085    const callback = integration.preprocessEvent.bind(integration) ;
25086    client.on('preprocessEvent', (event, hint) => callback(event, hint, client));
25087  }
25088
25089  if (client.addEventProcessor && typeof integration.processEvent === 'function') {
25090    const callback = integration.processEvent.bind(integration) ;
25091
25092    const processor = Object.assign((event, hint) => callback(event, hint, client), {
25093      id: integration.name,
25094    });
25095
25096    client.addEventProcessor(processor);
25097  }
25098
25099  debugBuild.DEBUG_BUILD && utils.logger.log(`Integration installed: ${integration.name}`);
25100}
25101
25102/** Add an integration to the current hub's client. */
25103function addIntegration(integration) {
25104  const client = exports$1.getClient();
25105
25106  if (!client || !client.addIntegration) {
25107    debugBuild.DEBUG_BUILD && utils.logger.warn(`Cannot add integration "${integration.name}" because no SDK Client is available.`);
25108    return;
25109  }
25110
25111  client.addIntegration(integration);
25112}
25113
25114// Polyfill for Array.findIndex(), which is not supported in ES5
25115function findIndex(arr, callback) {
25116  for (let i = 0; i < arr.length; i++) {
25117    if (callback(arr[i]) === true) {
25118      return i;
25119    }
25120  }
25121
25122  return -1;
25123}
25124
25125/**
25126 * Convert a new integration function to the legacy class syntax.
25127 * In v8, we can remove this and instead export the integration functions directly.
25128 *
25129 * @deprecated This will be removed in v8!
25130 */
25131function convertIntegrationFnToClass(
25132  name,
25133  fn,
25134) {
25135  return Object.assign(
25136    function ConvertedIntegration(...args) {
25137      return fn(...args);
25138    },
25139    { id: name },
25140  ) ;
25141}
25142
25143/**
25144 * Define an integration function that can be used to create an integration instance.
25145 * Note that this by design hides the implementation details of the integration, as they are considered internal.
25146 */
25147function defineIntegration(fn) {
25148  return fn;
25149}
25150
25151exports.addIntegration = addIntegration;
25152exports.afterSetupIntegrations = afterSetupIntegrations;
25153exports.convertIntegrationFnToClass = convertIntegrationFnToClass;
25154exports.defineIntegration = defineIntegration;
25155exports.getIntegrationsToSetup = getIntegrationsToSetup;
25156exports.installedIntegrations = installedIntegrations;
25157exports.setupIntegration = setupIntegration;
25158exports.setupIntegrations = setupIntegrations;
25159
25160
25161},{"./debug-build.js":245,"./eventProcessors.js":247,"./exports.js":248,"./hub.js":249,"@sentry/utils":319}],252:[function(require,module,exports){
25162Object.defineProperty(exports, '__esModule', { value: true });
25163
25164const utils = require('@sentry/utils');
25165const exports$1 = require('../exports.js');
25166const integration = require('../integration.js');
25167
25168let originalFunctionToString;
25169
25170const INTEGRATION_NAME = 'FunctionToString';
25171
25172const SETUP_CLIENTS = new WeakMap();
25173
25174const _functionToStringIntegration = (() => {
25175  return {
25176    name: INTEGRATION_NAME,
25177    setupOnce() {
25178      // eslint-disable-next-line @typescript-eslint/unbound-method
25179      originalFunctionToString = Function.prototype.toString;
25180
25181      // intrinsics (like Function.prototype) might be immutable in some environments
25182      // e.g. Node with --frozen-intrinsics, XS (an embedded JavaScript engine) or SES (a JavaScript proposal)
25183      try {
25184        // eslint-disable-next-line @typescript-eslint/no-explicit-any
25185        Function.prototype.toString = function ( ...args) {
25186          const originalFunction = utils.getOriginalFunction(this);
25187          const context =
25188            SETUP_CLIENTS.has(exports$1.getClient() ) && originalFunction !== undefined ? originalFunction : this;
25189          return originalFunctionToString.apply(context, args);
25190        };
25191      } catch (e) {
25192        // ignore errors here, just don't patch this
25193      }
25194    },
25195    setup(client) {
25196      SETUP_CLIENTS.set(client, true);
25197    },
25198  };
25199}) ;
25200
25201/**
25202 * Patch toString calls to return proper name for wrapped functions.
25203 *
25204 * ```js
25205 * Sentry.init({
25206 *   integrations: [
25207 *     functionToStringIntegration(),
25208 *   ],
25209 * });
25210 * ```
25211 */
25212const functionToStringIntegration = integration.defineIntegration(_functionToStringIntegration);
25213
25214/**
25215 * Patch toString calls to return proper name for wrapped functions.
25216 *
25217 * @deprecated Use `functionToStringIntegration()` instead.
25218 */
25219// eslint-disable-next-line deprecation/deprecation
25220const FunctionToString = integration.convertIntegrationFnToClass(
25221  INTEGRATION_NAME,
25222  functionToStringIntegration,
25223) ;
25224
25225// eslint-disable-next-line deprecation/deprecation
25226
25227exports.FunctionToString = FunctionToString;
25228exports.functionToStringIntegration = functionToStringIntegration;
25229
25230
25231},{"../exports.js":248,"../integration.js":251,"@sentry/utils":319}],253:[function(require,module,exports){
25232Object.defineProperty(exports, '__esModule', { value: true });
25233
25234const utils = require('@sentry/utils');
25235const debugBuild = require('../debug-build.js');
25236const integration = require('../integration.js');
25237
25238// "Script error." is hard coded into browsers for errors that it can't read.
25239// this is the result of a script being pulled in from an external domain and CORS.
25240const DEFAULT_IGNORE_ERRORS = [/^Script error\.?$/, /^Javascript error: Script error\.? on line 0$/];
25241
25242const DEFAULT_IGNORE_TRANSACTIONS = [
25243  /^.*\/healthcheck$/,
25244  /^.*\/healthy$/,
25245  /^.*\/live$/,
25246  /^.*\/ready$/,
25247  /^.*\/heartbeat$/,
25248  /^.*\/health$/,
25249  /^.*\/healthz$/,
25250];
25251
25252/** Options for the InboundFilters integration */
25253
25254const INTEGRATION_NAME = 'InboundFilters';
25255const _inboundFiltersIntegration = ((options = {}) => {
25256  return {
25257    name: INTEGRATION_NAME,
25258    // TODO v8: Remove this
25259    setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
25260    processEvent(event, _hint, client) {
25261      const clientOptions = client.getOptions();
25262      const mergedOptions = _mergeOptions(options, clientOptions);
25263      return _shouldDropEvent(event, mergedOptions) ? null : event;
25264    },
25265  };
25266}) ;
25267
25268const inboundFiltersIntegration = integration.defineIntegration(_inboundFiltersIntegration);
25269
25270/**
25271 * Inbound filters configurable by the user.
25272 * @deprecated Use `inboundFiltersIntegration()` instead.
25273 */
25274// eslint-disable-next-line deprecation/deprecation
25275const InboundFilters = integration.convertIntegrationFnToClass(
25276  INTEGRATION_NAME,
25277  inboundFiltersIntegration,
25278)
25279
25280;
25281
25282function _mergeOptions(
25283  internalOptions = {},
vendor: 4,472 bytes, lines 25284-25420
25284  clientOptions = {},
25285) {
25286  return {
25287    allowUrls: [...(internalOptions.allowUrls || []), ...(clientOptions.allowUrls || [])],
25288    denyUrls: [...(internalOptions.denyUrls || []), ...(clientOptions.denyUrls || [])],
25289    ignoreErrors: [
25290      ...(internalOptions.ignoreErrors || []),
25291      ...(clientOptions.ignoreErrors || []),
25292      ...(internalOptions.disableErrorDefaults ? [] : DEFAULT_IGNORE_ERRORS),
25293    ],
25294    ignoreTransactions: [
25295      ...(internalOptions.ignoreTransactions || []),
25296      ...(clientOptions.ignoreTransactions || []),
25297      ...(internalOptions.disableTransactionDefaults ? [] : DEFAULT_IGNORE_TRANSACTIONS),
25298    ],
25299    ignoreInternal: internalOptions.ignoreInternal !== undefined ? internalOptions.ignoreInternal : true,
25300  };
25301}
25302
25303function _shouldDropEvent(event, options) {
25304  if (options.ignoreInternal && _isSentryError(event)) {
25305    debugBuild.DEBUG_BUILD &&
25306      utils.logger.warn(`Event dropped due to being internal Sentry Error.\nEvent: ${utils.getEventDescription(event)}`);
25307    return true;
25308  }
25309  if (_isIgnoredError(event, options.ignoreErrors)) {
25310    debugBuild.DEBUG_BUILD &&
25311      utils.logger.warn(
25312        `Event dropped due to being matched by \`ignoreErrors\` option.\nEvent: ${utils.getEventDescription(event)}`,
25313      );
25314    return true;
25315  }
25316  if (_isIgnoredTransaction(event, options.ignoreTransactions)) {
25317    debugBuild.DEBUG_BUILD &&
25318      utils.logger.warn(
25319        `Event dropped due to being matched by \`ignoreTransactions\` option.\nEvent: ${utils.getEventDescription(event)}`,
25320      );
25321    return true;
25322  }
25323  if (_isDeniedUrl(event, options.denyUrls)) {
25324    debugBuild.DEBUG_BUILD &&
25325      utils.logger.warn(
25326        `Event dropped due to being matched by \`denyUrls\` option.\nEvent: ${utils.getEventDescription(
25327          event,
25328        )}.\nUrl: ${_getEventFilterUrl(event)}`,
25329      );
25330    return true;
25331  }
25332  if (!_isAllowedUrl(event, options.allowUrls)) {
25333    debugBuild.DEBUG_BUILD &&
25334      utils.logger.warn(
25335        `Event dropped due to not being matched by \`allowUrls\` option.\nEvent: ${utils.getEventDescription(
25336          event,
25337        )}.\nUrl: ${_getEventFilterUrl(event)}`,
25338      );
25339    return true;
25340  }
25341  return false;
25342}
25343
25344function _isIgnoredError(event, ignoreErrors) {
25345  // If event.type, this is not an error
25346  if (event.type || !ignoreErrors || !ignoreErrors.length) {
25347    return false;
25348  }
25349
25350  return _getPossibleEventMessages(event).some(message => utils.stringMatchesSomePattern(message, ignoreErrors));
25351}
25352
25353function _isIgnoredTransaction(event, ignoreTransactions) {
25354  if (event.type !== 'transaction' || !ignoreTransactions || !ignoreTransactions.length) {
25355    return false;
25356  }
25357
25358  const name = event.transaction;
25359  return name ? utils.stringMatchesSomePattern(name, ignoreTransactions) : false;
25360}
25361
25362function _isDeniedUrl(event, denyUrls) {
25363  // TODO: Use Glob instead?
25364  if (!denyUrls || !denyUrls.length) {
25365    return false;
25366  }
25367  const url = _getEventFilterUrl(event);
25368  return !url ? false : utils.stringMatchesSomePattern(url, denyUrls);
25369}
25370
25371function _isAllowedUrl(event, allowUrls) {
25372  // TODO: Use Glob instead?
25373  if (!allowUrls || !allowUrls.length) {
25374    return true;
25375  }
25376  const url = _getEventFilterUrl(event);
25377  return !url ? true : utils.stringMatchesSomePattern(url, allowUrls);
25378}
25379
25380function _getPossibleEventMessages(event) {
25381  const possibleMessages = [];
25382
25383  if (event.message) {
25384    possibleMessages.push(event.message);
25385  }
25386
25387  let lastException;
25388  try {
25389    // @ts-expect-error Try catching to save bundle size
25390    // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
25391    lastException = event.exception.values[event.exception.values.length - 1];
25392  } catch (e) {
25393    // try catching to save bundle size checking existence of variables
25394  }
25395
25396  if (lastException) {
25397    if (lastException.value) {
25398      possibleMessages.push(lastException.value);
25399      if (lastException.type) {
25400        possibleMessages.push(`${lastException.type}: ${lastException.value}`);
25401      }
25402    }
25403  }
25404
25405  if (debugBuild.DEBUG_BUILD && possibleMessages.length === 0) {
25406    utils.logger.error(`Could not extract message for event ${utils.getEventDescription(event)}`);
25407  }
25408
25409  return possibleMessages;
25410}
25411
25412function _isSentryError(event) {
25413  try {
25414    // @ts-expect-error can't be a sentry error if undefined
25415    // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
25416    return event.exception.values[0].type === 'SentryError';
25417  } catch (e) {
25418    // ignore
25419  }
25420  return false;
25421}
25422
25423function _getLastValidUrl(frames = []) {
25424  for (let i = frames.length - 1; i >= 0; i--) {
25425    const frame = frames[i];
25426
25427    if (frame && frame.filename !== '<anonymous>' && frame.filename !== '[native code]') {
25428      return frame.filename || null;
25429    }
25430  }
25431
25432  return null;
25433}
25434
25435function _getEventFilterUrl(event) {
25436  try {
25437    let frames;
25438    try {
25439      // @ts-expect-error we only care about frames if the whole thing here is defined
25440      frames = event.exception.values[0].stacktrace.frames;
25441    } catch (e) {
25442      // ignore
25443    }
25444    return frames ? _getLastValidUrl(frames) : null;
25445  } catch (oO) {
25446    debugBuild.DEBUG_BUILD && utils.logger.error(`Cannot extract url for event ${utils.getEventDescription(event)}`);
25447    return null;
25448  }
25449}
25450
25451exports.InboundFilters = InboundFilters;
25452exports.inboundFiltersIntegration = inboundFiltersIntegration;
25453
25454
25455},{"../debug-build.js":245,"../integration.js":251,"@sentry/utils":319}],254:[function(require,module,exports){
25456Object.defineProperty(exports, '__esModule', { value: true });
25457
25458const functiontostring = require('./functiontostring.js');
25459const inboundfilters = require('./inboundfilters.js');
25460const linkederrors = require('./linkederrors.js');
25461
25462/* eslint-disable deprecation/deprecation */
25463
25464exports.FunctionToString = functiontostring.FunctionToString;
25465exports.InboundFilters = inboundfilters.InboundFilters;
25466exports.LinkedErrors = linkederrors.LinkedErrors;
25467
25468
25469},{"./functiontostring.js":252,"./inboundfilters.js":253,"./linkederrors.js":255}],255:[function(require,module,exports){
25470Object.defineProperty(exports, '__esModule', { value: true });
25471
25472const utils = require('@sentry/utils');
25473const integration = require('../integration.js');
25474
25475const DEFAULT_KEY = 'cause';
25476const DEFAULT_LIMIT = 5;
25477
25478const INTEGRATION_NAME = 'LinkedErrors';
25479
25480const _linkedErrorsIntegration = ((options = {}) => {
25481  const limit = options.limit || DEFAULT_LIMIT;
25482  const key = options.key || DEFAULT_KEY;
25483
25484  return {
25485    name: INTEGRATION_NAME,
25486    // TODO v8: Remove this
25487    setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
25488    preprocessEvent(event, hint, client) {
25489      const options = client.getOptions();
25490
25491      utils.applyAggregateErrorsToEvent(
25492        utils.exceptionFromError,
25493        options.stackParser,
25494        options.maxValueLength,
25495        key,
25496        limit,
25497        event,
25498        hint,
25499      );
25500    },
25501  };
25502}) ;
25503
25504const linkedErrorsIntegration = integration.defineIntegration(_linkedErrorsIntegration);
25505
25506/**
25507 * Adds SDK info to an event.
25508 * @deprecated Use `linkedErrorsIntegration()` instead.
25509 */
25510// eslint-disable-next-line deprecation/deprecation
25511const LinkedErrors = integration.convertIntegrationFnToClass(INTEGRATION_NAME, linkedErrorsIntegration)
25512
25513;
25514
25515exports.LinkedErrors = LinkedErrors;
25516exports.linkedErrorsIntegration = linkedErrorsIntegration;
25517
25518
25519},{"../integration.js":251,"@sentry/utils":319}],256:[function(require,module,exports){
25520Object.defineProperty(exports, '__esModule', { value: true });
25521
25522const utils = require('@sentry/utils');
25523const integration = require('../integration.js');
25524const metadata = require('../metadata.js');
25525
25526const INTEGRATION_NAME = 'ModuleMetadata';
25527
25528const _moduleMetadataIntegration = (() => {
25529  return {
25530    name: INTEGRATION_NAME,
25531    // TODO v8: Remove this
25532    setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
25533    setup(client) {
25534      if (typeof client.on !== 'function') {
25535        return;
25536      }
25537
25538      // We need to strip metadata from stack frames before sending them to Sentry since these are client side only.
25539      client.on('beforeEnvelope', envelope => {
25540        utils.forEachEnvelopeItem(envelope, (item, type) => {
25541          if (type === 'event') {
25542            const event = Array.isArray(item) ? (item )[1] : undefined;
25543
25544            if (event) {
25545              metadata.stripMetadataFromStackFrames(event);
25546              item[1] = event;
25547            }
25548          }
25549        });
25550      });
25551    },
25552
25553    processEvent(event, _hint, client) {
25554      const stackParser = client.getOptions().stackParser;
25555      metadata.addMetadataToStackFrames(stackParser, event);
25556      return event;
25557    },
25558  };
25559}) ;
25560
25561const moduleMetadataIntegration = integration.defineIntegration(_moduleMetadataIntegration);
25562
25563/**
25564 * Adds module metadata to stack frames.
25565 *
25566 * Metadata can be injected by the Sentry bundler plugins using the `_experiments.moduleMetadata` config option.
25567 *
25568 * When this integration is added, the metadata passed to the bundler plugin is added to the stack frames of all events
25569 * under the `module_metadata` property. This can be used to help in tagging or routing of events from different teams
25570 * our sources
25571 *
25572 * @deprecated Use `moduleMetadataIntegration()` instead.
25573 */
25574// eslint-disable-next-line deprecation/deprecation
25575const ModuleMetadata = integration.convertIntegrationFnToClass(
25576  INTEGRATION_NAME,
25577  moduleMetadataIntegration,
25578)
25579
25580;
25581
25582exports.ModuleMetadata = ModuleMetadata;
25583exports.moduleMetadataIntegration = moduleMetadataIntegration;
25584
25585
25586},{"../integration.js":251,"../metadata.js":258,"@sentry/utils":319}],257:[function(require,module,exports){
25587Object.defineProperty(exports, '__esModule', { value: true });
25588
25589const utils = require('@sentry/utils');
25590const integration = require('../integration.js');
25591const spanUtils = require('../utils/spanUtils.js');
25592
25593const DEFAULT_OPTIONS = {
25594  include: {
25595    cookies: true,
25596    data: true,
25597    headers: true,
25598    ip: false,
25599    query_string: true,
25600    url: true,
25601    user: {
25602      id: true,
25603      username: true,
25604      email: true,
25605    },
25606  },
25607  transactionNamingScheme: 'methodPath',
25608};
25609
25610const INTEGRATION_NAME = 'RequestData';
25611
25612const _requestDataIntegration = ((options = {}) => {
25613  const _addRequestData = utils.addRequestDataToEvent;
25614  const _options = {
25615    ...DEFAULT_OPTIONS,
25616    ...options,
25617    include: {
25618      // @ts-expect-error It's mad because `method` isn't a known `include` key. (It's only here and not set by default in
25619      // `addRequestDataToEvent` for legacy reasons. TODO (v8): Change that.)
25620      method: true,
25621      ...DEFAULT_OPTIONS.include,
25622      ...options.include,
25623      user:
25624        options.include && typeof options.include.user === 'boolean'
25625          ? options.include.user
25626          : {
25627              ...DEFAULT_OPTIONS.include.user,
25628              // Unclear why TS still thinks `options.include.user` could be a boolean at this point
25629              ...((options.include || {}).user ),
25630            },
25631    },
25632  };
25633
25634  return {
25635    name: INTEGRATION_NAME,
25636    // TODO v8: Remove this
25637    setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
25638    processEvent(event, _hint, client) {
25639      // Note: In the long run, most of the logic here should probably move into the request data utility functions. For
25640      // the moment it lives here, though, until https://github.com/getsentry/sentry-javascript/issues/5718 is addressed.
25641      // (TL;DR: Those functions touch many parts of the repo in many different ways, and need to be clened up. Once
25642      // that's happened, it will be easier to add this logic in without worrying about unexpected side effects.)
25643      const { transactionNamingScheme } = _options;
25644
25645      const { sdkProcessingMetadata = {} } = event;
25646      const req = sdkProcessingMetadata.request;
25647
25648      if (!req) {
25649        return event;
25650      }
25651
25652      // The Express request handler takes a similar `include` option to that which can be passed to this integration.
25653      // If passed there, we store it in `sdkProcessingMetadata`. TODO(v8): Force express and GCP people to use this
25654      // integration, so that all of this passing and conversion isn't necessary
25655      const addRequestDataOptions =
25656        sdkProcessingMetadata.requestDataOptionsFromExpressHandler ||
25657        sdkProcessingMetadata.requestDataOptionsFromGCPWrapper ||
25658        convertReqDataIntegrationOptsToAddReqDataOpts(_options);
25659
25660      const processedEvent = _addRequestData(event, req, addRequestDataOptions);
25661
25662      // Transaction events already have the right `transaction` value
25663      if (event.type === 'transaction' || transactionNamingScheme === 'handler') {
25664        return processedEvent;
25665      }
25666
25667      // In all other cases, use the request's associated transaction (if any) to overwrite the event's `transaction`
25668      // value with a high-quality one
25669      const reqWithTransaction = req ;
25670      const transaction = reqWithTransaction._sentryTransaction;
25671      if (transaction) {
25672        const name = spanUtils.spanToJSON(transaction).description || '';
25673
25674        // TODO (v8): Remove the nextjs check and just base it on `transactionNamingScheme` for all SDKs. (We have to
25675        // keep it the way it is for the moment, because changing the names of transactions in Sentry has the potential
25676        // to break things like alert rules.)
25677        const shouldIncludeMethodInTransactionName =
25678          getSDKName(client) === 'sentry.javascript.nextjs'
25679            ? name.startsWith('/api')
25680            : transactionNamingScheme !== 'path';
25681
25682        const [transactionValue] = utils.extractPathForTransaction(req, {
25683          path: true,
25684          method: shouldIncludeMethodInTransactionName,
25685          customRoute: name,
25686        });
25687
25688        processedEvent.transaction = transactionValue;
25689      }
25690
25691      return processedEvent;
25692    },
25693  };
25694}) ;
25695
25696const requestDataIntegration = integration.defineIntegration(_requestDataIntegration);
25697
25698/**
25699 * Add data about a request to an event. Primarily for use in Node-based SDKs, but included in `@sentry/integrations`
25700 * so it can be used in cross-platform SDKs like `@sentry/nextjs`.
25701 * @deprecated Use `requestDataIntegration()` instead.
25702 */
25703// eslint-disable-next-line deprecation/deprecation
25704const RequestData = integration.convertIntegrationFnToClass(INTEGRATION_NAME, requestDataIntegration)
25705
25706;
25707
25708/** Convert this integration's options to match what `addRequestDataToEvent` expects */
25709/** TODO: Can possibly be deleted once https://github.com/getsentry/sentry-javascript/issues/5718 is fixed */
25710function convertReqDataIntegrationOptsToAddReqDataOpts(
25711  integrationOptions,
25712) {
25713  const {
25714    transactionNamingScheme,
25715    include: { ip, user, ...requestOptions },
25716  } = integrationOptions;
25717
25718  const requestIncludeKeys = [];
25719  for (const [key, value] of Object.entries(requestOptions)) {
25720    if (value) {
25721      requestIncludeKeys.push(key);
25722    }
25723  }
25724
25725  let addReqDataUserOpt;
25726  if (user === undefined) {
25727    addReqDataUserOpt = true;
25728  } else if (typeof user === 'boolean') {
25729    addReqDataUserOpt = user;
25730  } else {
25731    const userIncludeKeys = [];
25732    for (const [key, value] of Object.entries(user)) {
25733      if (value) {
25734        userIncludeKeys.push(key);
25735      }
25736    }
25737    addReqDataUserOpt = userIncludeKeys;
25738  }
25739
25740  return {
25741    include: {
25742      ip,
25743      user: addReqDataUserOpt,
25744      request: requestIncludeKeys.length !== 0 ? requestIncludeKeys : undefined,
25745      transaction: transactionNamingScheme,
25746    },
25747  };
25748}
25749
25750function getSDKName(client) {
25751  try {
25752    // For a long chain like this, it's fewer bytes to combine a try-catch with assuming everything is there than to
25753    // write out a long chain of `a && a.b && a.b.c && ...`
25754    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
25755    return client.getOptions()._metadata.sdk.name;
25756  } catch (err) {
25757    // In theory we should never get here
25758    return undefined;
25759  }
25760}
25761
25762exports.RequestData = RequestData;
25763exports.requestDataIntegration = requestDataIntegration;
25764
25765
25766},{"../integration.js":251,"../utils/spanUtils.js":297,"@sentry/utils":319}],258:[function(require,module,exports){
25767Object.defineProperty(exports, '__esModule', { value: true });
25768
25769const utils = require('@sentry/utils');
25770
25771/** Keys are source filename/url, values are metadata objects. */
25772// eslint-disable-next-line @typescript-eslint/no-explicit-any
25773const filenameMetadataMap = new Map();
25774/** Set of stack strings that have already been parsed. */
25775const parsedStacks = new Set();
25776
25777function ensureMetadataStacksAreParsed(parser) {
25778  if (!utils.GLOBAL_OBJ._sentryModuleMetadata) {
25779    return;
25780  }
25781
25782  for (const stack of Object.keys(utils.GLOBAL_OBJ._sentryModuleMetadata)) {
25783    const metadata = utils.GLOBAL_OBJ._sentryModuleMetadata[stack];
25784
25785    if (parsedStacks.has(stack)) {
25786      continue;
25787    }
25788
25789    // Ensure this stack doesn't get parsed again
25790    parsedStacks.add(stack);
25791
25792    const frames = parser(stack);
25793
25794    // Go through the frames starting from the top of the stack and find the first one with a filename
25795    for (const frame of frames.reverse()) {
25796      if (frame.filename) {
25797        // Save the metadata for this filename
25798        filenameMetadataMap.set(frame.filename, metadata);
25799        break;
25800      }
25801    }
25802  }
25803}
25804
25805/**
25806 * Retrieve metadata for a specific JavaScript file URL.
25807 *
25808 * Metadata is injected by the Sentry bundler plugins using the `_experiments.moduleMetadata` config option.
25809 */
25810// eslint-disable-next-line @typescript-eslint/no-explicit-any
25811function getMetadataForUrl(parser, filename) {
25812  ensureMetadataStacksAreParsed(parser);
25813  return filenameMetadataMap.get(filename);
25814}
25815
25816/**
25817 * Adds metadata to stack frames.
25818 *
25819 * Metadata is injected by the Sentry bundler plugins using the `_experiments.moduleMetadata` config option.
25820 */
25821function addMetadataToStackFrames(parser, event) {
25822  try {
25823    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
25824    event.exception.values.forEach(exception => {
25825      if (!exception.stacktrace) {
25826        return;
25827      }
25828
25829      for (const frame of exception.stacktrace.frames || []) {
25830        if (!frame.filename) {
25831          continue;
25832        }
25833
25834        const metadata = getMetadataForUrl(parser, frame.filename);
25835
25836        if (metadata) {
25837          frame.module_metadata = metadata;
25838        }
25839      }
25840    });
25841  } catch (_) {
25842    // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.
25843  }
25844}
25845
25846/**
25847 * Strips metadata from stack frames.
25848 */
25849function stripMetadataFromStackFrames(event) {
25850  try {
25851    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
25852    event.exception.values.forEach(exception => {
25853      if (!exception.stacktrace) {
25854        return;
25855      }
25856
25857      for (const frame of exception.stacktrace.frames || []) {
25858        delete frame.module_metadata;
25859      }
25860    });
25861  } catch (_) {
25862    // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.
25863  }
25864}
25865
25866exports.addMetadataToStackFrames = addMetadataToStackFrames;
25867exports.getMetadataForUrl = getMetadataForUrl;
25868exports.stripMetadataFromStackFrames = stripMetadataFromStackFrames;
25869
25870
25871},{"@sentry/utils":319}],259:[function(require,module,exports){
25872Object.defineProperty(exports, '__esModule', { value: true });
25873
25874const utils$1 = require('@sentry/utils');
25875const constants = require('./constants.js');
25876const instance = require('./instance.js');
25877const metricSummary = require('./metric-summary.js');
25878const utils = require('./utils.js');
25879
25880/**
25881 * A metrics aggregator that aggregates metrics in memory and flushes them periodically.
25882 */
25883class MetricsAggregator  {
25884  // TODO(@anonrig): Use FinalizationRegistry to have a proper way of flushing the buckets
25885  // when the aggregator is garbage collected.
25886  // Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry
25887
25888  // Different metrics have different weights. We use this to limit the number of metrics
25889  // that we store in memory.
25890
25891  // SDKs are required to shift the flush interval by random() * rollup_in_seconds.
25892  // That shift is determined once per startup to create jittering.
25893
25894  // An SDK is required to perform force flushing ahead of scheduled time if the memory
25895  // pressure is too high. There is no rule for this other than that SDKs should be tracking
25896  // abstract aggregation complexity (eg: a counter only carries a single float, whereas a
25897  // distribution is a float per emission).
25898  //
25899  // Force flush is used on either shutdown, flush() or when we exceed the max weight.
25900
25901   constructor(  _client) {this._client = _client;
25902    this._buckets = new Map();
25903    this._bucketsTotalWeight = 0;
25904    this._interval = setInterval(() => this._flush(), constants.DEFAULT_FLUSH_INTERVAL);
25905    this._flushShift = Math.floor((Math.random() * constants.DEFAULT_FLUSH_INTERVAL) / 1000);
25906    this._forceFlush = false;
25907  }
25908
25909  /**
25910   * @inheritDoc
25911   */
25912   add(
25913    metricType,
25914    unsanitizedName,
25915    value,
25916    unit = 'none',
25917    unsanitizedTags = {},
25918    maybeFloatTimestamp = utils$1.timestampInSeconds(),
25919  ) {
25920    const timestamp = Math.floor(maybeFloatTimestamp);
25921    const name = unsanitizedName.replace(constants.NAME_AND_TAG_KEY_NORMALIZATION_REGEX, '_');
25922    const tags = utils.sanitizeTags(unsanitizedTags);
25923
25924    const bucketKey = utils.getBucketKey(metricType, name, unit, tags);
25925
25926    let bucketItem = this._buckets.get(bucketKey);
25927    // If this is a set metric, we need to calculate the delta from the previous weight.
25928    const previousWeight = bucketItem && metricType === constants.SET_METRIC_TYPE ? bucketItem.metric.weight : 0;
25929
25930    if (bucketItem) {
25931      bucketItem.metric.add(value);
25932      // TODO(abhi): Do we need this check?
25933      if (bucketItem.timestamp < timestamp) {
25934        bucketItem.timestamp = timestamp;
25935      }
25936    } else {
25937      bucketItem = {
25938        // @ts-expect-error we don't need to narrow down the type of value here, saves bundle size.
25939        metric: new instance.METRIC_MAP[metricType](value),
25940        timestamp,
25941        metricType,
25942        name,
25943        unit,
25944        tags,
25945      };
25946      this._buckets.set(bucketKey, bucketItem);
25947    }
25948
25949    // If value is a string, it's a set metric so calculate the delta from the previous weight.
25950    const val = typeof value === 'string' ? bucketItem.metric.weight - previousWeight : value;
25951    metricSummary.updateMetricSummaryOnActiveSpan(metricType, name, val, unit, unsanitizedTags, bucketKey);
25952
25953    // We need to keep track of the total weight of the buckets so that we can
25954    // flush them when we exceed the max weight.
25955    this._bucketsTotalWeight += bucketItem.metric.weight;
25956
25957    if (this._bucketsTotalWeight >= constants.MAX_WEIGHT) {
25958      this.flush();
25959    }
25960  }
25961
25962  /**
25963   * Flushes the current metrics to the transport via the transport.
25964   */
25965   flush() {
25966    this._forceFlush = true;
25967    this._flush();
25968  }
25969
25970  /**
25971   * Shuts down metrics aggregator and clears all metrics.
25972   */
25973   close() {
25974    this._forceFlush = true;
25975    clearInterval(this._interval);
25976    this._flush();
25977  }
25978
25979  /**
25980   * Flushes the buckets according to the internal state of the aggregator.
25981   * If it is a force flush, which happens on shutdown, it will flush all buckets.
25982   * Otherwise, it will only flush buckets that are older than the flush interval,
25983   * and according to the flush shift.
25984   *
25985   * This function mutates `_forceFlush` and `_bucketsTotalWeight` properties.
25986   */
25987   _flush() {
25988    // TODO(@anonrig): Add Atomics for locking to avoid having force flush and regular flush
25989    // running at the same time.
25990    // Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics
25991
25992    // This path eliminates the need for checking for timestamps since we're forcing a flush.
25993    // Remember to reset the flag, or it will always flush all metrics.
25994    if (this._forceFlush) {
25995      this._forceFlush = false;
25996      this._bucketsTotalWeight = 0;
25997      this._captureMetrics(this._buckets);
25998      this._buckets.clear();
25999      return;
26000    }
26001    const cutoffSeconds = Math.floor(utils$1.timestampInSeconds()) - constants.DEFAULT_FLUSH_INTERVAL / 1000 - this._flushShift;
26002    // TODO(@anonrig): Optimization opportunity.
26003    // Convert this map to an array and store key in the bucketItem.
26004    const flushedBuckets = new Map();
26005    for (const [key, bucket] of this._buckets) {
26006      if (bucket.timestamp <= cutoffSeconds) {
26007        flushedBuckets.set(key, bucket);
26008        this._bucketsTotalWeight -= bucket.metric.weight;
26009      }
26010    }
26011
26012    for (const [key] of flushedBuckets) {
26013      this._buckets.delete(key);
26014    }
26015
26016    this._captureMetrics(flushedBuckets);
26017  }
26018
26019  /**
26020   * Only captures a subset of the buckets passed to this function.
26021   * @param flushedBuckets
26022   */
26023   _captureMetrics(flushedBuckets) {
26024    if (flushedBuckets.size > 0 && this._client.captureAggregateMetrics) {
26025      // TODO(@anonrig): Optimization opportunity.
26026      // This copy operation can be avoided if we store the key in the bucketItem.
26027      const buckets = Array.from(flushedBuckets).map(([, bucketItem]) => bucketItem);
26028      this._client.captureAggregateMetrics(buckets);
26029    }
26030  }
26031}
26032
26033exports.MetricsAggregator = MetricsAggregator;
26034
26035
26036},{"./constants.js":261,"./instance.js":264,"./metric-summary.js":266,"./utils.js":267,"@sentry/utils":319}],260:[function(require,module,exports){
26037Object.defineProperty(exports, '__esModule', { value: true });
26038
26039const utils$1 = require('@sentry/utils');
26040const constants = require('./constants.js');
26041const instance = require('./instance.js');
26042const metricSummary = require('./metric-summary.js');
26043const utils = require('./utils.js');
26044
26045/**
26046 * A simple metrics aggregator that aggregates metrics in memory and flushes them periodically.
26047 * Default flush interval is 5 seconds.
26048 *
26049 * @experimental This API is experimental and might change in the future.
26050 */
26051class BrowserMetricsAggregator  {
26052  // TODO(@anonrig): Use FinalizationRegistry to have a proper way of flushing the buckets
26053  // when the aggregator is garbage collected.
26054  // Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry
26055
26056   constructor(  _client) {this._client = _client;
26057    this._buckets = new Map();
26058    this._interval = setInterval(() => this.flush(), constants.DEFAULT_BROWSER_FLUSH_INTERVAL);
26059  }
26060
26061  /**
26062   * @inheritDoc
26063   */
26064   add(
26065    metricType,
26066    unsanitizedName,
26067    value,
26068    unit = 'none',
26069    unsanitizedTags = {},
26070    maybeFloatTimestamp = utils$1.timestampInSeconds(),
26071  ) {
26072    const timestamp = Math.floor(maybeFloatTimestamp);
26073    const name = unsanitizedName.replace(constants.NAME_AND_TAG_KEY_NORMALIZATION_REGEX, '_');
26074    const tags = utils.sanitizeTags(unsanitizedTags);
26075
26076    const bucketKey = utils.getBucketKey(metricType, name, unit, tags);
26077
26078    let bucketItem = this._buckets.get(bucketKey);
26079    // If this is a set metric, we need to calculate the delta from the previous weight.
26080    const previousWeight = bucketItem && metricType === constants.SET_METRIC_TYPE ? bucketItem.metric.weight : 0;
26081
26082    if (bucketItem) {
26083      bucketItem.metric.add(value);
26084      // TODO(abhi): Do we need this check?
26085      if (bucketItem.timestamp < timestamp) {
26086        bucketItem.timestamp = timestamp;
26087      }
26088    } else {
26089      bucketItem = {
26090        // @ts-expect-error we don't need to narrow down the type of value here, saves bundle size.
26091        metric: new instance.METRIC_MAP[metricType](value),
26092        timestamp,
26093        metricType,
26094        name,
26095        unit,
26096        tags,
26097      };
26098      this._buckets.set(bucketKey, bucketItem);
26099    }
26100
26101    // If value is a string, it's a set metric so calculate the delta from the previous weight.
26102    const val = typeof value === 'string' ? bucketItem.metric.weight - previousWeight : value;
26103    metricSummary.updateMetricSummaryOnActiveSpan(metricType, name, val, unit, unsanitizedTags, bucketKey);
26104  }
26105
26106  /**
26107   * @inheritDoc
26108   */
26109   flush() {
26110    // short circuit if buckets are empty.
26111    if (this._buckets.size === 0) {
26112      return;
26113    }
26114    if (this._client.captureAggregateMetrics) {
26115      // TODO(@anonrig): Use Object.values() when we support ES6+
26116      const metricBuckets = Array.from(this._buckets).map(([, bucketItem]) => bucketItem);
26117      this._client.captureAggregateMetrics(metricBuckets);
26118    }
26119    this._buckets.clear();
26120  }
26121
26122  /**
26123   * @inheritDoc
26124   */
26125   close() {
26126    clearInterval(this._interval);
26127    this.flush();
26128  }
26129}
26130
26131exports.BrowserMetricsAggregator = BrowserMetricsAggregator;
26132
26133
26134},{"./constants.js":261,"./instance.js":264,"./metric-summary.js":266,"./utils.js":267,"@sentry/utils":319}],261:[function(require,module,exports){
26135Object.defineProperty(exports, '__esModule', { value: true });
26136
26137const COUNTER_METRIC_TYPE = 'c' ;
26138const GAUGE_METRIC_TYPE = 'g' ;
26139const SET_METRIC_TYPE = 's' ;
26140const DISTRIBUTION_METRIC_TYPE = 'd' ;
26141
26142/**
26143 * Normalization regex for metric names and metric tag names.
26144 *
26145 * This enforces that names and tag keys only contain alphanumeric characters,
26146 * underscores, forward slashes, periods, and dashes.
26147 *
26148 * See: https://develop.sentry.dev/sdk/metrics/#normalization
26149 */
26150const NAME_AND_TAG_KEY_NORMALIZATION_REGEX = /[^a-zA-Z0-9_/.-]+/g;
26151
26152/**
26153 * Normalization regex for metric tag values.
26154 *
26155 * This enforces that values only contain words, digits, or the following
26156 * special characters: _:/@.{}[\]$-
26157 *
26158 * See: https://develop.sentry.dev/sdk/metrics/#normalization
26159 */
26160const TAG_VALUE_NORMALIZATION_REGEX = /[^\w\d\s_:/@.{}[\]$-]+/g;
26161
26162/**
26163 * This does not match spec in https://develop.sentry.dev/sdk/metrics
26164 * but was chosen to optimize for the most common case in browser environments.
26165 */
26166const DEFAULT_BROWSER_FLUSH_INTERVAL = 5000;
26167
26168/**
26169 * SDKs are required to bucket into 10 second intervals (rollup in seconds)
26170 * which is the current lower bound of metric accuracy.
26171 */
26172const DEFAULT_FLUSH_INTERVAL = 10000;
26173
26174/**
26175 * The maximum number of metrics that should be stored in memory.
26176 */
26177const MAX_WEIGHT = 10000;
26178
26179exports.COUNTER_METRIC_TYPE = COUNTER_METRIC_TYPE;
26180exports.DEFAULT_BROWSER_FLUSH_INTERVAL = DEFAULT_BROWSER_FLUSH_INTERVAL;
26181exports.DEFAULT_FLUSH_INTERVAL = DEFAULT_FLUSH_INTERVAL;
26182exports.DISTRIBUTION_METRIC_TYPE = DISTRIBUTION_METRIC_TYPE;
26183exports.GAUGE_METRIC_TYPE = GAUGE_METRIC_TYPE;
26184exports.MAX_WEIGHT = MAX_WEIGHT;
26185exports.NAME_AND_TAG_KEY_NORMALIZATION_REGEX = NAME_AND_TAG_KEY_NORMALIZATION_REGEX;
26186exports.SET_METRIC_TYPE = SET_METRIC_TYPE;
26187exports.TAG_VALUE_NORMALIZATION_REGEX = TAG_VALUE_NORMALIZATION_REGEX;
26188
26189
26190},{}],262:[function(require,module,exports){
26191Object.defineProperty(exports, '__esModule', { value: true });
26192
26193const utils = require('@sentry/utils');
26194const utils$1 = require('./utils.js');
26195
26196/**
26197 * Create envelope from a metric aggregate.
26198 */
26199function createMetricEnvelope(
26200  metricBucketItems,
26201  dsn,
26202  metadata,
26203  tunnel,
26204) {
26205  const headers = {
26206    sent_at: new Date().toISOString(),
26207  };
26208
26209  if (metadata && metadata.sdk) {
26210    headers.sdk = {
26211      name: metadata.sdk.name,
26212      version: metadata.sdk.version,
26213    };
26214  }
26215
26216  if (!!tunnel && dsn) {
26217    headers.dsn = utils.dsnToString(dsn);
26218  }
26219
26220  const item = createMetricEnvelopeItem(metricBucketItems);
26221  return utils.createEnvelope(headers, [item]);
26222}
26223
26224function createMetricEnvelopeItem(metricBucketItems) {
26225  const payload = utils$1.serializeMetricBuckets(metricBucketItems);
26226  const metricHeaders = {
26227    type: 'statsd',
26228    length: payload.length,
26229  };
26230  return [metricHeaders, payload];
26231}
26232
26233exports.createMetricEnvelope = createMetricEnvelope;
26234
26235
26236},{"./utils.js":267,"@sentry/utils":319}],263:[function(require,module,exports){
26237Object.defineProperty(exports, '__esModule', { value: true });
26238
26239const utils = require('@sentry/utils');
26240const debugBuild = require('../debug-build.js');
26241const exports$1 = require('../exports.js');
26242const spanUtils = require('../utils/spanUtils.js');
26243const constants = require('./constants.js');
26244const integration = require('./integration.js');
26245
26246function addToMetricsAggregator(
26247  metricType,
26248  name,
26249  value,
26250  data = {},
26251) {
26252  const client = exports$1.getClient();
26253  const scope = exports$1.getCurrentScope();
26254  if (client) {
26255    if (!client.metricsAggregator) {
26256      debugBuild.DEBUG_BUILD &&
26257        utils.logger.warn('No metrics aggregator enabled. Please add the MetricsAggregator integration to use metrics APIs');
26258      return;
26259    }
26260    const { unit, tags, timestamp } = data;
26261    const { release, environment } = client.getOptions();
26262    // eslint-disable-next-line deprecation/deprecation
26263    const transaction = scope.getTransaction();
26264    const metricTags = {};
26265    if (release) {
26266      metricTags.release = release;
26267    }
26268    if (environment) {
26269      metricTags.environment = environment;
26270    }
26271    if (transaction) {
26272      metricTags.transaction = spanUtils.spanToJSON(transaction).description || '';
26273    }
26274
26275    debugBuild.DEBUG_BUILD && utils.logger.log(`Adding value of ${value} to ${metricType} metric ${name}`);
26276    client.metricsAggregator.add(metricType, name, value, unit, { ...metricTags, ...tags }, timestamp);
26277  }
26278}
26279
26280/**
26281 * Adds a value to a counter metric
26282 *
26283 * @experimental This API is experimental and might have breaking changes in the future.
26284 */
26285function increment(name, value = 1, data) {
26286  addToMetricsAggregator(constants.COUNTER_METRIC_TYPE, name, value, data);
26287}
26288
26289/**
26290 * Adds a value to a distribution metric
26291 *
26292 * @experimental This API is experimental and might have breaking changes in the future.
26293 */
26294function distribution(name, value, data) {
26295  addToMetricsAggregator(constants.DISTRIBUTION_METRIC_TYPE, name, value, data);
26296}
26297
26298/**
26299 * Adds a value to a set metric. Value must be a string or integer.
26300 *
26301 * @experimental This API is experimental and might have breaking changes in the future.
26302 */
26303function set(name, value, data) {
26304  addToMetricsAggregator(constants.SET_METRIC_TYPE, name, value, data);
26305}
26306
26307/**
26308 * Adds a value to a gauge metric
26309 *
26310 * @experimental This API is experimental and might have breaking changes in the future.
26311 */
26312function gauge(name, value, data) {
26313  addToMetricsAggregator(constants.GAUGE_METRIC_TYPE, name, value, data);
26314}
26315
26316const metrics = {
26317  increment,
26318  distribution,
26319  set,
26320  gauge,
26321  /** @deprecated Use `metrics.metricsAggregratorIntegration()` instead. */
26322  // eslint-disable-next-line deprecation/deprecation
26323  MetricsAggregator: integration.MetricsAggregator,
26324  metricsAggregatorIntegration: integration.metricsAggregatorIntegration,
26325};
26326
26327exports.distribution = distribution;
26328exports.gauge = gauge;
26329exports.increment = increment;
26330exports.metrics = metrics;
26331exports.set = set;
26332
26333
26334},{"../debug-build.js":245,"../exports.js":248,"../utils/spanUtils.js":297,"./constants.js":261,"./integration.js":265,"@sentry/utils":319}],264:[function(require,module,exports){
26335Object.defineProperty(exports, '__esModule', { value: true });
26336
26337const constants = require('./constants.js');
26338const utils = require('./utils.js');
26339
26340/**
26341 * A metric instance representing a counter.
26342 */
26343class CounterMetric  {
26344   constructor( _value) {this._value = _value;}
26345
26346  /** @inheritDoc */
26347   get weight() {
26348    return 1;
26349  }
26350
26351  /** @inheritdoc */
26352   add(value) {
26353    this._value += value;
26354  }
26355
26356  /** @inheritdoc */
26357   toString() {
26358    return `${this._value}`;
26359  }
26360}
26361
26362/**
26363 * A metric instance representing a gauge.
26364 */
26365class GaugeMetric  {
26366
26367   constructor(value) {
26368    this._last = value;
26369    this._min = value;
26370    this._max = value;
26371    this._sum = value;
26372    this._count = 1;
26373  }
26374
26375  /** @inheritDoc */
26376   get weight() {
26377    return 5;
26378  }
26379
26380  /** @inheritdoc */
26381   add(value) {
26382    this._last = value;
26383    if (value < this._min) {
26384      this._min = value;
26385    }
26386    if (value > this._max) {
26387      this._max = value;
26388    }
26389    this._sum += value;
26390    this._count++;
26391  }
26392
26393  /** @inheritdoc */
26394   toString() {
26395    return `${this._last}:${this._min}:${this._max}:${this._sum}:${this._count}`;
26396  }
26397}
26398
26399/**
26400 * A metric instance representing a distribution.
26401 */
26402class DistributionMetric  {
26403
26404   constructor(first) {
26405    this._value = [first];
26406  }
26407
26408  /** @inheritDoc */
26409   get weight() {
26410    return this._value.length;
26411  }
26412
26413  /** @inheritdoc */
26414   add(value) {
26415    this._value.push(value);
26416  }
26417
26418  /** @inheritdoc */
26419   toString() {
26420    return this._value.join(':');
26421  }
26422}
26423
26424/**
26425 * A metric instance representing a set.
26426 */
26427class SetMetric  {
26428
26429   constructor( first) {this.first = first;
26430    this._value = new Set([first]);
26431  }
26432
26433  /** @inheritDoc */
26434   get weight() {
26435    return this._value.size;
26436  }
26437
26438  /** @inheritdoc */
26439   add(value) {
26440    this._value.add(value);
26441  }
26442
26443  /** @inheritdoc */
26444   toString() {
26445    return Array.from(this._value)
26446      .map(val => (typeof val === 'string' ? utils.simpleHash(val) : val))
26447      .join(':');
26448  }
26449}
26450
26451const METRIC_MAP = {
26452  [constants.COUNTER_METRIC_TYPE]: CounterMetric,
26453  [constants.GAUGE_METRIC_TYPE]: GaugeMetric,
26454  [constants.DISTRIBUTION_METRIC_TYPE]: DistributionMetric,
26455  [constants.SET_METRIC_TYPE]: SetMetric,
26456};
26457
26458exports.CounterMetric = CounterMetric;
26459exports.DistributionMetric = DistributionMetric;
26460exports.GaugeMetric = GaugeMetric;
26461exports.METRIC_MAP = METRIC_MAP;
26462exports.SetMetric = SetMetric;
26463
26464
26465},{"./constants.js":261,"./utils.js":267}],265:[function(require,module,exports){
26466Object.defineProperty(exports, '__esModule', { value: true });
26467
26468const integration = require('../integration.js');
26469const browserAggregator = require('./browser-aggregator.js');
26470
26471const INTEGRATION_NAME = 'MetricsAggregator';
26472
26473const _metricsAggregatorIntegration = (() => {
26474  return {
26475    name: INTEGRATION_NAME,
26476    // TODO v8: Remove this
26477    setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
26478    setup(client) {
26479      client.metricsAggregator = new browserAggregator.BrowserMetricsAggregator(client);
26480    },
26481  };
26482}) ;
26483
26484const metricsAggregatorIntegration = integration.defineIntegration(_metricsAggregatorIntegration);
26485
26486/**
26487 * Enables Sentry metrics monitoring.
26488 *
26489 * @experimental This API is experimental and might having breaking changes in the future.
26490 * @deprecated Use `metricsAggegratorIntegration()` instead.
26491 */
26492// eslint-disable-next-line deprecation/deprecation
26493const MetricsAggregator = integration.convertIntegrationFnToClass(
26494  INTEGRATION_NAME,
26495  metricsAggregatorIntegration,
26496) ;
26497
26498exports.MetricsAggregator = MetricsAggregator;
26499exports.metricsAggregatorIntegration = metricsAggregatorIntegration;
26500
26501
26502},{"../integration.js":251,"./browser-aggregator.js":260}],266:[function(require,module,exports){
26503Object.defineProperty(exports, '__esModule', { value: true });
26504
26505const utils = require('@sentry/utils');
26506require('../debug-build.js');
26507require('../tracing/errors.js');
26508require('../tracing/spanstatus.js');
26509const trace = require('../tracing/trace.js');
26510
26511/**
26512 * key: bucketKey
26513 * value: [exportKey, MetricSummary]
26514 */
26515
26516let SPAN_METRIC_SUMMARY;
26517
26518function getMetricStorageForSpan(span) {
26519  return SPAN_METRIC_SUMMARY ? SPAN_METRIC_SUMMARY.get(span) : undefined;
26520}
26521
26522/**
26523 * Fetches the metric summary if it exists for the passed span
26524 */
26525function getMetricSummaryJsonForSpan(span) {
26526  const storage = getMetricStorageForSpan(span);
26527
26528  if (!storage) {
26529    return undefined;
26530  }
26531  const output = {};
26532
26533  for (const [, [exportKey, summary]] of storage) {
26534    if (!output[exportKey]) {
26535      output[exportKey] = [];
26536    }
26537
26538    output[exportKey].push(utils.dropUndefinedKeys(summary));
26539  }
26540
26541  return output;
26542}
26543
26544/**
26545 * Updates the metric summary on the currently active span
26546 */
26547function updateMetricSummaryOnActiveSpan(
26548  metricType,
26549  sanitizedName,
26550  value,
26551  unit,
26552  tags,
26553  bucketKey,
26554) {
26555  const span = trace.getActiveSpan();
26556  if (span) {
26557    const storage = getMetricStorageForSpan(span) || new Map();
26558
26559    const exportKey = `${metricType}:${sanitizedName}@${unit}`;
26560    const bucketItem = storage.get(bucketKey);
26561
26562    if (bucketItem) {
26563      const [, summary] = bucketItem;
26564      storage.set(bucketKey, [
26565        exportKey,
26566        {
26567          min: Math.min(summary.min, value),
26568          max: Math.max(summary.max, value),
26569          count: (summary.count += 1),
26570          sum: (summary.sum += value),
26571          tags: summary.tags,
26572        },
26573      ]);
26574    } else {
26575      storage.set(bucketKey, [
26576        exportKey,
26577        {
26578          min: value,
26579          max: value,
26580          count: 1,
26581          sum: value,
26582          tags,
26583        },
26584      ]);
26585    }
26586
26587    if (!SPAN_METRIC_SUMMARY) {
26588      SPAN_METRIC_SUMMARY = new WeakMap();
26589    }
26590
26591    SPAN_METRIC_SUMMARY.set(span, storage);
26592  }
26593}
26594
26595exports.getMetricSummaryJsonForSpan = getMetricSummaryJsonForSpan;
26596exports.updateMetricSummaryOnActiveSpan = updateMetricSummaryOnActiveSpan;
26597
26598
26599},{"../debug-build.js":245,"../tracing/errors.js":276,"../tracing/spanstatus.js":282,"../tracing/trace.js":283,"@sentry/utils":319}],267:[function(require,module,exports){
26600Object.defineProperty(exports, '__esModule', { value: true });
26601
26602const utils = require('@sentry/utils');
26603const constants = require('./constants.js');
26604
26605/**
26606 * Generate bucket key from metric properties.
26607 */
26608function getBucketKey(
26609  metricType,
26610  name,
26611  unit,
26612  tags,
26613) {
26614  const stringifiedTags = Object.entries(utils.dropUndefinedKeys(tags)).sort((a, b) => a[0].localeCompare(b[0]));
26615  return `${metricType}${name}${unit}${stringifiedTags}`;
26616}
26617
26618/* eslint-disable no-bitwise */
26619/**
26620 * Simple hash function for strings.
26621 */
26622function simpleHash(s) {
26623  let rv = 0;
26624  for (let i = 0; i < s.length; i++) {
26625    const c = s.charCodeAt(i);
26626    rv = (rv << 5) - rv + c;
26627    rv &= rv;
26628  }
26629  return rv >>> 0;
26630}
26631/* eslint-enable no-bitwise */
26632
26633/**
26634 * Serialize metrics buckets into a string based on statsd format.
26635 *
26636 * Example of format:
26637 * metric.name@second:1:1.2|d|#a:value,b:anothervalue|T12345677
26638 * Segments:
26639 * name: metric.name
26640 * unit: second
26641 * value: [1, 1.2]
26642 * type of metric: d (distribution)
26643 * tags: { a: value, b: anothervalue }
26644 * timestamp: 12345677
26645 */
26646function serializeMetricBuckets(metricBucketItems) {
26647  let out = '';
26648  for (const item of metricBucketItems) {
26649    const tagEntries = Object.entries(item.tags);
26650    const maybeTags = tagEntries.length > 0 ? `|#${tagEntries.map(([key, value]) => `${key}:${value}`).join(',')}` : '';
26651    out += `${item.name}@${item.unit}:${item.metric}|${item.metricType}${maybeTags}|T${item.timestamp}\n`;
26652  }
26653  return out;
26654}
26655
26656/**
26657 * Sanitizes tags.
26658 */
26659function sanitizeTags(unsanitizedTags) {
26660  const tags = {};
26661  for (const key in unsanitizedTags) {
26662    if (Object.prototype.hasOwnProperty.call(unsanitizedTags, key)) {
26663      const sanitizedKey = key.replace(constants.NAME_AND_TAG_KEY_NORMALIZATION_REGEX, '_');
26664      tags[sanitizedKey] = String(unsanitizedTags[key]).replace(constants.TAG_VALUE_NORMALIZATION_REGEX, '');
26665    }
26666  }
26667  return tags;
26668}
26669
26670exports.getBucketKey = getBucketKey;
26671exports.sanitizeTags = sanitizeTags;
26672exports.serializeMetricBuckets = serializeMetricBuckets;
26673exports.simpleHash = simpleHash;
26674
26675
26676},{"./constants.js":261,"@sentry/utils":319}],268:[function(require,module,exports){
26677Object.defineProperty(exports, '__esModule', { value: true });
26678
26679const utils = require('@sentry/utils');
26680const eventProcessors = require('./eventProcessors.js');
26681const session = require('./session.js');
26682const applyScopeDataToEvent = require('./utils/applyScopeDataToEvent.js');
26683
26684/**
26685 * Default value for maximum number of breadcrumbs added to an event.
26686 */
26687const DEFAULT_MAX_BREADCRUMBS = 100;
26688
26689/**
26690 * The global scope is kept in this module.
26691 * When accessing this via `getGlobalScope()` we'll make sure to set one if none is currently present.
26692 */
26693let globalScope;
26694
26695/**
26696 * Holds additional event information. {@link Scope.applyToEvent} will be
26697 * called by the client before an event will be sent.
26698 */
26699class Scope  {
26700  /** Flag if notifying is happening. */
26701
26702  /** Callback for client to receive scope changes. */
26703
26704  /** Callback list that will be called after {@link applyToEvent}. */
26705
26706  /** Array of breadcrumbs. */
26707
26708  /** User */
26709
26710  /** Tags */
26711
26712  /** Extra */
26713
26714  /** Contexts */
26715
26716  /** Attachments */
26717
26718  /** Propagation Context for distributed tracing */
26719
26720  /**
26721   * A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get
26722   * sent to Sentry
26723   */
26724
26725  /** Fingerprint */
26726
26727  /** Severity */
26728  // eslint-disable-next-line deprecation/deprecation
26729
26730  /**
26731   * Transaction Name
26732   */
26733
26734  /** Span */
26735
26736  /** Session */
26737
26738  /** Request Mode Session Status */
26739
26740  /** The client on this scope */
26741
26742  // NOTE: Any field which gets added here should get added not only to the constructor but also to the `clone` method.
26743
26744   constructor() {
26745    this._notifyingListeners = false;
vendor: 9,158 bytes, lines 26746-27135
26746    this._scopeListeners = [];
26747    this._eventProcessors = [];
26748    this._breadcrumbs = [];
26749    this._attachments = [];
26750    this._user = {};
26751    this._tags = {};
26752    this._extra = {};
26753    this._contexts = {};
26754    this._sdkProcessingMetadata = {};
26755    this._propagationContext = generatePropagationContext();
26756  }
26757
26758  /**
26759   * Inherit values from the parent scope.
26760   * @deprecated Use `scope.clone()` and `new Scope()` instead.
26761   */
26762   static clone(scope) {
26763    return scope ? scope.clone() : new Scope();
26764  }
26765
26766  /**
26767   * Clone this scope instance.
26768   */
26769   clone() {
26770    const newScope = new Scope();
26771    newScope._breadcrumbs = [...this._breadcrumbs];
26772    newScope._tags = { ...this._tags };
26773    newScope._extra = { ...this._extra };
26774    newScope._contexts = { ...this._contexts };
26775    newScope._user = this._user;
26776    newScope._level = this._level;
26777    newScope._span = this._span;
26778    newScope._session = this._session;
26779    newScope._transactionName = this._transactionName;
26780    newScope._fingerprint = this._fingerprint;
26781    newScope._eventProcessors = [...this._eventProcessors];
26782    newScope._requestSession = this._requestSession;
26783    newScope._attachments = [...this._attachments];
26784    newScope._sdkProcessingMetadata = { ...this._sdkProcessingMetadata };
26785    newScope._propagationContext = { ...this._propagationContext };
26786    newScope._client = this._client;
26787
26788    return newScope;
26789  }
26790
26791  /** Update the client on the scope. */
26792   setClient(client) {
26793    this._client = client;
26794  }
26795
26796  /**
26797   * Get the client assigned to this scope.
26798   *
26799   * It is generally recommended to use the global function `Sentry.getClient()` instead, unless you know what you are doing.
26800   */
26801   getClient() {
26802    return this._client;
26803  }
26804
26805  /**
26806   * Add internal on change listener. Used for sub SDKs that need to store the scope.
26807   * @hidden
26808   */
26809   addScopeListener(callback) {
26810    this._scopeListeners.push(callback);
26811  }
26812
26813  /**
26814   * @inheritDoc
26815   */
26816   addEventProcessor(callback) {
26817    this._eventProcessors.push(callback);
26818    return this;
26819  }
26820
26821  /**
26822   * @inheritDoc
26823   */
26824   setUser(user) {
26825    // If null is passed we want to unset everything, but still define keys,
26826    // so that later down in the pipeline any existing values are cleared.
26827    this._user = user || {
26828      email: undefined,
26829      id: undefined,
26830      ip_address: undefined,
26831      segment: undefined,
26832      username: undefined,
26833    };
26834
26835    if (this._session) {
26836      session.updateSession(this._session, { user });
26837    }
26838
26839    this._notifyScopeListeners();
26840    return this;
26841  }
26842
26843  /**
26844   * @inheritDoc
26845   */
26846   getUser() {
26847    return this._user;
26848  }
26849
26850  /**
26851   * @inheritDoc
26852   */
26853   getRequestSession() {
26854    return this._requestSession;
26855  }
26856
26857  /**
26858   * @inheritDoc
26859   */
26860   setRequestSession(requestSession) {
26861    this._requestSession = requestSession;
26862    return this;
26863  }
26864
26865  /**
26866   * @inheritDoc
26867   */
26868   setTags(tags) {
26869    this._tags = {
26870      ...this._tags,
26871      ...tags,
26872    };
26873    this._notifyScopeListeners();
26874    return this;
26875  }
26876
26877  /**
26878   * @inheritDoc
26879   */
26880   setTag(key, value) {
26881    this._tags = { ...this._tags, [key]: value };
26882    this._notifyScopeListeners();
26883    return this;
26884  }
26885
26886  /**
26887   * @inheritDoc
26888   */
26889   setExtras(extras) {
26890    this._extra = {
26891      ...this._extra,
26892      ...extras,
26893    };
26894    this._notifyScopeListeners();
26895    return this;
26896  }
26897
26898  /**
26899   * @inheritDoc
26900   */
26901   setExtra(key, extra) {
26902    this._extra = { ...this._extra, [key]: extra };
26903    this._notifyScopeListeners();
26904    return this;
26905  }
26906
26907  /**
26908   * @inheritDoc
26909   */
26910   setFingerprint(fingerprint) {
26911    this._fingerprint = fingerprint;
26912    this._notifyScopeListeners();
26913    return this;
26914  }
26915
26916  /**
26917   * @inheritDoc
26918   */
26919   setLevel(
26920    // eslint-disable-next-line deprecation/deprecation
26921    level,
26922  ) {
26923    this._level = level;
26924    this._notifyScopeListeners();
26925    return this;
26926  }
26927
26928  /**
26929   * Sets the transaction name on the scope for future events.
26930   */
26931   setTransactionName(name) {
26932    this._transactionName = name;
26933    this._notifyScopeListeners();
26934    return this;
26935  }
26936
26937  /**
26938   * @inheritDoc
26939   */
26940   setContext(key, context) {
26941    if (context === null) {
26942      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
26943      delete this._contexts[key];
26944    } else {
26945      this._contexts[key] = context;
26946    }
26947
26948    this._notifyScopeListeners();
26949    return this;
26950  }
26951
26952  /**
26953   * Sets the Span on the scope.
26954   * @param span Span
26955   * @deprecated Instead of setting a span on a scope, use `startSpan()`/`startSpanManual()` instead.
26956   */
26957   setSpan(span) {
26958    this._span = span;
26959    this._notifyScopeListeners();
26960    return this;
26961  }
26962
26963  /**
26964   * Returns the `Span` if there is one.
26965   * @deprecated Use `getActiveSpan()` instead.
26966   */
26967   getSpan() {
26968    return this._span;
26969  }
26970
26971  /**
26972   * Returns the `Transaction` attached to the scope (if there is one).
26973   * @deprecated You should not rely on the transaction, but just use `startSpan()` APIs instead.
26974   */
26975   getTransaction() {
26976    // Often, this span (if it exists at all) will be a transaction, but it's not guaranteed to be. Regardless, it will
26977    // have a pointer to the currently-active transaction.
26978    const span = this._span;
26979    // Cannot replace with getRootSpan because getRootSpan returns a span, not a transaction
26980    // Also, this method will be removed anyway.
26981    // eslint-disable-next-line deprecation/deprecation
26982    return span && span.transaction;
26983  }
26984
26985  /**
26986   * @inheritDoc
26987   */
26988   setSession(session) {
26989    if (!session) {
26990      delete this._session;
26991    } else {
26992      this._session = session;
26993    }
26994    this._notifyScopeListeners();
26995    return this;
26996  }
26997
26998  /**
26999   * @inheritDoc
27000   */
27001   getSession() {
27002    return this._session;
27003  }
27004
27005  /**
27006   * @inheritDoc
27007   */
27008   update(captureContext) {
27009    if (!captureContext) {
27010      return this;
27011    }
27012
27013    const scopeToMerge = typeof captureContext === 'function' ? captureContext(this) : captureContext;
27014
27015    if (scopeToMerge instanceof Scope) {
27016      const scopeData = scopeToMerge.getScopeData();
27017
27018      this._tags = { ...this._tags, ...scopeData.tags };
27019      this._extra = { ...this._extra, ...scopeData.extra };
27020      this._contexts = { ...this._contexts, ...scopeData.contexts };
27021      if (scopeData.user && Object.keys(scopeData.user).length) {
27022        this._user = scopeData.user;
27023      }
27024      if (scopeData.level) {
27025        this._level = scopeData.level;
27026      }
27027      if (scopeData.fingerprint.length) {
27028        this._fingerprint = scopeData.fingerprint;
27029      }
27030      if (scopeToMerge.getRequestSession()) {
27031        this._requestSession = scopeToMerge.getRequestSession();
27032      }
27033      if (scopeData.propagationContext) {
27034        this._propagationContext = scopeData.propagationContext;
27035      }
27036    } else if (utils.isPlainObject(scopeToMerge)) {
27037      const scopeContext = captureContext ;
27038      this._tags = { ...this._tags, ...scopeContext.tags };
27039      this._extra = { ...this._extra, ...scopeContext.extra };
27040      this._contexts = { ...this._contexts, ...scopeContext.contexts };
27041      if (scopeContext.user) {
27042        this._user = scopeContext.user;
27043      }
27044      if (scopeContext.level) {
27045        this._level = scopeContext.level;
27046      }
27047      if (scopeContext.fingerprint) {
27048        this._fingerprint = scopeContext.fingerprint;
27049      }
27050      if (scopeContext.requestSession) {
27051        this._requestSession = scopeContext.requestSession;
27052      }
27053      if (scopeContext.propagationContext) {
27054        this._propagationContext = scopeContext.propagationContext;
27055      }
27056    }
27057
27058    return this;
27059  }
27060
27061  /**
27062   * @inheritDoc
27063   */
27064   clear() {
27065    this._breadcrumbs = [];
27066    this._tags = {};
27067    this._extra = {};
27068    this._user = {};
27069    this._contexts = {};
27070    this._level = undefined;
27071    this._transactionName = undefined;
27072    this._fingerprint = undefined;
27073    this._requestSession = undefined;
27074    this._span = undefined;
27075    this._session = undefined;
27076    this._notifyScopeListeners();
27077    this._attachments = [];
27078    this._propagationContext = generatePropagationContext();
27079    return this;
27080  }
27081
27082  /**
27083   * @inheritDoc
27084   */
27085   addBreadcrumb(breadcrumb, maxBreadcrumbs) {
27086    const maxCrumbs = typeof maxBreadcrumbs === 'number' ? maxBreadcrumbs : DEFAULT_MAX_BREADCRUMBS;
27087
27088    // No data has been changed, so don't notify scope listeners
27089    if (maxCrumbs <= 0) {
27090      return this;
27091    }
27092
27093    const mergedBreadcrumb = {
27094      timestamp: utils.dateTimestampInSeconds(),
27095      ...breadcrumb,
27096    };
27097
27098    const breadcrumbs = this._breadcrumbs;
27099    breadcrumbs.push(mergedBreadcrumb);
27100    this._breadcrumbs = breadcrumbs.length > maxCrumbs ? breadcrumbs.slice(-maxCrumbs) : breadcrumbs;
27101
27102    this._notifyScopeListeners();
27103
27104    return this;
27105  }
27106
27107  /**
27108   * @inheritDoc
27109   */
27110   getLastBreadcrumb() {
27111    return this._breadcrumbs[this._breadcrumbs.length - 1];
27112  }
27113
27114  /**
27115   * @inheritDoc
27116   */
27117   clearBreadcrumbs() {
27118    this._breadcrumbs = [];
27119    this._notifyScopeListeners();
27120    return this;
27121  }
27122
27123  /**
27124   * @inheritDoc
27125   */
27126   addAttachment(attachment) {
27127    this._attachments.push(attachment);
27128    return this;
27129  }
27130
27131  /**
27132   * @inheritDoc
27133   * @deprecated Use `getScopeData()` instead.
27134   */
27135   getAttachments() {
27136    const data = this.getScopeData();
27137
27138    return data.attachments;
27139  }
27140
27141  /**
27142   * @inheritDoc
27143   */
27144   clearAttachments() {
27145    this._attachments = [];
27146    return this;
27147  }
27148
27149  /** @inheritDoc */
27150   getScopeData() {
27151    const {
27152      _breadcrumbs,
27153      _attachments,
27154      _contexts,
27155      _tags,
27156      _extra,
27157      _user,
27158      _level,
27159      _fingerprint,
27160      _eventProcessors,
27161      _propagationContext,
27162      _sdkProcessingMetadata,
27163      _transactionName,
27164      _span,
27165    } = this;
27166
27167    return {
27168      breadcrumbs: _breadcrumbs,
27169      attachments: _attachments,
27170      contexts: _contexts,
27171      tags: _tags,
27172      extra: _extra,
27173      user: _user,
27174      level: _level,
27175      fingerprint: _fingerprint || [],
27176      eventProcessors: _eventProcessors,
27177      propagationContext: _propagationContext,
27178      sdkProcessingMetadata: _sdkProcessingMetadata,
27179      transactionName: _transactionName,
27180      span: _span,
27181    };
27182  }
27183
27184  /**
27185   * Applies data from the scope to the event and runs all event processors on it.
27186   *
27187   * @param event Event
27188   * @param hint Object containing additional information about the original exception, for use by the event processors.
27189   * @hidden
27190   * @deprecated Use `applyScopeDataToEvent()` directly
27191   */
27192   applyToEvent(
27193    event,
27194    hint = {},
27195    additionalEventProcessors = [],
27196  ) {
27197    applyScopeDataToEvent.applyScopeDataToEvent(event, this.getScopeData());
27198
27199    // TODO (v8): Update this order to be: Global > Client > Scope
27200    const eventProcessors$1 = [
27201      ...additionalEventProcessors,
27202      // eslint-disable-next-line deprecation/deprecation
27203      ...eventProcessors.getGlobalEventProcessors(),
27204      ...this._eventProcessors,
27205    ];
27206
27207    return eventProcessors.notifyEventProcessors(eventProcessors$1, event, hint);
27208  }
27209
27210  /**
27211   * Add data which will be accessible during event processing but won't get sent to Sentry
27212   */
27213   setSDKProcessingMetadata(newData) {
27214    this._sdkProcessingMetadata = { ...this._sdkProcessingMetadata, ...newData };
27215
27216    return this;
27217  }
27218
27219  /**
27220   * @inheritDoc
27221   */
27222   setPropagationContext(context) {
27223    this._propagationContext = context;
27224    return this;
27225  }
27226
27227  /**
27228   * @inheritDoc
27229   */
27230   getPropagationContext() {
27231    return this._propagationContext;
27232  }
27233
27234  /**
27235   * Capture an exception for this scope.
27236   *
27237   * @param exception The exception to capture.
27238   * @param hint Optinal additional data to attach to the Sentry event.
27239   * @returns the id of the captured Sentry event.
27240   */
27241   captureException(exception, hint) {
27242    const eventId = hint && hint.event_id ? hint.event_id : utils.uuid4();
27243
27244    if (!this._client) {
27245      utils.logger.warn('No client configured on scope - will not capture exception!');
27246      return eventId;
27247    }
27248
27249    const syntheticException = new Error('Sentry syntheticException');
27250
27251    this._client.captureException(
27252      exception,
27253      {
27254        originalException: exception,
27255        syntheticException,
27256        ...hint,
27257        event_id: eventId,
27258      },
27259      this,
27260    );
27261
27262    return eventId;
27263  }
27264
27265  /**
27266   * Capture a message for this scope.
27267   *
27268   * @param message The message to capture.
27269   * @param level An optional severity level to report the message with.
27270   * @param hint Optional additional data to attach to the Sentry event.
27271   * @returns the id of the captured message.
27272   */
27273   captureMessage(message, level, hint) {
27274    const eventId = hint && hint.event_id ? hint.event_id : utils.uuid4();
27275
27276    if (!this._client) {
27277      utils.logger.warn('No client configured on scope - will not capture message!');
27278      return eventId;
27279    }
27280
27281    const syntheticException = new Error(message);
27282
27283    this._client.captureMessage(
27284      message,
27285      level,
27286      {
27287        originalException: message,
27288        syntheticException,
27289        ...hint,
27290        event_id: eventId,
27291      },
27292      this,
27293    );
27294
27295    return eventId;
27296  }
27297
27298  /**
27299   * Captures a manually created event for this scope and sends it to Sentry.
27300   *
27301   * @param exception The event to capture.
27302   * @param hint Optional additional data to attach to the Sentry event.
27303   * @returns the id of the captured event.
27304   */
27305   captureEvent(event, hint) {
27306    const eventId = hint && hint.event_id ? hint.event_id : utils.uuid4();
27307
27308    if (!this._client) {
27309      utils.logger.warn('No client configured on scope - will not capture event!');
27310      return eventId;
27311    }
27312
27313    this._client.captureEvent(event, { ...hint, event_id: eventId }, this);
27314
27315    return eventId;
27316  }
27317
27318  /**
27319   * This will be called on every set call.
27320   */
27321   _notifyScopeListeners() {
27322    // We need this check for this._notifyingListeners to be able to work on scope during updates
27323    // If this check is not here we'll produce endless recursion when something is done with the scope
27324    // during the callback.
27325    if (!this._notifyingListeners) {
27326      this._notifyingListeners = true;
27327      this._scopeListeners.forEach(callback => {
27328        callback(this);
27329      });
27330      this._notifyingListeners = false;
27331    }
27332  }
27333}
27334
27335/**
27336 * Get the global scope.
27337 * This scope is applied to _all_ events.
27338 */
27339function getGlobalScope() {
27340  if (!globalScope) {
27341    globalScope = new Scope();
27342  }
27343
27344  return globalScope;
27345}
27346
27347/**
27348 * This is mainly needed for tests.
27349 * DO NOT USE this, as this is an internal API and subject to change.
27350 * @hidden
27351 */
27352function setGlobalScope(scope) {
27353  globalScope = scope;
27354}
27355
27356function generatePropagationContext() {
27357  return {
27358    traceId: utils.uuid4(),
27359    spanId: utils.uuid4().substring(16),
27360  };
27361}
27362
27363exports.Scope = Scope;
27364exports.getGlobalScope = getGlobalScope;
27365exports.setGlobalScope = setGlobalScope;
27366
27367
27368},{"./eventProcessors.js":247,"./session.js":272,"./utils/applyScopeDataToEvent.js":289,"@sentry/utils":319}],269:[function(require,module,exports){
27369Object.defineProperty(exports, '__esModule', { value: true });
27370
27371const utils = require('@sentry/utils');
27372const debugBuild = require('./debug-build.js');
27373const exports$1 = require('./exports.js');
27374const hub = require('./hub.js');
27375
27376/** A class object that can instantiate Client objects. */
27377
27378/**
27379 * Internal function to create a new SDK client instance. The client is
27380 * installed and then bound to the current scope.
27381 *
27382 * @param clientClass The client class to instantiate.
27383 * @param options Options to pass to the client.
27384 */
27385function initAndBind(
27386  clientClass,
27387  options,
27388) {
27389  if (options.debug === true) {
27390    if (debugBuild.DEBUG_BUILD) {
27391      utils.logger.enable();
27392    } else {
27393      // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped
27394      utils.consoleSandbox(() => {
27395        // eslint-disable-next-line no-console
27396        console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');
27397      });
27398    }
27399  }
27400  const scope = exports$1.getCurrentScope();
27401  scope.update(options.initialScope);
27402
27403  const client = new clientClass(options);
27404  setCurrentClient(client);
27405  initializeClient(client);
27406}
27407
27408/**
27409 * Make the given client the current client.
27410 */
27411function setCurrentClient(client) {
27412  // eslint-disable-next-line deprecation/deprecation
27413  const hub$1 = hub.getCurrentHub();
27414  // eslint-disable-next-line deprecation/deprecation
27415  const top = hub$1.getStackTop();
27416  top.client = client;
27417  top.scope.setClient(client);
27418}
27419
27420/**
27421 * Initialize the client for the current scope.
27422 * Make sure to call this after `setCurrentClient()`.
27423 */
27424function initializeClient(client) {
27425  if (client.init) {
27426    client.init();
27427    // TODO v8: Remove this fallback
27428    // eslint-disable-next-line deprecation/deprecation
27429  } else if (client.setupIntegrations) {
27430    // eslint-disable-next-line deprecation/deprecation
27431    client.setupIntegrations();
27432  }
27433}
27434
27435exports.initAndBind = initAndBind;
27436exports.setCurrentClient = setCurrentClient;
27437
27438
27439},{"./debug-build.js":245,"./exports.js":248,"./hub.js":249,"@sentry/utils":319}],270:[function(require,module,exports){
27440Object.defineProperty(exports, '__esModule', { value: true });
27441
27442/**
27443 * Use this attribute to represent the source of a span.
27444 * Should be one of: custom, url, route, view, component, task, unknown
27445 *
27446 */
27447const SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = 'sentry.source';
27448
27449/**
27450 * Use this attribute to represent the sample rate used for a span.
27451 */
27452const SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = 'sentry.sample_rate';
27453
27454/**
27455 * Use this attribute to represent the operation of a span.
27456 */
27457const SEMANTIC_ATTRIBUTE_SENTRY_OP = 'sentry.op';
27458
27459/**
27460 * Use this attribute to represent the origin of a span.
27461 */
27462const SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'sentry.origin';
27463
27464/**
27465 * The id of the profile that this span occured in.
27466 */
27467const SEMANTIC_ATTRIBUTE_PROFILE_ID = 'profile_id';
27468
27469exports.SEMANTIC_ATTRIBUTE_PROFILE_ID = SEMANTIC_ATTRIBUTE_PROFILE_ID;
27470exports.SEMANTIC_ATTRIBUTE_SENTRY_OP = SEMANTIC_ATTRIBUTE_SENTRY_OP;
27471exports.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN;
27472exports.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE;
27473exports.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = SEMANTIC_ATTRIBUTE_SENTRY_SOURCE;
27474
27475
27476},{}],271:[function(require,module,exports){
27477Object.defineProperty(exports, '__esModule', { value: true });
27478
27479const utils = require('@sentry/utils');
27480const baseclient = require('./baseclient.js');
27481const checkin = require('./checkin.js');
27482const debugBuild = require('./debug-build.js');
27483const exports$1 = require('./exports.js');
27484const aggregator = require('./metrics/aggregator.js');
27485const sessionflusher = require('./sessionflusher.js');
27486const hubextensions = require('./tracing/hubextensions.js');
27487const spanUtils = require('./utils/spanUtils.js');
27488const getRootSpan = require('./utils/getRootSpan.js');
27489require('./tracing/spanstatus.js');
27490const dynamicSamplingContext = require('./tracing/dynamicSamplingContext.js');
27491
27492/**
27493 * The Sentry Server Runtime Client SDK.
27494 */
27495class ServerRuntimeClient
27496
27497 extends baseclient.BaseClient {
27498
27499  /**
27500   * Creates a new Edge SDK instance.
27501   * @param options Configuration options for this SDK.
27502   */
27503   constructor(options) {
27504    // Server clients always support tracing
27505    hubextensions.addTracingExtensions();
27506
27507    super(options);
27508
27509    if (options._experiments && options._experiments['metricsAggregator']) {
27510      this.metricsAggregator = new aggregator.MetricsAggregator(this);
27511    }
27512  }
27513
27514  /**
27515   * @inheritDoc
27516   */
27517   eventFromException(exception, hint) {
27518    return utils.resolvedSyncPromise(utils.eventFromUnknownInput(exports$1.getClient(), this._options.stackParser, exception, hint));
27519  }
27520
27521  /**
27522   * @inheritDoc
27523   */
27524   eventFromMessage(
27525    message,
27526    // eslint-disable-next-line deprecation/deprecation
27527    level = 'info',
27528    hint,
27529  ) {
27530    return utils.resolvedSyncPromise(
27531      utils.eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace),
27532    );
27533  }
27534
27535  /**
27536   * @inheritDoc
27537   */
27538  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
27539   captureException(exception, hint, scope) {
27540    // Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only
27541    // when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload
27542    // sent to the Server only when the `requestHandler` middleware is used
27543    if (this._options.autoSessionTracking && this._sessionFlusher && scope) {
27544      const requestSession = scope.getRequestSession();
27545
27546      // Necessary checks to ensure this is code block is executed only within a request
27547      // Should override the status only if `requestSession.status` is `Ok`, which is its initial stage
27548      if (requestSession && requestSession.status === 'ok') {
27549        requestSession.status = 'errored';
27550      }
27551    }
27552
27553    return super.captureException(exception, hint, scope);
27554  }
27555
27556  /**
27557   * @inheritDoc
27558   */
27559   captureEvent(event, hint, scope) {
27560    // Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only
27561    // when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload
27562    // sent to the Server only when the `requestHandler` middleware is used
27563    if (this._options.autoSessionTracking && this._sessionFlusher && scope) {
27564      const eventType = event.type || 'exception';
27565      const isException =
27566        eventType === 'exception' && event.exception && event.exception.values && event.exception.values.length > 0;
27567
27568      // If the event is of type Exception, then a request session should be captured
27569      if (isException) {
27570        const requestSession = scope.getRequestSession();
27571
27572        // Ensure that this is happening within the bounds of a request, and make sure not to override
27573        // Session Status if Errored / Crashed
27574        if (requestSession && requestSession.status === 'ok') {
27575          requestSession.status = 'errored';
27576        }
27577      }
27578    }
27579
27580    return super.captureEvent(event, hint, scope);
27581  }
27582
27583  /**
27584   *
27585   * @inheritdoc
27586   */
27587   close(timeout) {
27588    if (this._sessionFlusher) {
27589      this._sessionFlusher.close();
27590    }
27591    return super.close(timeout);
27592  }
27593
27594  /** Method that initialises an instance of SessionFlusher on Client */
27595   initSessionFlusher() {
27596    const { release, environment } = this._options;
27597    if (!release) {
27598      debugBuild.DEBUG_BUILD && utils.logger.warn('Cannot initialise an instance of SessionFlusher if no release is provided!');
27599    } else {
27600      this._sessionFlusher = new sessionflusher.SessionFlusher(this, {
27601        release,
27602        environment,
27603      });
27604    }
27605  }
27606
27607  /**
27608   * Create a cron monitor check in and send it to Sentry.
27609   *
27610   * @param checkIn An object that describes a check in.
27611   * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want
27612   * to create a monitor automatically when sending a check in.
27613   */
27614   captureCheckIn(checkIn, monitorConfig, scope) {
27615    const id = 'checkInId' in checkIn && checkIn.checkInId ? checkIn.checkInId : utils.uuid4();
27616    if (!this._isEnabled()) {
27617      debugBuild.DEBUG_BUILD && utils.logger.warn('SDK not enabled, will not capture checkin.');
27618      return id;
27619    }
27620
27621    const options = this.getOptions();
27622    const { release, environment, tunnel } = options;
27623
27624    const serializedCheckIn = {
27625      check_in_id: id,
27626      monitor_slug: checkIn.monitorSlug,
27627      status: checkIn.status,
27628      release,
27629      environment,
27630    };
27631
27632    if ('duration' in checkIn) {
27633      serializedCheckIn.duration = checkIn.duration;
27634    }
27635
27636    if (monitorConfig) {
27637      serializedCheckIn.monitor_config = {
27638        schedule: monitorConfig.schedule,
27639        checkin_margin: monitorConfig.checkinMargin,
27640        max_runtime: monitorConfig.maxRuntime,
27641        timezone: monitorConfig.timezone,
27642      };
27643    }
27644
27645    const [dynamicSamplingContext, traceContext] = this._getTraceInfoFromScope(scope);
27646    if (traceContext) {
27647      serializedCheckIn.contexts = {
27648        trace: traceContext,
27649      };
27650    }
27651
27652    const envelope = checkin.createCheckInEnvelope(
27653      serializedCheckIn,
27654      dynamicSamplingContext,
27655      this.getSdkMetadata(),
27656      tunnel,
27657      this.getDsn(),
27658    );
27659
27660    debugBuild.DEBUG_BUILD && utils.logger.info('Sending checkin:', checkIn.monitorSlug, checkIn.status);
27661
27662    // _sendEnvelope should not throw
27663    // eslint-disable-next-line @typescript-eslint/no-floating-promises
27664    this._sendEnvelope(envelope);
27665
27666    return id;
27667  }
27668
27669  /**
27670   * Method responsible for capturing/ending a request session by calling `incrementSessionStatusCount` to increment
27671   * appropriate session aggregates bucket
27672   */
27673   _captureRequestSession() {
27674    if (!this._sessionFlusher) {
27675      debugBuild.DEBUG_BUILD && utils.logger.warn('Discarded request mode session because autoSessionTracking option was disabled');
27676    } else {
27677      this._sessionFlusher.incrementSessionStatusCount();
27678    }
27679  }
27680
27681  /**
27682   * @inheritDoc
27683   */
27684   _prepareEvent(
27685    event,
27686    hint,
27687    scope,
27688    isolationScope,
27689  ) {
27690    if (this._options.platform) {
27691      event.platform = event.platform || this._options.platform;
27692    }
27693
27694    if (this._options.runtime) {
27695      event.contexts = {
27696        ...event.contexts,
27697        runtime: (event.contexts || {}).runtime || this._options.runtime,
27698      };
27699    }
27700
27701    if (this._options.serverName) {
27702      event.server_name = event.server_name || this._options.serverName;
27703    }
27704
27705    return super._prepareEvent(event, hint, scope, isolationScope);
27706  }
27707
27708  /** Extract trace information from scope */
27709   _getTraceInfoFromScope(
27710    scope,
27711  ) {
27712    if (!scope) {
27713      return [undefined, undefined];
27714    }
27715
27716    // eslint-disable-next-line deprecation/deprecation
27717    const span = scope.getSpan();
27718    if (span) {
27719      const samplingContext = getRootSpan.getRootSpan(span) ? dynamicSamplingContext.getDynamicSamplingContextFromSpan(span) : undefined;
27720      return [samplingContext, spanUtils.spanToTraceContext(span)];
27721    }
27722
27723    const { traceId, spanId, parentSpanId, dsc } = scope.getPropagationContext();
27724    const traceContext = {
27725      trace_id: traceId,
27726      span_id: spanId,
27727      parent_span_id: parentSpanId,
27728    };
27729    if (dsc) {
27730      return [dsc, traceContext];
27731    }
27732
27733    return [dynamicSamplingContext.getDynamicSamplingContextFromClient(traceId, this, scope), traceContext];
27734  }
27735}
27736
27737exports.ServerRuntimeClient = ServerRuntimeClient;
27738
27739
27740},{"./baseclient.js":242,"./checkin.js":243,"./debug-build.js":245,"./exports.js":248,"./metrics/aggregator.js":259,"./sessionflusher.js":273,"./tracing/dynamicSamplingContext.js":275,"./tracing/hubextensions.js":277,"./tracing/spanstatus.js":282,"./utils/getRootSpan.js":290,"./utils/spanUtils.js":297,"@sentry/utils":319}],272:[function(require,module,exports){
27741Object.defineProperty(exports, '__esModule', { value: true });
27742
27743const utils = require('@sentry/utils');
27744
27745/**
27746 * Creates a new `Session` object by setting certain default parameters. If optional @param context
27747 * is passed, the passed properties are applied to the session object.
27748 *
27749 * @param context (optional) additional properties to be applied to the returned session object
27750 *
27751 * @returns a new `Session` object
27752 */
27753function makeSession(context) {
27754  // Both timestamp and started are in seconds since the UNIX epoch.
27755  const startingTime = utils.timestampInSeconds();
27756
27757  const session = {
27758    sid: utils.uuid4(),
27759    init: true,
27760    timestamp: startingTime,
27761    started: startingTime,
27762    duration: 0,
27763    status: 'ok',
27764    errors: 0,
27765    ignoreDuration: false,
27766    toJSON: () => sessionToJSON(session),
27767  };
27768
27769  if (context) {
27770    updateSession(session, context);
27771  }
27772
27773  return session;
27774}
27775
27776/**
27777 * Updates a session object with the properties passed in the context.
27778 *
27779 * Note that this function mutates the passed object and returns void.
27780 * (Had to do this instead of returning a new and updated session because closing and sending a session
27781 * makes an update to the session after it was passed to the sending logic.
27782 * @see BaseClient.captureSession )
27783 *
27784 * @param session the `Session` to update
27785 * @param context the `SessionContext` holding the properties that should be updated in @param session
27786 */
27787// eslint-disable-next-line complexity
27788function updateSession(session, context = {}) {
27789  if (context.user) {
27790    if (!session.ipAddress && context.user.ip_address) {
27791      session.ipAddress = context.user.ip_address;
27792    }
27793
27794    if (!session.did && !context.did) {
27795      session.did = context.user.id || context.user.email || context.user.username;
27796    }
27797  }
27798
27799  session.timestamp = context.timestamp || utils.timestampInSeconds();
27800
27801  if (context.abnormal_mechanism) {
27802    session.abnormal_mechanism = context.abnormal_mechanism;
27803  }
27804
27805  if (context.ignoreDuration) {
27806    session.ignoreDuration = context.ignoreDuration;
27807  }
27808  if (context.sid) {
27809    // Good enough uuid validation. — Kamil
27810    session.sid = context.sid.length === 32 ? context.sid : utils.uuid4();
27811  }
27812  if (context.init !== undefined) {
27813    session.init = context.init;
27814  }
27815  if (!session.did && context.did) {
27816    session.did = `${context.did}`;
27817  }
27818  if (typeof context.started === 'number') {
27819    session.started = context.started;
27820  }
27821  if (session.ignoreDuration) {
27822    session.duration = undefined;
27823  } else if (typeof context.duration === 'number') {
27824    session.duration = context.duration;
27825  } else {
27826    const duration = session.timestamp - session.started;
27827    session.duration = duration >= 0 ? duration : 0;
27828  }
27829  if (context.release) {
27830    session.release = context.release;
27831  }
27832  if (context.environment) {
27833    session.environment = context.environment;
27834  }
27835  if (!session.ipAddress && context.ipAddress) {
27836    session.ipAddress = context.ipAddress;
27837  }
27838  if (!session.userAgent && context.userAgent) {
27839    session.userAgent = context.userAgent;
27840  }
27841  if (typeof context.errors === 'number') {
27842    session.errors = context.errors;
27843  }
27844  if (context.status) {
27845    session.status = context.status;
27846  }
27847}
27848
27849/**
27850 * Closes a session by setting its status and updating the session object with it.
27851 * Internally calls `updateSession` to update the passed session object.
27852 *
27853 * Note that this function mutates the passed session (@see updateSession for explanation).
27854 *
27855 * @param session the `Session` object to be closed
27856 * @param status the `SessionStatus` with which the session was closed. If you don't pass a status,
27857 *               this function will keep the previously set status, unless it was `'ok'` in which case
27858 *               it is changed to `'exited'`.
27859 */
27860function closeSession(session, status) {
27861  let context = {};
27862  if (status) {
27863    context = { status };
27864  } else if (session.status === 'ok') {
27865    context = { status: 'exited' };
27866  }
27867
27868  updateSession(session, context);
27869}
27870
27871/**
27872 * Serializes a passed session object to a JSON object with a slightly different structure.
27873 * This is necessary because the Sentry backend requires a slightly different schema of a session
27874 * than the one the JS SDKs use internally.
27875 *
27876 * @param session the session to be converted
27877 *
27878 * @returns a JSON object of the passed session
27879 */
27880function sessionToJSON(session) {
27881  return utils.dropUndefinedKeys({
27882    sid: `${session.sid}`,
27883    init: session.init,
27884    // Make sure that sec is converted to ms for date constructor
27885    started: new Date(session.started * 1000).toISOString(),
27886    timestamp: new Date(session.timestamp * 1000).toISOString(),
27887    status: session.status,
27888    errors: session.errors,
27889    did: typeof session.did === 'number' || typeof session.did === 'string' ? `${session.did}` : undefined,
27890    duration: session.duration,
27891    abnormal_mechanism: session.abnormal_mechanism,
27892    attrs: {
27893      release: session.release,
27894      environment: session.environment,
27895      ip_address: session.ipAddress,
27896      user_agent: session.userAgent,
27897    },
27898  });
27899}
27900
27901exports.closeSession = closeSession;
27902exports.makeSession = makeSession;
27903exports.updateSession = updateSession;
27904
27905
27906},{"@sentry/utils":319}],273:[function(require,module,exports){
27907Object.defineProperty(exports, '__esModule', { value: true });
27908
27909const utils = require('@sentry/utils');
27910const exports$1 = require('./exports.js');
27911
27912/**
27913 * @inheritdoc
27914 */
27915class SessionFlusher  {
27916
27917   constructor(client, attrs) {
27918    this._client = client;
27919    this.flushTimeout = 60;
27920    this._pendingAggregates = {};
27921    this._isEnabled = true;
27922
27923    // Call to setInterval, so that flush is called every 60 seconds
27924    this._intervalId = setInterval(() => this.flush(), this.flushTimeout * 1000);
27925    this._sessionAttrs = attrs;
27926  }
27927
27928  /** Checks if `pendingAggregates` has entries, and if it does flushes them by calling `sendSession` */
27929   flush() {
27930    const sessionAggregates = this.getSessionAggregates();
27931    if (sessionAggregates.aggregates.length === 0) {
27932      return;
27933    }
27934    this._pendingAggregates = {};
27935    this._client.sendSession(sessionAggregates);
27936  }
27937
27938  /** Massages the entries in `pendingAggregates` and returns aggregated sessions */
27939   getSessionAggregates() {
27940    const aggregates = Object.keys(this._pendingAggregates).map((key) => {
27941      return this._pendingAggregates[parseInt(key)];
27942    });
27943
27944    const sessionAggregates = {
27945      attrs: this._sessionAttrs,
27946      aggregates,
27947    };
27948    return utils.dropUndefinedKeys(sessionAggregates);
27949  }
27950
27951  /** JSDoc */
27952   close() {
27953    clearInterval(this._intervalId);
27954    this._isEnabled = false;
27955    this.flush();
27956  }
27957
27958  /**
27959   * Wrapper function for _incrementSessionStatusCount that checks if the instance of SessionFlusher is enabled then
27960   * fetches the session status of the request from `Scope.getRequestSession().status` on the scope and passes them to
27961   * `_incrementSessionStatusCount` along with the start date
27962   */
27963   incrementSessionStatusCount() {
27964    if (!this._isEnabled) {
27965      return;
27966    }
27967    const scope = exports$1.getCurrentScope();
27968    const requestSession = scope.getRequestSession();
27969
27970    if (requestSession && requestSession.status) {
27971      this._incrementSessionStatusCount(requestSession.status, new Date());
27972      // This is not entirely necessarily but is added as a safe guard to indicate the bounds of a request and so in
27973      // case captureRequestSession is called more than once to prevent double count
27974      scope.setRequestSession(undefined);
27975      /* eslint-enable @typescript-eslint/no-unsafe-member-access */
27976    }
27977  }
27978
27979  /**
27980   * Increments status bucket in pendingAggregates buffer (internal state) corresponding to status of
27981   * the session received
27982   */
27983   _incrementSessionStatusCount(status, date) {
27984    // Truncate minutes and seconds on Session Started attribute to have one minute bucket keys
27985    const sessionStartedTrunc = new Date(date).setSeconds(0, 0);
27986    this._pendingAggregates[sessionStartedTrunc] = this._pendingAggregates[sessionStartedTrunc] || {};
27987
27988    // corresponds to aggregated sessions in one specific minute bucket
27989    // for example, {"started":"2021-03-16T08:00:00.000Z","exited":4, "errored": 1}
27990    const aggregationCounts = this._pendingAggregates[sessionStartedTrunc];
27991    if (!aggregationCounts.started) {
27992      aggregationCounts.started = new Date(sessionStartedTrunc).toISOString();
27993    }
27994
27995    switch (status) {
27996      case 'errored':
27997        aggregationCounts.errored = (aggregationCounts.errored || 0) + 1;
27998        return aggregationCounts.errored;
27999      case 'ok':
28000        aggregationCounts.exited = (aggregationCounts.exited || 0) + 1;
28001        return aggregationCounts.exited;
28002      default:
28003        aggregationCounts.crashed = (aggregationCounts.crashed || 0) + 1;
28004        return aggregationCounts.crashed;
28005    }
28006  }
28007}
28008
28009exports.SessionFlusher = SessionFlusher;
28010
28011
28012},{"./exports.js":248,"@sentry/utils":319}],274:[function(require,module,exports){
28013Object.defineProperty(exports, '__esModule', { value: true });
28014
28015const utils = require('@sentry/utils');
28016
28017/**
28018 * Create envelope from Span item.
28019 */
28020function createSpanEnvelope(spans, dsn) {
28021  const headers = {
28022    sent_at: new Date().toISOString(),
28023  };
28024
28025  if (dsn) {
28026    headers.dsn = utils.dsnToString(dsn);
28027  }
28028
28029  const items = spans.map(createSpanItem);
28030  return utils.createEnvelope(headers, items);
28031}
28032
28033function createSpanItem(span) {
28034  const spanHeaders = {
28035    type: 'span',
28036  };
28037  return [spanHeaders, span];
28038}
28039
28040exports.createSpanEnvelope = createSpanEnvelope;
28041
28042
28043},{"@sentry/utils":319}],275:[function(require,module,exports){
28044Object.defineProperty(exports, '__esModule', { value: true });
28045
28046const utils = require('@sentry/utils');
28047const constants = require('../constants.js');
28048const exports$1 = require('../exports.js');
28049const getRootSpan = require('../utils/getRootSpan.js');
28050const spanUtils = require('../utils/spanUtils.js');
28051
28052/**
28053 * Creates a dynamic sampling context from a client.
28054 *
28055 * Dispatches the `createDsc` lifecycle hook as a side effect.
28056 */
28057function getDynamicSamplingContextFromClient(
28058  trace_id,
28059  client,
28060  scope,
28061) {
28062  const options = client.getOptions();
28063
28064  const { publicKey: public_key } = client.getDsn() || {};
28065  // TODO(v8): Remove segment from User
28066  // eslint-disable-next-line deprecation/deprecation
28067  const { segment: user_segment } = (scope && scope.getUser()) || {};
28068
28069  const dsc = utils.dropUndefinedKeys({
28070    environment: options.environment || constants.DEFAULT_ENVIRONMENT,
28071    release: options.release,
28072    user_segment,
28073    public_key,
28074    trace_id,
28075  }) ;
28076
28077  client.emit && client.emit('createDsc', dsc);
28078
28079  return dsc;
28080}
28081
28082/**
28083 * A Span with a frozen dynamic sampling context.
28084 */
28085
28086/**
28087 * Creates a dynamic sampling context from a span (and client and scope)
28088 *
28089 * @param span the span from which a few values like the root span name and sample rate are extracted.
28090 *
28091 * @returns a dynamic sampling context
28092 */
28093function getDynamicSamplingContextFromSpan(span) {
28094  const client = exports$1.getClient();
28095  if (!client) {
28096    return {};
28097  }
28098
28099  // passing emit=false here to only emit later once the DSC is actually populated
28100  const dsc = getDynamicSamplingContextFromClient(spanUtils.spanToJSON(span).trace_id || '', client, exports$1.getCurrentScope());
28101
28102  // TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext
28103  const txn = getRootSpan.getRootSpan(span) ;
28104  if (!txn) {
28105    return dsc;
28106  }
28107
28108  // TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext
28109  // For now we need to avoid breaking users who directly created a txn with a DSC, where this field is still set.
28110  // @see Transaction class constructor
28111  const v7FrozenDsc = txn && txn._frozenDynamicSamplingContext;
28112  if (v7FrozenDsc) {
28113    return v7FrozenDsc;
28114  }
28115
28116  // TODO (v8): Replace txn.metadata with txn.attributes[]
28117  // We can't do this yet because attributes aren't always set yet.
28118  // eslint-disable-next-line deprecation/deprecation
28119  const { sampleRate: maybeSampleRate, source }
28119 = txn.metadata;
28120  if (maybeSampleRate != null) {
28121    dsc.sample_rate = `${maybeSampleRate}`;
28122  }
28123
28124  // We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII
28125  const jsonSpan = spanUtils.spanToJSON(txn);
28126
28127  // after JSON conversion, txn.name becomes jsonSpan.description
28128  if (source && source !== 'url') {
28129    dsc.transaction = jsonSpan.description;
28130  }
28131
28132  dsc.sampled = String(spanUtils.spanIsSampled(txn));
28133
28134  client.emit && client.emit('createDsc', dsc);
28135
28136  return dsc;
28137}
28138
28139exports.getDynamicSamplingContextFromClient = getDynamicSamplingContextFromClient;
28140exports.getDynamicSamplingContextFromSpan = getDynamicSamplingContextFromSpan;
28141
28142
28143},{"../constants.js":244,"../exports.js":248,"../utils/getRootSpan.js":290,"../utils/spanUtils.js":297,"@sentry/utils":319}],276:[function(require,module,exports){
28144Object.defineProperty(exports, '__esModule', { value: true });
28145
28146const utils = require('@sentry/utils');
28147const debugBuild = require('../debug-build.js');
28148const utils$1 = require('./utils.js');
28149
28150let errorsInstrumented = false;
28151
28152/**
28153 * Configures global error listeners
28154 */
28155function registerErrorInstrumentation() {
28156  if (errorsInstrumented) {
28157    return;
28158  }
28159
28160  errorsInstrumented = true;
28161  utils.addGlobalErrorInstrumentationHandler(errorCallback);
28162  utils.addGlobalUnhandledRejectionInstrumentationHandler(errorCallback);
28163}
28164
28165/**
28166 * If an error or unhandled promise occurs, we mark the active transaction as failed
28167 */
28168function errorCallback() {
28169  // eslint-disable-next-line deprecation/deprecation
28170  const activeTransaction = utils$1.getActiveTransaction();
28171  if (activeTransaction) {
28172    const status = 'internal_error';
28173    debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Transaction: ${status} -> Global error occured`);
28174    activeTransaction.setStatus(status);
28175  }
28176}
28177
28178// The function name will be lost when bundling but we need to be able to identify this listener later to maintain the
28179// node.js default exit behaviour
28180errorCallback.tag = 'sentry_tracingErrorCallback';
28181
28182exports.registerErrorInstrumentation = registerErrorInstrumentation;
28183
28184
28185},{"../debug-build.js":245,"./utils.js":285,"@sentry/utils":319}],277:[function(require,module,exports){
28186Object.defineProperty(exports, '__esModule', { value: true });
28187
28188const utils = require('@sentry/utils');
28189const debugBuild = require('../debug-build.js');
28190const hub = require('../hub.js');
28191const spanUtils = require('../utils/spanUtils.js');
28192const errors = require('./errors.js');
28193const idletransaction = require('./idletransaction.js');
28194const sampling = require('./sampling.js');
28195const transaction = require('./transaction.js');
28196
28197/** Returns all trace headers that are currently on the top scope. */
28198function traceHeaders() {
28199  // eslint-disable-next-line deprecation/deprecation
28200  const scope = this.getScope();
28201  // eslint-disable-next-line deprecation/deprecation
28202  const span = scope.getSpan();
28203
28204  return span
28205    ? {
28206        'sentry-trace': spanUtils.spanToTraceHeader(span),
28207      }
28208    : {};
28209}
28210
28211/**
28212 * Creates a new transaction and adds a sampling decision if it doesn't yet have one.
28213 *
28214 * The Hub.startTransaction method delegates to this method to do its work, passing the Hub instance in as `this`, as if
28215 * it had been called on the hub directly. Exists as a separate function so that it can be injected into the class as an
28216 * "extension method."
28217 *
28218 * @param this: The Hub starting the transaction
28219 * @param transactionContext: Data used to configure the transaction
28220 * @param CustomSamplingContext: Optional data to be provided to the `tracesSampler` function (if any)
28221 *
28222 * @returns The new transaction
28223 *
28224 * @see {@link Hub.startTransaction}
28225 */
28226function _startTransaction(
28227
28228  transactionContext,
28229  customSamplingContext,
28230) {
28231  // eslint-disable-next-line deprecation/deprecation
28232  const client = this.getClient();
28233  const options = (client && client.getOptions()) || {};
28234
28235  const configInstrumenter = options.instrumenter || 'sentry';
28236  const transactionInstrumenter = transactionContext.instrumenter || 'sentry';
28237
28238  if (configInstrumenter !== transactionInstrumenter) {
28239    debugBuild.DEBUG_BUILD &&
28240      utils.logger.error(
28241        `A transaction was started with instrumenter=\`${transactionInstrumenter}\`, but the SDK is configured with the \`${configInstrumenter}\` instrumenter.
28242The transaction will not be sampled. Please use the ${configInstrumenter} instrumentation to start transactions.`,
28243      );
28244
28245    // eslint-disable-next-line deprecation/deprecation
28246    transactionContext.sampled = false;
28247  }
28248
28249  // eslint-disable-next-line deprecation/deprecation
28250  let transaction$1 = new transaction.Transaction(transactionContext, this);
28251  transaction$1 = sampling.sampleTransaction(transaction$1, options, {
28252    name: transactionContext.name,
28253    parentSampled: transactionContext.parentSampled,
28254    transactionContext,
28255    attributes: {
28256      // eslint-disable-next-line deprecation/deprecation
28257      ...transactionContext.data,
28258      ...transactionContext.attributes,
28259    },
28260    ...customSamplingContext,
28261  });
28262  if (transaction$1.isRecording()) {
28263    transaction$1.initSpanRecorder(options._experiments && (options._experiments.maxSpans ));
28264  }
28265  if (client && client.emit) {
28266    client.emit('startTransaction', transaction$1);
28267  }
28268  return transaction$1;
28269}
28270
28271/**
28272 * Create new idle transaction.
28273 */
28274function startIdleTransaction(
28275  hub,
28276  transactionContext,
28277  idleTimeout,
28278  finalTimeout,
28279  onScope,
28280  customSamplingContext,
28281  heartbeatInterval,
28282  delayAutoFinishUntilSignal = false,
28283) {
28284  // eslint-disable-next-line deprecation/deprecation
28285  const client = hub.getClient();
28286  const options = (client && client.getOptions()) || {};
28287
28288  // eslint-disable-next-line deprecation/deprecation
28289  let transaction = new idletransaction.IdleTransaction(
28290    transactionContext,
28291    hub,
28292    idleTimeout,
28293    finalTimeout,
28294    heartbeatInterval,
28295    onScope,
28296    delayAutoFinishUntilSignal,
28297  );
28298  transaction = sampling.sampleTransaction(transaction, options, {
28299    name: transactionContext.name,
28300    parentSampled: transactionContext.parentSampled,
28301    transactionContext,
28302    attributes: {
28303      // eslint-disable-next-line deprecation/deprecation
28304      ...transactionContext.data,
28305      ...transactionContext.attributes,
28306    },
28307    ...customSamplingContext,
28308  });
28309  if (transaction.isRecording()) {
28310    transaction.initSpanRecorder(options._experiments && (options._experiments.maxSpans ));
28311  }
28312  if (client && client.emit) {
28313    client.emit('startTransaction', transaction);
28314  }
28315  return transaction;
28316}
28317
28318/**
28319 * Adds tracing extensions to the global hub.
28320 */
28321function addTracingExtensions() {
28322  const carrier = hub.getMainCarrier();
28323  if (!carrier.__SENTRY__) {
28324    return;
28325  }
28326  carrier.__SENTRY__.extensions = carrier.__SENTRY__.extensions || {};
28327  if (!carrier.__SENTRY__.extensions.startTransaction) {
28328    carrier.__SENTRY__.extensions.startTransaction = _startTransaction;
28329  }
28330  if (!carrier.__SENTRY__.extensions.traceHeaders) {
28331    carrier.__SENTRY__.extensions.traceHeaders = traceHeaders;
28332  }
28333
28334  errors.registerErrorInstrumentation();
28335}
28336
28337exports.addTracingExtensions = addTracingExtensions;
28338exports.startIdleTransaction = startIdleTransaction;
28339
28340
28341},{"../debug-build.js":245,"../hub.js":249,"../utils/spanUtils.js":297,"./errors.js":276,"./idletransaction.js":278,"./sampling.js":280,"./transaction.js":284,"@sentry/utils":319}],278:[function(require,module,exports){
28342Object.defineProperty(exports, '__esModule', { value: true });
28343
28344const utils = require('@sentry/utils');
28345const debugBuild = require('../debug-build.js');
28346const spanUtils = require('../utils/spanUtils.js');
28347const span = require('./span.js');
28348const transaction = require('./transaction.js');
28349
28350const TRACING_DEFAULTS = {
28351  idleTimeout: 1000,
28352  finalTimeout: 30000,
28353  heartbeatInterval: 5000,
28354};
28355
28356const FINISH_REASON_TAG = 'finishReason';
28357
28358const IDLE_TRANSACTION_FINISH_REASONS = [
28359  'heartbeatFailed',
28360  'idleTimeout',
28361  'documentHidden',
28362  'finalTimeout',
28363  'externalFinish',
28364  'cancelled',
28365];
28366
28367/**
28368 * @inheritDoc
28369 */
28370class IdleTransactionSpanRecorder extends span.SpanRecorder {
28371   constructor(
28372      _pushActivity,
28373      _popActivity,
28374     transactionSpanId,
28375    maxlen,
28376  ) {
28377    super(maxlen);this._pushActivity = _pushActivity;this._popActivity = _popActivity;this.transactionSpanId = transactionSpanId;  }
28378
28379  /**
28380   * @inheritDoc
28381   */
28382   add(span) {
28383    // We should make sure we do not push and pop activities for
28384    // the transaction that this span recorder belongs to.
28385    if (span.spanContext().spanId !== this.transactionSpanId) {
28386      // We patch span.end() to pop an activity after setting an endTimestamp.
28387      // eslint-disable-next-line @typescript-eslint/unbound-method
28388      const originalEnd = span.end;
28389      span.end = (...rest) => {
28390        this._popActivity(span.spanContext().spanId);
28391        return originalEnd.apply(span, rest);
28392      };
28393
28394      // We should only push new activities if the span does not have an end timestamp.
28395      if (spanUtils.spanToJSON(span).timestamp === undefined) {
28396        this._pushActivity(span.spanContext().spanId);
28397      }
28398    }
28399
28400    super.add(span);
28401  }
28402}
28403
28404/**
28405 * An IdleTransaction is a transaction that automatically finishes. It does this by tracking child spans as activities.
28406 * You can have multiple IdleTransactions active, but if the `onScope` option is specified, the idle transaction will
28407 * put itself on the scope on creation.
28408 */
28409class IdleTransaction extends transaction.Transaction {
28410  // Activities store a list of active spans
28411
28412  // Track state of activities in previous heartbeat
28413
28414  // Amount of times heartbeat has counted. Will cause transaction to finish after 3 beats.
28415
28416  // We should not use heartbeat if we finished a transaction
28417
28418  // Idle timeout was canceled and we should finish the transaction with the last span end.
28419
28420  /**
28421   * Timer that tracks Transaction idleTimeout
28422   */
28423
28424  /**
28425   * @deprecated Transactions will be removed in v8. Use spans instead.
28426   */
28427   constructor(
28428    transactionContext,
28429      _idleHub,
28430    /**
28431     * The time to wait in ms until the idle transaction will be finished. This timer is started each time
28432     * there are no active spans on this transaction.
28433     */
28434      _idleTimeout = TRACING_DEFAULTS.idleTimeout,
28435    /**
28436     * The final value in ms that a transaction cannot exceed
28437     */
28438      _finalTimeout = TRACING_DEFAULTS.finalTimeout,
28439      _heartbeatInterval = TRACING_DEFAULTS.heartbeatInterval,
28440    // Whether or not the transaction should put itself on the scope when it starts and pop itself off when it ends
28441      _onScope = false,
28442    /**
28443     * When set to `true`, will disable the idle timeout (`_idleTimeout` option) and heartbeat mechanisms (`_heartbeatInterval`
28444     * option) until the `sendAutoFinishSignal()` method is called. The final timeout mechanism (`_finalTimeout` option)
28445     * will not be affected by this option, meaning the transaction will definitely be finished when the final timeout is
28446     * reached, no matter what this option is configured to.
28447     *
28448     * Defaults to `false`.
28449     */
28450    delayAutoFinishUntilSignal = false,
28451  ) {
28452    super(transactionContext, _idleHub);this._idleHub = _idleHub;this._idleTimeout = _idleTimeout;this._finalTimeout = _finalTimeout;this._heartbeatInterval = _heartbeatInterval;this._onScope = _onScope;
28453    this.activities = {};
28454    this._heartbeatCounter = 0;
28455    this._finished = false;
28456    this._idleTimeoutCanceledPermanently = false;
28457    this._beforeFinishCallbacks = [];
28458    this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[4];
28459    this._autoFinishAllowed = !delayAutoFinishUntilSignal;
28460
28461    if (_onScope) {
28462      // We set the transaction here on the scope so error events pick up the trace
28463      // context and attach it to the error.
28464      debugBuild.DEBUG_BUILD && utils.logger.log(`Setting idle transaction on scope. Span ID: ${this.spanContext().spanId}`);
28465      // eslint-disable-next-line deprecation/deprecation
28466      _idleHub.getScope().setSpan(this);
28467    }
28468
28469    if (!delayAutoFinishUntilSignal) {
28470      this._restartIdleTimeout();
28471    }
28472
28473    setTimeout(() => {
28474      if (!this._finished) {
28475        this.setStatus('deadline_exceeded');
28476        this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[3];
28477        this.end();
28478      }
28479    }, this._finalTimeout);
28480  }
28481
28482  /** {@inheritDoc} */
28483   end(endTimestamp) {
28484    const endTimestampInS = spanUtils.spanTimeInputToSeconds(endTimestamp);
28485
28486    this._finished = true;
28487    this.activities = {};
28488
28489    // eslint-disable-next-line deprecation/deprecation
28490    if (this.op === 'ui.action.click') {
28491      this.setAttribute(FINISH_REASON_TAG, this._finishReason);
28492    }
28493
28494    // eslint-disable-next-line deprecation/deprecation
28495    if (this.spanRecorder) {
28496      debugBuild.DEBUG_BUILD &&
28497        // eslint-disable-next-line deprecation/deprecation
28498        utils.logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestampInS * 1000).toISOString(), this.op);
28499
28500      for (const callback of this._beforeFinishCallbacks) {
28501        callback(this, endTimestampInS);
28502      }
28503
28504      // eslint-disable-next-line deprecation/deprecation
28505      this.spanRecorder.spans = this.spanRecorder.spans.filter((span) => {
28506        // If we are dealing with the transaction itself, we just return it
28507        if (span.spanContext().spanId === this.spanContext().spanId) {
28508          return true;
28509        }
28510
28511        // We cancel all pending spans with status "cancelled" to indicate the idle transaction was finished early
28512        if (!spanUtils.spanToJSON(span).timestamp) {
28513          span.setStatus('cancelled');
28514          span.end(endTimestampInS);
28515          debugBuild.DEBUG_BUILD &&
28516            utils.logger.log('[Tracing] cancelling span since transaction ended early', JSON.stringify(span, undefined, 2));
28517        }
28518
28519        const { start_timestamp: startTime, timestamp: endTime } = spanUtils.spanToJSON(span);
28520        const spanStartedBeforeTransactionFinish = startTime && startTime < endTimestampInS;
28521
28522        // Add a delta with idle timeout so that we prevent false positives
28523        const timeoutWithMarginOfError = (this._finalTimeout + this._idleTimeout) / 1000;
28524        const spanEndedBeforeFinalTimeout = endTime && startTime && endTime - startTime < timeoutWithMarginOfError;
28525
28526        if (debugBuild.DEBUG_BUILD) {
28527          const stringifiedSpan = JSON.stringify(span, undefined, 2);
28528          if (!spanStartedBeforeTransactionFinish) {
28529            utils.logger.log('[Tracing] discarding Span since it happened after Transaction was finished', stringifiedSpan);
28530          } else if (!spanEndedBeforeFinalTimeout) {
28531            utils.logger.log('[Tracing] discarding Span since it finished after Transaction final timeout', stringifiedSpan);
28532          }
28533        }
28534
28535        return spanStartedBeforeTransactionFinish && spanEndedBeforeFinalTimeout;
28536      });
28537
28538      debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] flushing IdleTransaction');
28539    } else {
28540      debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] No active IdleTransaction');
28541    }
28542
28543    // if `this._onScope` is `true`, the transaction put itself on the scope when it started
28544    if (this._onScope) {
28545      // eslint-disable-next-line deprecation/deprecation
28546      const scope = this._idleHub.getScope();
28547      // eslint-disable-next-line deprecation/deprecation
28548      if (scope.getTransaction() === this) {
28549        // eslint-disable-next-line deprecation/deprecation
28550        scope.setSpan(undefined);
28551      }
28552    }
28553
28554    return super.end(endTimestamp);
28555  }
28556
28557  /**
28558   * Register a callback function that gets executed before the transaction finishes.
28559   * Useful for cleanup or if you want to add any additional spans based on current context.
28560   *
28561   * This is exposed because users have no other way of running something before an idle transaction
28562   * finishes.
28563   */
28564   registerBeforeFinishCallback(callback) {
28565    this._beforeFinishCallbacks.push(callback);
28566  }
28567
28568  /**
28569   * @inheritDoc
28570   */
28571   initSpanRecorder(maxlen) {
28572    // eslint-disable-next-line deprecation/deprecation
28573    if (!this.spanRecorder) {
28574      const pushActivity = (id) => {
28575        if (this._finished) {
28576          return;
28577        }
28578        this._pushActivity(id);
28579      };
28580      const popActivity = (id) => {
28581        if (this._finished) {
28582          return;
28583        }
28584        this._popActivity(id);
28585      };
28586
28587      // eslint-disable-next-line deprecation/deprecation
28588      this.spanRecorder = new IdleTransactionSpanRecorder(pushActivity, popActivity, this.spanContext().spanId, maxlen);
28589
28590      // Start heartbeat so that transactions do not run forever.
28591      debugBuild.DEBUG_BUILD && utils.logger.log('Starting heartbeat');
28592      this._pingHeartbeat();
28593    }
28594    // eslint-disable-next-line deprecation/deprecation
28595    this.spanRecorder.add(this);
28596  }
28597
28598  /**
28599   * Cancels the existing idle timeout, if there is one.
28600   * @param restartOnChildSpanChange Default is `true`.
28601   *                                 If set to false the transaction will end
28602   *                                 with the last child span.
28603   */
28604   cancelIdleTimeout(
28605    endTimestamp,
28606    {
28607      restartOnChildSpanChange,
28608    }
28609
28610 = {
28611      restartOnChildSpanChange: true,
28612    },
28613  ) {
28614    this._idleTimeoutCanceledPermanently = restartOnChildSpanChange === false;
28615    if (this._idleTimeoutID) {
28616      clearTimeout(this._idleTimeoutID);
28617      this._idleTimeoutID = undefined;
28618
28619      if (Object.keys(this.activities).length === 0 && this._idleTimeoutCanceledPermanently) {
28620        this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5];
28621        this.end(endTimestamp);
28622      }
28623    }
28624  }
28625
28626  /**
28627   * Temporary method used to externally set the transaction's `finishReason`
28628   *
28629   * ** WARNING**
28630   * This is for the purpose of experimentation only and will be removed in the near future, do not use!
28631   *
28632   * @internal
28633   *
28634   */
28635   setFinishReason(reason) {
28636    this._finishReason = reason;
28637  }
28638
28639  /**
28640   * Permits the IdleTransaction to automatically end itself via the idle timeout and heartbeat mechanisms when the `delayAutoFinishUntilSignal` option was set to `true`.
28641   */
28642   sendAutoFinishSignal() {
28643    if (!this._autoFinishAllowed) {
28644      debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] Received finish signal for idle transaction.');
28645      this._restartIdleTimeout();
28646      this._autoFinishAllowed = true;
28647    }
28648  }
28649
28650  /**
28651   * Restarts idle timeout, if there is no running idle timeout it will start one.
28652   */
28653   _restartIdleTimeout(endTimestamp) {
28654    this.cancelIdleTimeout();
28655    this._idleTimeoutID = setTimeout(() => {
28656      if (!this._finished && Object.keys(this.activities).length === 0) {
28657        this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[1];
28658        this.end(endTimestamp);
28659      }
28660    }, this._idleTimeout);
28661  }
28662
28663  /**
28664   * Start tracking a specific activity.
28665   * @param spanId The span id that represents the activity
28666   */
28667   _pushActivity(spanId) {
28668    this.cancelIdleTimeout(undefined, { restartOnChildSpanChange: !this._idleTimeoutCanceledPermanently });
28669    debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] pushActivity: ${spanId}`);
28670    this.activities[spanId] = true;
28671    debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] new activities count', Object.keys(this.activities).length);
28672  }
28673
28674  /**
28675   * Remove an activity from usage
28676   * @param spanId The span id that represents the activity
28677   */
28678   _popActivity(spanId) {
28679    if (this.activities[spanId]) {
28680      debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] popActivity ${spanId}`);
28681      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
28682      delete this.activities[spanId];
28683      debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] new activities count', Object.keys(this.activities).length);
28684    }
28685
28686    if (Object.keys(this.activities).length === 0) {
28687      const endTimestamp = utils.timestampInSeconds();
28688      if (this._idleTimeoutCanceledPermanently) {
28689        if (this._autoFinishAllowed) {
28690          this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5];
28691          this.end(endTimestamp);
28692        }
28693      } else {
28694        // We need to add the timeout here to have the real endtimestamp of the transaction
28695        // Remember timestampInSeconds is in seconds, timeout is in ms
28696        this._restartIdleTimeout(endTimestamp + this._idleTimeout / 1000);
28697      }
28698    }
28699  }
28700
28701  /**
28702   * Checks when entries of this.activities are not changing for 3 beats.
28703   * If this occurs we finish the transaction.
28704   */
28705   _beat() {
28706    // We should not be running heartbeat if the idle transaction is finished.
28707    if (this._finished) {
28708      return;
28709    }
28710
28711    const heartbeatString = Object.keys(this.activities).join('');
28712
28713    if (heartbeatString === this._prevHeartbeatString) {
28714      this._heartbeatCounter++;
28715    } else {
28716      this._heartbeatCounter = 1;
28717    }
28718
28719    this._prevHeartbeatString = heartbeatString;
28720
28721    if (this._heartbeatCounter >= 3) {
28722      if (this._autoFinishAllowed) {
28723        debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] Transaction finished because of no change for 3 heart beats');
28724        this.setStatus('deadline_exceeded');
28725        this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[0];
28726        this.end();
28727      }
28728    } else {
28729      this._pingHeartbeat();
28730    }
28731  }
28732
28733  /**
28734   * Pings the heartbeat
28735   */
28736   _pingHeartbeat() {
28737    debugBuild.DEBUG_BUILD && utils.logger.log(`pinging Heartbeat -> current counter: ${this._heartbeatCounter}`);
28738    setTimeout(() => {
28739      this._beat();
28740    }, this._heartbeatInterval);
28741  }
28742}
28743
28744exports.IdleTransaction = IdleTransaction;
28745exports.IdleTransactionSpanRecorder = IdleTransactionSpanRecorder;
28746exports.TRACING_DEFAULTS = TRACING_DEFAULTS;
28747
28748
28749},{"../debug-build.js":245,"../utils/spanUtils.js":297,"./span.js":281,"./transaction.js":284,"@sentry/utils":319}],279:[function(require,module,exports){
28750Object.defineProperty(exports, '__esModule', { value: true });
28751
28752const utils = require('./utils.js');
28753
28754/**
28755 * Adds a measurement to the current active transaction.
28756 */
28757function setMeasurement(name, value, unit) {
28758  // eslint-disable-next-line deprecation/deprecation
28759  const transaction = utils.getActiveTransaction();
28760  if (transaction) {
28761    // eslint-disable-next-line deprecation/deprecation
28762    transaction.setMeasurement(name, value, unit);
28763  }
28764}
28765
28766exports.setMeasurement = setMeasurement;
28767
28768
28769},{"./utils.js":285}],280:[function(require,module,exports){
28770Object.defineProperty(exports, '__esModule', { value: true });
28771
28772const utils = require('@sentry/utils');
28773const debugBuild = require('../debug-build.js');
28774const semanticAttributes = require('../semanticAttributes.js');
28775const hasTracingEnabled = require('../utils/hasTracingEnabled.js');
28776const spanUtils = require('../utils/spanUtils.js');
28777
28778/**
28779 * Makes a sampling decision for the given transaction and stores it on the transaction.
28780 *
28781 * Called every time a transaction is created. Only transactions which emerge with a `sampled` value of `true` will be
28782 * sent to Sentry.
28783 *
28784 * This method muttes the given `transaction` and will set the `sampled` value on it.
28785 * It returns the same transaction, for convenience.
28786 */
28787function sampleTransaction(
28788  transaction,
28789  options,
28790  samplingContext,
28791) {
28792  // nothing to do if tracing is not enabled
28793  if (!hasTracingEnabled.hasTracingEnabled(options)) {
28794    // eslint-disable-next-line deprecation/deprecation
28795    transaction.sampled = false;
28796    return transaction;
28797  }
28798
28799  // if the user has forced a sampling decision by passing a `sampled` value in their transaction context, go with that
28800  // eslint-disable-next-line deprecation/deprecation
28801  if (transaction.sampled !== undefined) {
28802    // eslint-disable-next-line deprecation/deprecation
28803    transaction.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, Number(transaction.sampled));
28804    return transaction;
28805  }
28806
28807  // we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should
28808  // work; prefer the hook if so
28809  let sampleRate;
28810  if (typeof options.tracesSampler === 'function') {
28811    sampleRate = options.tracesSampler(samplingContext);
28812    transaction.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, Number(sampleRate));
28813  } else if (samplingContext.parentSampled !== undefined) {
28814    sampleRate = samplingContext.parentSampled;
28815  } else if (typeof options.tracesSampleRate !== 'undefined') {
28816    sampleRate = options.tracesSampleRate;
28817    transaction.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, Number(sampleRate));
28818  } else {
28819    // When `enableTracing === true`, we use a sample rate of 100%
28820    sampleRate = 1;
28821    transaction.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, sampleRate);
28822  }
28823
28824  // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The
28825  // only valid values are booleans or numbers between 0 and 1.)
28826  if (!isValidSampleRate(sampleRate)) {
28827    debugBuild.DEBUG_BUILD && utils.logger.warn('[Tracing] Discarding transaction because of invalid sample rate.');
28828    // eslint-disable-next-line deprecation/deprecation
28829    transaction.sampled = false;
28830    return transaction;
28831  }
28832
28833  // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped
28834  if (!sampleRate) {
28835    debugBuild.DEBUG_BUILD &&
28836      utils.logger.log(
28837        `[Tracing] Discarding transaction because ${
28838          typeof options.tracesSampler === 'function'
28839            ? 'tracesSampler returned 0 or false'
28840            : 'a negative sampling decision was inherited or tracesSampleRate is set to 0'
28841        }`,
28842      );
28843    // eslint-disable-next-line deprecation/deprecation
28844    transaction.sampled = false;
28845    return transaction;
28846  }
28847
28848  // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is
28849  // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.
28850  // eslint-disable-next-line deprecation/deprecation
28851  transaction.sampled = Math.random() < (sampleRate );
28852
28853  // if we're not going to keep it, we're done
28854  // eslint-disable-next-line deprecation/deprecation
28855  if (!transaction.sampled) {
28856    debugBuild.DEBUG_BUILD &&
28857      utils.logger.log(
28858        `[Tracing] Discarding transaction because it's not included in the random sample (sampling rate = ${Number(
28859          sampleRate,
28860        )})`,
28861      );
28862    return transaction;
28863  }
28864
28865  debugBuild.DEBUG_BUILD &&
28866    // eslint-disable-next-line deprecation/deprecation
28867    utils.logger.log(`[Tracing] starting ${transaction.op} transaction - ${spanUtils.spanToJSON(transaction).description}`);
28868  return transaction;
28869}
28870
28871/**
28872 * Checks the given sample rate to make sure it is valid type and value (a boolean, or a number between 0 and 1).
28873 */
28874function isValidSampleRate(rate) {
28875  // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck
28876  // eslint-disable-next-line @typescript-eslint/no-explicit-any
28877  if (utils.isNaN(rate) || !(typeof rate === 'number' || typeof rate === 'boolean')) {
28878    debugBuild.DEBUG_BUILD &&
28879      utils.logger.warn(
28880        `[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify(
28881          rate,
28882        )} of type ${JSON.stringify(typeof rate)}.`,
28883      );
28884    return false;
28885  }
28886
28887  // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false
28888  if (rate < 0 || rate > 1) {
28889    debugBuild.DEBUG_BUILD &&
28890      utils.logger.warn(`[Tracing] Given sample rate is invalid. Sample rate must be between 0 and 1. Got ${rate}.`);
28891    return false;
28892  }
28893  return true;
28894}
28895
28896exports.isValidSampleRate = isValidSampleRate;
28897exports.sampleTransaction = sampleTransaction;
28898
28899
28900},{"../debug-build.js":245,"../semanticAttributes.js":270,"../utils/hasTracingEnabled.js":292,"../utils/spanUtils.js":297,"@sentry/utils":319}],281:[function(require,module,exports){
28901Object.defineProperty(exports, '__esModule', { value: true });
28902
28903const utils = require('@sentry/utils');
28904const debugBuild = require('../debug-build.js');
28905const metricSummary = require('../metrics/metric-summary.js');
28906const semanticAttributes = require('../semanticAttributes.js');
28907const getRootSpan = require('../utils/getRootSpan.js');
28908const spanUtils = require('../utils/spanUtils.js');
28909const spanstatus = require('./spanstatus.js');
28910
28911/**
28912 * Keeps track of finished spans for a given transaction
28913 * @internal
28914 * @hideconstructor
28915 * @hidden
28916 */
28917class SpanRecorder {
28918
28919   constructor(maxlen = 1000) {
28920    this._maxlen = maxlen;
28921    this.spans = [];
28922  }
28923
28924  /**
28925   * This is just so that we don't run out of memory while recording a lot
28926   * of spans. At some point we just stop and flush out the start of the
28927   * trace tree (i.e.the first n spans with the smallest
28928   * start_timestamp).
28929   */
28930   add(span) {
28931    if (this.spans.length > this._maxlen) {
28932      // eslint-disable-next-line deprecation/deprecation
28933      span.spanRecorder = undefined;
28934    } else {
28935      this.spans.push(span);
28936    }
28937  }
28938}
28939
28940/**
28941 * Span contains all data about a span
28942 */
28943class Span  {
28944  /**
28945   * Tags for the span.
28946   * @deprecated Use `spanToJSON(span).atttributes` instead.
28947   */
28948
28949  /**
28950   * Data for the span.
28951   * @deprecated Use `spanToJSON(span).atttributes` instead.
28952   */
28953  // eslint-disable-next-line @typescript-eslint/no-explicit-any
28954
28955  /**
28956   * List of spans that were finalized
28957   *
28958   * @deprecated This property will no longer be public. Span recording will be handled internally.
28959   */
28960
28961  /**
28962   * @inheritDoc
28963   * @deprecated Use top level `Sentry.getRootSpan()` instead
28964   */
28965
28966  /**
28967   * The instrumenter that created this span.
28968   *
28969   * TODO (v8): This can probably be replaced by an `instanceOf` check of the span class.
28970   *            the instrumenter can only be sentry or otel so we can check the span instance
28971   *            to verify which one it is and remove this field entirely.
28972   *
28973   * @deprecated This field will be removed.
28974   */
28975
28976  /** Epoch timestamp in seconds when the span started. */
28977
28978  /** Epoch timestamp in seconds when the span ended. */
28979
28980  /** Internal keeper of the status */
28981
28982  /**
28983   * You should never call the constructor manually, always use `Sentry.startTransaction()`
28984   * or call `startChild()` on an existing span.
28985   * @internal
28986   * @hideconstructor
28987   * @hidden
28988   */
28989   constructor(spanContext = {}) {
28990    this._traceId = spanContext.traceId || utils.uuid4();
28991    this._spanId = spanContext.spanId || utils.uuid4().substring(16);
28992    this._startTime = spanContext.startTimestamp || utils.timestampInSeconds();
28993    // eslint-disable-next-line deprecation/deprecation
28994    this.tags = spanContext.tags ? { ...spanContext.tags } : {};
28995    // eslint-disable-next-line deprecation/deprecation
28996    this.data = spanContext.data ? { ...spanContext.data } : {};
28997    // eslint-disable-next-line deprecation/deprecation
28998    this.instrumenter = spanContext.instrumenter || 'sentry';
28999
29000    this._attributes = {};
29001    this.setAttributes({
29002      [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanContext.origin || 'manual',
29003      [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP]: spanContext.op,
29004      ...spanContext.attributes,
29005    });
29006
29007    // eslint-disable-next-line deprecation/deprecation
29008    this._name = spanContext.name || spanContext.description;
29009
29010    if (spanContext.parentSpanId) {
29011      this._parentSpanId = spanContext.parentSpanId;
29012    }
29013    // We want to include booleans as well here
29014    if ('sampled' in spanContext) {
29015      this._sampled = spanContext.sampled;
29016    }
29017    if (spanContext.status) {
29018      this._status = spanContext.status;
29019    }
29020    if (spanContext.endTimestamp) {
29021      this._endTime = spanContext.endTimestamp;
29022    }
29023    if (spanContext.exclusiveTime) {
29024      this._exclusiveTime = spanContext.exclusiveTime;
29025    }
29026    this._measurements = spanContext.measurements ? { ...spanContext.measurements } : {};
29027  }
29028
29029  // This rule conflicts with another eslint rule :(
29030  /* eslint-disable @typescript-eslint/member-ordering */
29031
29032  /**
29033   * An alias for `description` of the Span.
29034   * @deprecated Use `spanToJSON(span).description` instead.
29035   */
29036   get name() {
29037    return this._name || '';
29038  }
29039
29040  /**
29041   * Update the name of the span.
29042   * @deprecated Use `spanToJSON(span).description` instead.
29043   */
29044   set name(name) {
29045    this.updateName(name);
29046  }
29047
29048  /**
29049   * Get the description of the Span.
29050   * @deprecated Use `spanToJSON(span).description` instead.
29051   */
29052   get description() {
29053    return this._name;
29054  }
29055
29056  /**
29057   * Get the description of the Span.
29058   * @deprecated Use `spanToJSON(span).description` instead.
29059   */
29060   set description(description) {
29061    this._name = description;
29062  }
29063
29064  /**
29065   * The ID of the trace.
29066   * @deprecated Use `spanContext().traceId` instead.
29067   */
29068   get traceId() {
29069    return this._traceId;
29070  }
29071
29072  /**
29073   * The ID of the trace.
29074   * @deprecated You cannot update the traceId of a span after span creation.
29075   */
29076   set traceId(traceId) {
29077    this._traceId = traceId;
29078  }
29079
29080  /**
29081   * The ID of the span.
29082   * @deprecated Use `spanContext().spanId` instead.
29083   */
29084   get spanId() {
29085    return this._spanId;
29086  }
29087
29088  /**
29089   * The ID of the span.
29090   * @deprecated You cannot update the spanId of a span after span creation.
29091   */
29092   set spanId(spanId) {
29093    this._spanId = spanId;
29094  }
29095
29096  /**
29097   * @inheritDoc
29098   *
29099   * @deprecated Use `startSpan` functions instead.
29100   */
29101   set parentSpanId(string) {
29102    this._parentSpanId = string;
29103  }
29104
29105  /**
29106   * @inheritDoc
29107   *
29108   * @deprecated Use `spanToJSON(span).parent_span_id` instead.
29109   */
29110   get parentSpanId() {
29111    return this._parentSpanId;
29112  }
29113
29114  /**
29115   * Was this span chosen to be sent as part of the sample?
29116   * @deprecated Use `isRecording()` instead.
29117   */
29118   get sampled() {
29119    return this._sampled;
29120  }
29121
29122  /**
29123   * Was this span chosen to be sent as part of the sample?
29124   * @deprecated You cannot update the sampling decision of a span after span creation.
29125   */
29126   set sampled(sampled) {
29127    this._sampled = sampled;
29128  }
29129
29130  /**
29131   * Attributes for the span.
29132   * @deprecated Use `spanToJSON(span).atttributes` instead.
29133   */
29134   get attributes() {
29135    return this._attributes;
29136  }
29137
29138  /**
29139   * Attributes for the span.
29140   * @deprecated Use `setAttributes()` instead.
29141   */
29142   set attributes(attributes) {
29143    this._attributes = attributes;
29144  }
29145
29146  /**
29147   * Timestamp in seconds (epoch time) indicating when the span started.
29148   * @deprecated Use `spanToJSON()` instead.
29149   */
29150   get startTimestamp() {
29151    return this._startTime;
29152  }
29153
29154  /**
29155   * Timestamp in seconds (epoch time) indicating when the span started.
29156   * @deprecated In v8, you will not be able to update the span start time after creation.
29157   */
29158   set startTimestamp(startTime) {
29159    this._startTime = startTime;
29160  }
29161
29162  /**
29163   * Timestamp in seconds when the span ended.
29164   * @deprecated Use `spanToJSON()` instead.
29165   */
29166   get endTimestamp() {
29167    return this._endTime;
29168  }
29169
29170  /**
29171   * Timestamp in seconds when the span ended.
29172   * @deprecated Set the end time via `span.end()` instead.
29173   */
29174   set endTimestamp(endTime) {
29175    this._endTime = endTime;
29176  }
29177
29178  /**
29179   * The status of the span.
29180   *
29181   * @deprecated Use `spanToJSON().status` instead to get the status.
29182   */
29183   get status() {
29184    return this._status;
29185  }
29186
29187  /**
29188   * The status of the span.
29189   *
29190   * @deprecated Use `.setStatus()` instead to set or update the status.
29191   */
29192   set status(status) {
29193    this._status = status;
29194  }
29195
29196  /**
29197   * Operation of the span
29198   *
29199   * @deprecated Use `spanToJSON().op` to read the op instead.
29200   */
29201   get op() {
29202    return this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP] ;
29203  }
29204
29205  /**
29206   * Operation of the span
29207   *
29208   * @deprecated Use `startSpan()` functions to set or `span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'op')
29209   *             to update the span instead.
29210   */
29211   set op(op) {
29212    this.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP, op);
29213  }
29214
29215  /**
29216   * The origin of the span, giving context about what created the span.
29217   *
29218   * @deprecated Use `spanToJSON().origin` to read the origin instead.
29219   */
29220   get origin() {
29221    return this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] ;
29222  }
29223
29224  /**
29225   * The origin of the span, giving context about what created the span.
29226   *
29227   * @deprecated Use `startSpan()` functions to set the origin instead.
29228   */
29229   set origin(origin) {
29230    this.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, origin);
29231  }
29232
29233  /* eslint-enable @typescript-eslint/member-ordering */
29234
29235  /** @inheritdoc */
29236   spanContext() {
29237    const { _spanId: spanId, _traceId: traceId, _sampled: sampled } = this;
29238    return {
29239      spanId,
29240      traceId,
29241      traceFlags: sampled ? spanUtils.TRACE_FLAG_SAMPLED : spanUtils.TRACE_FLAG_NONE,
29242    };
29243  }
29244
29245  /**
29246   * Creates a new `Span` while setting the current `Span.id` as `parentSpanId`.
29247   * Also the `sampled` decision will be inherited.
29248   *
29249   * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead.
29250   */
29251   startChild(
29252    spanContext,
29253  ) {
29254    const childSpan = new Span({
29255      ...spanContext,
29256      parentSpanId: this._spanId,
29257      sampled: this._sampled,
29258      traceId: this._traceId,
29259    });
29260
29261    // eslint-disable-next-line deprecation/deprecation
29262    childSpan.spanRecorder = this.spanRecorder;
29263    // eslint-disable-next-line deprecation/deprecation
29264    if (childSpan.spanRecorder) {
29265      // eslint-disable-next-line deprecation/deprecation
29266      childSpan.spanRecorder.add(childSpan);
29267    }
29268
29269    const rootSpan = getRootSpan.getRootSpan(this);
29270    // TODO: still set span.transaction here until we have a more permanent solution
29271    // Probably similarly to the weakmap we hold in node-experimental
29272    // eslint-disable-next-line deprecation/deprecation
29273    childSpan.transaction = rootSpan ;
29274
29275    if (debugBuild.DEBUG_BUILD && rootSpan) {
29276      const opStr = (spanContext && spanContext.op) || '< unknown op >';
29277      const nameStr = spanUtils.spanToJSON(childSpan).description || '< unknown name >';
29278      const idStr = rootSpan.spanContext().spanId;
29279
29280      const logMessage = `[Tracing] Starting '${opStr}' span on transaction '${nameStr}' (${idStr}).`;
29281      utils.logger.log(logMessage);
29282      this._logMessage = logMessage;
29283    }
29284
29285    return childSpan;
29286  }
29287
29288  /**
29289   * Sets the tag attribute on the current span.
29290   *
29291   * Can also be used to unset a tag, by passing `undefined`.
29292   *
29293   * @param key Tag key
29294   * @param value Tag value
29295   * @deprecated Use `setAttribute()` instead.
29296   */
29297   setTag(key, value) {
29298    // eslint-disable-next-line deprecation/deprecation
29299    this.tags = { ...this.tags, [key]: value };
29300    return this;
29301  }
29302
29303  /**
29304   * Sets the data attribute on the current span
29305   * @param key Data key
29306   * @param value Data value
29307   * @deprecated Use `setAttribute()` instead.
29308   */
29309  // eslint-disable-next-line @typescript-eslint/no-explicit-any
29310   setData(key, value) {
29311    // eslint-disable-next-line deprecation/deprecation
29312    this.data = { ...this.data, [key]: value };
29313    return this;
29314  }
29315
29316  /** @inheritdoc */
29317   setAttribute(key, value) {
29318    if (value === undefined) {
29319      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
29320      delete this._attributes[key];
29321    } else {
29322      this._attributes[key] = value;
29323    }
29324  }
29325
29326  /** @inheritdoc */
29327   setAttributes(attributes) {
29328    Object.keys(attributes).forEach(key => this.setAttribute(key, attributes[key]));
29329  }
29330
29331  /**
29332   * @inheritDoc
29333   */
29334   setStatus(value) {
29335    this._status = value;
29336    return this;
29337  }
29338
29339  /**
29340   * @inheritDoc
29341   * @deprecated Use top-level `setHttpStatus()` instead.
29342   */
29343   setHttpStatus(httpStatus) {
29344    spanstatus.setHttpStatus(this, httpStatus);
29345    return this;
29346  }
29347
29348  /**
29349   * @inheritdoc
29350   *
29351   * @deprecated Use `.updateName()` instead.
29352   */
29353   setName(name) {
29354    this.updateName(name);
29355  }
29356
29357  /**
29358   * @inheritDoc
29359   */
29360   updateName(name) {
29361    this._name = name;
29362    return this;
29363  }
29364
29365  /**
29366   * @inheritDoc
29367   *
29368   * @deprecated Use `spanToJSON(span).status === 'ok'` instead.
29369   */
29370   isSuccess() {
29371    return this._status === 'ok';
29372  }
29373
29374  /**
29375   * @inheritDoc
29376   *
29377   * @deprecated Use `.end()` instead.
29378   */
29379   finish(endTimestamp) {
29380    return this.end(endTimestamp);
29381  }
29382
29383  /** @inheritdoc */
29384   end(endTimestamp) {
29385    // If already ended, skip
29386    if (this._endTime) {
29387      return;
29388    }
29389    const rootSpan = getRootSpan.getRootSpan(this);
29390    if (
29391      debugBuild.DEBUG_BUILD &&
29392      // Don't call this for transactions
29393      rootSpan &&
29394      rootSpan.spanContext().spanId !== this._spanId
29395    ) {
29396      const logMessage = this._logMessage;
29397      if (logMessage) {
29398        utils.logger.log((logMessage ).replace('Starting', 'Finis
29398hing'));
29399      }
29400    }
29401
29402    this._endTime = spanUtils.spanTimeInputToSeconds(endTimestamp);
29403  }
29404
29405  /**
29406   * @inheritDoc
29407   *
29408   * @deprecated Use `spanToTraceHeader()` instead.
29409   */
29410   toTraceparent() {
29411    return spanUtils.spanToTraceHeader(this);
29412  }
29413
29414  /**
29415   * @inheritDoc
29416   *
29417   * @deprecated Use `spanToJSON()` or access the fields directly instead.
29418   */
29419   toContext() {
29420    return utils.dropUndefinedKeys({
29421      data: this._getData(),
29422      description: this._name,
29423      endTimestamp: this._endTime,
29424      // eslint-disable-next-line deprecation/deprecation
29425      op: this.op,
29426      parentSpanId: this._parentSpanId,
29427      sampled: this._sampled,
29428      spanId: this._spanId,
29429      startTimestamp: this._startTime,
29430      status: this._status,
29431      // eslint-disable-next-line deprecation/deprecation
29432      tags: this.tags,
29433      traceId: this._traceId,
29434    });
29435  }
29436
29437  /**
29438   * @inheritDoc
29439   *
29440   * @deprecated Update the fields directly instead.
29441   */
29442   updateWithContext(spanContext) {
29443    // eslint-disable-next-line deprecation/deprecation
29444    this.data = spanContext.data || {};
29445    // eslint-disable-next-line deprecation/deprecation
29446    this._name = spanContext.name || spanContext.description;
29447    this._endTime = spanContext.endTimestamp;
29448    // eslint-disable-next-line deprecation/deprecation
29449    this.op = spanContext.op;
29450    this._parentSpanId = spanContext.parentSpanId;
29451    this._sampled = spanContext.sampled;
29452    this._spanId = spanContext.spanId || this._spanId;
29453    this._startTime = spanContext.startTimestamp || this._startTime;
29454    this._status = spanContext.status;
29455    // eslint-disable-next-line deprecation/deprecation
29456    this.tags = spanContext.tags || {};
29457    this._traceId = spanContext.traceId || this._traceId;
29458
29459    return this;
29460  }
29461
29462  /**
29463   * @inheritDoc
29464   *
29465   * @deprecated Use `spanToTraceContext()` util function instead.
29466   */
29467   getTraceContext() {
29468    return spanUtils.spanToTraceContext(this);
29469  }
29470
29471  /**
29472   * Get JSON representation of this span.
29473   *
29474   * @hidden
29475   * @internal This method is purely for internal purposes and should not be used outside
29476   * of SDK code. If you need to get a JSON representation of a span,
29477   * use `spanToJSON(span)` instead.
29478   */
29479   getSpanJSON() {
29480    return utils.dropUndefinedKeys({
29481      data: this._getData(),
29482      description: this._name,
29483      op: this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP] ,
29484      parent_span_id: this._parentSpanId,
29485      span_id: this._spanId,
29486      start_timestamp: this._startTime,
29487      status: this._status,
29488      // eslint-disable-next-line deprecation/deprecation
29489      tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,
29490      timestamp: this._endTime,
29491      trace_id: this._traceId,
29492      origin: this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] ,
29493      _metrics_summary: metricSummary.getMetricSummaryJsonForSpan(this),
29494      profile_id: this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_PROFILE_ID] ,
29495      exclusive_time: this._exclusiveTime,
29496      measurements: Object.keys(this._measurements).length > 0 ? this._measurements : undefined,
29497    });
29498  }
29499
29500  /** @inheritdoc */
29501   isRecording() {
29502    return !this._endTime && !!this._sampled;
29503  }
29504
29505  /**
29506   * Convert the object to JSON.
29507   * @deprecated Use `spanToJSON(span)` instead.
29508   */
29509   toJSON() {
29510    return this.getSpanJSON();
29511  }
29512
29513  /**
29514   * Get the merged data for this span.
29515   * For now, this combines `data` and `attributes` together,
29516   * until eventually we can ingest `attributes` directly.
29517   */
29518   _getData()
29519
29520 {
29521    // eslint-disable-next-line deprecation/deprecation
29522    const { data, _attributes: attributes } = this;
29523
29524    const hasData = Object.keys(data).length > 0;
29525    const hasAttributes = Object.keys(attributes).length > 0;
29526
29527    if (!hasData && !hasAttributes) {
29528      return undefined;
29529    }
29530
29531    if (hasData && hasAttributes) {
29532      return {
29533        ...data,
29534        ...attributes,
29535      };
29536    }
29537
29538    return hasData ? data : attributes;
29539  }
29540}
29541
29542exports.Span = Span;
29543exports.SpanRecorder = SpanRecorder;
29544
29545
29546},{"../debug-build.js":245,"../metrics/metric-summary.js":266,"../semanticAttributes.js":270,"../utils/getRootSpan.js":290,"../utils/spanUtils.js":297,"./spanstatus.js":282,"@sentry/utils":319}],282:[function(require,module,exports){
29547Object.defineProperty(exports, '__esModule', { value: true });
29548
29549/** The status of an Span.
29550 *
29551 * @deprecated Use string literals - if you require type casting, cast to SpanStatusType type
29552 */
29553exports.SpanStatus = void 0; (function (SpanStatus) {
29554  /** The operation completed successfully. */
29555  const Ok = 'ok'; SpanStatus["Ok"] = Ok;
29556  /** Deadline expired before operation could complete. */
29557  const DeadlineExceeded = 'deadline_exceeded'; SpanStatus["DeadlineExceeded"] = DeadlineExceeded;
29558  /** 401 Unauthorized (actually does mean unauthenticated according to RFC 7235) */
29559  const Unauthenticated = 'unauthenticated'; SpanStatus["Unauthenticated"] = Unauthenticated;
29560  /** 403 Forbidden */
29561  const PermissionDenied = 'permission_denied'; SpanStatus["PermissionDenied"] = PermissionDenied;
29562  /** 404 Not Found. Some requested entity (file or directory) was not found. */
29563  const NotFound = 'not_found'; SpanStatus["NotFound"] = NotFound;
29564  /** 429 Too Many Requests */
29565  const ResourceExhausted = 'resource_exhausted'; SpanStatus["ResourceExhausted"] = ResourceExhausted;
29566  /** Client specified an invalid argument. 4xx. */
29567  const InvalidArgument = 'invalid_argument'; SpanStatus["InvalidArgument"] = InvalidArgument;
29568  /** 501 Not Implemented */
29569  const Unimplemented = 'unimplemented'; SpanStatus["Unimplemented"] = Unimplemented;
29570  /** 503 Service Unavailable */
29571  const Unavailable = 'unavailable'; SpanStatus["Unavailable"] = Unavailable;
29572  /** Other/generic 5xx. */
29573  const InternalError = 'internal_error'; SpanStatus["InternalError"] = InternalError;
29574  /** Unknown. Any non-standard HTTP status code. */
29575  const UnknownError = 'unknown_error'; SpanStatus["UnknownError"] = UnknownError;
29576  /** The operation was cancelled (typically by the user). */
29577  const Cancelled = 'cancelled'; SpanStatus["Cancelled"] = Cancelled;
29578  /** Already exists (409) */
29579  const AlreadyExists = 'already_exists'; SpanStatus["AlreadyExists"] = AlreadyExists;
29580  /** Operation was rejected because the system is not in a state required for the operation's */
29581  const FailedPrecondition = 'failed_precondition'; SpanStatus["FailedPrecondition"] = FailedPrecondition;
29582  /** The operation was aborted, typically due to a concurrency issue. */
29583  const Aborted = 'aborted'; SpanStatus["Aborted"] = Aborted;
29584  /** Operation was attempted past the valid range. */
29585  const OutOfRange = 'out_of_range'; SpanStatus["OutOfRange"] = OutOfRange;
29586  /** Unrecoverable data loss or corruption */
29587  const DataLoss = 'data_loss'; SpanStatus["DataLoss"] = DataLoss;
29588})(exports.SpanStatus || (exports.SpanStatus = {}));
29589
29590/**
29591 * Converts a HTTP status code into a {@link SpanStatusType}.
29592 *
29593 * @param httpStatus The HTTP response status code.
29594 * @returns The span status or unknown_error.
29595 */
29596function getSpanStatusFromHttpCode(httpStatus) {
29597  if (httpStatus < 400 && httpStatus >= 100) {
29598    return 'ok';
29599  }
29600
29601  if (httpStatus >= 400 && httpStatus < 500) {
29602    switch (httpStatus) {
29603      case 401:
29604        return 'unauthenticated';
29605      case 403:
29606        return 'permission_denied';
29607      case 404:
29608        return 'not_found';
29609      case 409:
29610        return 'already_exists';
29611      case 413:
29612        return 'failed_precondition';
29613      case 429:
29614        return 'resource_exhausted';
29615      default:
29616        return 'invalid_argument';
29617    }
29618  }
29619
29620  if (httpStatus >= 500 && httpStatus < 600) {
29621    switch (httpStatus) {
29622      case 501:
29623        return 'unimplemented';
29624      case 503:
29625        return 'unavailable';
29626      case 504:
29627        return 'deadline_exceeded';
29628      default:
29629        return 'internal_error';
29630    }
29631  }
29632
29633  return 'unknown_error';
29634}
29635
29636/**
29637 * Converts a HTTP status code into a {@link SpanStatusType}.
29638 *
29639 * @deprecated Use {@link spanStatusFromHttpCode} instead.
29640 * This export will be removed in v8 as the signature contains a typo.
29641 *
29642 * @param httpStatus The HTTP response status code.
29643 * @returns The span status or unknown_error.
29644 */
29645const spanStatusfromHttpCode = getSpanStatusFromHttpCode;
29646
29647/**
29648 * Sets the Http status attributes on the current span based on the http code.
29649 * Additionally, the span's status is updated, depending on the http code.
29650 */
29651function setHttpStatus(span, httpStatus) {
29652  // TODO (v8): Remove these calls
29653  // Relay does not require us to send the status code as a tag
29654  // For now, just because users might expect it to land as a tag we keep sending it.
29655  // Same with data.
29656  // In v8, we replace both, simply with
29657  // span.setAttribute('http.response.status_code', httpStatus);
29658
29659  // eslint-disable-next-line deprecation/deprecation
29660  span.setTag('http.status_code', String(httpStatus));
29661  // eslint-disable-next-line deprecation/deprecation
29662  span.setData('http.response.status_code', httpStatus);
29663
29664  const spanStatus = getSpanStatusFromHttpCode(httpStatus);
29665  if (spanStatus !== 'unknown_error') {
29666    span.setStatus(spanStatus);
29667  }
29668}
29669
29670exports.getSpanStatusFromHttpCode = getSpanStatusFromHttpCode;
29671exports.setHttpStatus = setHttpStatus;
29672exports.spanStatusfromHttpCode = spanStatusfromHttpCode;
29673
29674
29675},{}],283:[function(require,module,exports){
29676Object.defineProperty(exports, '__esModule', { value: true });
29677
29678const utils = require('@sentry/utils');
29679const debugBuild = require('../debug-build.js');
29680const hub = require('../hub.js');
29681const spanUtils = require('../utils/spanUtils.js');
29682require('./errors.js');
29683require('./spanstatus.js');
29684const dynamicSamplingContext = require('./dynamicSamplingContext.js');
29685const exports$1 = require('../exports.js');
29686const handleCallbackErrors = require('../utils/handleCallbackErrors.js');
29687const hasTracingEnabled = require('../utils/hasTracingEnabled.js');
29688
29689/**
29690 * Wraps a function with a transaction/span and finishes the span after the function is done.
29691 *
29692 * Note that if you have not enabled tracing extensions via `addTracingExtensions`
29693 * or you didn't set `tracesSampleRate`, this function will not generate spans
29694 * and the `span` returned from the callback will be undefined.
29695 *
29696 * This function is meant to be used internally and may break at any time. Use at your own risk.
29697 *
29698 * @internal
29699 * @private
29700 *
29701 * @deprecated Use `startSpan` instead.
29702 */
29703function trace(
29704  context,
29705  callback,
29706  // eslint-disable-next-line @typescript-eslint/no-empty-function
29707  onError = () => {},
29708  // eslint-disable-next-line @typescript-eslint/no-empty-function
29709  afterFinish = () => {},
29710) {
29711  // eslint-disable-next-line deprecation/deprecation
29712  const hub$1 = hub.getCurrentHub();
29713  const scope = exports$1.getCurrentScope();
29714  // eslint-disable-next-line deprecation/deprecation
29715  const parentSpan = scope.getSpan();
29716
29717  const spanContext = normalizeContext(context);
29718  const activeSpan = createChildSpanOrTransaction(hub$1, {
29719    parentSpan,
29720    spanContext,
29721    forceTransaction: false,
29722    scope,
29723  });
29724
29725  // eslint-disable-next-line deprecation/deprecation
29726  scope.setSpan(activeSpan);
29727
29728  return handleCallbackErrors.handleCallbackErrors(
29729    () => callback(activeSpan),
29730    error => {
29731      activeSpan && activeSpan.setStatus('internal_error');
29732      onError(error, activeSpan);
29733    },
29734    () => {
29735      activeSpan && activeSpan.end();
29736      // eslint-disable-next-line deprecation/deprecation
29737      scope.setSpan(parentSpan);
29738      afterFinish();
29739    },
29740  );
29741}
29742
29743/**
29744 * Wraps a function with a transaction/span and finishes the span after the function is done.
29745 * The created span is the active span and will be used as parent by other spans created inside the function
29746 * and can be accessed via `Sentry.getSpan()`, as long as the function is executed while the scope is active.
29747 *
29748 * If you want to create a span that is not set as active, use {@link startInactiveSpan}.
29749 *
29750 * Note that if you have not enabled tracing extensions via `addTracingExtensions`
29751 * or you didn't set `tracesSampleRate`, this function will not generate spans
29752 * and the `span` returned from the callback will be undefined.
29753 */
29754function startSpan(context, callback) {
29755  const spanContext = normalizeContext(context);
29756
29757  return hub.runWithAsyncContext(() => {
29758    return exports$1.withScope(context.scope, scope => {
29759      // eslint-disable-next-line deprecation/deprecation
29760      const hub$1 = hub.getCurrentHub();
29761      // eslint-disable-next-line deprecation/deprecation
29762      const parentSpan = scope.getSpan();
29763
29764      const shouldSkipSpan = context.onlyIfParent && !parentSpan;
29765      const activeSpan = shouldSkipSpan
29766        ? undefined
29767        : createChildSpanOrTransaction(hub$1, {
29768            parentSpan,
29769            spanContext,
29770            forceTransaction: context.forceTransaction,
29771            scope,
29772          });
29773
29774      return handleCallbackErrors.handleCallbackErrors(
29775        () => callback(activeSpan),
29776        () => {
29777          // Only update the span status if it hasn't been changed yet
29778          if (activeSpan) {
29779            const { status } = spanUtils.spanToJSON(activeSpan);
29780            if (!status || status === 'ok') {
29781              activeSpan.setStatus('internal_error');
29782            }
29783          }
29784        },
29785        () => activeSpan && activeSpan.end(),
29786      );
29787    });
29788  });
29789}
29790
29791/**
29792 * @deprecated Use {@link startSpan} instead.
29793 */
29794const startActiveSpan = startSpan;
29795
29796/**
29797 * Similar to `Sentry.startSpan`. Wraps a function with a transaction/span, but does not finish the span
29798 * after the function is done automatically. You'll have to call `span.end()` manually.
29799 *
29800 * The created span is the active span and will be used as parent by other spans created inside the function
29801 * and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active.
29802 *
29803 * Note that if you have not enabled tracing extensions via `addTracingExtensions`
29804 * or you didn't set `tracesSampleRate`, this function will not generate spans
29805 * and the `span` returned from the callback will be undefined.
29806 */
29807function startSpanManual(
29808  context,
29809  callback,
29810) {
29811  const spanContext = normalizeContext(context);
29812
29813  return hub.runWithAsyncContext(() => {
29814    return exports$1.withScope(context.scope, scope => {
29815      // eslint-disable-next-line deprecation/deprecation
29816      const hub$1 = hub.getCurrentHub();
29817      // eslint-disable-next-line deprecation/deprecation
29818      const parentSpan = scope.getSpan();
29819
29820      const shouldSkipSpan = context.onlyIfParent && !parentSpan;
29821      const activeSpan = shouldSkipSpan
29822        ? undefined
29823        : createChildSpanOrTransaction(hub$1, {
29824            parentSpan,
29825            spanContext,
29826            forceTransaction: context.forceTransaction,
29827            scope,
29828          });
29829
29830      function finishAndSetSpan() {
29831        activeSpan && activeSpan.end();
29832      }
29833
29834      return handleCallbackErrors.handleCallbackErrors(
29835        () => callback(activeSpan, finishAndSetSpan),
29836        () => {
29837          // Only update the span status if it hasn't been changed yet, and the span is not yet finished
29838          if (activeSpan && activeSpan.isRecording()) {
29839            const { status } = spanUtils.spanToJSON(activeSpan);
29840            if (!status || status === 'ok') {
29841              activeSpan.setStatus('internal_error');
29842            }
29843          }
29844        },
29845      );
29846    });
29847  });
29848}
29849
29850/**
29851 * Creates a span. This span is not set as active, so will not get automatic instrumentation spans
29852 * as children or be able to be accessed via `Sentry.getSpan()`.
29853 *
29854 * If you want to create a span that is set as active, use {@link startSpan}.
29855 *
29856 * Note that if you have not enabled tracing extensions via `addTracingExtensions`
29857 * or you didn't set `tracesSampleRate` or `tracesSampler`, this function will not generate spans
29858 * and the `span` returned from the callback will be undefined.
29859 */
29860function startInactiveSpan(context) {
29861  if (!hasTracingEnabled.hasTracingEnabled()) {
29862    return undefined;
29863  }
29864
29865  const spanContext = normalizeContext(context);
29866  // eslint-disable-next-line deprecation/deprecation
29867  const hub$1 = hub.getCurrentHub();
29868  const parentSpan = context.scope
29869    ? // eslint-disable-next-line deprecation/deprecation
29870      context.scope.getSpan()
29871    : getActiveSpan();
29872
29873  const shouldSkipSpan = context.onlyIfParent && !parentSpan;
29874
29875  if (shouldSkipSpan) {
29876    return undefined;
29877  }
29878
29879  const scope = context.scope || exports$1.getCurrentScope();
29880
29881  // Even though we don't actually want to make this span active on the current scope,
29882  // we need to make it active on a temporary scope that we use for event processing
29883  // as otherwise, it won't pick the correct span for the event when processing it
29884  const temporaryScope = (scope ).clone();
29885
29886  return createChildSpanOrTransaction(hub$1, {
29887    parentSpan,
29888    spanContext,
29889    forceTransaction: context.forceTransaction,
29890    scope: temporaryScope,
29891  });
29892}
29893
29894/**
29895 * Returns the currently active span.
29896 */
29897function getActiveSpan() {
29898  // eslint-disable-next-line deprecation/deprecation
29899  return exports$1.getCurrentScope().getSpan();
29900}
29901
29902const continueTrace = (
29903  {
29904    sentryTrace,
29905    baggage,
29906  }
29907
29908,
29909  callback,
29910) => {
29911  // TODO(v8): Change this function so it doesn't do anything besides setting the propagation context on the current scope:
29912  /*
29913    return withScope((scope) => {
29914      const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);
29915      scope.setPropagationContext(propagationContext);
29916      return callback();
29917    })
29918  */
29919
29920  const currentScope = exports$1.getCurrentScope();
29921
29922  // eslint-disable-next-line deprecation/deprecation
29923  const { traceparentData, dynamicSamplingContext, propagationContext } = utils.tracingContextFromHeaders(
29924    sentryTrace,
29925    baggage,
29926  );
29927
29928  currentScope.setPropagationContext(propagationContext);
29929
29930  if (debugBuild.DEBUG_BUILD && traceparentData) {
29931    utils.logger.log(`[Tracing] Continuing trace ${traceparentData.traceId}.`);
29932  }
29933
29934  const transactionContext = {
29935    ...traceparentData,
29936    metadata: utils.dropUndefinedKeys({
29937      dynamicSamplingContext,
29938    }),
29939  };
29940
29941  if (!callback) {
29942    return transactionContext;
29943  }
29944
29945  return hub.runWithAsyncContext(() => {
29946    return callback(transactionContext);
29947  });
29948};
29949
29950function createChildSpanOrTransaction(
29951  hub$1,
29952  {
29953    parentSpan,
29954    spanContext,
29955    forceTransaction,
29956    scope,
29957  }
29958
29959,
29960) {
29961  if (!hasTracingEnabled.hasTracingEnabled()) {
29962    return undefined;
29963  }
29964
29965  const isolationScope = hub.getIsolationScope();
29966
29967  let span;
29968  if (parentSpan && !forceTransaction) {
29969    // eslint-disable-next-line deprecation/deprecation
29970    span = parentSpan.startChild(spanContext);
29971  } else if (parentSpan) {
29972    // If we forced a transaction but have a parent span, make sure to continue from the parent span, not the scope
29973    const dsc = dynamicSamplingContext.getDynamicSamplingContextFromSpan(parentSpan);
29974    const { traceId, spanId: parentSpanId } = parentSpan.spanContext();
29975    const sampled = spanUtils.spanIsSampled(parentSpan);
29976
29977    // eslint-disable-next-line deprecation/deprecation
29978    span = hub$1.startTransaction({
29979      traceId,
29980      parentSpanId,
29981      parentSampled: sampled,
29982      ...spanContext,
29983      metadata: {
29984        dynamicSamplingContext: dsc,
29985        // eslint-disable-next-line deprecation/deprecation
29986        ...spanContext.metadata,
29987      },
29988    });
29989  } else {
29990    const { traceId, dsc, parentSpanId, sampled } = {
29991      ...isolationScope.getPropagationContext(),
29992      ...scope.getPropagationContext(),
29993    };
29994
29995    // eslint-disable-next-line deprecation/deprecation
29996    span = hub$1.startTransaction({
29997      traceId,
29998      parentSpanId,
29999      parentSampled: sampled,
30000      ...spanContext,
30001      metadata: {
30002        dynamicSamplingContext: dsc,
30003        // eslint-disable-next-line deprecation/deprecation
30004        ...spanContext.metadata,
30005      },
30006    });
30007  }
30008
30009  // We always set this as active span on the scope
30010  // In the case of this being an inactive span, we ensure to pass a detached scope in here in the first place
30011  // But by having this here, we can ensure that the lookup through `getCapturedScopesOnSpan` results in the correct scope & span combo
30012  // eslint-disable-next-line deprecation/deprecation
30013  scope.setSpan(span);
30014
30015  setCapturedScopesOnSpan(span, scope, isolationScope);
30016
30017  return span;
30018}
30019
30020/**
30021 * This converts StartSpanOptions to TransactionContext.
30022 * For the most part (for now) we accept the same options,
30023 * but some of them need to be transformed.
30024 *
30025 * Eventually the StartSpanOptions will be more aligned with OpenTelemetry.
30026 */
30027function normalizeContext(context) {
30028  if (context.startTime) {
30029    const ctx = { ...context };
30030    ctx.startTimestamp = spanUtils.spanTimeInputToSeconds(context.startTime);
30031    delete ctx.startTime;
30032    return ctx;
30033  }
30034
30035  return context;
30036}
30037
30038const SCOPE_ON_START_SPAN_FIELD = '_sentryScope';
30039const ISOLATION_SCOPE_ON_START_SPAN_FIELD = '_sentryIsolationScope';
30040
30041function setCapturedScopesOnSpan(span, scope, isolationScope) {
30042  if (span) {
30043    utils.addNonEnumerableProperty(span, ISOLATION_SCOPE_ON_START_SPAN_FIELD, isolationScope);
30044    utils.addNonEnumerableProperty(span, SCOPE_ON_START_SPAN_FIELD, scope);
30045  }
30046}
30047
30048/**
30049 * Grabs the scope and isolation scope off a span that were active when the span was started.
30050 */
30051function getCapturedScopesOnSpan(span) {
30052  return {
30053    scope: (span )[SCOPE_ON_START_SPAN_FIELD],
30054    isolationScope: (span )[ISOLATION_SCOPE_ON_START_SPAN_FIELD],
30055  };
30056}
30057
30058exports.continueTrace = continueTrace;
30059exports.getActiveSpan = getActiveSpan;
30060exports.getCapturedScopesOnSpan = getCapturedScopesOnSpan;
30061exports.startActiveSpan = startActiveSpan;
30062exports.startInactiveSpan = startInactiveSpan;
30063exports.startSpan = startSpan;
30064exports.startSpanManual = startSpanManual;
30065exports.trace = trace;
30066
30067
30068},{"../debug-build.js":245,"../exports.js":248,"../hub.js":249,"../utils/handleCallbackErrors.js":291,"../utils/hasTracingEnabled.js":292,"../utils/spanUtils.js":297,"./dynamicSamplingContext.js":275,"./errors.js":276,"./spanstatus.js":282,"@sentry/utils":319}],284:[function(require,module,exports){
30069Object.defineProperty(exports, '__esModule', { value: true });
30070
30071const utils = require('@sentry/utils');
30072const debugBuild = require('../debug-build.js');
30073const hub = require('../hub.js');
30074const metricSummary = require('../metrics/metric-summary.js');
30075const semanticAttributes = require('../semanticAttributes.js');
30076const spanUtils = require('../utils/spanUtils.js');
30077const dynamicSamplingContext = require('./dynamicSamplingContext.js');
30078const span = require('./span.js');
30079const trace = require('./trace.js');
30080
30081/** JSDoc */
30082class Transaction extends span.Span  {
30083  /**
30084   * The reference to the current hub.
30085   */
30086
30087  // DO NOT yet remove this property, it is used in a hack for v7 backwards compatibility.
30088
30089  /**
30090   * This constructor should never be called manually. Those instrumenting tracing should use
30091   * `Sentry.startTransaction()`, and internal methods should use `hub.startTransaction()`.
30092   * @internal
30093   * @hideconstructor
30094   * @hidden
30095   *
30096   * @deprecated Transactions will be removed in v8. Use spans instead.
30097   */
30098   constructor(transactionContext, hub$1) {
30099    super(transactionContext);
30100    this._contexts = {};
30101
30102    // eslint-disable-next-line deprecation/deprecation
30103    this._hub = hub$1 || hub.getCurrentHub();
30104
30105    this._name = transactionContext.name || '';
30106
30107    this._metadata = {
30108      // eslint-disable-next-line deprecation/deprecation
30109      ...transactionContext.metadata,
30110    };
30111
30112    this._trimEnd = transactionContext.trimEnd;
30113
30114    // this is because transactions are also spans, and spans have a transaction pointer
30115    // TODO (v8): Replace this with another way to set the root span
30116    // eslint-disable-next-line deprecation/deprecation
30117    this.transaction = this;
30118
30119    // If Dynamic Sampling Context is provided during the creation of the transaction, we freeze it as it usually means
30120    // there is incoming Dynamic Sampling Context. (Either through an incoming request, a baggage meta-tag, or other means)
30121    const incomingDynamicSamplingContext = this._metadata.dynamicSamplingContext;
30122    if (incomingDynamicSamplingContext) {
30123      // We shallow copy this in case anything writes to the original reference of the passed in `dynamicSamplingContext`
30124      this._frozenDynamicSamplingContext = { ...incomingDynamicSamplingContext };
30125    }
30126  }
30127
30128  // This sadly conflicts with the getter/setter ordering :(
30129  /* eslint-disable @typescript-eslint/member-ordering */
30130
30131  /**
30132   * Getter for `name` property.
30133   * @deprecated Use `spanToJSON(span).description` instead.
30134   */
30135   get name() {
30136    return this._name;
30137  }
30138
30139  /**
30140   * Setter for `name` property, which also sets `source` as custom.
30141   * @deprecated Use `updateName()` and `setMetadata()` instead.
30142   */
30143   set name(newName) {
30144    // eslint-disable-next-line deprecation/deprecation
30145    this.setName(newName);
30146  }
30147
30148  /**
30149   * Get the metadata for this transaction.
30150   * @deprecated Use `spanGetMetadata(transaction)` instead.
30151   */
30152   get metadata() {
30153    // We merge attributes in for backwards compatibility
30154    return {
30155      // Defaults
30156      // eslint-disable-next-line deprecation/deprecation
30157      source: 'custom',
30158      spanMetadata: {},
30159
30160      // Legacy metadata
30161      ...this._metadata,
30162
30163      // From attributes
30164      ...(this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] && {
30165        source: this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] ,
30166      }),
30167      ...(this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE] && {
30168        sampleRate: this._attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE] ,
30169      }),
30170    };
30171  }
30172
30173  /**
30174   * Update the metadata for this transaction.
30175   * @deprecated Use `spanGetMetadata(transaction)` instead.
30176   */
30177   set metadata(metadata) {
30178    this._metadata = metadata;
30179  }
30180
30181  /* eslint-enable @typescript-eslint/member-ordering */
30182
30183  /**
30184   * Setter for `name` property, which also sets `source` on the metadata.
30185   *
30186   * @deprecated Use `.updateName()` and `.setAttribute()` instead.
30187   */
30188   setName(name, source = 'custom') {
30189    this._name = name;
30190    this.setAttribute(semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source);
30191  }
30192
30193  /** @inheritdoc */
30194   updateName(name) {
30195    this._name = name;
30196    return this;
30197  }
30198
30199  /**
30200   * Attaches SpanRecorder to the span itself
30201   * @param maxlen maximum number of spans that can be recorded
30202   */
30203   initSpanRecorder(maxlen = 1000) {
30204    // eslint-disable-next-line deprecation/deprecation
30205    if (!this.spanRecorder) {
30206      // eslint-disable-next-line deprecation/deprecation
30207      this.spanRecorder = new span.SpanRecorder(maxlen);
30208    }
30209    // eslint-disable-next-line deprecation/deprecation
30210    this.spanRecorder.add(this);
30211  }
30212
30213  /**
30214   * Set the context of a transaction event.
30215   * @deprecated Use either `.setAttribute()`, or set the context on the scope before creating the transaction.
30216   */
30217   setContext(key, context) {
30218    if (context === null) {
30219      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
30220      delete this._contexts[key];
30221    } else {
30222      this._contexts[key] = context;
30223    }
30224  }
30225
30226  /**
30227   * @inheritDoc
30228   *
30229   * @deprecated Use top-level `setMeasurement()` instead.
30230   */
30231   setMeasurement(name, value, unit = '') {
30232    this._measurements[name] = { value, unit };
30233  }
30234
30235  /**
30236   * Store metadata on this transaction.
30237   * @deprecated Use attributes or store data on the scope instead.
30238   */
30239   setMetadata(newMetadata) {
30240    this._metadata = { ...this._metadata, ...newMetadata };
30241  }
30242
30243  /**
30244   * @inheritDoc
30245   */
30246   end(endTimestamp) {
30247    const timestampInS = spanUtils.spanTimeInputToSeconds(endTimestamp);
30248    const transaction = this._finishTransaction(timestampInS);
30249    if (!transaction) {
30250      return undefined;
30251    }
30252    // eslint-disable-next-line deprecation/deprecation
30253    return this._hub.captureEvent(transaction);
30254  }
30255
30256  /**
30257   * @inheritDoc
30258   */
30259   toContext() {
30260    // eslint-disable-next-line deprecation/deprecation
30261    const spanContext = super.toContext();
30262
30263    return utils.dropUndefinedKeys({
30264      ...spanContext,
30265      name: this._name,
30266      trimEnd: this._trimEnd,
30267    });
30268  }
30269
30270  /**
30271   * @inheritDoc
30272   */
30273   updateWithContext(transactionContext) {
30274    // eslint-disable-next-line deprecation/deprecation
30275    super.updateWithContext(transactionContext);
30276
30277    this._name = transactionContext.name || '';
30278    this._trimEnd = transactionContext.trimEnd;
30279
30280    return this;
30281  }
30282
30283  /**
30284   * @inheritdoc
30285   *
30286   * @experimental
30287   *
30288   * @deprecated Use top-level `getDynamicSamplingContextFromSpan` instead.
30289   */
30290   getDynamicSamplingContext() {
30291    return dynamicSamplingContext.getDynamicSamplingContextFromSpan(this);
30292  }
30293
30294  /**
30295   * Override the current hub with a new one.
30296   * Used if you want another hub to finish the transaction.
30297   *
30298   * @internal
30299   */
30300   setHub(hub) {
30301    this._hub = hub;
30302  }
30303
30304  /**
30305   * Get the profile id of the transaction.
30306   */
30307   getProfileId() {
30308    if (this._contexts !== undefined && this._contexts['profile'] !== undefined) {
30309      return this._contexts['profile'].profile_id ;
30310    }
30311    return undefined;
30312  }
30313
30314  /**
30315   * Finish the transaction & prepare the event to send to Sentry.
30316   */
30317   _finishTransaction(endTimestamp) {
30318    // This transaction is already finished, so we should not flush it again.
30319    if (this._endTime !== undefined) {
30320      return undefined;
30321    }
30322
30323    if (!this._name) {
30324      debugBuild.DEBUG_BUILD && utils.logger.warn('Transaction has no name, falling back to `<unlabeled transaction>`.');
30325      this._name = '<unlabeled transaction>';
30326    }
30327
30328    // just sets the end timestamp
30329    super.end(endTimestamp);
30330
30331    // eslint-disable-next-line deprecation/deprecation
30332    const client = this._hub.getClient();
30333    if (client && client.emit) {
30334      client.emit('finishTransaction', this);
30335    }
30336
30337    if (this._sampled !== true) {
30338      // At this point if `sampled !== true` we want to discard the transaction.
30339      debugBuild.DEBUG_BUILD && utils.logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.');
30340
30341      if (client) {
30342        client.recordDroppedEvent('sample_rate', 'transaction');
30343      }
30344
30345      return undefined;
30346    }
30347
30348    // eslint-disable-next-line deprecation/deprecation
30349    const finishedSpans = this.spanRecorder
30350      ? // eslint-disable-next-line deprecation/deprecation
30351        this.spanRecorder.spans.filter(span => span !== this && spanUtils.spanToJSON(span).timestamp)
30352      : [];
30353
30354    if (this._trimEnd && finishedSpans.length > 0) {
30355      const endTimes = finishedSpans.map(span => spanUtils.spanToJSON(span).timestamp).filter(Boolean) ;
30356      this._endTime = endTimes.reduce((prev, current) => {
30357        return prev > current ? prev : current;
30358      });
30359    }
30360
30361    const { scope: capturedSpanScope, isolationScope: capturedSpanIsolationScope } = trace.getCapturedScopesOnSpan(this);
30362
30363    // eslint-disable-next-line deprecation/deprecation
30364    const { metadata } = this;
30365    // eslint-disable-next-line deprecation/deprecation
30366    const { source } = metadata;
30367
30368    const transaction = {
30369      contexts: {
30370        ...this._contexts,
30371        // We don't want to override trace context
30372        trace: spanUtils.spanToTraceContext(this),
30373      },
30374      // TODO: Pass spans serialized via `spanToJSON()` here instead in v8.
30375      spans: finishedSpans,
30376      start_timestamp: this._startTime,
30377      // eslint-disable-next-line deprecation/deprecation
30378      tags: this.tags,
30379      timestamp: this._endTime,
30380      transaction: this._name,
30381      type: 'transaction',
30382      sdkProcessingMetadata: {
30383        ...metadata,
30384        capturedSpanScope,
30385        capturedSpanIsolationScope,
30386        ...utils.dropUndefinedKeys({
30387          dynamicSamplingContext: dynamicSamplingContext.getDynamicSamplingContextFromSpan(this),
30388        }),
30389      },
30390      _metrics_summary: metricSummary.getMetricSummaryJsonForSpan(this),
30391      ...(source && {
30392        transaction_info: {
30393          source,
30394        },
30395      }),
30396    };
30397
30398    const hasMeasurements = Object.keys(this._measurements).length > 0;
30399
30400    if (hasMeasurements) {
30401      debugBuild.DEBUG_BUILD &&
30402        utils.logger.log(
30403          '[Measurements] Adding measurements to transaction',
30404          JSON.stringify(this._measurements, undefined, 2),
30405        );
30406      transaction.measurements = this._measurements;
30407    }
30408
30409    // eslint-disable-next-line deprecation/deprecation
30410    debugBuild.DEBUG_BUILD && utils.logger.log(`[Tracing] Finishing ${this.op} transaction: ${this._name}.`);
30411
30412    return transaction;
30413  }
30414}
30415
30416exports.Transaction = Transaction;
30417
30418
30419},{"../debug-build.js":245,"../hub.js":249,"../metrics/metric-summary.js":266,"../semanticAttributes.js":270,"../utils/spanUtils.js":297,"./dynamicSamplingContext.js":275,"./span.js":281,"./trace.js":283,"@sentry/utils":319}],285:[function(require,module,exports){
30420Object.defineProperty(exports, '__esModule', { value: true });
30421
30422const utils = require('@sentry/utils');
30423const hub = require('../hub.js');
30424
30425/**
30426 * Grabs active transaction off scope.
30427 *
30428 * @deprecated You should not rely on the transaction, but just use `startSpan()` APIs instead.
30429 */
30430function getActiveTransaction(maybeHub) {
30431  // eslint-disable-next-line deprecation/deprecation
30432  const hub$1 = maybeHub || hub.getCurrentHub();
30433  // eslint-disable-next-line deprecation/deprecation
30434  const scope = hub$1.getScope();
30435  // eslint-disable-next-line deprecation/deprecation
30436  return scope.getTransaction() ;
30437}
30438
30439/**
30440 * The `extractTraceparentData` function and `TRACEPARENT_REGEXP` constant used
30441 * to be declared in this file. It was later moved into `@sentry/utils` as part of a
30442 * move to remove `@sentry/tracing` dependencies from `@sentry/node` (`extractTraceparentData`
30443 * is the only tracing function used by `@sentry/node`).
30444 *
30445 * These exports are kept here for backwards compatability's sake.
30446 *
30447 * See https://github.com/getsentry/sentry-javascript/issues/4642 for more details.
30448 *
30449 * @deprecated Import this function from `@sentry/utils` instead
30450 */
30451const extractTraceparentData = utils.extractTraceparentData;
30452
30453exports.stripUrlQueryAndFragment = utils.stripUrlQueryAndFragment;
30454exports.extractTraceparentData = extractTraceparentData;
30455exports.getActiveTransaction = getActiveTransaction;
30456
30457
30458},{"../hub.js":249,"@sentry/utils":319}],286:[function(require,module,exports){
30459Object.defineProperty(exports, '__esModule', { value: true });
30460
30461const utils = require('@sentry/utils');
30462const debugBuild = require('../debug-build.js');
30463
30464const DEFAULT_TRANSPORT_BUFFER_SIZE = 30;
30465
30466/**
30467 * Creates an instance of a Sentry `Transport`
30468 *
30469 * @param options
30470 * @param makeRequest
30471 */
30472function createTransport(
30473  options,
30474  makeRequest,
30475  buffer = utils.makePromiseBuffer(
30476    options.bufferSize || DEFAULT_TRANSPORT_BUFFER_SIZE,
30477  ),
30478) {
30479  let rateLimits = {};
30480  const flush = (timeout) => buffer.drain(timeout);
30481
30482  function send(envelope) {
30483    const filteredEnvelopeItems = [];
30484
30485    // Drop rate limited items from envelope
30486    utils.forEachEnvelopeItem(envelope, (item, type) => {
30487      const envelopeItemDataCategory = utils.envelopeItemTypeToDataCategory(type);
30488      if (utils.isRateLimited(rateLimits, envelopeItemDataCategory)) {
30489        const event = getEventForEnvelopeItem(item, type);
30490        options.recordDroppedEvent('ratelimit_backoff', envelopeItemDataCategory, event);
30491      } else {
30492        filteredEnvelopeItems.push(item);
30493      }
30494    });
30495
30496    // Skip sending if envelope is empty after filtering out rate limited events
30497    if (filteredEnvelopeItems.length === 0) {
30498      return utils.resolvedSyncPromise();
30499    }
30500
30501    // eslint-disable-next-line @typescript-eslint/no-explicit-any
30502    const filteredEnvelope = utils.createEnvelope(envelope[0], filteredEnvelopeItems );
30503
30504    // Creates client report for each item in an envelope
30505    const recordEnvelopeLoss = (reason) => {
30506      utils.forEachEnvelopeItem(filteredEnvelope, (item, type) => {
30507        const event = getEventForEnvelopeItem(item, type);
30508        options.recordDroppedEvent(reason, utils.envelopeItemTypeToDataCategory(type), event);
30509      });
30510    };
30511
30512    const requestTask = () =>
30513      makeRequest({ body: utils.serializeEnvelope(filteredEnvelope, options.textEncoder) }).then(
30514        response => {
30515          // We don't want to throw on NOK responses, but we want to at least log them
30516          if (response.statusCode !== undefined && (response.statusCode < 200 || response.statusCode >= 300)) {
30517            debugBuild.DEBUG_BUILD && utils.logger.warn(`Sentry responded with status code ${response.statusCode} to sent event.`);
30518          }
30519
30520          rateLimits = utils.updateRateLimits(rateLimits, response);
30521          return response;
30522        },
30523        error => {
30524          recordEnvelopeLoss('network_error');
30525          throw error;
30526        },
30527      );
30528
30529    return buffer.add(requestTask).then(
30530      result => result,
30531      error => {
30532        if (error instanceof utils.SentryError) {
30533          debugBuild.DEBUG_BUILD && utils.logger.error('Skipped sending event because buffer is full.');
30534          recordEnvelopeLoss('queue_overflow');
30535          return utils.resolvedSyncPromise();
30536        } else {
30537          throw error;
30538        }
30539      },
30540    );
30541  }
30542
30543  // We use this to identifify if the transport is the base transport
30544  // TODO (v8): Remove this again as we'll no longer need it
30545  send.__sentry__baseTransport__ = true;
30546
30547  return {
30548    send,
30549    flush,
30550  };
30551}
30552
30553function getEventForEnvelopeItem(item, type) {
30554  if (type !== 'event' && type !== 'transaction') {
30555    return undefined;
30556  }
30557
30558  return Array.isArray(item) ? (item )[1] : undefined;
30559}
30560
30561exports.DEFAULT_TRANSPORT_BUFFER_SIZE = DEFAULT_TRANSPORT_BUFFER_SIZE;
30562exports.createTransport = createTransport;
30563
30564
30565},{"../debug-build.js":245,"@sentry/utils":319}],287:[function(require,module,exports){
30566Object.defineProperty(exports, '__esModule', { value: true });
30567
30568const utils = require('@sentry/utils');
30569const api = require('../api.js');
30570
30571/**
30572 * Gets an event from an envelope.
30573 *
30574 * This is only exported for use in the tests
30575 */
30576function eventFromEnvelope(env, types) {
30577  let event;
30578
30579  utils.forEachEnvelopeItem(env, (item, type) => {
30580    if (types.includes(type)) {
30581      event = Array.isArray(item) ? (item )[1] : undefined;
30582    }
30583    // bail out if we found an event
30584    return !!event;
30585  });
30586
30587  return event;
30588}
30589
30590/**
30591 * Creates a transport that overrides the release on all events.
30592 */
30593function makeOverrideReleaseTransport(
30594  createTransport,
30595  release,
30596) {
30597  return options => {
30598    const transport = createTransport(options);
30599
30600    return {
30601      send: async (envelope) => {
30602        const event = eventFromEnvelope(envelope, ['event', 'transaction', 'profile', 'replay_event']);
30603
30604        if (event) {
30605          event.release = release;
30606        }
30607        return transport.send(envelope);
30608      },
30609      flush: timeout => transport.flush(timeout),
30610    };
30611  };
30612}
30613
30614/**
30615 * Creates a transport that can send events to different DSNs depending on the envelope contents.
30616 */
30617function makeMultiplexedTransport(
30618  createTransport,
30619  matcher,
30620) {
30621  return options => {
30622    const fallbackTransport = createTransport(options);
30623    const otherTransports = {};
30624
30625    function getTransport(dsn, release) {
30626      // We create a transport for every unique dsn/release combination as there may be code from multiple releases in
30627      // use at the same time
30628      const key = release ? `${dsn}:${release}` : dsn;
30629
30630      if (!otherTransports[key]) {
30631        const validatedDsn = utils.dsnFromString(dsn);
30632        if (!validatedDsn) {
30633          return undefined;
30634        }
30635        const url = api.getEnvelopeEndpointWithUrlEncodedAuth(validatedDsn);
30636
30637        otherTransports[key] = release
30638          ? makeOverrideReleaseTransport(createTransport, release)({ ...options, url })
30639          : createTransport({ ...options, url });
30640      }
30641
30642      return otherTransports[key];
30643    }
30644
30645    async function send(envelope) {
30646      function getEvent(types) {
30647        const eventTypes = types && types.length ? types : ['event'];
30648        return eventFromEnvelope(envelope, eventTypes);
30649      }
30650
30651      const transports = matcher({ envelope, getEvent })
30652        .map(result => {
30653          if (typeof result === 'string') {
30654            return getTransport(result, undefined);
30655          } else {
30656            return getTransport(result.dsn, result.release);
30657          }
30658        })
30659        .filter((t) => !!t);
30660
30661      // If we have no transports to send to, use the fallback transport
30662      if (transports.length === 0) {
30663        transports.push(fallbackTransport);
30664      }
30665
30666      const results = await Promise.all(transports.map(transport => transport.send(envelope)));
30667
30668      return results[0];
30669    }
30670
30671    async function flush(timeout) {
30672      const allTransports = [...Object.keys(otherTransports).map(dsn => otherTransports[dsn]), fallbackTransport];
30673      const results = await Promise.all(allTransports.map(transport => transport.flush(timeout)));
30674      return results.every(r => r);
30675    }
30676
30677    return {
30678      send,
30679      flush,
30680    };
30681  };
30682}
30683
30684exports.eventFromEnvelope = eventFromEnvelope;
30685exports.makeMultiplexedTransport = makeMultiplexedTransport;
30686
30687
30688},{"../api.js":241,"@sentry/utils":319}],288:[function(require,module,exports){
30689Object.defineProperty(exports, '__esModule', { value: true });
30690
30691const utils = require('@sentry/utils');
30692const debugBuild = require('../debug-build.js');
30693
30694const MIN_DELAY = 100; // 100 ms
30695const START_DELAY = 5000; // 5 seconds
30696const MAX_DELAY = 3.6e6; // 1 hour
30697
30698function log(msg, error) {
30699  debugBuild.DEBUG_BUILD && utils.logger.info(`[Offline]: ${msg}`, error);
30700}
30701
30702/**
30703 * Wraps a transport and stores and retries events when they fail to send.
30704 *
30705 * @param createTransport The transport to wrap.
30706 */
30707function makeOfflineTransport(
30708  createTransport,
30709) {
30710  return options => {
30711    const transport = createTransport(options);
30712    const store = options.createStore ? options.createStore(options) : undefined;
30713
30714    let retryDelay = START_DELAY;
30715    let flushTimer;
30716
30717    function shouldQueue(env, error, retryDelay) {
30718      // We don't queue Session Replay envelopes because they are:
30719      // - Ordered and Replay relies on the response status to know when they're successfully sent.
30720      // - Likely to fill the queue quickly and block other events from being sent.
30721      // We also want to drop client reports because they can be generated when we retry sending events while offline.
30722      if (utils.envelopeContainsItemType(env, ['replay_event', 'replay_recording', 'client_report'])) {
30723        return false;
30724      }
30725
30726      if (options.shouldStore) {
30727        return options.shouldStore(env, error, retryDelay);
30728      }
30729
30730      return true;
30731    }
30732
30733    function flushIn(delay) {
30734      if (!store) {
30735        return;
30736      }
30737
30738      if (flushTimer) {
30739        clearTimeout(flushTimer );
30740      }
30741
30742      flushTimer = setTimeout(async () => {
30743        flushTimer = undefined;
30744
30745        const found = await store.pop();
30746        if (found) {
30747          log('Attempting to send previously queued event');
30748          void send(found).catch(e => {
30749            log('Failed to retry sending', e);
30750          });
30751        }
30752      }, delay) ;
30753
30754      // We need to unref the timer in node.js, otherwise the node process never exit.
30755      if (typeof flushTimer !== 'number' && flushTimer.unref) {
30756        flushTimer.unref();
30757      }
30758    }
30759
30760    function flushWithBackOff() {
30761      if (flushTimer) {
30762        return;
30763      }
30764
30765      flushIn(retryDelay);
30766
30767      retryDelay = Math.min(retryDelay * 2, MAX_DELAY);
30768    }
30769
30770    async function send(envelope) {
30771      try {
30772        const result = await transport.send(envelope);
30773
30774        let delay = MIN_DELAY;
30775
30776        if (result) {
30777          // If there's a retry-after header, use that as the next delay.
30778          if (result.headers && result.headers['retry-after']) {
30779            delay = utils.parseRetryAfterHeader(result.headers['retry-after']);
30780          } // If we have a server error, return now so we don't flush the queue.
30781          else if ((result.statusCode || 0) >= 400) {
30782            return result;
30783          }
30784        }
30785
30786        flushIn(delay);
30787        retryDelay = START_DELAY;
30788        return result;
30789      } catch (e) {
30790        if (store && (await shouldQueue(envelope, e , retryDelay))) {
30791          await store.insert(envelope);
30792          flushWithBackOff();
30793          log('Error sending. Event queued', e );
30794          return {};
30795        } else {
30796          throw e;
30797        }
30798      }
30799    }
30800
30801    if (options.flushAtStartup) {
30802      flushWithBackOff();
30803    }
30804
30805    return {
30806      send,
30807      flush: t => transport.flush(t),
30808    };
30809  };
30810}
30811
30812exports.MIN_DELAY = MIN_DELAY;
30813exports.START_DELAY = START_DELAY;
30814exports.makeOfflineTransport = makeOfflineTransport;
30815
30816
30817},{"../debug-build.js":245,"@sentry/utils":319}],289:[function(require,module,exports){
30818Object.defineProperty(exports, '__esModule', { value: true });
30819
30820const utils = require('@sentry/utils');
30821const dynamicSamplingContext = require('../tracing/dynamicSamplingContext.js');
30822const getRootSpan = require('./getRootSpan.js');
30823const spanUtils = require('./spanUtils.js');
30824
30825/**
30826 * Applies data from the scope to the event and runs all event processors on it.
30827 */
30828function applyScopeDataToEvent(event, data) {
30829  const { fingerprint, span, breadcrumbs, sdkProcessingMetadata } = data;
30830
30831  // Apply general data
30832  applyDataToEvent(event, data);
30833
30834  // We want to set the trace context for normal events only if there isn't already
30835  // a trace context on the event. There is a product feature in place where we link
30836  // errors with transaction and it relies on that.
30837  if (span) {
30838    applySpanToEvent(event, span);
30839  }
30840
30841  applyFingerprintToEvent(event, fingerprint);
30842  applyBreadcrumbsToEvent(event, breadcrumbs);
30843  applySdkMetadataToEvent(event, sdkProcessingMetadata);
30844}
30845
30846/** Merge data of two scopes together. */
30847function mergeScopeData(data, mergeData) {
30848  const {
30849    extra,
30850    tags,
30851    user,
30852    contexts,
30853    level,
30854    sdkProcessingMetadata,
30855    breadcrumbs,
30856    fingerprint,
30857    eventProcessors,
30858    attachments,
30859    propagationContext,
30860    // eslint-disable-next-line deprecation/deprecation
30861    transactionName,
30862    span,
30863  } = mergeData;
30864
30865  mergeAndOverwriteScopeData(data, 'extra', extra);
30866  mergeAndOverwriteScopeData(data, 'tags', tags);
30867  mergeAndOverwriteScopeData(data, 'user', user);
30868  mergeAndOverwriteScopeData(data, 'contexts', contexts);
30869  mergeAndOverwriteScopeData(data, 'sdkProcessingMetadata', sdkProcessingMetadata);
30870
30871  if (level) {
30872    data.level = level;
30873  }
30874
30875  if (transactionName) {
30876    // eslint-disable-next-line deprecation/deprecation
30877    data.transactionName = transactionName;
30878  }
30879
30880  if (span) {
30881    data.span = span;
30882  }
30883
30884  if (breadcrumbs.length) {
30885    data.breadcrumbs = [...data.breadcrumbs, ...breadcrumbs];
30886  }
30887
30888  if (fingerprint.length) {
30889    data.fingerprint = [...data.fingerprint, ...fingerprint];
30890  }
30891
30892  if (eventProcessors.length) {
30893    data.eventProcessors = [...data.eventProcessors, ...eventProcessors];
30894  }
30895
30896  if (attachments.length) {
30897    data.attachments = [...data.attachments, ...attachments];
30898  }
30899
30900  data.propagationContext = { ...data.propagationContext, ...propagationContext };
30901}
30902
30903/**
30904 * Merges certain scope data. Undefined values will overwrite any existing values.
30905 * Exported only for tests.
30906 */
30907function mergeAndOverwriteScopeData
30908
30909(data, prop, mergeVal) {
30910  if (mergeVal && Object.keys(mergeVal).length) {
30911    // Clone object
30912    data[prop] = { ...data[prop] };
30913    for (const key in mergeVal) {
30914      if (Object.prototype.hasOwnProperty.call(mergeVal, key)) {
30915        data[prop][key] = mergeVal[key];
30916      }
30917    }
30918  }
30919}
30920
30921function applyDataToEvent(event, data) {
30922  const {
30923    extra,
30924    tags,
30925    user,
30926    contexts,
30927    level,
30928    // eslint-disable-next-line deprecation/deprecation
30929    transactionName,
30930  } = data;
30931
30932  const cleanedExtra = utils.dropUndefinedKeys(extra);
30933  if (cleanedExtra && Object.keys(cleanedExtra).length) {
30934    event.extra = { ...cleanedExtra, ...event.extra };
30935  }
30936
30937  const cleanedTags = utils.dropUndefinedKeys(tags);
30938  if (cleanedTags && Object.keys(cleanedTags).length) {
30939    event.tags = { ...cleanedTags, ...event.tags };
30940  }
30941
30942  const cleanedUser = utils.dropUndefinedKeys(user);
30943  if (cleanedUser && Object.keys(cleanedUser).length) {
30944    event.user = { ...cleanedUser, ...event.user };
30945  }
30946
30947  const cleanedContexts = utils.dropUndefinedKeys(contexts);
30948  if (cleanedContexts && Object.keys(cleanedContexts).length) {
30949    event.contexts = { ...cleanedContexts, ...event.contexts };
30950  }
30951
30952  if (level) {
30953    event.level = level;
30954  }
30955
30956  if (transactionName) {
30957    event.transaction = transactionName;
30958  }
30959}
30960
30961function applyBreadcrumbsToEvent(event, breadcrumbs) {
30962  const mergedBreadcrumbs = [...(event.breadcrumbs || []), ...breadcrumbs];
30963  event.breadcrumbs = mergedBreadcrumbs.length ? mergedBreadcrumbs : undefined;
30964}
30965
30966function applySdkMetadataToEvent(event, sdkProcessingMetadata) {
30967  event.sdkProcessingMetadata = {
30968    ...event.sdkProcessingMetadata,
30969    ...sdkProcessingMetadata,
30970  };
30971}
30972
30973function applySpanToEvent(event, span) {
30974  event.contexts = { trace: spanUtils.spanToTraceContext(span), ...event.contexts };
30975  const rootSpan = getRootSpan.getRootSpan(span);
30976  if (rootSpan) {
30977    event.sdkProcessingMetadata = {
30978      dynamicSamplingContext: dynamicSamplingContext.getDynamicSamplingContextFromSpan(span),
30979      ...event.sdkProcessingMetadata,
30980    };
30981    const transactionName = spanUtils.spanToJSON(rootSpan).description;
30982    if (transactionName) {
30983      event.tags = { transaction: transactionName, ...event.tags };
30984    }
30985  }
30986}
30987
30988/**
30989 * Applies fingerprint from the scope to the event if there's one,
30990 * uses message if there's one instead or get rid of empty fingerprint
30991 */
30992function applyFingerprintToEvent(event, fingerprint) {
30993  // Make sure it's an array first and we actually have something in place
30994  event.fingerprint = event.fingerprint ? utils.arrayify(event.fingerprint) : [];
30995
30996  // If we have something on the scope, then merge it with event
30997  if (fingerprint) {
30998    event.fingerprint = event.fingerprint.concat(fingerprint);
30999  }
31000
31001  // If we have no data at all, remove empty array default
31002  if (event.fingerprint && !event.fingerprint.length) {
31003    delete event.fingerprint;
31004  }
31005}
31006
31007exports.applyScopeDataToEvent = applyScopeDataToEvent;
31008exports.mergeAndOverwriteScopeData = mergeAndOverwriteScopeData;
31009exports.mergeScopeData = mergeScopeData;
31010
31011
31012},{"../tracing/dynamicSamplingContext.js":275,"./getRootSpan.js":290,"./spanUtils.js":297,"@sentry/utils":319}],290:[function(require,module,exports){
31013Object.defineProperty(exports, '__esModule', { value: true });
31014
31015/**
31016 * Returns the root span of a given span.
31017 *
31018 * As long as we use `Transaction`s internally, the returned root span
31019 * will be a `Transaction` but be aware that this might change in the future.
31020 *
31021 * If the given span has no root span or transaction, `undefined` is returned.
31022 */
31023function getRootSpan(span) {
31024  // TODO (v8): Remove this check and just return span
31025  // eslint-disable-next-line deprecation/deprecation
31026  return span.transaction;
31027}
31028
31029exports.getRootSpan = getRootSpan;
31030
31031
31032},{}],291:[function(require,module,exports){
31033Object.defineProperty(exports, '__esModule', { value: true });
31034
31035const utils = require('@sentry/utils');
31036
31037/**
31038 * Wrap a callback function with error handling.
31039 * If an error is thrown, it will be passed to the `onError` callback and re-thrown.
31040 *
31041 * If the return value of the function is a promise, it will be handled with `maybeHandlePromiseRejection`.
31042 *
31043 * If an `onFinally` callback is provided, this will be called when the callback has finished
31044 * - so if it returns a promise, once the promise resolved/rejected,
31045 * else once the callback has finished executing.
31046 * The `onFinally` callback will _always_ be called, no matter if an error was thrown or not.
31047 */
31048function handleCallbackErrors
31049
31050(
31051  fn,
31052  onError,
31053  // eslint-disable-next-line @typescript-eslint/no-empty-function
31054  onFinally = () => {},
31055) {
31056  let maybePromiseResult;
31057  try {
31058    maybePromiseResult = fn();
31059  } catch (e) {
31060    onError(e);
31061    onFinally();
31062    throw e;
31063  }
31064
31065  return maybeHandlePromiseRejection(maybePromiseResult, onError, onFinally);
31066}
31067
31068/**
31069 * Maybe handle a promise rejection.
31070 * This expects to be given a value that _may_ be a promise, or any other value.
31071 * If it is a promise, and it rejects, it will call the `onError` callback.
31072 * Other than this, it will generally return the given value as-is.
31073 */
31074function maybeHandlePromiseRejection(
31075  value,
31076  onError,
31077  onFinally,
31078) {
31079  if (utils.isThenable(value)) {
31080    // @ts-expect-error - the isThenable check returns the "wrong" type here
31081    return value.then(
31082      res => {
31083        onFinally();
31084        return res;
31085      },
31086      e => {
31087        onError(e);
31088        onFinally();
31089        throw e;
31090      },
31091    );
31092  }
31093
31094  onFinally();
31095  return value;
31096}
31097
31098exports.handleCallbackErrors = handleCallbackErrors;
31099
31100
31101},{"@sentry/utils":319}],292:[function(require,module,exports){
31102Object.defineProperty(exports, '__esModule', { value: true });
31103
31104const exports$1 = require('../exports.js');
31105
31106// Treeshakable guard to remove all code related to tracing
31107
31108/**
31109 * Determines if tracing is currently enabled.
31110 *
31111 * Tracing is enabled when at least one of `tracesSampleRate` and `tracesSampler` is defined in the SDK config.
31112 */
31113function hasTracingEnabled(
31114  maybeOptions,
31115) {
31116  if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) {
31117    return false;
31118  }
31119
31120  const client = exports$1.getClient();
31121  const options = maybeOptions || (client && client.getOptions());
31122  return !!options && (options.enableTracing || 'tracesSampleRate' in options || 'tracesSampler' in options);
31123}
31124
31125exports.hasTracingEnabled = hasTracingEnabled;
31126
31127
31128},{"../exports.js":248}],293:[function(require,module,exports){
31129Object.defineProperty(exports, '__esModule', { value: true });
31130
31131/**
31132 * Checks whether given url points to Sentry server
31133 * @param url url to verify
31134 *
31135 * TODO(v8): Remove Hub fallback type
31136 */
31137function isSentryRequestUrl(url, hubOrClient) {
31138  const client =
31139    hubOrClient && isHub(hubOrClient)
31140      ? // eslint-disable-next-line deprecation/deprecation
31141        hubOrClient.getClient()
31142      : hubOrClient;
31143  const dsn = client && client.getDsn();
31144  const tunnel = client && client.getOptions().tunnel;
31145
31146  return checkDsn(url, dsn) || checkTunnel(url, tunnel);
31147}
31148
31149function checkTunnel(url, tunnel) {
31150  if (!tunnel) {
31151    return false;
31152  }
31153
31154  return removeTrailingSlash(url) === removeTrailingSlash(tunnel);
31155}
31156
31157function checkDsn(url, dsn) {
31158  return dsn ? url.includes(dsn.host) : false;
31159}
31160
31161function removeTrailingSlash(str) {
31162  return str[str.length - 1] === '/' ? str.slice(0, -1) : str;
31163}
31164
31165function isHub(hubOrClient) {
31166  // eslint-disable-next-line deprecation/deprecation
31167  return (hubOrClient ).getClient !== undefined;
31168}
31169
31170exports.isSentryRequestUrl = isSentryRequestUrl;
31171
31172
31173},{}],294:[function(require,module,exports){
31174Object.defineProperty(exports, '__esModule', { value: true });
31175
31176/**
31177 * Tagged template function which returns paramaterized representation of the message
31178 * For example: parameterize`This is a log statement with ${x} and ${y} params`, would return:
31179 * "__sentry_template_string__": 'This is a log statement with %s and %s params',
31180 * "__sentry_template_values__": ['first', 'second']
31181 * @param strings An array of string values splitted between expressions
31182 * @param values Expressions extracted from template string
31183 * @returns String with template information in __sentry_template_string__ and __sentry_template_values__ properties
31184 */
31185function parameterize(strings, ...values) {
31186  const formatted = new String(String.raw(strings, ...values)) ;
31187  formatted.__sentry_template_string__ = strings.join('\x00').replace(/%/g, '%%').replace(/\0/g, '%s');
31188  formatted.__sentry_template_values__ = values;
31189  return formatted;
31190}
31191
31192exports.parameterize = parameterize;
31193
31194
31195},{}],295:[function(require,module,exports){
31196Object.defineProperty(exports, '__esModule', { value: true });
31197
31198const utils = require('@sentry/utils');
31199const constants = require('../constants.js');
31200const eventProcessors = require('../eventProcessors.js');
31201const scope = require('../scope.js');
31202const applyScopeDataToEvent = require('./applyScopeDataToEvent.js');
31203const spanUtils = require('./spanUtils.js');
31204
31205/**
31206 * This type makes sure that we get either a CaptureContext, OR an EventHint.
31207 * It does not allow mixing them, which could lead to unexpected outcomes, e.g. this is disallowed:
31208 * { user: { id: '123' }, mechanism: { handled: false } }
31209 */
31210
31211/**
31212 * Adds common information to events.
31213 *
31214 * The information includes release and environment from `options`,
31215 * breadcrumbs and context (extra, tags and user) from the scope.
31216 *
31217 * Information that is already present in the event is never overwritten. For
31218 * nested objects, such as the context, keys are merged.
31219 *
31220 * Note: This also triggers callbacks for `addGlobalEventProcessor`, but not `beforeSend`.
31221 *
31222 * @param event The original event.
31223 * @param hint May contain additional information about the original exception.
31224 * @param scope A scope containing event metadata.
31225 * @returns A new event with more information.
31226 * @hidden
31227 */
31228function prepareEvent(
31229  options,
31230  event,
31231  hint,
31232  scope$1,
31233  client,
31234  isolationScope,
31235) {
31236  const { normalizeDepth = 3, normalizeMaxBreadth = 1000 } = options;
31237  const prepared = {
31238    ...event,
31239    event_id: event.event_id || hint.event_id || utils.uuid4(),
31240    timestamp: event.timestamp || utils.dateTimestampInSeconds(),
31241  };
31242  const integrations = hint.integrations || options.integrations.map(i => i.name);
31243
31244  applyClientOptions(prepared, options);
31245  applyIntegrationsMetadata(prepared, integrations);
31246
31247  // Only put debug IDs onto frames for error events.
31248  if (event.type === undefined) {
31249    applyDebugIds(prepared, options.stackParser);
31250  }
31251
31252  // If we have scope given to us, use it as the base for further modifications.
31253  // This allows us to prevent unnecessary copying of data if `captureContext` is not provided.
31254  const finalScope = getFinalScope(scope$1, hint.captureContext);
31255
31256  if (hint.mechanism) {
31257    utils.addExceptionMechanism(prepared, hint.mechanism);
31258  }
31259
31260  const clientEventProcessors = client && client.getEventProcessors ? client.getEventProcessors() : [];
31261
31262  // This should be the last thing called, since we want that
31263  // {@link Hub.addEventProcessor} gets the finished prepared event.
31264  // Merge scope data together
31265  const data = scope.getGlobalScope().getScopeData();
31266
31267  if (isolationScope) {
31268    const isolationData = isolationScope.getScopeData();
31269    applyScopeDataToEvent.mergeScopeData(data, isolationData);
31270  }
31271
31272  if (finalScope) {
31273    const finalScopeData = finalScope.getScopeData();
31274    applyScopeDataToEvent.mergeScopeData(data, finalScopeData);
31275  }
31276
31277  const attachments = [...(hint.attachments || []), ...data.attachments];
31278  if (attachments.length) {
31279    hint.attachments = attachments;
31280  }
31281
31282  applyScopeDataToEvent.applyScopeDataToEvent(prepared, data);
31283
31284  // TODO (v8): Update this order to be: Global > Client > Scope
31285  const eventProcessors$1 = [
31286    ...clientEventProcessors,
31287    // eslint-disable-next-line deprecation/deprecation
31288    ...eventProcessors.getGlobalEventProcessors(),
31289    // Run scope event processors _after_ all other processors
31290    ...data.eventProcessors,
31291  ];
31292
31293  const result = eventProcessors.notifyEventProcessors(eventProcessors$1, prepared, hint);
31294
31295  return result.then(evt => {
31296    if (evt) {
31297      // We apply the debug_meta field only after all event processors have ran, so that if any event processors modified
31298      // file names (e.g.the RewriteFrames integration) the filename -> debug ID relationship isn't destroyed.
31299      // This should not cause any PII issues, since we're only moving data that is already on the event and not adding
31300      // any new data
31301      applyDebugMeta(evt);
31302    }
31303
31304    if (typeof normalizeDepth === 'number' && normalizeDepth > 0) {
31305      return normalizeEvent(evt, normalizeDepth, normalizeMaxBreadth);
31306    }
31307    return evt;
31308  });
31309}
31310
31311/**
31312 *  Enhances event using the client configuration.
31313 *  It takes care of all "static" values like environment, release and `dist`,
31314 *  as well as truncating overly long values.
31315 * @param event event instance to be enhanced
31316 */
31317function applyClientOptions(event, options) {
31318  const { environment, release, dist, maxValueLength = 250 } = options;
31319
31320  if (!('environment' in event)) {
31321    event.environment = 'environment' in options ? environment : constants.DEFAULT_ENVIRONMENT;
31322  }
31323
31324  if (event.release === undefined && release !== undefined) {
31325    event.release = release;
31326  }
31327
31328  if (event.dist === undefined && dist !== undefined) {
31329    event.dist = dist;
31330  }
31331
31332  if (event.message) {
31333    event.message = utils.truncate(event.message, maxValueLength);
31334  }
31335
31336  const exception = event.exception && event.exception.values && event.exception.values[0];
31337  if (exception && exception.value) {
31338    exception.value = utils.truncate(exception.value, maxValueLength);
31339  }
31340
31341  const request = event.request;
31342  if (request && request.url) {
31343    request.url = utils.truncate(request.url, maxValueLength);
31344  }
31345}
31346
31347const debugIdStackParserCache = new WeakMap();
31348
31349/**
31350 * Puts debug IDs into the stack frames of an error event.
31351 */
31352function applyDebugIds(event, stackParser) {
31353  const debugIdMap = utils.GLOBAL_OBJ._sentryDebugIds;
31354
31355  if (!debugIdMap) {
31356    return;
31357  }
31358
31359  let debugIdStackFramesCache;
31360  const cachedDebugIdStackFrameCache = debugIdStackParserCache.get(stackParser);
31361  if (cachedDebugIdStackFrameCache) {
31362    debugIdStackFramesCache = cachedDebugIdStackFrameCache;
31363  } else {
31364    debugIdStackFramesCache = new Map();
31365    debugIdStackParserCache.set(stackParser, debugIdStackFramesCache);
31366  }
31367
31368  // Build a map of filename -> debug_id
31369  const filenameDebugIdMap = Object.keys(debugIdMap).reduce((acc, debugIdStackTrace) => {
31370    let parsedStack;
31371    const cachedParsedStack = debugIdStackFramesCache.get(debugIdStackTrace);
31372    if (cachedParsedStack) {
31373      parsedStack = cachedParsedStack;
31374    } else {
31375      parsedStack = stackParser(debugIdStackTrace);
31376      debugIdStackFramesCache.set(debugIdStackTrace, parsedStack);
31377    }
31378
31379    for (let i = parsedStack.length - 1; i >= 0; i--) {
31380      const stackFrame = parsedStack[i];
31381      if (stackFrame.filename) {
31382        acc[stackFrame.filename] = debugIdMap[debugIdStackTrace];
31383        break;
31384      }
31385    }
31386    return acc;
31387  }, {});
31388
31389  try {
31390    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
vendor: 3,304 bytes, lines 31391-31495
31391    event.exception.values.forEach(exception => {
31392      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
31393      exception.stacktrace.frames.forEach(frame => {
31394        if (frame.filename) {
31395          frame.debug_id = filenameDebugIdMap[frame.filename];
31396        }
31397      });
31398    });
31399  } catch (e) {
31400    // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.
31401  }
31402}
31403
31404/**
31405 * Moves debug IDs from the stack frames of an error event into the debug_meta field.
31406 */
31407function applyDebugMeta(event) {
31408  // Extract debug IDs and filenames from the stack frames on the event.
31409  const filenameDebugIdMap = {};
31410  try {
31411    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
31412    event.exception.values.forEach(exception => {
31413      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
31414      exception.stacktrace.frames.forEach(frame => {
31415        if (frame.debug_id) {
31416          if (frame.abs_path) {
31417            filenameDebugIdMap[frame.abs_path] = frame.debug_id;
31418          } else if (frame.filename) {
31419            filenameDebugIdMap[frame.filename] = frame.debug_id;
31420          }
31421          delete frame.debug_id;
31422        }
31423      });
31424    });
31425  } catch (e) {
31426    // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.
31427  }
31428
31429  if (Object.keys(filenameDebugIdMap).length === 0) {
31430    return;
31431  }
31432
31433  // Fill debug_meta information
31434  event.debug_meta = event.debug_meta || {};
31435  event.debug_meta.images = event.debug_meta.images || [];
31436  const images = event.debug_meta.images;
31437  Object.keys(filenameDebugIdMap).forEach(filename => {
31438    images.push({
31439      type: 'sourcemap',
31440      code_file: filename,
31441      debug_id: filenameDebugIdMap[filename],
31442    });
31443  });
31444}
31445
31446/**
31447 * This function adds all used integrations to the SDK info in the event.
31448 * @param event The event that will be filled with all integrations.
31449 */
31450function applyIntegrationsMetadata(event, integrationNames) {
31451  if (integrationNames.length > 0) {
31452    event.sdk = event.sdk || {};
31453    event.sdk.integrations = [...(event.sdk.integrations || []), ...integrationNames];
31454  }
31455}
31456
31457/**
31458 * Applies `normalize` function on necessary `Event` attributes to make them safe for serialization.
31459 * Normalized keys:
31460 * - `breadcrumbs.data`
31461 * - `user`
31462 * - `contexts`
31463 * - `extra`
31464 * @param event Event
31465 * @returns Normalized event
31466 */
31467function normalizeEvent(event, depth, maxBreadth) {
31468  if (!event) {
31469    return null;
31470  }
31471
31472  const normalized = {
31473    ...event,
31474    ...(event.breadcrumbs && {
31475      breadcrumbs: event.breadcrumbs.map(b => ({
31476        ...b,
31477        ...(b.data && {
31478          data: utils.normalize(b.data, depth, maxBreadth),
31479        }),
31480      })),
31481    }),
31482    ...(event.user && {
31483      user: utils.normalize(event.user, depth, maxBreadth),
31484    }),
31485    ...(event.contexts && {
31486      contexts: utils.normalize(event.contexts, depth, maxBreadth),
31487    }),
31488    ...(event.extra && {
31489      extra: utils.normalize(event.extra, depth, maxBreadth),
31490    }),
31491  };
31492
31493  // event.contexts.trace stores information about a Transaction. Similarly,
31494  // event.spans[] stores information about child Spans. Given that a
31495  // Transaction is conceptually a Span, normalization should apply to both
31496  // Transactions and Spans consistently.
31497  // For now the decision is to skip normalization of Transactions and Spans,
31498  // so this block overwrites the normalized event to add back the original
31499  // Transaction information prior to normalization.
31500  if (event.contexts && event.contexts.trace && normalized.contexts) {
31501    normalized.contexts.trace = event.contexts.trace;
31502
31503    // event.contexts.trace.data may contain circular/dangerous data so we need to normalize it
31504    if (event.contexts.trace.data) {
31505      normalized.contexts.trace.data = utils.normalize(event.contexts.trace.data, depth, maxBreadth);
31506    }
31507  }
31508
31509  // event.spans[].data may contain circular/dangerous data so we need to normalize it
31510  if (event.spans) {
31511    normalized.spans = event.spans.map(span => {
31512      const data = spanUtils.spanToJSON(span).data;
31513
31514      if (data) {
31515        // This is a bit weird, as we generally have `Span` instances here, but to be safe we do not assume so
31516        // eslint-disable-next-line deprecation/deprecation
31517        span.data = utils.normalize(data, depth, maxBreadth);
31518      }
31519
31520      return span;
31521    });
31522  }
31523
31524  return normalized;
31525}
31526
31527function getFinalScope(scope$1, captureContext) {
31528  if (!captureContext) {
31529    return scope$1;
31530  }
31531
31532  const finalScope = scope$1 ? scope$1.clone() : new scope.Scope();
31533  finalScope.update(captureContext);
31534  return finalScope;
31535}
31536
31537/**
31538 * Parse either an `EventHint` directly, or convert a `CaptureContext` to an `EventHint`.
31539 * This is used to allow to update method signatures that used to accept a `CaptureContext` but should now accept an `EventHint`.
31540 */
31541function parseEventHintOrCaptureContext(
31542  hint,
31543) {
31544  if (!hint) {
31545    return undefined;
31546  }
31547
31548  // If you pass a Scope or `() => Scope` as CaptureContext, we just return this as captureContext
31549  if (hintIsScopeOrFunction(hint)) {
31550    return { captureContext: hint };
31551  }
31552
31553  if (hintIsScopeContext(hint)) {
31554    return {
31555      captureContext: hint,
31556    };
31557  }
31558
31559  return hint;
31560}
31561
31562function hintIsScopeOrFunction(
31563  hint,
31564) {
31565  return hint instanceof scope.Scope || typeof hint === 'function';
31566}
31567
31568const captureContextKeys = [
31569  'user',
31570  'level',
31571  'extra',
31572  'contexts',
31573  'tags',
31574  'fingerprint',
31575  'requestSession',
31576  'propagationContext',
31577] ;
31578
31579function hintIsScopeContext(hint) {
31580  return Object.keys(hint).some(key => captureContextKeys.includes(key ));
31581}
31582
31583exports.applyDebugIds = applyDebugIds;
31584exports.applyDebugMeta = applyDebugMeta;
31585exports.parseEventHintOrCaptureContext = parseEventHintOrCaptureContext;
31586exports.prepareEvent = prepareEvent;
31587
31588
31589},{"../constants.js":244,"../eventProcessors.js":247,"../scope.js":268,"./applyScopeDataToEvent.js":289,"./spanUtils.js":297,"@sentry/utils":319}],296:[function(require,module,exports){
31590Object.defineProperty(exports, '__esModule', { value: true });
31591
31592const version = require('../version.js');
31593
31594/**
31595 * A builder for the SDK metadata in the options for the SDK initialization.
31596 *
31597 * Note: This function is identical to `buildMetadata` in Remix and NextJS and SvelteKit.
31598 * We don't extract it for bundle size reasons.
31599 * @see https://github.com/getsentry/sentry-javascript/pull/7404
31600 * @see https://github.com/getsentry/sentry-javascript/pull/4196
31601 *
31602 * If you make changes to this function consider updating the others as well.
31603 *
31604 * @param options SDK options object that gets mutated
31605 * @param names list of package names
31606 */
31607function applySdkMetadata(options, name, names = [name], source = 'npm') {
31608  const metadata = options._metadata || {};
31609
31610  if (!metadata.sdk) {
31611    metadata.sdk = {
31612      name: `sentry.javascript.${name}`,
31613      packages: names.map(name => ({
31614        name: `${source}:@sentry/${name}`,
31615        version: version.SDK_VERSION,
31616      })),
31617      version: version.SDK_VERSION,
31618    };
31619  }
31620
31621  options._metadata = metadata;
31622}
31623
31624exports.applySdkMetadata = applySdkMetadata;
31625
31626
31627},{"../version.js":298}],297:[function(require,module,exports){
31628Object.defineProperty(exports, '__esModule', { value: true });
31629
31630const utils = require('@sentry/utils');
31631
31632// These are aligned with OpenTelemetry trace flags
31633const TRACE_FLAG_NONE = 0x0;
31634const TRACE_FLAG_SAMPLED = 0x1;
31635
31636/**
31637 * Convert a span to a trace context, which can be sent as the `trace` context in an event.
31638 */
31639function spanToTraceContext(span) {
31640  const { spanId: span_id, traceId: trace_id } = span.spanContext();
31641  const { data, op, parent_span_id, status, tags, origin } = spanToJSON(span);
31642
31643  return utils.dropUndefinedKeys({
31644    data,
31645    op,
31646    parent_span_id,
31647    span_id,
31648    status,
31649    tags,
31650    trace_id,
31651    origin,
31652  });
31653}
31654
31655/**
31656 * Convert a Span to a Sentry trace header.
31657 */
31658function spanToTraceHeader(span) {
31659  const { traceId, spanId } = span.spanContext();
31660  const sampled = spanIsSampled(span);
31661  return utils.generateSentryTraceHeader(traceId, spanId, sampled);
31662}
31663
31664/**
31665 * Convert a span time input intp a timestamp in seconds.
31666 */
31667function spanTimeInputToSeconds(input) {
31668  if (typeof input === 'number') {
31669    return ensureTimestampInSeconds(input);
31670  }
31671
31672  if (Array.isArray(input)) {
31673    // See {@link HrTime} for the array-based time format
31674    return input[0] + input[1] / 1e9;
31675  }
31676
31677  if (input instanceof Date) {
31678    return ensureTimestampInSeconds(input.getTime());
31679  }
31680
31681  return utils.timestampInSeconds();
31682}
31683
31684/**
31685 * Converts a timestamp to second, if it was in milliseconds, or keeps it as second.
31686 */
31687function ensureTimestampInSeconds(timestamp) {
31688  const isMs = timestamp > 9999999999;
31689  return isMs ? timestamp / 1000 : timestamp;
31690}
31691
31692/**
31693 * Convert a span to a JSON representation.
31694 * Note that all fields returned here are optional and need to be guarded against.
31695 *
31696 * Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json).
31697 * This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility.
31698 * And `spanToJSON` needs the Span class from `span.ts` to check here.
31699 * TODO v8: When we remove the deprecated stuff from `span.ts`, we can remove the circular dependency again.
31700 */
31701function spanToJSON(span) {
31702  if (spanIsSpanClass(span)) {
31703    return span.getSpanJSON();
31704  }
31705
31706  // Fallback: We also check for `.toJSON()` here...
31707  // eslint-disable-next-line deprecation/deprecation
31708  if (typeof span.toJSON === 'function') {
31709    // eslint-disable-next-line deprecation/deprecation
31710    return span.toJSON();
31711  }
31712
31713  return {};
31714}
31715
31716/**
31717 * Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof.
31718 * :( So instead we approximate this by checking if it has the `getSpanJSON` method.
31719 */
31720function spanIsSpanClass(span) {
31721  return typeof (span ).getSpanJSON === 'function';
31722}
31723
31724/**
31725 * Returns true if a span is sampled.
31726 * In most cases, you should just use `span.isRecording()` instead.
31727 * However, this has a slightly different semantic, as it also returns false if the span is finished.
31728 * So in the case where this distinction is important, use this method.
31729 */
31730function spanIsSampled(span) {
31731  // We align our trace flags with the ones OpenTelemetry use
31732  // So we also check for sampled the same way they do.
31733  const { traceFlags } = span.spanContext();
31734  // eslint-disable-next-line no-bitwise
31735  return Boolean(traceFlags & TRACE_FLAG_SAMPLED);
31736}
31737
31738exports.TRACE_FLAG_NONE = TRACE_FLAG_NONE;
31739exports.TRACE_FLAG_SAMPLED = TRACE_FLAG_SAMPLED;
31740exports.spanIsSampled = spanIsSampled;
31741exports.spanTimeInputToSeconds = spanTimeInputToSeconds;
31742exports.spanToJSON = spanToJSON;
31743exports.spanToTraceContext = spanToTraceContext;
31744exports.spanToTraceHeader = spanToTraceHeader;
31745
31746
31747},{"@sentry/utils":319}],298:[function(require,module,exports){
31748Object.defineProperty(exports, '__esModule', { value: true });
31749
31750const SDK_VERSION = '7.107.0';
31751
31752exports.SDK_VERSION = SDK_VERSION;
31753
31754
31755},{}],299:[function(require,module,exports){
31756var {
31757    _nullishCoalesce,
31758    _optionalChain
31759} = require('@sentry/utils');
31760
31761Object.defineProperty(exports, '__esModule', { value: true });
31762
31763const core = require('@sentry/core');
31764const utils = require('@sentry/utils');
31765const tracing = require('@sentry-internal/tracing');
31766
31767// exporting a separate copy of `WINDOW` rather than exporting the one from `@sentry/browser`
31768// prevents the browser package from being bundled in the CDN bundle, and avoids a
31769// circular dependency between the browser and replay packages should `@sentry/browser` import
31770// from `@sentry/replay` in the future
31771const WINDOW = utils.GLOBAL_OBJ ;
31772
31773const REPLAY_SESSION_KEY = 'sentryReplaySession';
31774const REPLAY_EVENT_NAME = 'replay_event';
31775const UNABLE_TO_SEND_REPLAY = 'Unable to send Replay';
31776
31777// The idle limit for a session after which recording is paused.
31778const SESSION_IDLE_PAUSE_DURATION = 300000; // 5 minutes in ms
31779
31780// The idle limit for a session after which the session expires.
31781const SESSION_IDLE_EXPIRE_DURATION = 900000; // 15 minutes in ms
31782
31783/** Default flush delays */
31784const DEFAULT_FLUSH_MIN_DELAY = 5000;
31785// XXX: Temp fix for our debounce logic where `maxWait` would never occur if it
31786// was the same as `wait`
31787const DEFAULT_FLUSH_MAX_DELAY = 5500;
31788
31789/* How long to wait for error checkouts */
31790const BUFFER_CHECKOUT_TIME = 60000;
31791
31792const RETRY_BASE_INTERVAL = 5000;
31793const RETRY_MAX_COUNT = 3;
31794
31795/* The max (uncompressed) size in bytes of a network body. Any body larger than this will be truncated. */
31796const NETWORK_BODY_MAX_SIZE = 150000;
31797
31798/* The max size of a single console arg that is captured. Any arg larger than this will be truncated. */
31799const CONSOLE_ARG_MAX_SIZE = 5000;
31800
31801/* Min. time to wait before we consider something a slow click. */
31802const SLOW_CLICK_THRESHOLD = 3000;
31803/* For scroll actions after a click, we only look for a very short time period to detect programmatic scrolling. */
31804const SLOW_CLICK_SCROLL_TIMEOUT = 300;
31805
31806/** When encountering a total segment size exceeding this size, stop the replay (as we cannot properly ingest it). */
31807const REPLAY_MAX_EVENT_BUFFER_SIZE = 20000000; // ~20MB
31808
31809/** Replays must be min. 5s long before we send them. */
31810const MIN_REPLAY_DURATION = 4999;
31811/* The max. allowed value that the minReplayDuration can be set to. */
31812const MIN_REPLAY_DURATION_LIMIT = 15000;
31813
31814/** The max. length of a replay. */
31815const MAX_REPLAY_DURATION = 3600000; // 60 minutes in ms;
31816
31817function _nullishCoalesce$1(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }function _optionalChain$5(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var NodeType$1;
31818(function (NodeType) {
31819    NodeType[NodeType["Document"] = 0] = "Document";
31820    NodeType[NodeType["DocumentType"] = 1] = "DocumentType";
31821    NodeType[NodeType["Element"] = 2] = "Element";
31822    NodeType[NodeType["Text"] = 3] = "Text";
31823    NodeType[NodeType["CDATA"] = 4] = "CDATA";
31824    NodeType[NodeType["Comment"] = 5] = "Comment";
31825})(NodeType$1 || (NodeType$1 = {}));
31826
31827function isElement$1(n) {
31828    return n.nodeType === n.ELEMENT_NODE;
31829}
31830function isShadowRoot(n) {
31831    const host = _optionalChain$5([n, 'optionalAccess', _ => _.host]);
31832    return Boolean(_optionalChain$5([host, 'optionalAccess', _2 => _2.shadowRoot]) === n);
31833}
31834function isNativeShadowDom(shadowRoot) {
31835    return Object.prototype.toString.call(shadowRoot) === '[object ShadowRoot]';
31836}
31837function fixBrowserCompatibilityIssuesInCSS(cssText) {
31838    if (cssText.includes(' background-clip: text;') &&
31839        !cssText.includes(' -webkit-background-clip: text;')) {
31840        cssText = cssText.replace(' background-clip: text;', ' -webkit-background-clip: text; background-clip: text;');
31841    }
31842    return cssText;
31843}
31844function escapeImportStatement(rule) {
31845    const { cssText } = rule;
31846    if (cssText.split('"').length < 3)
31847        return cssText;
31848    const statement = ['@import', `url(${JSON.stringify(rule.href)})`];
31849    if (rule.layerName === '') {
31850        statement.push(`layer`);
31851    }
31852    else if (rule.layerName) {
31853        statement.push(`layer(${rule.layerName})`);
31854    }
31855    if (rule.supportsText) {
31856        statement.push(`supports(${rule.supportsText})`);
31857    }
31858    if (rule.media.length) {
31859        statement.push(rule.media.mediaText);
31860    }
31861    return statement.join(' ') + ';';
31862}
31863function stringifyStylesheet(s) {
31864    try {
31865        const rules = s.rules || s.cssRules;
31866        return rules
31867            ? fixBrowserCompatibilityIssuesInCSS(Array.from(rules, stringifyRule).join(''))
31868            : null;
31869    }
31870    catch (error) {
31871        return null;
31872    }
31873}
31874function stringifyRule(rule) {
31875    let importStringified;
31876    if (isCSSImportRule(rule)) {
31877        try {
31878            importStringified =
31879                stringifyStylesheet(rule.styleSheet) ||
31880                    escapeImportStatement(rule);
31881        }
31882        catch (error) {
31883        }
31884    }
31885    else if (isCSSStyleRule(rule) && rule.selectorText.includes(':')) {
31886        return fixSafariColons(rule.cssText);
31887    }
31888    return importStringified || rule.cssText;
31889}
31890function fixSafariColons(cssStringified) {
31891    const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
31892    return cssStringified.replace(regex, '$1\\$2');
31893}
31894function isCSSImportRule(rule) {
31895    return 'styleSheet' in rule;
31896}
31897function isCSSStyleRule(rule) {
31898    return 'selectorText' in rule;
31899}
31900class Mirror {
31901    constructor() {
31902        this.idNodeMap = new Map();
31903        this.nodeMetaMap = new WeakMap();
31904    }
31905    getId(n) {
31906        if (!n)
31907            return -1;
31908        const id = _optionalChain$5([this, 'access', _3 => _3.getMeta, 'call', _4 => _4(n), 'optionalAccess', _5 => _5.id]);
31909        return _nullishCoalesce$1(id, () => ( -1));
31910    }
31911    getNode(id) {
31912        return this.idNodeMap.get(id) || null;
31913    }
31914    getIds() {
31915        return Array.from(this.idNodeMap.keys());
31916    }
31917    getMeta(n) {
31918        return this.nodeMetaMap.get(n) || null;
31919    }
31920    removeNodeFromMap(n) {
31921        const id = this.getId(n);
31922        this.idNodeMap.delete(id);
31923        if (n.childNodes) {
31924            n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));
31925        }
31926    }
31927    has(id) {
31928        return this.idNodeMap.has(id);
31929    }
31930    hasNode(node) {
31931        return this.nodeMetaMap.has(node);
31932    }
31933    add(n, meta) {
31934        const id = meta.id;
31935        this.idNodeMap.set(id, n);
31936        this.nodeMetaMap.set(n, meta);
31937    }
31938    replace(id, n) {
31939        const oldNode = this.getNode(id);
31940        if (oldNode) {
31941            const meta = this.nodeMetaMap.get(oldNode);
31942            if (meta)
31943                this.nodeMetaMap.set(n, meta);
31944        }
31945        this.idNodeMap.set(id, n);
31946    }
31947    reset() {
31948        this.idNodeMap = new Map();
31949        this.nodeMetaMap = new WeakMap();
31950    }
31951}
31952function createMirror() {
31953    return new Mirror();
31954}
31955function shouldMaskInput({ maskInputOptions, tagName, type, }) {
31956    if (tagName === 'OPTION') {
31957        tagName = 'SELECT';
31958    }
31959    return Boolean(maskInputOptions[tagName.toLowerCase()] ||
31960        (type && maskInputOptions[type]) ||
31961        type === 'password' ||
31962        (tagName === 'INPUT' && !type && maskInputOptions['text']));
31963}
31964function maskInputValue({ isMasked, element, value, maskInputFn, }) {
31965    let text = value || '';
31966    if (!isMasked) {
31967        return text;
31968    }
31969    if (maskInputFn) {
31970        text = maskInputFn(text, element);
31971    }
31972    return '*'.repeat(text.length);
31973}
31974function toLowerCase(str) {
31975    return str.toLowerCase();
31976}
31977function toUpperCase(str) {
31978    return str.toUpperCase();
31979}
31980const ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';
31981function is2DCanvasBlank(canvas) {
31982    const ctx = canvas.getContext('2d');
31983    if (!ctx)
31984        return true;
31985    const chunkSize = 50;
31986    for (let x = 0; x < canvas.width; x += chunkSize) {
31987        for (let y = 0; y < canvas.height; y += chunkSize) {
31988            const getImageData = ctx.getImageData;
31989            const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData
31990                ? getImageData[ORIGINAL_ATTRIBUTE_NAME]
31991                : getImageData;
31992            const pixelBuffer = new Uint32Array(originalGetImageData.call(ctx, x, y, Math.min(chunkSize, canvas.width - x), Math.min(chunkSize, canvas.height - y)).data.buffer);
31993            if (pixelBuffer.some((pixel) => pixel !== 0))
31994                return false;
vendor: 4,204 bytes, lines 31995-32131
31995        }
31996    }
31997    return true;
31998}
31999function getInputType(element) {
32000    const type = element.type;
32001    return element.hasAttribute('data-rr-is-password')
32002        ? 'password'
32003        : type
32004            ?
32005                toLowerCase(type)
32006            : null;
32007}
32008function getInputValue(el, tagName, type) {
32009    if (tagName === 'INPUT' && (type === 'radio' || type === 'checkbox')) {
32010        return el.getAttribute('value') || '';
32011    }
32012    return el.value;
32013}
32014
32015let _id = 1;
32016const tagNameRegex = new RegExp('[^a-z0-9-_:]');
32017const IGNORED_NODE = -2;
32018function genId() {
32019    return _id++;
32020}
32021function getValidTagName(element) {
32022    if (element instanceof HTMLFormElement) {
32023        return 'form';
32024    }
32025    const processedTagName = toLowerCase(element.tagName);
32026    if (tagNameRegex.test(processedTagName)) {
32027        return 'div';
32028    }
32029    return processedTagName;
32030}
32031function extractOrigin(url) {
32032    let origin = '';
32033    if (url.indexOf('//') > -1) {
32034        origin = url.split('/').slice(0, 3).join('/');
32035    }
32036    else {
32037        origin = url.split('/')[0];
32038    }
32039    origin = origin.split('?')[0];
32040    return origin;
32041}
32042let canvasService;
32043let canvasCtx;
32044const URL_IN_CSS_REF = /url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm;
32045const URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\/\//i;
32046const URL_WWW_MATCH = /^www\..*/i;
32047const DATA_URI = /^(data:)([^,]*),(.*)/i;
32048function absoluteToStylesheet(cssText, href) {
32049    return (cssText || '').replace(URL_IN_CSS_REF, (origin, quote1, path1, quote2, path2, path3) => {
32050        const filePath = path1 || path2 || path3;
32051        const maybeQuote = quote1 || quote2 || '';
32052        if (!filePath) {
32053            return origin;
32054        }
32055        if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {
32056            return `url(${maybeQuote}${filePath}${maybeQuote})`;
32057        }
32058        if (DATA_URI.test(filePath)) {
32059            return `url(${maybeQuote}${filePath}${maybeQuote})`;
32060        }
32061        if (filePath[0] === '/') {
32062            return `url(${maybeQuote}${extractOrigin(href) + filePath}${maybeQuote})`;
32063        }
32064        const stack = href.split('/');
32065        const parts = filePath.split('/');
32066        stack.pop();
32067        for (const part of parts) {
32068            if (part === '.') {
32069                continue;
32070            }
32071            else if (part === '..') {
32072                stack.pop();
32073            }
32074            else {
32075                stack.push(part);
32076            }
32077        }
32078        return `url(${maybeQuote}${stack.join('/')}${maybeQuote})`;
32079    });
32080}
32081const SRCSET_NOT_SPACES = /^[^ \t\n\r\u000c]+/;
32082const SRCSET_COMMAS_OR_SPACES = /^[, \t\n\r\u000c]+/;
32083function getAbsoluteSrcsetString(doc, attributeValue) {
32084    if (attributeValue.trim() === '') {
32085        return attributeValue;
32086    }
32087    let pos = 0;
32088    function collectCharacters(regEx) {
32089        let chars;
32090        const match = regEx.exec(attributeValue.substring(pos));
32091        if (match) {
32092            chars = match[0];
32093            pos += chars.length;
32094            return chars;
32095        }
32096        return '';
32097    }
32098    const output = [];
32099    while (true) {
32100        collectCharacters(SRCSET_COMMAS_OR_SPACES);
32101        if (pos >= attributeValue.length) {
32102            break;
32103        }
32104        let url = collectCharacters(SRCSET_NOT_SPACES);
32105        if (url.slice(-1) === ',') {
32106            url = absoluteToDoc(doc, url.substring(0, url.length - 1));
32107            output.push(url);
32108        }
32109        else {
32110            let descriptorsStr = '';
32111            url = absoluteToDoc(doc, url);
32112            let inParens = false;
32113            while (true) {
32114                const c = attributeValue.charAt(pos);
32115                if (c === '') {
32116                    output.push((url + descriptorsStr).trim());
32117                    break;
32118                }
32119                else if (!inParens) {
32120                    if (c === ',') {
32121                        pos += 1;
32122                        output.push((url + descriptorsStr).trim());
32123                        break;
32124                    }
32125                    else if (c === '(') {
32126                        inParens = true;
32127                    }
32128                }
32129                else {
32130                    if (c === ')') {
32131                        inParens = false;
32132                    }
32133                }
32134                descriptorsStr += c;
32135                pos += 1;
32136            }
32137        }
32138    }
32139    return output.join(', ');
32140}
32141function absoluteToDoc(doc, attributeValue) {
32142    if (!attributeValue || attributeValue.trim() === '') {
32143        return attributeValue;
32144    }
32145    const a = doc.createElement('a');
32146    a.href = attributeValue;
32147    return a.href;
32148}
32149function isSVGElement(el) {
32150    return Boolean(el.tagName === 'svg' || el.ownerSVGElement);
32151}
32152function getHref() {
32153    const a = document.createElement('a');
32154    a.href = '';
32155    return a.href;
32156}
32157function transformAttribute(doc, tagName, name, value, element, maskAttributeFn) {
32158    if (!value) {
32159        return value;
32160    }
32161    if (name === 'src' ||
32162        (name === 'href' && !(tagName === 'use' && value[0] === '#'))) {
32163        return absoluteToDoc(doc, value);
32164    }
32165    else if (name === 'xlink:href' && value[0] !== '#') {
32166        return absoluteToDoc(doc, value);
32167    }
32168    else if (name === 'background' &&
32169        (tagName === 'table' || tagName === 'td' || tagName === 'th')) {
32170        return absoluteToDoc(doc, value);
32171    }
32172    else if (name === 'srcset') {
32173        return getAbsoluteSrcsetString(doc, value);
32174    }
32175    else if (name === 'style') {
32176        return absoluteToStylesheet(value, getHref());
32177    }
32178    else if (tagName === 'object' && name === 'data') {
32179        return absoluteToDoc(doc, value);
32180    }
32181    if (typeof maskAttributeFn === 'function') {
32182        return maskAttributeFn(name, value, element);
32183    }
32184    return value;
32185}
32186function ignoreAttribute(tagName, name, _value) {
32187    return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';
32188}
32189function _isBlockedElement(element, blockClass, blockSelector, unblockSelector) {
32190    try {
32191        if (unblockSelector && element.matches(unblockSelector)) {
32192            return false;
32193        }
32194        if (typeof blockClass === 'string') {
32195            if (element.classList.contains(blockClass)) {
32196                return true;
32197            }
32198        }
32199        else {
32200            for (let eIndex = element.classList.length; eIndex--;) {
32201                const className = element.classList[eIndex];
32202                if (blockClass.test(className)) {
32203                    return true;
32204                }
32205            }
32206        }
32207        if (blockSelector) {
32208            return element.matches(blockSelector);
32209        }
32210    }
32211    catch (e) {
32212    }
32213    return false;
32214}
32215function elementClassMatchesRegex(el, regex) {
32216    for (let eIndex = el.classList.length; eIndex--;) {
32217        const className = el.classList[eIndex];
32218        if (regex.test(className)) {
32219            return true;
32220        }
32221    }
32222    return false;
32223}
32224function distanceToMatch(node, matchPredicate, limit = Infinity, distance = 0) {
32225    if (!node)
32226        return -1;
32227    if (node.nodeType !== node.ELEMENT_NODE)
32228        return -1;
32229    if (distance > limit)
32230        return -1;
32231    if (matchPredicate(node))
32232        return distance;
32233    return distanceToMatch(node.parentNode, matchPredicate, limit, distance + 1);
32234}
32235function createMatchPredicate(className, selector) {
32236    return (node) => {
32237        const el = node;
32238        if (el === null)
32239            return false;
32240        try {
32241            if (className) {
32242                if (typeof className === 'string') {
32243                    if (el.matches(`.${className}`))
32244                        return true;
32245                }
32246                else if (elementClassMatchesRegex(el, className)) {
32247                    return true;
32248                }
32249            }
32250            if (selector && el.matches(selector))
32251                return true;
32252            return false;
32253        }
32254        catch (e2) {
32255            return false;
32256        }
32257    };
32258}
32259function needMaskingText(node, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText) {
32260    try {
32261        const el = node.nodeType === node.ELEMENT_NODE
32262            ? node
32263            : node.parentElement;
32264        if (el === null)
32265            return false;
32266        if (el.tagName === 'INPUT') {
32267            const autocomplete = el.getAttribute('autocomplete');
32268            const disallowedAutocompleteValues = [
32269                'current-password',
32270                'new-password',
32271                'cc-number',
32272                'cc-exp',
32273                'cc-exp-month',
32274                'cc-exp-year',
32275                'cc-csc',
32276            ];
32277            if (disallowedAutocompleteValues.includes(autocomplete)) {
32278                return true;
32279            }
32280        }
32281        let maskDistance = -1;
32282        let unmaskDistance = -1;
32283        if (maskAllText) {
32284            unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector));
32285            if (unmaskDistance < 0) {
32286                return true;
32287            }
32288            maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector), unmaskDistance >= 0 ? unmaskDistance : Infinity);
32289        }
32290        else {
32291            maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector));
32292            if (maskDistance < 0) {
32293                return false;
32294            }
32295            unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector), maskDistance >= 0 ? maskDistance : Infinity);
32296        }
32297        return maskDistance >= 0
32298            ? unmaskDistance >= 0
32299                ? maskDistance <= unmaskDistance
32300                : true
32301            : unmaskDistance >= 0
32302                ? false
32303                : !!maskAllText;
32304    }
32305    catch (e) {
32306    }
32307    return !!maskAllText;
32308}
32309function onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {
32310    const win = iframeEl.contentWindow;
32311    if (!win) {
32312        return;
32313    }
32314    let fired = false;
32315    let readyState;
32316    try {
32317        readyState = win.document.readyState;
32318    }
32319    catch (error) {
32320        return;
32321    }
32322    if (readyState !== 'complete') {
32323        const timer = setTimeout(() => {
32324            if (!fired) {
32325                listener();
32326                fired = true;
32327            }
32328        }, iframeLoadTimeout);
32329        iframeEl.addEventListener('load', () => {
32330            clearTimeout(timer);
32331            fired = true;
32332            listener();
32333        });
32334        return;
32335    }
32336    const blankUrl = 'about:blank';
32337    if (win.location.href !== blankUrl ||
32338        iframeEl.src === blankUrl ||
32339        iframeEl.src === '') {
32340        setTimeout(listener, 0);
32341        return iframeEl.addEventListener('load', listener);
32342    }
32343    iframeEl.addEventListener('load', listener);
32344}
32345function onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {
32346    let fired = false;
32347    let styleSheetLoaded;
32348    try {
32349        styleSheetLoaded = link.sheet;
32350    }
32351    catch (error) {
32352        return;
32353    }
32354    if (styleSheetLoaded)
32355        return;
32356    const timer = setTimeout(() => {
32357        if (!fired) {
32358            listener();
32359            fired = true;
32360        }
32361    }, styleSheetLoadTimeout);
32362    link.addEventListener('load', () => {
32363        clearTimeout(timer);
32364        fired = true;
32365        listener();
32366    });
32367}
32368function serializeNode(n, options) {
32369    const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskAttributeFn, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, inlineStylesheet, maskInputOptions = {}, maskTextFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, } = options;
32370    const rootId = getRootId(doc, mirror);
32371    switch (n.nodeType) {
32372        case n.DOCUMENT_NODE:
32373            if (n.compatMode !== 'CSS1Compat') {
32374                return {
32375                    type: NodeType$1.Document,
32376                    childNodes: [],
32377                    compatMode: n.compatMode,
32378                };
32379            }
32380            else {
32381                return {
32382                    type: NodeType$1.Document,
32383                    childNodes: [],
32384                };
32385            }
32386        case n.DOCUMENT_TYPE_NODE:
32387            return {
32388                type: NodeType$1.DocumentType,
32389                name: n.name,
32390                publicId: n.publicId,
32391                systemId: n.systemId,
32392                rootId,
32393            };
32394        case n.ELEMENT_NODE:
32395            return serializeElementNode(n, {
32396                doc,
32397                blockClass,
32398                blockSelector,
32399                unblockSelector,
32400                inlineStylesheet,
32401                maskAttributeFn,
32402                maskInputOptions,
32403                maskInputFn,
32404                dataURLOptions,
32405                inlineImages,
32406                recordCanvas,
32407                keepIframeSrcFn,
32408                newlyAddedElement,
32409                rootId,
32410                maskAllText,
32411                maskTextClass,
32412                unmaskTextClass,
32413                maskTextSelector,
32414                unmaskTextSelector,
32415            });
32416        case n.TEXT_NODE:
32417            return serializeTextNode(n, {
32418                maskAllText,
32419                maskTextClass,
32420                unmaskTextClass,
32421                maskTextSelector,
32422                unmaskTextSelector,
32423                maskTextFn,
32424                maskInputOptions,
32425                maskInputFn,
32426                rootId,
32427            });
32428        case n.CDATA_SECTION_NODE:
32429            return {
32430                type: NodeType$1.CDATA,
32431                textContent: '',
32432                rootId,
32433            };
32434        case n.COMMENT_NODE:
32435            return {
32436                type: NodeType$1.Comment,
32437                textContent: n.textContent || '',
32438                rootId,
32439            };
32440        default:
32441            return false;
32442    }
32443}
32444function getRootId(doc, mirror) {
32445    if (!mirror.hasNode(doc))
32446        return undefined;
32447    const docId = mirror.getId(doc);
32448    return docId === 1 ? undefined : docId;
32449}
32450function serializeTextNode(n, options) {
32451    const { maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, maskTextFn, maskInputOptions, maskInputFn, rootId, } = options;
32452    const parentTagName = n.parentNode && n.parentNode.tagName;
32453    let textContent = n.textContent;
32454    const isStyle = parentTagName === 'STYLE' ? true : undefined;
32455    const isScript = parentTagName === 'SCRIPT' ? true : undefined;
32456    const isTextarea = parentTagName === 'TEXTAREA' ? true : undefined;
32457    if (isStyle && textContent) {
32458        try {
32459            if (n.nextSibling || n.previousSibling) {
32460            }
32461            else if (_optionalChain$5([n, 'access', _6 => _6.parentNode, 'access', _7 => _7.sheet, 'optionalAccess', _8 => _8.cssRules])) {
32462                textContent = stringifyStylesheet(n.parentNode.sheet);
32463            }
32464        }
32465        catch (err) {
32466            console.warn(`Cannot get CSS styles from text's parentNode. Error: ${err}`, n);
32467        }
32468        textContent = absoluteToStylesheet(textContent, getHref());
32469    }
32470    if (isScript) {
32471        textContent = 'SCRIPT_PLACEHOLDER';
32472    }
32473    const forceMask = needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText);
32474    if (!isStyle && !isScript && !isTextarea && textContent && forceMask) {
32475        textContent = maskTextFn
32476            ? maskTextFn(textContent)
32477            : textContent.replace(/[\S]/g, '*');
32478    }
32479    if (isTextarea && textContent && (maskInputOptions.textarea || forceMask)) {
32480        textContent = maskInputFn
32481            ? maskInputFn(textContent, n.parentNode)
32482            : textContent.replace(/[\S]/g, '*');
32483    }
32484    if (parentTagName === 'OPTION' && textContent) {
32485        const isInputMasked = shouldMaskInput({
32486            type: null,
32487            tagName: parentTagName,
32488            maskInputOptions,
32489        });
32490        textContent = maskInputValue({
32491            isMasked: needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked),
32492            element: n,
32493            value: textContent,
32494            maskInputFn,
32495        });
32496    }
32497    return {
32498        type: NodeType$1.Text,
32499        textContent: textContent || '',
32500        isStyle,
32501        rootId,
32502    };
32503}
32504function serializeElementNode(n, options) {
32505    const { doc, blockClass, blockSelector, unblockSelector, inlineStylesheet, maskInputOptions = {}, maskAttributeFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, rootId, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, } = options;
32506    const needBlock = _isBlockedElement(n, blockClass, blockSelector, unblockSelector);
32507    const tagName = getValidTagName(n);
32508    let attributes = {};
32509    const len = n.attributes.length;
32510    for (let i = 0; i < len; i++) {
32511        const attr = n.attributes[i];
32512        if (attr.name && !ignoreAttribute(tagName, attr.name, attr.value)) {
32513            attributes[attr.name] = transformAttribute(doc, tagName, toLowerCase(attr.name), attr.value, n, maskAttributeFn);
32514        }
32515    }
32516    if (tagName === 'link' && inlineStylesheet) {
32517        const stylesheet = Array.from(doc.styleSheets).find((s) => {
32518            return s.href === n.href;
32519        });
32520        let cssText = null;
32521        if (stylesheet) {
32522            cssText = stringifyStylesheet(stylesheet);
32523        }
32524        if (cssText) {
32525            delete attributes.rel;
32526            delete attributes.href;
32527            attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);
32528        }
32529    }
32530    if (tagName === 'style' &&
32531        n.sheet &&
32532        !(n.innerText || n.textContent || '').trim().length) {
32533        const cssText = stringifyStylesheet(n.sheet);
32534        if (cssText) {
32535            attributes._cssText = absoluteToStylesheet(cssText, getHref());
32536        }
32537    }
32538    if (tagName === 'input' ||
32539        tagName === 'textarea' ||
32540        tagName === 'select' ||
32541        tagName === 'option') {
32542        const el = n;
32543        const type = getInputType(el);
32544        const value = getInputValue(el, toUpperCase(tagName), type);
32545        const checked = el.checked;
32546        if (type !== 'submit' && type !== 'button' && value) {
32547            const forceMask = needMaskingText(el, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, shouldMaskInput({
32548                type,
32549                tagName: toUpperCase(tagName),
32550                maskInputOptions,
32551            }));
32552            attributes.value = maskInputValue({
32553                isMasked: forceMask,
32554                element: el,
32555                value,
32556                maskInputFn,
32557            });
32558        }
32559        if (checked) {
32560            attributes.checked = checked;
32561        }
32562    }
32563    if (tagName === 'option') {
32564        if (n.selected && !maskInputOptions['select']) {
32565            attributes.selected = true;
32566        }
32567        else {
32568            delete attributes.selected;
32569        }
32570    }
32571    if (tagName === 'canvas' && recordCanvas) {
32572        if (n.__context === '2d') {
32573            if (!is2DCanvasBlank(n)) {
32574                attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
32575            }
32576        }
32577        else if (!('__context' in n)) {
32578            const canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
32579            const blankCanvas = document.createElement('canvas');
32580            blankCanvas.width = n.width;
32581            blankCanvas.height = n.height;
32582            const blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);
32583            if (canvasDataURL !== blankCanvasDataURL) {
32584                attributes.rr_dataURL = canvasDataURL;
32585            }
32586        }
32587    }
32588    if (tagName === 'img' && inlineImages) {
32589        if (!canvasService) {
32590            canvasService = doc.createElement('canvas');
32591            canvasCtx = canvasService.getContext('2d');
32592        }
32593        const image = n;
32594        const oldValue = image.crossOrigin;
32595        image.crossOrigin = 'anonymous';
32596        const recordInlineImage = () => {
32597            image.removeEventListener('load', recordInlineImage);
32598            try {
32599                canvasService.width = image.naturalWidth;
32600                canvasService.height = image.naturalHeight;
32601                canvasCtx.drawImage(image, 0, 0);
32602                attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);
32603            }
32604            catch (err) {
32605                console.warn(`Cannot inline img src=${image.currentSrc}! Error: ${err}`);
32606            }
32607            oldValue
32608                ? (attributes.crossOrigin = oldValue)
32609                : image.removeAttribute('crossorigin');
32610        };
32611        if (image.complete && image.naturalWidth !== 0)
32612            recordInlineImage();
32613        else
32614            image.addEventListener('load', recordInlineImage);
32615    }
32616    if (tagName === 'audio' || tagName === 'video') {
32617        attributes.rr_mediaState = n.paused
32618            ? 'paused'
32619            : 'played';
32620        attributes.rr_mediaCurrentTime = n.currentTime;
32621    }
32622    if (!newlyAddedElement) {
32623        if (n.scrollLeft) {
32624            attributes.rr_scrollLeft = n.scrollLeft;
32625        }
32626        if (n.scrollTop) {
32627            attributes.rr_scrollTop = n.scrollTop;
32628        }
32629    }
32630    if (needBlock) {
32631        const { width, height } = n.getBoundingClientRect();
32632        attributes = {
32633            class: attributes.class,
32634            rr_width: `${width}px`,
32635            rr_height: `${height}px`,
32636        };
32637    }
32638    if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {
32639        if (!n.contentDocument) {
32640            attributes.rr_src = attributes.src;
32641        }
32642        delete attributes.src;
32643    }
32644    let isCustomElement;
32645    try {
32646        if (customElements.get(tagName))
32647            isCustomElement = true;
32648    }
32649    catch (e) {
32650    }
32651    return {
32652        type: NodeType$1.Element,
32653        tagName,
32654        attributes,
32655        childNodes: [],
32656        isSVG: isSVGElement(n) || undefined,
32657        needBlock,
32658        rootId,
32659        isCustom: isCustomElement,
32660    };
32661}
32662function lowerIfExists(maybeAttr) {
32663    if (maybeAttr === undefined || maybeAttr === null) {
32664        return '';
32665    }
32666    else {
32667        return maybeAttr.toLowerCase();
32668    }
32669}
32670function slimDOMExcluded(sn, slimDOMOptions) {
32671    if (slimDOMOptions.comment && sn.type === NodeType$1.Comment) {
32672        return true;
32673    }
32674    else if (sn.type === NodeType$1.Element) {
32675        if (slimDOMOptions.script &&
32676            (sn.tagName === 'script' ||
32677                (sn.tagName === 'link' &&
32678                    (sn.attributes.rel === 'preload' ||
32679                        sn.attributes.rel === 'modulepreload') &&
32680                    sn.attributes.as === 'script') ||
32681                (sn.tagName === 'link' &&
32682                    sn.attributes.rel === 'prefetch' &&
32683                    typeof sn.attributes.href === 'string' &&
32684                    sn.attributes.href.endsWith('.js')))) {
32685            return true;
32686        }
32687        else if (slimDOMOptions.headFavicon &&
32688            ((sn.tagName === 'link' && sn.attributes.rel === 'shortcut icon') ||
32689                (sn.tagName === 'meta' &&
32690                    (lowerIfExists(sn.attributes.name).match(/^msapplication-tile(image|color)$/) ||
32691                        lowerIfExists(sn.attributes.name) === 'application-name' ||
32692                        lowerIfExists(sn.attributes.rel) === 'icon' ||
32693                        lowerIfExists(sn.attributes.rel) === 'apple-touch-icon' ||
32694                        lowerIfExists(sn.attributes.rel) === 'shortcut icon')))) {
32695            return true;
32696        }
32697        else if (sn.tagName === 'meta') {
32698            if (slimDOMOptions.headMetaDescKeywords &&
32699                lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {
32700                return true;
32701            }
32702            else if (slimDOMOptions.headMetaSocial &&
32703                (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) ||
32704                    lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) ||
32705                    lowerIfExists(sn.attributes.name) === 'pinterest')) {
32706                return true;
32707            }
32708            else if (slimDOMOptions.headMetaRobots &&
32709                (lowerIfExists(sn.attributes.name) === 'robots' ||
32710                    lowerIfExists(sn.attributes.name) === 'googlebot' ||
32711                    lowerIfExists(sn.attributes.name) === 'bingbot')) {
32712                return true;
32713            }
32714            else if (slimDOMOptions.headMetaHttpEquiv &&
32715                sn.attributes['http-equiv'] !== undefined) {
32716                return true;
32717            }
32718            else if (slimDOMOptions.headMetaAuthorship &&
32719                (lowerIfExists(sn.attributes.name) === 'author' ||
32720                    lowerIfExists(sn.attributes.name) === 'generator' ||
32721                    lowerIfExists(sn.attributes.name) === 'framework' ||
32722                    lowerIfExists(sn.attributes.name) === 'publisher' ||
32723                    lowerIfExists(sn.attributes.name) === 'progid' ||
32724                    lowerIfExists(sn.attributes.property).match(/^article:/) ||
32725                    lowerIfExists(sn.attributes.property).match(/^product:/))) {
32726                return true;
32727            }
32728            else if (slimDOMOptions.headMetaVerification &&
32729                (lowerIfExists(sn.attributes.name) === 'google-site-verification' ||
32730                    lowerIfExists(sn.attributes.name) === 'yandex-verification' ||
32731                    lowerIfExists(sn.attributes.name) === 'csrf-token' ||
32732                    lowerIfExists(sn.attributes.name) === 'p:domain_verify' ||
32733                    lowerIfExists(sn.attributes.name) === 'verify-v1' ||
32734                    lowerIfExists(sn.attributes.name) === 'verification' ||
32735                    lowerIfExists(sn.attributes.name) === 'shopify-checkout-api-token')) {
32736                return true;
32737            }
32738        }
32739    }
32740    return false;
32741}
32742function serializeNodeWithId(n, options) {
32743    const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, skipChild = false, inlineStylesheet = true, maskInputOptions = {}, maskAttributeFn, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions = {}, inlineImages = false, recordCanvas = false, onSerialize, onIframeLoad, iframeLoadTimeout = 5000, onStylesheetLoad, stylesheetLoadTimeout = 5000, keepIframeSrcFn = () => false, newlyAddedElement = false, } = options;
32744    let { preserveWhiteSpace = true } = options;
32745    const _serializedNode = serializeNode(n, {
32746        doc,
32747        mirror,
32748        blockClass,
32749        blockSelector,
32750        maskAllText,
32751        unblockSelector,
32752        maskTextClass,
32753        unmaskTextClass,
32754        maskTextSelector,
32755        unmaskTextSelector,
32756        inlineStylesheet,
32757        maskInputOptions,
32758        maskAttributeFn,
32759        maskTextFn,
32760        maskInputFn,
32761        dataURLOptions,
32762        inlineImages,
32763        recordCanvas,
32764        keepIframeSrcFn,
32765        newlyAddedElement,
32766    });
32767    if (!_serializedNode) {
32768        console.warn(n, 'not serialized');
32769        return null;
32770    }
32771    let id;
32772    if (mirror.hasNode(n)) {
32773        id = mirror.getId(n);
32774    }
32775    else if (slimDOMExcluded(_serializedNode, slimDOMOptions) ||
32776        (!preserveWhiteSpace &&
32777            _serializedNode.type === NodeType$1.Text &&
32778            !_serializedNode.isStyle &&
32779            !_serializedNode.textContent.replace(/^\s+|\s+$/gm, '').length)) {
32780        id = IGNORED_NODE;
32781    }
32782    else {
32783        id = genId();
32784    }
32785    const serializedNode = Object.assign(_serializedNode, { id });
32786    mirror.add(n, serializedNode);
32787    if (id === IGNORED_NODE) {
32788        return null;
32789    }
32790    if (onSerialize) {
32791        onSerialize(n);
32792    }
32793    let recordChild = !skipChild;
32794    if (serializedNode.type === NodeType$1.Element) {
32795        recordChild = recordChild && !serializedNode.needBlock;
32796        delete serializedNode.needBlock;
32797        const shadowRoot = n.shadowRoot;
32798        if (shadowRoot && isNativeShadowDom(shadowRoot))
32799            serializedNode.isShadowHost = true;
32800    }
32801    if ((serializedNode.type === NodeType$1.Document ||
32802        serializedNode.type === NodeType$1.Element) &&
32803        recordChild) {
32804        if (slimDOMOptions.headWhitespace &&
32805            serializedNode.type === NodeType$1.Element &&
32806            serializedNode.tagName === 'head') {
32807            preserveWhiteSpace = false;
32808        }
32809        const bypassOptions = {
32810            doc,
32811            mirror,
32812            blockClass,
32813            blockSelector,
32814            maskAllText,
32815            unblockSelector,
32816            maskTextClass,
32817            unmaskTextClass,
32818            maskTextSelector,
32819            unmaskTextSelector,
32820            skipChild,
32821            inlineStylesheet,
32822            maskInputOptions,
32823            maskAttributeFn,
32824            maskTextFn,
32825            maskInputFn,
32826            slimDOMOptions,
32827            dataURLOptions,
32828            inlineImages,
32829            recordCanvas,
32830            preserveWhiteSpace,
32831            onSerialize,
32832            onIframeLoad,
32833            iframeLoadTimeout,
32834            onStylesheetLoad,
32835            stylesheetLoadTimeout,
32836            keepIframeSrcFn,
32837        };
32838        for (const childN of Array.from(n.childNodes)) {
32839            const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
32840            if (serializedChildNode) {
32841                serializedNode.childNodes.push(serializedChildNode);
32842            }
32843        }
32844        if (isElement$1(n) && n.shadowRoot) {
32845            for (const childN of Array.from(n.shadowRoot.childNodes)) {
32846                const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
32847                if (serializedChildNode) {
32848                    isNativeShadowDom(n.shadowRoot) &&
32849                        (serializedChildNode.isShadow = true);
32850                    serializedNode.childNodes.push(serializedChildNode);
32851                }
32852            }
32853        }
32854    }
32855    if (n.parentNode &&
32856        isShadowRoot(n.parentNode) &&
32857        isNativeShadowDom(n.parentNode)) {
32858        serializedNode.isShadow = true;
32859    }
32860    if (serializedNode.type === NodeType$1.Element &&
32861        serializedNode.tagName === 'iframe') {
32862        onceIframeLoaded(n, () => {
32863            const iframeDoc = n.contentDocument;
32864            if (iframeDoc && onIframeLoad) {
32865                const serializedIframeNode = serializeNodeWithId(iframeDoc, {
32866                    doc: iframeDoc,
32867                    mirror,
32868                    blockClass,
32869                    blockSelector,
32870                    unblockSelector,
32871                    maskAllText,
32872                    maskTextClass,
32873                    unmaskTextClass,
32874                    maskTextSelector,
32875                    unmaskTextSelector,
32876                    skipChild: false,
32877                    inlineStylesheet,
32878                    maskInputOptions,
32879                    maskAttributeFn,
32880                    maskTextFn,
32881                    maskInputFn,
32882                    slimDOMOptions,
32883                    dataURLOptions,
32884                    inlineImages,
32885                    recordCanvas,
32886                    preserveWhiteSpace,
32887                    onSerialize,
32888                    onIframeLoad,
32889                    iframeLoadTimeout,
32890                    onStylesheetLoad,
32891                    stylesheetLoadTimeout,
32892                    keepIframeSrcFn,
32893                });
32894                if (serializedIframeNode) {
32895                    onIframeLoad(n, serializedIframeNode);
32896                }
32897            }
32898        }, iframeLoadTimeout);
32899    }
32900    if (serializedNode.type === NodeType$1.Element &&
32901        serializedNode.tagName === 'link' &&
32902        serializedNode.attributes.rel === 'stylesheet') {
32903        onceStylesheetLoaded(n, () => {
32904            if (onStylesheetLoad) {
32905                const serializedLinkNode = serializeNodeWithId(n, {
32906                    doc,
32907                    mirror,
32908                    blockClass,
32909                    blockSelector,
32910                    unblockSelector,
32911                    maskAllText,
32912                    maskTextClass,
32913                    unmaskTextClass,
32914                    maskTextSelector,
32915                    unmaskTextSelector,
32916                    skipChild: false,
32917                    inlineStylesheet,
32918                    maskInputOptions,
32919                    maskAttributeFn,
32920                    maskTextFn,
32921                    maskInputFn,
32922                    slimDOMOptions,
32923                    dataURLOptions,
32924                    inlineImages,
32925                    recordCanvas,
32926                    preserveWhiteSpace,
32927                    onSerialize,
32928                    onIframeLoad,
32929                    iframeLoadTimeout,
32930                    onStylesheetLoad,
32931                    stylesheetLoadTimeout,
32932                    keepIframeSrcFn,
32933                });
32934                if (serializedLinkNode) {
32935                    onStylesheetLoad(n, serializedLinkNode);
32936                }
32937            }
32938        }, stylesheetLoadTimeout);
32939    }
32940    return serializedNode;
32941}
32942function snapshot(n, options) {
32943    const { mirror = new Mirror(), blockClass = 'rr-block', blockSelector = null, unblockSelector = null, maskAllText = false, maskTextClass = 'rr-mask', unmaskTextClass = null, maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, inlineImages = false, recordCanvas = false, maskAllInputs = false, maskAttributeFn, maskTextFn, maskInputFn, slimDOM = false, dataURLOptions, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn = () => false, } = options || {};
32944    const maskInputOptions = maskAllInputs === true
32945        ? {
32946            color: true,
32947            date: true,
32948            'datetime-local': true,
32949            email: true,
32950            month: true,
32951            number: true,
32952            range: true,
32953            search: true,
32954            tel: true,
32955            text: true,
32956            time: true,
32957            url: true,
32958            week: true,
32959            textarea: true,
32960            select: true,
32961        }
32962        : maskAllInputs === false
32963            ? {}
32964            : maskAllInputs;
32965    const slimDOMOptions = slimDOM === true || slimDOM === 'all'
32966        ?
32967            {
32968                script: true,
32969                comment: true,
32970                headFavicon: true,
32971                headWhitespace: true,
32972                headMetaDescKeywords: slimDOM === 'all',
32973                headMetaSocial: true,
32974                headMetaRobots: true,
32975                headMetaHttpEquiv: true,
32976                headMetaAuthorship: true,
32977                headMetaVerification: true,
32978            }
32979        : slimDOM === false
32980            ? {}
32981            : slimDOM;
32982    return serializeNodeWithId(n, {
32983        doc: n,
32984        mirror,
32985        blockClass,
32986        blockSelector,
32987        unblockSelector,
32988        maskAllText,
32989        maskTextClass,
32990        unmaskTextClass,
32991        maskTextSelector,
32992        unmaskTextSelector,
32993        skipChild: false,
32994        inlineStylesheet,
32995        maskInputOptions,
32996        maskAttributeFn,
32997        maskTextFn,
32998        maskInputFn,
32999        slimDOMOptions,
33000        dataURLOptions,
33001        inlineImages,
33002        recordCanvas,
33003        preserveWhiteSpace,
33004        onSerialize,
33005        onIframeLoad,
33006        iframeLoadTimeout,
33007        onStylesheetLoad,
33008        stylesheetLoadTimeout,
33009        keepIframeSrcFn,
33010        newlyAddedElement: false,
33011    });
33012}
33013
33014function _optionalChain$4(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
33015function on(type, fn, target = document) {
33016    const options = { capture: true, passive: true };
33017    target.addEventListener(type, fn, options);
33018    return () => target.removeEventListener(type, fn, options);
33019}
33020const DEPARTED_MIRROR_ACCESS_WARNING = 'Please stop import mirror directly. Instead of that,' +
33021    '\r\n' +
33022    'now you can use replayer.getMirror() to access the mirror instance of a replayer,' +
33023    '\r\n' +
33024    'or you can use record.mirror to access the mirror instance during recording.';
33025let _mirror = {
33026    map: {},
33027    getId() {
33028        console.error(DEPARTED_MIRROR_ACCESS_WARNING);
33029        return -1;
33030    },
33031    getNode() {
33032        console.error(DEPARTED_MIRROR_ACCESS_WARNING);
33033        return null;
33034    },
33035    removeNodeFromMap() {
33036        console.error(DEPARTED_MIRROR_ACCESS_WARNING);
33037    },
33038    has() {
33039        console.error(DEPARTED_MIRROR_ACCESS_WARNING);
33040        return false;
33041    },
33042    reset() {
33043        console.error(DEPARTED_MIRROR_ACCESS_WARNING);
33044    },
33045};
33046if (typeof window !== 'undefined' && window.Proxy && window.Reflect) {
33047    _mirror = new Proxy(_mirror, {
33048        get(target, prop, receiver) {
33049            if (prop === 'map') {
33050                console.error(DEPARTED_MIRROR_ACCESS_WARNING);
33051            }
33052            return Reflect.get(target, prop, receiver);
33053        },
33054    });
33055}
33056function throttle$1(func, wait, options = {}) {
33057    let timeout = null;
33058    let previous = 0;
33059    return function (...args) {
33060        const now = Date.now();
33061        if (!previous && options.leading === false) {
33062            previous = now;
33063        }
33064        const remaining = wait - (now - previous);
33065        const context = this;
33066        if (remaining <= 0 || remaining > wait) {
33067            if (timeout) {
33068                clearTimeout(timeout);
33069                timeout = null;
33070            }
33071            previous = now;
33072            func.apply(context, args);
33073        }
33074        else if (!timeout && options.trailing !== false) {
33075            timeout = setTimeout(() => {
33076                previous = options.leading === false ? 0 : Date.now();
33077                timeout = null;
33078                func.apply(context, args);
33079            }, remaining);
33080        }
33081    };
33082}
33083function hookSetter(target, key, d, isRevoked, win = window) {
33084    const original = win.Object.getOwnPropertyDescriptor(target, key);
33085    win.Object.defineProperty(target, key, isRevoked
33086        ? d
33087        : {
33088            set(value) {
33089                setTimeout(() => {
33090                    d.set.call(this, value);
33091                }, 0);
33092                if (original && original.set) {
33093                    original.set.call(this, value);
33094                }
33095            },
33096        });
33097    return () => hookSetter(target, key, original || {}, true);
33098}
33099function patch(source, name, replacement) {
33100    try {
33101        if (!(name in source)) {
33102            return () => {
33103            };
33104        }
33105        const original = source[name];
33106        const wrapped = replacement(original);
33107        if (typeof wrapped === 'function') {
33108            wrapped.prototype = wrapped.prototype || {};
33109            Object.defineProperties(wrapped, {
33110                __rrweb_original__: {
33111                    enumerable: false,
33112                    value: original,
33113                },
33114            });
33115        }
33116        source[name] = wrapped;
33117        return () => {
33118            source[name] = original;
33119        };
33120    }
33121    catch (e2) {
33122        return () => {
33123        };
33124    }
33125}
33126let nowTimestamp = Date.now;
33127if (!(/[1-9][0-9]{12}/.test(Date.now().toString()))) {
33128    nowTimestamp = () => new Date().getTime();
33129}
33130function getWindowScroll(win) {
33131    const doc = win.document;
33132    return {
33133        left: doc.scrollingElement
33134            ? doc.scrollingElement.scrollLeft
33135            : win.pageXOffset !== undefined
33136                ? win.pageXOffset
33137                : _optionalChain$4([doc, 'optionalAccess', _ => _.documentElement, 'access', _2 => _2.scrollLeft]) ||
33138                    _optionalChain$4([doc, 'optionalAccess', _3 => _3.body, 'optionalAccess', _4 => _4.parentElement, 'optionalAccess', _5 => _5.scrollLeft]) ||
33139                    _optionalChain$4([doc, 'optionalAccess', _6 => _6.body, 'optionalAccess', _7 => _7.scrollLeft]) ||
33140                    0,
33141        top: doc.scrollingElement
33142            ? doc.scrollingElement.scrollTop
33143            : win.pageYOffset !== undefined
33144                ? win.pageYOffset
33145                : _optionalChain$4([doc, 'optionalAccess', _8 => _8.documentElement, 'access', _9 => _9.scrollTop]) ||
33146                    _optionalChain$4([doc, 'optionalAccess', _10 => _10.body, 'optionalAccess', _11 => _11.parentElement, 'optionalAccess', _12 => _12.scrollTop]) ||
33147                    _optionalChain$4([doc, 'optionalAccess', _13 => _13.body, 'optionalAccess', _14 => _14.scrollTop]) ||
33148                    0,
33149    };
33150}
33151function getWindowHeight() {
33152    return (window.innerHeight ||
33153        (document.documentElement && document.documentElement.clientHeight) ||
33154        (document.body && document.body.clientHeight));
33155}
33156function getWindowWidth() {
33157    return (window.innerWidth ||
33158        (document.documentElement && document.documentElement.clientWidth) ||
33159        (document.body && document.body.clientWidth));
33160}
33161function isBlocked(node, blockClass, blockSelector, unblockSelector, checkAncestors) {
33162    if (!node) {
33163        return false;
33164    }
33165    const el = node.nodeType === node.ELEMENT_NODE
33166        ? node
33167        : node.parentElement;
33168    if (!el)
33169        return false;
33170    const blockedPredicate = createMatchPredicate(blockClass, blockSelector);
33171    if (!checkAncestors) {
33172        const isUnblocked = unblockSelector && el.matches(unblockSelector);
33173        return blockedPredicate(el) && !isUnblocked;
33174    }
33175    const blockDistance = distanceToMatch(el, blockedPredicate);
33176    let unblockDistance = -1;
33177    if (blockDistance < 0) {
33178        return false;
33179    }
33180    if (unblockSelector) {
33181        unblockDistance = distanceToMatch(el, createMatchPredicate(null, unblockSelector));
33182    }
33183    if (blockDistance > -1 && unblockDistance < 0) {
33184        return true;
33185    }
33186    return blockDistance < unblockDistance;
33187}
33188function isSerialized(n, mirror) {
33189    return mirror.getId(n) !== -1;
33190}
33191function isIgnored(n, mirror) {
33192    return mirror.getId(n) === IGNORED_NODE;
33193}
33194function isAncestorRemoved(target, mirror) {
33195    if (isShadowRoot(target)) {
33196        return false;
33197    }
33198    const id = mirror.getId(target);
33199    if (!mirror.has(id)) {
33200        return true;
33201    }
33202    if (target.parentNode &&
33203        target.parentNode.nodeType === target.DOCUMENT_NODE) {
33204        return false;
33205    }
33206    if (!target.parentNode) {
33207        return true;
33208    }
33209    return isAncestorRemoved(target.parentNode, mirror);
33210}
33211function legacy_isTouchEvent(event) {
33212    return Boolean(event.changedTouches);
33213}
33214function polyfill(win = window) {
33215    if ('NodeList' in win && !win.NodeList.prototype.forEach) {
33216        win.NodeList.prototype.forEach = Array.prototype
33217            .forEach;
33218    }
33219    if ('DOMTokenList' in win && !win.DOMTokenList.prototype.forEach) {
33220        win.DOMTokenList.prototype.forEach = Array.prototype
33221            .forEach;
33222    }
33223    if (!Node.prototype.contains) {
33224        Node.prototype.contains = (...args) => {
33225            let node = args[0];
33226            if (!(0 in args)) {
33227                throw new TypeError('1 argument is required');
33228            }
33229            do {
33230                if (this === node) {
33231                    return true;
33232                }
33233            } while ((node = node && node.parentNode));
33234            return false;
33235        };
33236    }
33237}
33238function isSerializedIframe(n, mirror) {
33239    return Boolean(n.nodeName === 'IFRAME' && mirror.getMeta(n));
33240}
33241function isSerializedStylesheet(n, mirror) {
33242    return Boolean(n.nodeName === 'LINK' &&
33243        n.nodeType === n.ELEMENT_NODE &&
33244        n.getAttribute &&
33245        n.getAttribute('rel') === 'stylesheet' &&
33246        mirror.getMeta(n));
33247}
33248function hasShadowRoot(n) {
33249    return Boolean(_optionalChain$4([n, 'optionalAccess', _18 => _18.shadowRoot]));
33250}
33251class StyleSheetMirror {
33252    constructor() {
33253        this.id = 1;
33254        this.styleIDMap = new WeakMap();
33255        this.idStyleMap = new Map();
33256    }
33257    getId(stylesheet) {
33258        return _nullishCoalesce(this.styleIDMap.get(stylesheet), () => ( -1));
33259    }
33260    has(stylesheet) {
33261        return this.styleIDMap.has(stylesheet);
33262    }
33263    add(stylesheet, id) {
33264        if (this.has(stylesheet))
33265            return this.getId(stylesheet);
33266        let newId;
33267        if (id === undefined) {
33268            newId = this.id++;
33269        }
33270        else
33271            newId = id;
33272        this.styleIDMap.set(stylesheet, newId);
33273        this.idStyleMap.set(newId, stylesheet);
33274        return newId;
33275    }
33276    getStyle(id) {
33277        return this.idStyleMap.get(id) || null;
33278    }
33279    reset() {
33280        this.styleIDMap = new WeakMap();
33281        this.idStyleMap = new Map();
33282        this.id = 1;
33283    }
33284    generateId() {
33285        return this.id++;
33286    }
33287}
33288function getShadowHost(n) {
33289    let shadowHost = null;
33290    if (_optionalChain$4([n, 'access', _19 => _19.getRootNode, 'optionalCall', _20 => _20(), 'optionalAccess', _21 => _21.nodeType]) === Node.DOCUMENT_FRAGMENT_NODE &&
33291        n.getRootNode().host)
33292        shadowHost = n.getRootNode().host;
33293    return shadowHost;
33294}
33295function getRootShadowHost(n) {
33296    let rootShadowHost = n;
33297    let shadowHost;
33298    while ((shadowHost = getShadowHost(rootShadowHost)))
33299        rootShadowHost = shadowHost;
33300    return rootShadowHost;
33301}
33302function shadowHostInDom(n) {
33303    const doc = n.ownerDocument;
33304    if (!doc)
33305        return false;
33306    const shadowHost = getRootShadowHost(n);
33307    return doc.contains(shadowHost);
33308}
33309function inDom(n) {
33310    const doc = n.ownerDocument;
33311    if (!doc)
33312        return false;
33313    return doc.contains(n) || shadowHostInDom(n);
33314}
33315let cachedRequestAnimationFrameImplementation;
33316function getRequestAnimationFrameImplementation() {
33317    if (cachedRequestAnimationFrameImplementation) {
33318        return cachedRequestAnimationFrameImplementation;
33319    }
33320    const document = window.document;
33321    let requestAnimationFrameImplementation = window.requestAnimationFrame;
33322    if (document && typeof document.createElement === 'function') {
33323        try {
33324            const sandbox = document.createElement('iframe');
33325            sandbox.hidden = true;
33326            document.head.appendChild(sandbox);
33327            const contentWindow = sandbox.contentWindow;
33328            if (contentWindow && contentWindow.requestAnimationFrame) {
33329                requestAnimationFrameImplementation =
33330                    contentWindow.requestAnimationFrame;
33331            }
33332            document.head.removeChild(sandbox);
33333        }
33334        catch (e) {
33335        }
33336    }
33337    return (cachedRequestAnimationFrameImplementation =
33338        requestAnimationFrameImplementation.bind(window));
33339}
33340function onRequestAnimationFrame(...rest) {
33341    return getRequestAnimationFrameImplementation()(...rest);
33342}
33343
33344var EventType = /* @__PURE__ */ ((EventType2) => {
33345  EventType2[EventType2["DomContentLoaded"] = 0] = "DomContentLoaded";
33346  EventType2[EventType2["Load"] = 1] = "Load";
33347  EventType2[EventType2["FullSnapshot"] = 2] = "FullSnapshot";
33348  EventType2[EventType2["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
33349  EventType2[EventType2["Meta"] = 4] = "Meta";
33350  EventType2[EventType2["Custom"] = 5] = "Custom";
33351  EventType2[EventType2["Plugin"] = 6] = "Plugin";
33352  return EventType2;
33353})(EventType || {});
33354var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
33355  IncrementalSource2[IncrementalSource2["Mutation"] = 0] = "Mutation";
33356  IncrementalSource2[IncrementalSource2["MouseMove"] = 1] = "MouseMove";
33357  IncrementalSource2[IncrementalSource2["MouseInteraction"] = 2] = "MouseInteraction";
33358  IncrementalSource2[IncrementalSource2["Scroll"] = 3] = "Scroll";
33359  IncrementalSource2[IncrementalSource2["ViewportResize"] = 4] = "ViewportResize";
33360  IncrementalSource2[IncrementalSource2["Input"] = 5] = "Input";
33361  IncrementalSource2[IncrementalSource2["TouchMove"] = 6] = "TouchMove";
33362  IncrementalSource2[IncrementalSource2["MediaInteraction"] = 7] = "MediaInteraction";
33363  IncrementalSource2[IncrementalSource2["StyleSheetRule"] = 8] = "StyleSheetRule";
33364  IncrementalSource2[IncrementalSource2["CanvasMutation"] = 9] = "CanvasMutation";
33365  IncrementalSource2[IncrementalSource2["Font"] = 10] = "Font";
33366  IncrementalSource2[IncrementalSource2["Log"] = 11] = "Log";
33367  IncrementalSource2[IncrementalSource2["Drag"] = 12] = "Drag";
33368  IncrementalSource2[IncrementalSource2["StyleDeclaration"] = 13] = "StyleDeclaration";
33369  IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
33370  IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
33371  IncrementalSource2[IncrementalSource2["CustomElement"] = 16] = "CustomElement";
33372  return IncrementalSource2;
33373})(IncrementalSource || {});
33374var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
33375  MouseInteractions2[MouseInteractions2["MouseUp"] = 0] = "MouseUp";
33376  MouseInteractions2[MouseInteractions2["MouseDown"] = 1] = "MouseDown";
33377  MouseInteractions2[MouseInteractions2["Click"] = 2] = "Click";
33378  MouseInteractions2[MouseInteractions2["ContextMenu"] = 3] = "ContextMenu";
33379  MouseInteractions2[MouseInteractions2["DblClick"] = 4] = "DblClick";
33380  MouseInteractions2[MouseInteractions2["Focus"] = 5] = "Focus";
33381  MouseInteractions2[MouseInteractions2["Blur"] = 6] = "Blur";
33382  MouseInteractions2[MouseInteractions2["TouchStart"] = 7] = "TouchStart";
33383  MouseInteractions2[MouseInteractions2["TouchMove_Departed"] = 8] = "TouchMove_Departed";
33384  MouseInteractions2[MouseInteractions2["TouchEnd"] = 9] = "TouchEnd";
33385  MouseInteractions2[MouseInteractions2["TouchCancel"] = 10] = "TouchCancel";
33386  return MouseInteractions2;
33387})(MouseInteractions || {});
33388var PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {
33389  PointerTypes2[PointerTypes2["Mouse"] = 0] = "Mouse";
33390  PointerTypes2[PointerTypes2["Pen"] = 1] = "Pen";
33391  PointerTypes2[PointerTypes2["Touch"] = 2] = "Touch";
33392  return PointerTypes2;
33393})(PointerTypes || {});
33394
33395function _optionalChain$3(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
33396function isNodeInLinkedList(n) {
33397    return '__ln' in n;
33398}
33399class DoubleLinkedList {
33400    constructor() {
33401        this.length = 0;
33402        this.head = null;
33403        this.tail = null;
33404    }
33405    get(position) {
33406        if (position >= this.length) {
33407            throw new Error('Position outside of list range');
33408        }
33409        let current = this.head;
33410        for (let index = 0; index < position; index++) {
33411            current = _optionalChain$3([current, 'optionalAccess', _ => _.next]) || null;
33412        }
33413        return current;
33414    }
33415    addNode(n) {
33416        const node = {
33417            value: n,
33418            previous: null,
33419            next: null,
33420        };
33421        n.__ln = node;
33422        if (n.previousSibling && isNodeInLinkedList(n.previousSibling)) {
33423            const current = n.previousSibling.__ln.next;
33424            node.next = current;
33425            node.previous = n.previousSibling.__ln;
33426            n.previousSibling.__ln.next = node;
33427            if (current) {
33428                current.previous = node;
33429            }
33430        }
33431        else if (n.nextSibling &&
33432            isNodeInLinkedList(n.nextSibling) &&
33433            n.nextSibling.__ln.previous) {
33434            const current = n.nextSibling.__ln.previous;
33435            node.previous = current;
33436            node.next = n.nextSibling.__ln;
33437            n.nextSibling.__ln.previous = node;
33438            if (current) {
33439                current.next = node;
33440            }
33441        }
33442        else {
33443            if (this.head) {
33444                this.head.previous = node;
33445            }
33446            node.next = this.head;
33447            this.head = node;
33448        }
33449        if (node.next === null) {
33450            this.tail = node;
33451        }
33452        this.length++;
33453    }
33454    removeNode(n) {
33455        const current = n.__ln;
33456        if (!this.head) {
33457            return;
33458        }
33459        if (!current.previous) {
33460            this.head = current.next;
33461            if (this.head) {
33462                this.head.previous = null;
33463            }
33464            else {
33465                this.tail = null;
33466            }
33467        }
33468        else {
33469            current.previous.next = current.next;
33470            if (current.next) {
33471                current.next.previous = current.previous;
33472            }
33473            else {
33474                this.tail = current.previous;
33475            }
33476        }
33477        if (n.__ln) {
33478            delete n.__ln;
33479        }
33480        this.length--;
33481    }
33482}
33483const moveKey = (id, parentId) => `${id}@${parentId}`;
33484class MutationBuffer {
33485    constructor() {
33486        this.frozen = false;
vendor: 5,440 bytes, lines 33487-33615
33487        this.locked = false;
33488        this.texts = [];
33489        this.attributes = [];
33490        this.removes = [];
33491        this.mapRemoves = [];
33492        this.movedMap = {};
33493        this.addedSet = new Set();
33494        this.movedSet = new Set();
33495        this.droppedSet = new Set();
33496        this.processMutations = (mutations) => {
33497            mutations.forEach(this.processMutation);
33498            this.emit();
33499        };
33500        this.emit = () => {
33501            if (this.frozen || this.locked) {
33502                return;
33503            }
33504            const adds = [];
33505            const addedIds = new Set();
33506            const addList = new DoubleLinkedList();
33507            const getNextId = (n) => {
33508                let ns = n;
33509                let nextId = IGNORED_NODE;
33510                while (nextId === IGNORED_NODE) {
33511                    ns = ns && ns.nextSibling;
33512                    nextId = ns && this.mirror.getId(ns);
33513                }
33514                return nextId;
33515            };
33516            const pushAdd = (n) => {
33517                if (!n.parentNode || !inDom(n)) {
33518                    return;
33519                }
33520                const parentId = isShadowRoot(n.parentNode)
33521                    ? this.mirror.getId(getShadowHost(n))
33522                    : this.mirror.getId(n.parentNode);
33523                const nextId = getNextId(n);
33524                if (parentId === -1 || nextId === -1) {
33525                    return addList.addNode(n);
33526                }
33527                const sn = serializeNodeWithId(n, {
33528                    doc: this.doc,
33529                    mirror: this.mirror,
33530                    blockClass: this.blockClass,
33531                    blockSelector: this.blockSelector,
33532                    maskAllText: this.maskAllText,
33533                    unblockSelector: this.unblockSelector,
33534                    maskTextClass: this.maskTextClass,
33535                    unmaskTextClass: this.unmaskTextClass,
33536                    maskTextSelector: this.maskTextSelector,
33537                    unmaskTextSelector: this.unmaskTextSelector,
33538                    skipChild: true,
33539                    newlyAddedElement: true,
33540                    inlineStylesheet: this.inlineStylesheet,
33541                    maskInputOptions: this.maskInputOptions,
33542                    maskAttributeFn: this.maskAttributeFn,
33543                    maskTextFn: this.maskTextFn,
33544                    maskInputFn: this.maskInputFn,
33545                    slimDOMOptions: this.slimDOMOptions,
33546                    dataURLOptions: this.dataURLOptions,
33547                    recordCanvas: this.recordCanvas,
33548                    inlineImages: this.inlineImages,
33549                    onSerialize: (currentN) => {
33550                        if (isSerializedIframe(currentN, this.mirror)) {
33551                            this.iframeManager.addIframe(currentN);
33552                        }
33553                        if (isSerializedStylesheet(currentN, this.mirror)) {
33554                            this.stylesheetManager.trackLinkElement(currentN);
33555                        }
33556                        if (hasShadowRoot(n)) {
33557                            this.shadowDomManager.addShadowRoot(n.shadowRoot, this.doc);
33558                        }
33559                    },
33560                    onIframeLoad: (iframe, childSn) => {
33561                        this.iframeManager.attachIframe(iframe, childSn);
33562                        this.shadowDomManager.observeAttachShadow(iframe);
33563                    },
33564                    onStylesheetLoad: (link, childSn) => {
33565                        this.stylesheetManager.attachLinkElement(link, childSn);
33566                    },
33567                });
33568                if (sn) {
33569                    adds.push({
33570                        parentId,
33571                        nextId,
33572                        node: sn,
33573                    });
33574                    addedIds.add(sn.id);
33575                }
33576            };
33577            while (this.mapRemoves.length) {
33578                this.mirror.removeNodeFromMap(this.mapRemoves.shift());
33579            }
33580            for (const n of this.movedSet) {
33581                if (isParentRemoved(this.removes, n, this.mirror) &&
33582                    !this.movedSet.has(n.parentNode)) {
33583                    continue;
33584                }
33585                pushAdd(n);
33586            }
33587            for (const n of this.addedSet) {
33588                if (!isAncestorInSet(this.droppedSet, n) &&
33589                    !isParentRemoved(this.removes, n, this.mirror)) {
33590                    pushAdd(n);
33591                }
33592                else if (isAncestorInSet(this.movedSet, n)) {
33593                    pushAdd(n);
33594                }
33595                else {
33596                    this.droppedSet.add(n);
33597                }
33598            }
33599            let candidate = null;
33600            while (addList.length) {
33601                let node = null;
33602                if (candidate) {
33603                    const parentId = this.mirror.getId(candidate.value.parentNode);
33604                    const nextId = getNextId(candidate.value);
33605                    if (parentId !== -1 && nextId !== -1) {
33606                        node = candidate;
33607                    }
33608                }
33609                if (!node) {
33610                    let tailNode = addList.tail;
33611                    while (tailNode) {
33612                        const _node = tailNode;
33613                        tailNode = tailNode.previous;
33614                        if (_node) {
33615                            const parentId = this.mirror.getId(_no
33615de.value.parentNode);
33616                            const nextId = getNextId(_node.value);
33617                            if (nextId === -1)
33618                                continue;
33619                            else if (parentId !== -1) {
33620                                node = _node;
33621                                break;
33622                            }
33623                            else {
33624                                const unhandledNode = _node.value;
33625                                if (unhandledNode.parentNode &&
33626                                    unhandledNode.parentNode.nodeType ===
33627                                        Node.DOCUMENT_FRAGMENT_NODE) {
33628                                    const shadowHost = unhandledNode.parentNode
33629                                        .host;
33630                                    const parentId = this.mirror.getId(shadowHost);
33631                                    if (parentId !== -1) {
33632                                        node = _node;
33633                                        break;
33634                                    }
33635                                }
33636                            }
33637                        }
33638                    }
33639                }
33640                if (!node) {
33641                    while (addList.head) {
33642                        addList.removeNode(addList.head.value);
33643                    }
33644                    break;
33645                }
33646                candidate = node.previous;
33647                addList.removeNode(node.value);
33648                pushAdd(node.value);
33649            }
33650            const payload = {
33651                texts: this.texts
33652                    .map((text) => ({
33653                    id: this.mirror.getId(text.node),
33654                    value: text.value,
33655                }))
33656                    .filter((text) => !addedIds.has(text.id))
33657                    .filter((text) => this.mirror.has(text.id)),
33658                attributes: this.attributes
33659                    .map((attribute) => {
33660                    const { attributes } = attribute;
33661                    if (typeof attributes.style === 'string') {
33662                        const diffAsStr = JSON.stringify(attribute.styleDiff);
33663                        const unchangedAsStr = JSON.stringify(attribute._unchangedStyles);
33664                        if (diffAsStr.length < attributes.style.length) {
33665                            if ((diffAsStr + unchangedAsStr).split('var(').length ===
33666                                attributes.style.split('var(').length) {
33667                                attributes.style = attribute.styleDiff;
33668                            }
33669                        }
33670                    }
33671                    return {
33672                        id: this.mirror.getId(attribute.node),
33673                        attributes: attributes,
33674                    };
33675                })
33676                    .filter((attribute) => !addedIds.has(attribute.id))
33677                    .filter((attribute) => this.mirror.has(attribute.id)),
33678                removes: this.removes,
33679                adds,
33680            };
33681            if (!payload.texts.length &&
33682                !payload.attributes.length &&
33683                !payload.removes.length &&
33684                !payload.adds.length) {
33685                return;
33686            }
33687            this.texts = [];
33688            this.attributes = [];
33689            this.removes = [];
33690            this.addedSet = new Set();
33691            this.movedSet = new Set();
33692            this.droppedSet = new Set();
33693            this.movedMap = {};
33694            this.mutationCb(payload);
33695        };
33696        this.processMutation = (m) => {
33697            if (isIgnored(m.target, this.mirror)) {
33698                return;
33699            }
33700            let unattachedDoc;
33701            try {
33702                unattachedDoc = document.implementation.createHTMLDocument();
33703            }
33704            catch (e) {
33705                unattachedDoc = this.doc;
33706            }
33707            switch (m.type) {
33708                case 'characterData': {
33709                    const value = m.target.textContent;
33710                    if (!isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) &&
33711                        value !== m.oldValue) {
33712                        this.texts.push({
33713                            value: needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextClass, this.unmaskTextSelector, this.maskAllText) && value
33714                                ? this.maskTextFn
33715                                    ? this.maskTextFn(value)
33716                                    : value.replace(/[\S]/g, '*')
33717                                : value,
33718                            node: m.target,
33719                        });
33720                    }
33721                    break;
33722                }
33723                case 'attributes': {
33724                    const target = m.target;
33725                    let attributeName = m.attributeName;
33726                    let value = m.target.getAttribute(attributeName);
33727                    if (attributeName === 'value') {
33728                        const type = getInputType(target);
33729                        const tagName = target.tagName;
33730                        value = getInputValue(target, tagName, type);
33731                        const isInputMasked = shouldMaskInput({
33732                            maskInputOptions: this.maskInputOptions,
33733                            tagName,
33734                            type,
33735                        });
33736                        const forceMask = needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextClass, this.unmaskTextSelector, isInputMasked);
33737                        value = maskInputValue({
33738                            isMasked: forceMask,
33739                            element: target,
33740                            value,
33741                            maskInputFn: this.maskInputFn,
33742                        });
33743                    }
33744                    if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) ||
33745                        value === m.oldValue) {
33746                        return;
33747                    }
33748                    let item = this.attributes.find((a) => a.node === m.target);
33749                    if (target.tagName === 'IFRAME' &&
33750                        attributeName === 'src' &&
33751                        !this.keepIframeSrcFn(value)) {
33752                        if (!target.contentDocument) {
33753                            attributeName = 'rr_src';
33754                        }
33755                        else {
33756                            return;
33757                        }
33758                    }
33759                    if (!item) {
33760                        item = {
33761                            node: m.target,
33762                            attributes: {},
33763                            styleDiff: {},
33764                            _unchangedStyles: {},
33765                        };
33766                        this.attributes.push(item);
33767                    }
33768                    if (attributeName === 'type' &&
33769                        target.tagName === 'INPUT' &&
33770                        (m.oldValue || '').toLowerCase() === 'password') {
33771                        target.setAttribute('data-rr-is-password', 'true');
33772                    }
33773                    if (!ignoreAttribute(target.tagName, attributeName)) {
33774                        item.attributes[attributeName] = transformAttribute(this.doc, toLowerCase(target.tagName), toLowerCase(attributeName), value, target, this.maskAttributeFn);
33775                        if (attributeName === 'style') {
33776                            const old = unattachedDoc.createElement('span');
33777                            if (m.oldValue) {
33778                                old.setAttribute('style', m.oldValue);
33779                            }
33780                            for (const pname of Array.from(target.style)) {
33781                                const newValue = target.style.getPropertyValue(pname);
33782                                const newPriority = target.style.getPropertyPriority(pname);
33783                                if (newValue !== old.style.getPropertyValue(pname) ||
33784                                    newPriority !== old.style.getPropertyPriority(pname)) {
33785                                    if (newPriority === '') {
33786                                        item.styleDiff[pname] = newValue;
33787                                    }
33788                                    else {
33789                                        item.styleDiff[pname] = [newValue, newPriority];
33790                                    }
33791                                }
33792                                else {
33793                                    item._unchangedStyles[pname] = [newValue, newPriority];
33794                                }
33795                            }
33796                            for (const pname of Array.from(old.style)) {
33797                                if (target.style.getPropertyValue(pname) === '') {
33798                                    item.styleDiff[pname] = false;
33799                                }
33800                            }
33801                        }
33802                    }
33803                    break;
33804                }
33805                case 'childList': {
33806                    if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, true)) {
33807                        return;
33808                    }
33809                    m.addedNodes.forEach((n) => this.genAdds(n, m.target));
33810                    m.removedNodes.forEach((n) => {
33811                        const nodeId = this.mirror.getId(n);
33812                        const parentId = isShadowRoot(m.target)
33813                            ? this.mirror.getId(m.target.host)
33814                            : this.mirror.getId(m.target);
33815                        if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) ||
33816                            isIgnored(n, this.mirror) ||
33817                            !isSerialized(n, this.mirror)) {
33818                            return;
33819                        }
33820                        if (this.addedSet.has(n)) {
33821                            deepDelete(this.addedSet, n);
33822                            this.droppedSet.add(n);
33823                        }
33824                        else if (this.addedSet.has(m.target) && nodeId === -1) ;
33825                        else if (isAncestorRemoved(m.target, this.mirror)) ;
33826                        else if (this.movedSet.has(n) &&
33827                            this.movedMap[moveKey(nodeId, parentId)]) {
33828                            deepDelete(this.movedSet, n);
33829                        }
33830                        else {
33831                            this.removes.push({
33832                                parentId,
33833                                id: nodeId,
33834                                isShadow: isShadowRoot(m.target) && isNativeShadowDom(m.target)
33835                                    ? true
33836                                    : undefined,
33837                            });
33838                        }
33839                        this.mapRemoves.push(n);
33840                    });
33841                    break;
33842                }
33843            }
33844        };
33845        this.genAdds = (n, target) => {
33846            if (this.processedNodeManager.inOtherBuffer(n, this))
33847                return;
33848            if (this.addedSet.has(n) || this.movedSet.has(n))
33849                return;
33850            if (this.mirror.hasNode(n)) {
33851                if (isIgnored(n, this.mirror)) {
33852                    return;
33853                }
33854                this.movedSet.add(n);
33855                let targetId = null;
33856                if (target && this.mirror.hasNode(target)) {
33857                    targetId = this.mirror.getId(target);
33858                }
33859                if (targetId && targetId !== -1) {
33860                    this.movedMap[moveKey(this.mirror.getId(n), targetId)] = true;
33861                }
33862            }
33863            else {
33864                this.addedSet.add(n);
33865                this.droppedSet.delete(n);
33866            }
33867            if (!isBlocked(n, this.blockClass, this.blockSelector, this.unblockSelector, false)) {
33868                n.childNodes.forEach((childN) => this.genAdds(childN));
33869                if (hasShadowRoot(n)) {
33870                    n.shadowRoot.childNodes.forEach((childN) => {
33871                        this.processedNodeManager.add(childN, this);
33872                        this.genAdds(childN, n);
33873                    });
33874                }
33875            }
33876        };
33877    }
33878    init(options) {
33879        [
33880            'mutationCb',
33881            'blockClass',
33882            'blockSelector',
33883            'unblockSelector',
33884            'maskAllText',
33885            'maskTextClass',
33886            'unmaskTextClass',
33887            'maskTextSelector',
33888            'unmaskTextSelector',
33889            'inlineStylesheet',
33890            'maskInputOptions',
33891            'maskAttributeFn',
33892            'maskTextFn',
33893            'maskInputFn',
33894            'keepIframeSrcFn',
33895            'recordCanvas',
33896            'inlineImages',
33897            'slimDOMOptions',
33898            'dataURLOptions',
33899            'doc',
33900            'mirror',
33901            'iframeManager',
33902            'stylesheetManager',
33903            'shadowDomManager',
33904            'canvasManager',
33905            'processedNodeManager',
33906        ].forEach((key) => {
33907            this[key] = options[key];
33908        });
33909    }
33910    freeze() {
33911        this.frozen = true;
33912        this.canvasManager.freeze();
33913    }
33914    unfreeze() {
33915        this.frozen = false;
33916        this.canvasManager.unfreeze();
33917        this.emit();
33918    }
33919    isFrozen() {
33920        return this.frozen;
33921    }
33922    lock() {
33923        this.locked = true;
33924        this.canvasManager.lock();
33925    }
33926    unlock() {
33927        this.locked = false;
33928        this.canvasManager.unlock();
33929        this.emit();
33930    }
33931    reset() {
33932        this.shadowDomManager.reset();
33933        this.canvasManager.reset();
33934    }
33935}
33936function deepDelete(addsSet, n) {
33937    addsSet.delete(n);
33938    n.childNodes.forEach((childN) => deepDelete(addsSet, childN));
33939}
33940function isParentRemoved(removes, n, mirror) {
33941    if (removes.length === 0)
33942        return false;
33943    return _isParentRemoved(removes, n, mirror);
33944}
33945function _isParentRemoved(removes, n, mirror) {
33946    const { parentNode } = n;
33947    if (!parentNode) {
33948        return false;
33949    }
33950    const parentId = mirror.getId(parentNode);
33951    if (removes.some((r) => r.id === parentId)) {
33952        return true;
33953    }
33954    return _isParentRemoved(removes, parentNode, mirror);
33955}
33956function isAncestorInSet(set, n) {
33957    if (set.size === 0)
33958        return false;
33959    return _isAncestorInSet(set, n);
33960}
33961function _isAncestorInSet(set, n) {
33962    const { parentNode } = n;
33963    if (!parentNode) {
33964        return false;
33965    }
33966    if (set.has(parentNode)) {
33967        return true;
33968    }
33969    return _isAncestorInSet(set, parentNode);
33970}
33971
33972let errorHandler;
33973function registerErrorHandler(handler) {
33974    errorHandler = handler;
33975}
33976function unregisterErrorHandler() {
33977    errorHandler = undefined;
33978}
33979const callbackWrapper = (cb) => {
33980    if (!errorHandler) {
33981        return cb;
33982    }
33983    const rrwebWrapped = ((...rest) => {
33984        try {
33985            return cb(...rest);
33986        }
33987        catch (error) {
33988            if (errorHandler && errorHandler(error) === true) {
33989                return () => {
33990                };
33991            }
33992            throw error;
33993        }
33994    });
33995    return rrwebWrapped;
33996};
33997
33998function _optionalChain$2(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
33999const mutationBuffers = [];
34000function getEventTarget(event) {
34001    try {
34002        if ('composedPath' in event) {
34003            const path = event.composedPath();
34004            if (path.length) {
34005                return path[0];
34006            }
34007        }
34008        else if ('path' in event && event.path.length) {
34009            return event.path[0];
34010        }
34011    }
34012    catch (e2) {
34013    }
34014    return event && event.target;
34015}
34016function initMutationObserver(options, rootEl) {
34017    const mutationBuffer = new MutationBuffer();
34018    mutationBuffers.push(mutationBuffer);
34019    mutationBuffer.init(options);
34020    let mutationObserverCtor = window.MutationObserver ||
34021        window.__rrMutationObserver;
34022    const angularZoneSymbol = _optionalChain$2([window, 'optionalAccess', _ => _.Zone, 'optionalAccess', _2 => _2.__symbol__, 'optionalCall', _3 => _3('MutationObserver')]);
34023    if (angularZoneSymbol &&
34024        window[angularZoneSymbol]) {
34025        mutationObserverCtor = window[angularZoneSymbol];
34026    }
34027    const observer = new mutationObserverCtor(callbackWrapper((mutations) => {
34028        if (options.onMutation && options.onMutation(mutations) === false) {
34029            return;
34030        }
34031        mutationBuffer.processMutations.bind(mutationBuffer)(mutations);
34032    }));
34033    observer.observe(rootEl, {
34034        attributes: true,
34035        attributeOldValue: true,
34036        characterData: true,
34037        characterDataOldValue: true,
34038        childList: true,
34039        subtree: true,
34040    });
34041    return observer;
34042}
34043function initMoveObserver({ mousemoveCb, sampling, doc, mirror, }) {
34044    if (sampling.mousemove === false) {
34045        return () => {
34046        };
34047    }
34048    const threshold = typeof sampling.mousemove === 'number' ? sampling.mousemove : 50;
34049    const callbackThreshold = typeof sampling.mousemoveCallback === 'number'
34050        ? sampling.mousemoveCallback
34051        : 500;
34052    let positions = [];
34053    let timeBaseline;
34054    const wrappedCb = throttle$1(callbackWrapper((source) => {
34055        const totalOffset = Date.now() - timeBaseline;
34056        mousemoveCb(positions.map((p) => {
34057            p.timeOffset -= totalOffset;
34058            return p;
34059        }), source);
34060        positions = [];
34061        timeBaseline = null;
34062    }), callbackThreshold);
34063    const updatePosition = callbackWrapper(throttle$1(callbackWrapper((evt) => {
34064        const target = getEventTarget(evt);
34065        const { clientX, clientY } = legacy_isTouchEvent(evt)
34066            ? evt.changedTouches[0]
34067            : evt;
34068        if (!timeBaseline) {
34069            timeBaseline = nowTimestamp();
34070        }
34071        positions.push({
34072            x: clientX,
34073            y: clientY,
34074            id: mirror.getId(target),
34075            timeOffset: nowTimestamp() - timeBaseline,
34076        });
34077        wrappedCb(typeof DragEvent !== 'undefined' && evt instanceof DragEvent
34078            ? IncrementalSource.Drag
34079            : evt instanceof MouseEvent
34080                ? IncrementalSource.MouseMove
34081                : IncrementalSource.TouchMove);
34082    }), threshold, {
34083        trailing: false,
34084    }));
34085    const handlers = [
34086        on('mousemove', updatePosition, doc),
34087        on('touchmove', updatePosition, doc),
34088        on('drag', updatePosition, doc),
34089    ];
34090    return callbackWrapper(() => {
34091        handlers.forEach((h) => h());
34092    });
34093}
34094function initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockClass, blockSelector, unblockSelector, sampling, }) {
34095    if (sampling.mouseInteraction === false) {
34096        return () => {
34097        };
34098    }
34099    const disableMap = sampling.mouseInteraction === true ||
34100        sampling.mouseInteraction === undefined
34101        ? {}
34102        : sampling.mouseInteraction;
34103    const handlers = [];
34104    let currentPointerType = null;
34105    const getHandler = (eventKey) => {
34106        return (event) => {
34107            const target = getEventTarget(event);
34108            if (isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
34109                return;
34110            }
34111            let pointerType = null;
34112            let thisEventKey = eventKey;
34113            if ('pointerType' in event) {
34114                switch (event.pointerType) {
34115                    case 'mouse':
34116                        pointerType = PointerTypes.Mouse;
34117                        break;
34118                    case 'touch':
34119                        pointerType = PointerTypes.Touch;
34120                        break;
34121                    case 'pen':
34122                        pointerType = PointerTypes.Pen;
34123                        break;
34124                }
34125                if (pointerType === PointerTypes.Touch) {
34126                    if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {
34127                        thisEventKey = 'TouchStart';
34128                    }
34129                    else if (MouseInteractions[eventKey] === MouseInteractions.MouseUp) {
34130                        thisEventKey = 'TouchEnd';
34131                    }
34132                }
34133                else if (pointerType === PointerTypes.Pen) ;
34134            }
34135            else if (legacy_isTouchEvent(event)) {
34136                pointerType = PointerTypes.Touch;
34137            }
34138            if (pointerType !== null) {
34139                currentPointerType = pointerType;
34140                if ((thisEventKey.startsWith('Touch') &&
34141                    pointerType === PointerTypes.Touch) ||
34142                    (thisEventKey.startsWith('Mouse') &&
34143                        pointerType === PointerTypes.Mouse)) {
34144                    pointerType = null;
34145                }
34146            }
34147            else if (MouseInteractions[eventKey] === MouseInteractions.Click) {
34148                pointerType = currentPointerType;
34149                currentPointerType = null;
34150            }
34151            const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;
34152            if (!e) {
34153                return;
34154            }
34155            const id = mirror.getId(target);
34156            const { clientX, clientY } = e;
34157            callbackWrapper(mouseInteractionCb)({
34158                type: MouseInteractions[thisEventKey],
34159                id,
34160                x: clientX,
34161                y: clientY,
34162                ...(pointerType !== null && { pointerType }),
34163            });
34164        };
34165    };
34166    Object.keys(MouseInteractions)
34167        .filter((key) => Number.isNaN(Number(key)) &&
34168        !key.endsWith('_Departed') &&
34169        disableMap[key] !== false)
34170        .forEach((eventKey) => {
34171        let eventName = toLowerCase(eventKey);
34172        const handler = getHandler(eventKey);
34173        if (window.PointerEvent) {
34174            switch (MouseInteractions[eventKey]) {
34175                case MouseInteractions.MouseDown:
34176                case MouseInteractions.MouseUp:
34177                    eventName = eventName.replace('mouse', 'pointer');
34178                    break;
34179                case MouseInteractions.TouchStart:
34180                case MouseInteractions.TouchEnd:
34181                    return;
34182            }
34183        }
34184        handlers.push(on(eventName, handler, doc));
34185    });
34186    return callbackWrapper(() => {
34187        handlers.forEach((h) => h());
34188    });
34189}
34190function initScrollObserver({ scrollCb, doc, mirror, blockClass, blockSelector, unblockSelector, sampling, }) {
34191    const updatePosition = callbackWrapper(throttle$1(callbackWrapper((evt) => {
34192        const target = getEventTarget(evt);
34193        if (!target ||
34194            isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
34195            return;
34196        }
34197        const id = mirror.getId(target);
34198        if (target === doc && doc.defaultView) {
34199            const scrollLeftTop = getWindowScroll(doc.defaultView);
34200            scrollCb({
34201                id,
34202                x: scrollLeftTop.left,
34203                y: scrollLeftTop.top,
34204            });
34205        }
34206        else {
34207            scrollCb({
34208                id,
34209                x: target.scrollLeft,
34210                y: target.scrollTop,
34211            });
34212        }
34213    }), sampling.scroll || 100));
34214    return on('scroll', updatePosition, doc);
34215}
34216function initViewportResizeObserver({ viewportResizeCb }, { win }) {
34217    let lastH = -1;
34218    let lastW = -1;
34219    const updateDimension = callbackWrapper(throttle$1(callbackWrapper(() => {
34220        const height = getWindowHeight();
34221        const width = getWindowWidth();
34222        if (lastH !== height || lastW !== width) {
34223            viewportResizeCb({
34224                width: Number(width),
34225                height: Number(height),
34226            });
34227            lastH = height;
34228            lastW = width;
34229        }
34230    }), 200));
34231    return on('resize', updateDimension, win);
34232}
34233const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
34234const lastInputValueMap = new WeakMap();
34235function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, unblockSelector, ignoreClass, ignoreSelector, maskInputOptions, maskInputFn, sampling, userTriggeredOnInput, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, }) {
34236    function eventHandler(event) {
34237        let target = getEventTarget(event);
34238        const userTriggered = event.isTrusted;
34239        const tagName = target && toUpperCase(target.tagName);
34240        if (tagName === 'OPTION')
34241            target = target.parentElement;
34242        if (!target ||
34243            !tagName ||
34244            INPUT_TAGS.indexOf(tagName) < 0 ||
34245            isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
34246            return;
34247        }
34248        const el = target;
34249        if (el.classList.contains(ignoreClass) ||
34250            (ignoreSelector && el.matches(ignoreSelector))) {
34251            return;
34252        }
34253        const type = getInputType(target);
34254        let text = getInputValue(el, tagName, type);
34255        let isChecked = false;
34256        const isInputMasked = shouldMaskInput({
34257            maskInputOptions,
34258            tagName,
34259            type,
34260        });
34261        const forceMask = needMaskingText(target, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked);
34262        if (type === 'radio' || type === 'checkbox') {
34263            isChecked = target.checked;
34264        }
34265        text = maskInputValue({
34266            isMasked: forceMask,
34267            element: target,
34268            value: text,
34269            maskInputFn,
34270        });
34271        cbWithDedup(target, userTriggeredOnInput
34272            ? { text, isChecked, userTriggered }
34273            : { text, isChecked });
34274        const name = target.name;
34275        if (type === 'radio' && name && isChecked) {
34276            doc
34277                .querySelectorAll(`input[type="radio"][name="${name}"]`)
34278                .forEach((el) => {
34279                if (el !== target) {
34280                    const text = maskInputValue({
34281                        isMasked: forceMask,
34282                        element: el,
34283                        value: getInputValue(el, tagName, type),
34284                        maskInputFn,
34285                    });
34286                    cbWithDedup(el, userTriggeredOnInput
34287                        ? { text, isChecked: !isChecked, userTriggered: false }
34288                        : { text, isChecked: !isChecked });
34289                }
34290            });
34291        }
34292    }
34293    function cbWithDedup(target, v) {
34294        const lastInputValue = lastInputValueMap.get(target);
34295        if (!lastInputValue ||
34296            lastInputValue.text !== v.text ||
34297            lastInputValue.isChecked !== v.isChecked) {
34298            lastInputValueMap.set(target, v);
34299            const id = mirror.getId(target);
34300            callbackWrapper(inputCb)({
34301                ...v,
34302                id,
34303            });
34304        }
34305    }
34306    const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];
34307    const handlers = events.map((eventName) => on(eventName, callbackWrapper(eventHandler), doc));
34308    const currentWindow = doc.defaultView;
34309    if (!currentWindow) {
34310        return () => {
34311            handlers.forEach((h) => h());
34312        };
34313    }
34314    const propertyDescriptor = currentWindow.Object.getOwnPropertyDescriptor(currentWindow.HTMLInputElement.prototype, 'value');
34315    const hookProperties = [
34316        [currentWindow.HTMLInputElement.prototype, 'value'],
34317        [currentWindow.HTMLInputElement.prototype, 'checked'],
34318        [currentWindow.HTMLSelectElement.prototype, 'value'],
34319        [currentWindow.HTMLTextAreaElement.prototype, 'value'],
34320        [currentWindow.HTMLSelectElement.prototype, 'selectedIndex'],
34321        [currentWindow.HTMLOptionElement.prototype, 'selected'],
34322    ];
34323    if (propertyDescriptor && propertyDescriptor.set) {
34324        handlers.push(...hookProperties.map((p) => hookSetter(p[0], p[1], {
34325            set() {
34326                callbackWrapper(eventHandler)({
34327                    target: this,
34328                    isTrusted: false,
34329                });
34330            },
34331        }, false, currentWindow)));
34332    }
34333    return callbackWrapper(() => {
34334        handlers.forEach((h) => h());
34335    });
34336}
34337function getNestedCSSRulePositions(rule) {
34338    const positions = [];
34339    function recurse(childRule, pos) {
34340        if ((hasNestedCSSRule('CSSGroupingRule') &&
34341            childRule.parentRule instanceof CSSGroupingRule) ||
34342            (hasNestedCSSRule('CSSMediaRule') &&
34343                childRule.parentRule instanceof CSSMediaRule) ||
34344            (hasNestedCSSRule('CSSSupportsRule') &&
34345                childRule.parentRule instanceof CSSSupportsRule) ||
34346            (hasNestedCSSRule('CSSConditionRule') &&
34347                childRule.parentRule instanceof CSSConditionRule)) {
34348            const rules = Array.from(childRule.parentRule.cssRules);
34349            const index = rules.indexOf(childRule);
34350            pos.unshift(index);
34351        }
34352        else if (childRule.parentStyleSheet) {
34353            const rules = Array.from(childRule.parentStyleSheet.cssRules);
34354            const index = rules.indexOf(childRule);
34355            pos.unshift(index);
34356        }
34357        return pos;
34358    }
34359    return recurse(rule, positions);
34360}
34361function getIdAndStyleId(sheet, mirror, styleMirror) {
34362    let id, styleId;
34363    if (!sheet)
34364        return {};
34365    if (sheet.ownerNode)
34366        id = mirror.getId(sheet.ownerNode);
34367    else
34368        styleId = styleMirror.getId(sheet);
34369    return {
34370        styleId,
34371        id,
34372    };
34373}
34374function initStyleSheetObserver({ styleSheetRuleCb, mirror, stylesheetManager }, { win }) {
34375    if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {
34376        return () => {
34377        };
34378    }
34379    const insertRule = win.CSSStyleSheet.prototype.insertRule;
34380    win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {
34381        apply: callbackWrapper((target, thisArg, argumentsList) => {
34382            const [rule, index] = argumentsList;
34383            const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
34384            if ((id && id !== -1) || (styleId && styleId !== -1)) {
34385                styleSheetRuleCb({
34386                    id,
34387                    styleId,
34388                    adds: [{ rule, index }],
34389                });
34390            }
34391            return target.apply(thisArg, argumentsList);
34392        }),
34393    });
34394    const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
34395    win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {
34396        apply: callbackWrapper((target, thisArg, argumentsList) => {
34397            const [index] = argumentsList;
34398            const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
34399            if ((id && id !== -1) || (styleId && styleId !== -1)) {
34400                styleSheetRuleCb({
34401                    id,
34402                    styleId,
34403                    removes: [{ index }],
34404                });
34405            }
34406            return target.apply(thisArg, argumentsList);
34407        }),
34408    });
34409    let replace;
34410    if (win.CSSStyleSheet.prototype.replace) {
34411        replace = win.CSSStyleSheet.prototype.replace;
34412        win.CSSStyleSheet.prototype.replace = new Proxy(replace, {
34413            apply: callbackWrapper((target, thisArg, argumentsList) => {
34414                const [text] = argumentsList;
34415                const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
34416                if ((id && id !== -1) || (styleId && styleId !== -1)) {
34417                    styleSheetRuleCb({
34418                        id,
34419                        styleId,
34420                        replace: text,
34421                    });
34422                }
34423                return target.apply(thisArg, argumentsList);
34424            }),
34425        });
34426    }
34427    let replaceSync;
34428    if (win.CSSStyleSheet.prototype.replaceSync) {
34429        replaceSync = win.CSSStyleSheet.prototype.replaceSync;
34430        win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {
34431            apply: callbackWrapper((target, thisArg, argumentsList) => {
34432                const [text] = argumentsList;
34433                const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
34434                if ((id && id !== -1) || (styleId && styleId !== -1)) {
34435                    styleSheetRuleCb({
34436                        id,
34437                        styleId,
34438                        replaceSync: text,
34439                    });
34440                }
34441                return target.apply(thisArg, argumentsList);
34442            }),
34443        });
34444    }
34445    const supportedNestedCSSRuleTypes = {};
34446    if (canMonkeyPatchNestedCSSRule('CSSGroupingRule')) {
34447        supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;
34448    }
34449    else {
34450        if (canMonkeyPatchNestedCSSRule('CSSMediaRule')) {
34451            supportedNestedCSSRuleTypes.CSSMediaRule = win.CSSMediaRule;
34452        }
34453        if (canMonkeyPatchNestedCSSRule('CSSConditionRule')) {
34454            supportedNestedCSSRuleTypes.CSSConditionRule = win.CSSConditionRule;
34455        }
34456        if (canMonkeyPatchNestedCSSRule('CSSSupportsRule')) {
34457            supportedNestedCSSRuleTypes.CSSSupportsRule = win.CSSSupportsRule;
34458        }
34459    }
34460    const unmodifiedFunctions = {};
34461    Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
34462        unmodifiedFunctions[typeKey] = {
34463            insertRule: type.prototype.insertRule,
34464            deleteRule: type.prototype.deleteRule,
34465        };
34466        type.prototype.insertRule = new Proxy(unmodifiedFunctions[typeKey].insertRule, {
34467            apply: callbackWrapper((target, thisArg, argumentsList) => {
34468                const [rule, index] = argumentsList;
34469                const { id, styleId } = getIdAndStyleId(thisArg.parentStyleSheet, mirror, stylesheetManager.styleMirror);
34470                if ((id && id !== -1) || (styleId && styleId !== -1)) {
34471                    styleSheetRuleCb({
34472                        id,
34473                        styleId,
34474                        adds: [
34475                            {
34476                                rule,
34477                                index: [
34478                                    ...getNestedCSSRulePositions(thisArg),
34479                                    index || 0,
34480                                ],
34481                            },
34482                        ],
34483                    });
34484                }
34485                return target.apply(thisArg, argumentsList);
34486            }),
34487        });
34488        type.prototype.deleteRule = new Proxy(unmodifiedFunctions[typeKey].deleteRule, {
34489            apply: callbackWrapper((target, thisArg, argumentsList) => {
34490                const [index] = argumentsList;
34491                const { id, styleId } = getIdAndStyleId(thisArg.parentStyleSheet, mirror, stylesheetManager.styleMirror);
34492                if ((id && id !== -1) || (styleId && styleId !== -1)) {
34493                    styleSheetRuleCb({
34494                        id,
34495                        styleId,
34496                        removes: [
34497                            { index: [...getNestedCSSRulePositions(thisArg), index] },
34498                        ],
34499                    });
34500                }
34501                return target.apply(thisArg, argumentsList);
34502            }),
34503        });
34504    });
34505    return callbackWrapper(() => {
34506        win.CSSStyleSheet.prototype.insertRule = insertRule;
34507        win.CSSStyleSheet.prototype.deleteRule = deleteRule;
34508        replace && (win.CSSStyleSheet.prototype.replace = replace);
34509        replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);
34510        Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
34511            type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;
34512            type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;
34513        });
34514    });
34515}
34516function initAdoptedStyleSheetObserver({ mirror, stylesheetManager, }, host) {
34517    let hostId = null;
34518    if (host.nodeName === '#document')
34519        hostId = mirror.getId(host);
34520    else
34521        hostId = mirror.getId(host.host);
34522    const patchTarget = host.nodeName === '#document'
34523        ? _optionalChain$2([host, 'access', _4 => _4.defaultView, 'optionalAccess', _5 => _5.Document])
34524        : _optionalChain$2([host, 'access', _6 => _6.ownerDocument, 'optionalAccess', _7 => _7.defaultView, 'optionalAccess', _8 => _8.ShadowRoot]);
34525    const originalPropertyDescriptor = _optionalChain$2([patchTarget, 'optionalAccess', _9 => _9.prototype])
34526        ? Object.getOwnPropertyDescriptor(_optionalChain$2([patchTarget, 'optionalAccess', _10 => _10.prototype]), 'adoptedStyleSheets')
34527        : undefined;
34528    if (hostId === null ||
34529        hostId === -1 ||
34530        !patchTarget ||
34531        !originalPropertyDescriptor)
34532        return () => {
34533        };
34534    Object.defineProperty(host, 'adoptedStyleSheets', {
34535        configurable: originalPropertyDescriptor.configurable,
34536        enumerable: originalPropertyDescriptor.enumerable,
34537        get() {
34538            return _optionalChain$2([originalPropertyDescriptor, 'access', _11 => _11.get, 'optionalAccess', _12 => _12.call, 'call', _13 => _13(this)]);
34539        },
34540        set(sheets) {
34541            const result = _optionalChain$2([originalPropertyDescriptor, 'access', _14 => _14.set, 'optionalAccess', _15 => _15.call, 'call', _16 => _16(this, sheets)]);
34542            if (hostId !== null && hostId !== -1) {
34543                try {
34544                    stylesheetManager.adoptStyleSheets(sheets, hostId);
34545                }
34546                catch (e) {
34547                }
34548            }
34549            return result;
34550        },
34551    });
34552    return callbackWrapper(() => {
34553        Object.defineProperty(host, 'adoptedStyleSheets', {
34554            configurable: originalPropertyDescriptor.configurable,
34555            enumerable: originalPropertyDescriptor.enumerable,
34556            get: originalPropertyDescriptor.get,
34557            set: originalPropertyDescriptor.set,
34558        });
34559    });
34560}
34561function initStyleDeclarationObserver({ styleDeclarationCb, mirror, ignoreCSSAttributes, stylesheetManager, }, { win }) {
34562    const setProperty = win.CSSStyleDeclaration.prototype.setProperty;
34563    win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {
34564        apply: callbackWrapper((target, thisArg, argumentsList) => {
34565            const [property, value, priority] = argumentsList;
34566            if (ignoreCSSAttributes.has(property)) {
34567                return setProperty.apply(thisArg, [property, value, priority]);
34568            }
34569            const { id, styleId } = getIdAndStyleId(_optionalChain$2([thisArg, 'access', _17 => _17.parentRule, 'optionalAccess', _18 => _18.parentStyleSheet]), mirror, stylesheetManager.styleMirror);
34570            if ((id && id !== -1) || (styleId && styleId !== -1)) {
34571                styleDeclarationCb({
34572                    id,
34573                    styleId,
34574                    set: {
34575                        property,
34576                        value,
34577                        priority,
34578                    },
34579                    index: getNestedCSSRulePositions(thisArg.parentRule),
34580                });
34581            }
34582            return target.apply(thisArg, argumentsList);
34583        }),
34584    });
34585    const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;
34586    win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {
34587        apply: callbackWrapper((target, thisArg, argumentsList) => {
34588            const [property] = argumentsList;
34589            if (ignoreCSSAttributes.has(property)) {
34590                return removeProperty.apply(thisArg, [property]);
34591            }
34592            const { id, styleId } = getIdAndStyleId(_optionalChain$2([thisArg, 'access', _19 => _19.parentRule, 'optionalAccess', _20 => _20.parentStyleSheet]), mirror, stylesheetManager.styleMirror);
34593            if ((id && id !== -1) || (styleId && styleId !== -1)) {
34594                styleDeclarationCb({
34595                    id,
34596                    styleId,
34597                    remove: {
34598                        property,
34599                    },
34600                    index: getNestedCSSRulePositions(thisArg.parentRule),
34601                });
34602            }
34603            return target.apply(thisArg, argumentsList);
34604        }),
34605    });
34606    return callbackWrapper(() => {
34607        win.CSSStyleDeclaration.prototype.setProperty = setProperty;
34608        win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;
34609    });
34610}
34611function initMediaInteractionObserver({ mediaInteractionCb, blockClass, blockSelector, unblockSelector, mirror, sampling, doc, }) {
34612    const handler = callbackWrapper((type) => throttle$1(callbackWrapper((event) => {
34613        const target = getEventTarget(event);
34614        if (!target ||
34615            isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
34616            return;
34617        }
34618        const { currentTime, volume, muted, playbackRate } = target;
34619        mediaInteractionCb({
34620            type,
34621            id: mirror.getId(target),
34622            currentTime,
34623            volume,
34624            muted,
34625            playbackRate,
34626        });
34627    }), sampling.media || 500));
34628    const handlers = [
34629        on('play', handler(0), doc),
34630        on('pause', handler(1), doc),
34631        on('seeked', handler(2), doc),
34632        on('volumechange', handler(3), doc),
34633        on('ratechange', handler(4), doc),
34634    ];
34635    return callbackWrapper(() => {
34636        handlers.forEach((h) => h());
34637    });
34638}
34639function initFontObserver({ fontCb, doc }) {
34640    const win = doc.defaultView;
34641    if (!win) {
34642        return () => {
34643        };
34644    }
34645    const handlers = [];
34646    const fontMap = new WeakMap();
34647    const originalFontFace = win.FontFace;
34648    win.FontFace = function FontFace(family, source, descriptors) {
34649        const fontFace = new originalFontFace(family, source, descriptors);
34650        fontMap.set(fontFace, {
34651            family,
34652            buffer: typeof source !== 'string',
34653            descriptors,
34654            fontSource: typeof source === 'string'
34655                ? source
34656                : JSON.stringify(Array.from(new Uint8Array(source))),
34657        });
34658        return fontFace;
34659    };
34660    const restoreHandler = patch(doc.fonts, 'add', function (original) {
34661        return function (fontFace) {
34662            setTimeout(callbackWrapper(() => {
34663                const p = fontMap.get(fontFace);
34664                if (p) {
34665                    fontCb(p);
34666                    fontMap.delete(fontFace);
34667                }
34668            }), 0);
34669            return original.apply(this, [fontFace]);
34670        };
34671    });
34672    handlers.push(() => {
34673        win.FontFace = originalFontFace;
34674    });
34675    handlers.push(restoreHandler);
34676    return callbackWrapper(() => {
34677        handlers.forEach((h) => h());
34678    });
34679}
34680function initSelectionObserver(param) {
34681    const { doc, mirror, blockClass, blockSelector, unblockSelector, selectionCb, } = param;
34682    let collapsed = true;
34683    const updateSelection = callbackWrapper(() => {
34684        const selection = doc.getSelection();
34685        if (!selection || (collapsed && _optionalChain$2([selection, 'optionalAccess', _21 => _21.isCollapsed])))
34686            return;
34687        collapsed = selection.isCollapsed || false;
34688        const ranges = [];
34689        const count = selection.rangeCount || 0;
34690        for (let i = 0; i < count; i++) {
34691            const range = selection.getRangeAt(i);
34692            const { startContainer, startOffset, endContainer, endOffset } = range;
34693            const blocked = isBlocked(startContainer, blockClass, blockSelector, unblockSelector, true) ||
34694                isBlocked(endContainer, blockClass, blockSelector, unblockSelector, true);
34695            if (blocked)
34696                continue;
34697            ranges.push({
34698                start: mirror.getId(startContainer),
34699                startOffset,
34700                end: mirror.getId(endContainer),
34701                endOffset,
34702            });
34703        }
34704        selectionCb({ ranges });
34705    });
34706    updateSelection();
34707    return on('selectionchange', updateSelection);
34708}
34709function initCustomElementObserver({ doc, customElementCb, }) {
34710    const win = doc.defaultView;
34711    if (!win || !win.customElements)
34712        return () => { };
34713    const restoreHandler = patch(win.customElements, 'define', function (original) {
34714        return function (name, constructor, options) {
34715            try {
34716                customElementCb({
34717                    define: {
34718                        name,
34719                    },
34720                });
34721            }
34722            catch (e) {
34723            }
34724            return original.apply(this, [name, constructor, options]);
34725        };
34726    });
34727    return restoreHandler;
34728}
34729function initObservers(o, _hooks = {}) {
34730    const currentWindow = o.doc.defaultView;
34731    if (!currentWindow) {
34732        return () => {
34733        };
34734    }
34735    const mutationObserver = initMutationObserver(o, o.doc);
34736    const mousemoveHandler = initMoveObserver(o);
34737    const mouseInteractionHandler = initMouseInteractionObserver(o);
34738    const scrollHandler = initScrollObserver(o);
34739    const viewportResizeHandler = initViewportResizeObserver(o, {
34740        win: currentWindow,
34741    });
34742    const inputHandler = initInputObserver(o);
34743    const mediaInteractionHandler = initMediaInteractionObserver(o);
34744    const styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });
34745    const adoptedStyleSheetObserver = initAdoptedStyleSheetObserver(o, o.doc);
34746    const styleDeclarationObserver = initStyleDeclarationObserver(o, {
34747        win: currentWindow,
34748    });
34749    const fontObserver = o.collectFonts
34750        ? initFontObserver(o)
34751        : () => {
34752        };
34753    const selectionObserver = initSelectionObserver(o);
34754    const customElementObserver = initCustomElementObserver(o);
34755    const pluginHandlers = [];
34756    for (const plugin of o.plugins) {
34757        pluginHandlers.push(plugin.observer(plugin.callback, currentWindow, plugin.options));
34758    }
34759    return callbackWrapper(() => {
34760        mutationBuffers.forEach((b) => b.reset());
34761        mutationObserver.disconnect();
34762        mousemoveHandler();
34763        mouseInteractionHandler();
34764        scrollHandler();
34765        viewportResizeHandler();
34766        inputHandler();
34767        mediaInteractionHandler();
34768        styleSheetObserver();
34769        adoptedStyleSheetObserver();
34770        styleDeclarationObserver();
34771        fontObserver();
34772        selectionObserver();
34773        customElementObserver();
34774        pluginHandlers.forEach((h) => h());
34775    });
34776}
34777function hasNestedCSSRule(prop) {
34778    return typeof window[prop] !== 'undefined';
34779}
34780function canMonkeyPatchNestedCSSRule(prop) {
34781    return Boolean(typeof window[prop] !== 'undefined' &&
34782        window[prop].prototype &&
34783        'insertRule' in window[prop].prototype &&
34784        'deleteRule' in window[prop].prototype);
34785}
34786
34787class CrossOriginIframeMirror {
34788    constructor(generateIdFn) {
34789        this.generateIdFn = generateIdFn;
34790        this.iframeIdToRemoteIdMap = new WeakMap();
34791        this.iframeRemoteIdToIdMap = new WeakMap();
34792    }
34793    getId(iframe, remoteId, idToRemoteMap, remoteToIdMap) {
34794        const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);
34795        const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);
34796        let id = idToRemoteIdMap.get(remoteId);
34797        if (!id) {
34798            id = this.generateIdFn();
34799            idToRemoteIdMap.set(remoteId, id);
34800            remoteIdToIdMap.set(id, remoteId);
34801        }
34802        return id;
34803    }
34804    getIds(iframe, remoteId) {
34805        const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);
34806        const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);
34807        return remoteId.map((id) => this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap));
34808    }
34809    getRemoteId(iframe, id, map) {
34810        const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);
34811        if (typeof id !== 'number')
34812            return id;
34813        const remoteId = remoteIdToIdMap.get(id);
34814        if (!remoteId)
34815            return -1;
34816        return remoteId;
34817    }
34818    getRemoteIds(iframe, ids) {
34819        const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);
34820        return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));
34821    }
34822    reset(iframe) {
34823        if (!iframe) {
34824            this.iframeIdToRemoteIdMap = new WeakMap();
34825            this.iframeRemoteIdToIdMap = new WeakMap();
34826            return;
34827        }
34828        this.iframeIdToRemoteIdMap.delete(iframe);
34829        this.iframeRemoteIdToIdMap.delete(iframe);
34830    }
34831    getIdToRemoteIdMap(iframe) {
34832        let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);
34833        if (!idToRemoteIdMap) {
34834            idToRemoteIdMap = new Map();
34835            this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);
34836        }
34837        return idToRemoteIdMap;
34838    }
34839    getRemoteIdToIdMap(iframe) {
34840        let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);
34841        if (!remoteIdToIdMap) {
34842            remoteIdToIdMap = new Map();
34843            this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);
34844        }
34845        return remoteIdToIdMap;
34846    }
34847}
34848
34849function _optionalChain$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
34850class IframeManagerNoop {
34851    constructor() {
34852        this.crossOriginIframeMirror = new CrossOriginIframeMirror(genId);
34853        this.crossOriginIframeRootIdMap = new WeakMap();
34854    }
34855    addIframe() {
34856    }
34857    addLoadListener() {
34858    }
34859    attachIframe() {
34860    }
34861}
34862class IframeManager {
34863    constructor(options) {
34864        this.iframes = new WeakMap();
34865        this.crossOriginIframeMap = new WeakMap();
34866        this.crossOriginIframeMirror = new CrossOriginIframeMirror(genId);
34867        this.crossOriginIframeRootIdMap = new WeakMap();
34868        this.mutationCb = options.mutationCb;
34869        this.wrappedEmit = options.wrappedEmit;
34870        this.stylesheetManager = options.stylesheetManager;
34871        this.recordCrossOriginIframes = options.recordCrossOriginIframes;
34872        this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(this.stylesheetManager.styleMirror.generateId.bind(this.stylesheetManager.styleMirror));
34873        this.mirror = options.mirror;
34874        if (this.recordCrossOriginIframes) {
34875            window.addEventListener('message', this.handleMessage.bind(this));
34876        }
34877    }
34878    addIframe(iframeEl) {
34879        this.iframes.set(iframeEl, true);
34880        if (iframeEl.contentWindow)
34881            this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);
34882    }
34883    addLoadListener(cb) {
34884        this.loadListener = cb;
34885    }
34886    attachIframe(iframeEl, childSn) {
34887        this.mutationCb({
34888            adds: [
34889                {
34890                    parentId: this.mirror.getId(iframeEl),
34891                    nextId: null,
34892                    node: childSn,
34893                },
34894            ],
34895            removes: [],
34896            texts: [],
34897            attributes: [],
34898            isAttachIframe: true,
34899        });
34900        _optionalChain$1([this, 'access', _ => _.loadListener, 'optionalCall', _2 => _2(iframeEl)]);
34901        if (iframeEl.contentDocument &&
34902            iframeEl.contentDocument.adoptedStyleSheets &&
34903            iframeEl.contentDocument.adoptedStyleSheets.length > 0)
34904            this.stylesheetManager.adoptStyleSheets(iframeEl.contentDocument.adoptedStyleSheets, this.mirror.getId(iframeEl.contentDocument));
34905    }
34906    handleMessage(message) {
34907        const crossOriginMessageEvent = message;
34908        if (crossOriginMessageEvent.data.type !== 'rrweb' ||
34909            crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin)
34910            return;
34911        const iframeSourceWindow = message.source;
34912        if (!iframeSourceWindow)
34913            return;
34914        const iframeEl = this.crossOriginIframeMap.get(message.source);
34915        if (!iframeEl)
34916            return;
34917        const transformedEvent = this.transformCrossOriginEvent(iframeEl, crossOriginMessageEvent.data.event);
34918        if (transformedEvent)
34919            this.wrappedEmit(transformedEvent, crossOriginMessageEvent.data.isCheckout);
34920    }
34921    transformCrossOriginEvent(iframeEl, e) {
34922        switch (e.type) {
34923            case EventType.FullSnapshot: {
34924                this.crossOriginIframeMirror.reset(iframeEl);
34925                this.crossOriginIframeStyleMirror.reset(iframeEl);
34926                this.replaceIdOnNode(e.data.node, iframeEl);
34927                const rootId = e.data.node.id;
34928                this.crossOriginIframeRootIdMap.set(iframeEl, rootId);
34929                this.patchRootIdOnNode(e.data.node, rootId);
34930                return {
34931                    timestamp: e.timestamp,
34932                    type: EventType.IncrementalSnapshot,
34933                    data: {
34934                        source: IncrementalSource.Mutation,
34935                        adds: [
34936                            {
34937                                parentId: this.mirror.getId(iframeEl),
34938                                nextId: null,
34939                                node: e.data.node,
34940                            },
34941                        ],
34942                        removes: [],
34943                        texts: [],
34944                        attributes: [],
34945                        isAttachIframe: true,
34946                    },
34947                };
34948            }
34949            case EventType.Meta:
34950            case EventType.Load:
34951            case EventType.DomContentLoaded: {
34952                return false;
34953            }
34954            case EventType.Plugin: {
34955                return e;
34956            }
34957            case EventType.Custom: {
34958                this.replaceIds(e.data.payload, iframeEl, ['id', 'parentId', 'previousId', 'nextId']);
34959                return e;
34960            }
34961            case EventType.IncrementalSnapshot: {
34962                switch (e.data.source) {
34963                    case IncrementalSource.Mutation: {
34964                        e.data.adds.forEach((n) => {
34965                            this.replaceIds(n, iframeEl, [
34966                                'parentId',
34967                                'nextId',
34968                                'previousId',
34969                            ]);
34970                            this.replaceIdOnNode(n.node, iframeEl);
34971                            const rootId = this.crossOriginIframeRootIdMap.get(iframeEl);
34972                            rootId && this.patchRootIdOnNode(n.node, rootId);
34973                        });
34974                        e.data.removes.forEach((n) => {
34975                            this.replaceIds(n, iframeEl, ['parentId', 'id']);
34976                        });
34977                        e.data.attributes.forEach((n) => {
34978                            this.replaceIds(n, iframeEl, ['id']);
34979                        });
34980                        e.data.texts.forEach((n) => {
34981                            this.replaceIds(n, iframeEl, ['id']);
34982                        });
34983                        return e;
34984                    }
34985                    case IncrementalSource.Drag:
34986                    case IncrementalSource.TouchMove:
34987                    case IncrementalSource.MouseMove: {
34988                        e.data.positions.forEach((p) => {
34989                            this.replaceIds(p, iframeEl, ['id']);
34990                        });
34991                        return e;
34992                    }
34993                    case IncrementalSource.ViewportResize: {
34994                        return false;
34995                    }
34996                    case IncrementalSource.MediaInteraction:
34997                    case IncrementalSource.MouseInteraction:
34998                    case IncrementalSource.Scroll:
34999                    case IncrementalSource.CanvasMutation:
35000                    case IncrementalSource.Input: {
35001                        this.replaceIds(e.data, iframeEl, ['id']);
35002                        return e;
35003                    }
35004                    case IncrementalSource.StyleSheetRule:
35005                    case IncrementalSource.StyleDeclaration: {
35006                        this.replaceIds(e.data, iframeEl, ['id']);
35007                        this.replaceStyleIds(e.data, iframeEl, ['styleId']);
35008                        return e;
35009                    }
35010                    case IncrementalSource.Font: {
35011                        return e;
35012                    }
35013                    case IncrementalSource.Selection: {
35014                        e.data.ranges.forEach((range) => {
35015                            this.replaceIds(range, iframeEl, ['start', 'end']);
35016                        });
35017                        return e;
35018                    }
35019                    case IncrementalSource.AdoptedStyleSheet: {
35020                        this.replaceIds(e.data, iframeEl, ['id']);
35021                        this.replaceStyleIds(e.data, iframeEl, ['styleIds']);
35022                        _optionalChain$1([e, 'access', _3 => _3.data, 'access', _4 => _4.styles, 'optionalAccess', _5 => _5.forEach, 'call', _6 => _6((style) => {
35023                            this.replaceStyleIds(style, iframeEl, ['styleId']);
35024                        })]);
35025                        return e;
35026                    }
35027                }
35028            }
35029        }
35030        return false;
35031    }
35032    replace(iframeMirror, obj, iframeEl, keys) {
35033        for (const key of keys) {
35034            if (!Array.isArray(obj[key]) && typeof obj[key] !== 'number')
35035                continue;
35036            if (Array.isArray(obj[key])) {
35037                obj[key] = iframeMirror.getIds(iframeEl, obj[key]);
35038            }
35039            else {
35040                obj[key] = iframeMirror.getId(iframeEl, obj[key]);
35041            }
35042        }
35043        return obj;
35044    }
35045    replaceIds(obj, iframeEl, keys) {
35046        return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);
35047    }
35048    replaceStyleIds(obj, iframeEl, keys) {
35049        return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);
35050    }
35051    replaceIdOnNode(node, iframeEl) {
35052        this.replaceIds(node, iframeEl, ['id', 'rootId']);
35053        if ('childNodes' in node) {
35054            node.childNodes.forEach((child) => {
35055                this.replaceIdOnNode(child, iframeEl);
35056            });
35057        }
35058    }
35059    patchRootIdOnNode(node, rootId) {
35060        if (node.type !== NodeType$1.Document && !node.rootId)
35061            node.rootId = rootId;
35062        if ('childNodes' in node) {
35063            node.childNodes.forEach((child) => {
35064                this.patchRootIdOnNode(child, rootId);
35065            });
35066        }
35067    }
35068}
35069
35070class ShadowDomManagerNoop {
35071    init() {
35072    }
35073    addShadowRoot() {
35074    }
35075    observeAttachShadow() {
35076    }
35077    reset() {
35078    }
35079}
35080class ShadowDomManager {
35081    constructor(options) {
35082        this.shadowDoms = new WeakSet();
35083        this.restoreHandlers = [];
35084        this.mutationCb = options.mutationCb;
35085        this.scrollCb = options.scrollCb;
35086        this.bypassOptions = options.bypassOptions;
35087        this.mirror = options.mirror;
35088        this.init();
35089    }
35090    init() {
35091        this.reset();
35092        this.patchAttachShadow(Element, document);
35093    }
35094    addShadowRoot(shadowRoot, doc) {
35095        if (!isNativeShadowDom(shadowRoot))
35096            return;
35097        if (this.shadowDoms.has(shadowRoot))
35098            return;
35099        this.shadowDoms.add(shadowRoot);
35100        const observer = initMutationObserver({
35101            ...this.bypassOptions,
35102            doc,
35103            mutationCb: this.mutationCb,
35104            mirror: this.mirror,
35105            shadowDomManager: this,
35106        }, shadowRoot);
35107        this.restoreHandlers.push(() => observer.disconnect());
35108        this.restoreHandlers.push(initScrollObserver({
35109            ...this.bypassOptions,
35110            scrollCb: this.scrollCb,
35111            doc: shadowRoot,
35112            mirror: this.mirror,
35113        }));
35114        setTimeout(() => {
35115            if (shadowRoot.adoptedStyleSheets &&
35116                shadowRoot.adoptedStyleSheets.length > 0)
35117                this.bypassOptions.stylesheetManager.adoptStyleSheets(shadowRoot.adoptedStyleSheets, this.mirror.getId(shadowRoot.host));
35118            this.restoreHandlers.push(initAdoptedStyleSheetObserver({
35119                mirror: this.mirror,
35120                stylesheetManager: this.bypassOptions.stylesheetManager,
35121            }, shadowRoot));
35122        }, 0);
35123    }
35124    observeAttachShadow(iframeElement) {
35125        if (!iframeElement.contentWindow || !iframeElement.contentDocument)
35126            return;
35127        this.patchAttachShadow(iframeElement.contentWindow.Element, iframeElement.contentDocument);
35128    }
35129    patchAttachShadow(element, doc) {
35130        const manager = this;
35131        this.restoreHandlers.push(patch(element.prototype, 'attachShadow', function (original) {
35132            return function (option) {
35133                const shadowRoot = original.call(this, option);
35134                if (this.shadowRoot && inDom(this))
35135                    manager.addShadowRoot(this.shadowRoot, doc);
35136                return shadowRoot;
35137            };
35138        }));
35139    }
35140    reset() {
35141        this.restoreHandlers.forEach((handler) => {
35142            try {
35143                handler();
35144            }
35145            catch (e) {
35146            }
35147        });
35148        this.restoreHandlers = [];
35149        this.shadowDoms = new WeakSet();
35150    }
35151}
35152
35153class CanvasManagerNoop {
35154    reset() {
35155    }
35156    freeze() {
35157    }
35158    unfreeze() {
35159    }
35160    lock() {
35161    }
35162    unlock() {
35163    }
35164    snapshot() {
35165    }
35166}
35167
35168class StylesheetManager {
35169    constructor(options) {
35170        this.trackedLinkElements = new WeakSet();
35171        this.styleMirror = new StyleSheetMirror();
35172        this.mutationCb = options.mutationCb;
35173        this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;
35174    }
35175    attachLinkElement(linkEl, childSn) {
35176        if ('_cssText' in childSn.attributes)
35177            this.mutationCb({
35178                adds: [],
35179                removes: [],
35180                texts: [],
35181                attributes: [
35182                    {
35183                        id: childSn.id,
35184                        attributes: childSn
35185                            .attributes,
35186                    },
35187                ],
35188            });
35189        this.trackLinkElement(linkEl);
35190    }
35191    trackLinkElement(linkEl) {
35192        if (this.trackedLinkElements.has(linkEl))
35193            return;
35194        this.trackedLinkElements.add(linkEl);
35195        this.trackStylesheetInLinkElement(linkEl);
35196    }
35197    adoptStyleSheets(sheets, hostId) {
35198        if (sheets.length === 0)
35199            return;
35200        const adoptedStyleSheetData = {
35201            id: hostId,
35202            styleIds: [],
35203        };
35204        const styles = [];
35205        for (const sheet of sheets) {
35206            let styleId;
35207            if (!this.styleMirror.has(sheet)) {
35208                styleId = this.styleMirror.add(sheet);
35209                styles.push({
35210                    styleId,
35211                    rules: Array.from(sheet.rules || CSSRule, (r, index) => ({
35212                        rule: stringifyRule(r),
35213                        index,
35214                    })),
35215                });
35216            }
35217            else
35218                styleId = this.styleMirror.getId(sheet);
35219            adoptedStyleSheetData.styleIds.push(styleId);
35220        }
35221        if (styles.length > 0)
35222            adoptedStyleSheetData.styles = styles;
35223        this.adoptedStyleSheetCb(adoptedStyleSheetData);
35224    }
35225    reset() {
35226        this.styleMirror.reset();
35227        this.trackedLinkElements = new WeakSet();
35228    }
35229    trackStylesheetInLinkElement(linkEl) {
35230    }
35231}
35232
35233class ProcessedNodeManager {
35234    constructor() {
35235        this.nodeMap = new WeakMap();
35236        this.loop = true;
35237        this.periodicallyClear();
35238    }
35239    periodicallyClear() {
35240        onRequestAnimationFrame(() => {
35241            this.clear();
35242            if (this.loop)
35243                this.periodicallyClear();
35244        });
35245    }
35246    inOtherBuffer(node, thisBuffer) {
35247        const buffers = this.nodeMap.get(node);
35248        return (buffers && Array.from(buffers).some((buffer) =>
35248 buffer !== thisBuffer));
35249    }
35250    add(node, buffer) {
35251        this.nodeMap.set(node, (this.nodeMap.get(node) || new Set()).add(buffer));
35252    }
35253    clear() {
35254        this.nodeMap = new WeakMap();
35255    }
35256    destroy() {
35257        this.loop = false;
35258    }
35259}
35260
35261function wrapEvent(e) {
35262    const eWithTime = e;
35263    eWithTime.timestamp = nowTimestamp();
35264    return eWithTime;
35265}
35266let _takeFullSnapshot;
35267const mirror = createMirror();
35268function record(options = {}) {
35269    const { emit, checkoutEveryNms, checkoutEveryNth, blockClass = 'rr-block', blockSelector = null, unblockSelector = null, ignoreClass = 'rr-ignore', ignoreSelector = null, maskAllText = false, maskTextClass = 'rr-mask', unmaskTextClass = null, maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, maskAllInputs, maskInputOptions: _maskInputOptions, slimDOMOptions: _slimDOMOptions, maskAttributeFn, maskInputFn, maskTextFn, packFn, sampling = {}, dataURLOptions = {}, mousemoveWait, recordCanvas = false, recordCrossOriginIframes = false, recordAfter = options.recordAfter === 'DOMContentLoaded'
35270        ? options.recordAfter
35271        : 'load', userTriggeredOnInput = false, collectFonts = false, inlineImages = false, plugins, keepIframeSrcFn = () => false, ignoreCSSAttributes = new Set([]), errorHandler, onMutation, getCanvasManager, } = options;
35272    registerErrorHandler(errorHandler);
35273    const inEmittingFrame = recordCrossOriginIframes
35274        ? window.parent === window
35275        : true;
35276    let passEmitsToParent = false;
35277    if (!inEmittingFrame) {
35278        try {
35279            if (window.parent.document) {
35280                passEmitsToParent = false;
35281            }
35282        }
35283        catch (e) {
35284            passEmitsToParent = true;
35285        }
35286    }
35287    if (inEmittingFrame && !emit) {
35288        throw new Error('emit function is required');
35289    }
35290    if (mousemoveWait !== undefined && sampling.mousemove === undefined) {
35291        sampling.mousemove = mousemoveWait;
35292    }
35293    mirror.reset();
35294    const maskInputOptions = maskAllInputs === true
35295        ? {
35296            color: true,
35297            date: true,
35298            'datetime-local': true,
35299            email: true,
35300            month: true,
35301            number: true,
35302            range: true,
35303            search: true,
35304            tel: true,
35305            text: true,
35306            time: true,
35307            url: true,
35308            week: true,
35309            textarea: true,
35310            select: true,
35311            radio: true,
35312            checkbox: true,
35313        }
35314        : _maskInputOptions !== undefined
35315            ? _maskInputOptions
35316            : {};
35317    const slimDOMOptions = _slimDOMOptions === true || _slimDOMOptions === 'all'
35318        ? {
35319            script: true,
35320            comment: true,
35321            headFavicon: true,
35322            headWhitespace: true,
35323            headMetaSocial: true,
35324            headMetaRobots: true,
35325            headMetaHttpEquiv: true,
35326            headMetaVerification: true,
35327            headMetaAuthorship: _slimDOMOptions === 'all',
35328            headMetaDescKeywords: _slimDOMOptions === 'all',
35329        }
35330        : _slimDOMOptions
35331            ? _slimDOMOptions
35332            : {};
35333    polyfill();
35334    let lastFullSnapshotEvent;
35335    let incrementalSnapshotCount = 0;
35336    const eventProcessor = (e) => {
35337        for (const plugin of plugins || []) {
35338            if (plugin.eventProcessor) {
35339                e = plugin.eventProcessor(e);
35340            }
35341        }
35342        if (packFn &&
35343            !passEmitsToParent) {
35344            e = packFn(e);
35345        }
35346        return e;
35347    };
35348    const wrappedEmit = (e, isCheckout) => {
35349        if (_optionalChain([mutationBuffers, 'access', _ => _[0], 'optionalAccess', _2 => _2.isFrozen, 'call', _3 => _3()]) &&
35350            e.type !== EventType.FullSnapshot &&
35351            !(e.type === EventType.IncrementalSnapshot &&
35352                e.data.source === IncrementalSource.Mutation)) {
35353            mutationBuffers.forEach((buf) => buf.unfreeze());
35354        }
35355        if (inEmittingFrame) {
35356            _optionalChain([emit, 'optionalCall', _4 => _4(eventProcessor(e), isCheckout)]);
35357        }
35358        else if (passEmitsToParent) {
35359            const message = {
35360                type: 'rrweb',
35361                event: eventProcessor(e),
35362                origin: window.location.origin,
35363                isCheckout,
35364            };
35365            window.parent.postMessage(message, '*');
35366        }
35367        if (e.type === EventType.FullSnapshot) {
35368            lastFullSnapshotEvent = e;
35369            incrementalSnapshotCount = 0;
35370        }
35371        else if (e.type === EventType.IncrementalSnapshot) {
35372            if (e.data.source === IncrementalSource.Mutation &&
35373                e.data.isAttachIframe) {
35374                return;
35375            }
35376            incrementalSnapshotCount++;
35377            const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;
35378            const exceedTime = checkoutEveryNms &&
35379                e.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;
35380            if (exceedCount || exceedTime) {
35381                takeFullSnapshot(true);
35382            }
35383        }
35384    };
35385    const wrappedMutationEmit = (m) => {
35386        wrappedEmit(wrapEvent({
35387            type: EventType.IncrementalSnapshot,
35388            data: {
35389                source: IncrementalSource.Mutation,
35390                ...m,
35391            },
35392        }));
35393    };
35394    const wrappedScrollEmit = (p) => wrappedEmit(wrapEvent({
35395        type: EventType.IncrementalSnapshot,
35396        data: {
35397            source: IncrementalSource.Scroll,
35398            ...p,
35399        },
35400    }));
35401    const wrappedCanvasMutationEmit = (p) => wrappedEmit(wrapEvent({
35402        type: EventType.IncrementalSnapshot,
35403        data: {
35404            source: IncrementalSource.CanvasMutation,
35405            ...p,
35406        },
35407    }));
35408    const wrappedAdoptedStyleSheetEmit = (a) => wrappedEmit(wrapEvent({
35409        type: EventType.IncrementalSnapshot,
35410        data: {
35411            source: IncrementalSource.AdoptedStyleSheet,
35412            ...a,
35413        },
35414    }));
35415    const stylesheetManager = new StylesheetManager({
35416        mutationCb: wrappedMutationEmit,
35417        adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit,
35418    });
35419    const iframeManager = typeof __RRWEB_EXCLUDE_IFRAME__ === 'boolean' && __RRWEB_EXCLUDE_IFRAME__
35420        ? new IframeManagerNoop()
35421        : new IframeManager({
35422            mirror,
35423            mutationCb: wrappedMutationEmit,
35424            stylesheetManager: stylesheetManager,
35425            recordCrossOriginIframes,
35426            wrappedEmit,
35427        });
35428    for (const plugin of plugins || []) {
35429        if (plugin.getMirror)
35430            plugin.getMirror({
35431                nodeMirror: mirror,
35432                crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,
35433                crossOriginIframeStyleMirror: iframeManager.crossOriginIframeStyleMirror,
35434            });
35435    }
35436    const processedNodeManager = new ProcessedNodeManager();
35437    const canvasManager = _getCanvasManager(getCanvasManager, {
35438        mirror,
35439        win: window,
35440        mutationCb: (p) => wrappedEmit(wrapEvent({
35441            type: EventType.IncrementalSnapshot,
35442            data: {
35443                source: IncrementalSource.CanvasMutation,
35444                ...p,
35445            },
35446        })),
35447        recordCanvas,
35448        blockClass,
35449        blockSelector,
35450        unblockSelector,
35451        sampling: sampling['canvas'],
35452        dataURLOptions,
35453        errorHandler,
35454    });
35455    const shadowDomManager = typeof __RRWEB_EXCLUDE_SHADOW_DOM__ === 'boolean' &&
35456        __RRWEB_EXCLUDE_SHADOW_DOM__
35457        ? new ShadowDomManagerNoop()
35458        : new ShadowDomManager({
35459            mutationCb: wrappedMutationEmit,
35460            scrollCb: wrappedScrollEmit,
35461            bypassOptions: {
35462                onMutation,
35463                blockClass,
35464                blockSelector,
35465                unblockSelector,
35466                maskAllText,
35467                maskTextClass,
35468                unmaskTextClass,
35469                maskTextSelector,
35470                unmaskTextSelector,
35471                inlineStylesheet,
35472                maskInputOptions,
35473                dataURLOptions,
35474                maskAttributeFn,
35475                maskTextFn,
35476                maskInputFn,
35477                recordCanvas,
35478                inlineImages,
35479                sampling,
35480                slimDOMOptions,
35481                iframeManager,
35482                stylesheetManager,
35483                canvasManager,
35484                keepIframeSrcFn,
35485                processedNodeManager,
35486            },
35487            mirror,
35488        });
35489    const takeFullSnapshot = (isCheckout = false) => {
35490        wrappedEmit(wrapEvent({
35491            type: EventType.Meta,
35492            data: {
35493                href: window.location.href,
35494                width: getWindowWidth(),
35495                height: getWindowHeight(),
35496            },
35497        }), isCheckout);
35498        stylesheetManager.reset();
35499        shadowDomManager.init();
35500        mutationBuffers.forEach((buf) => buf.lock());
35501        const node = snapshot(document, {
35502            mirror,
35503            blockClass,
35504            blockSelector,
35505            unblockSelector,
35506            maskAllText,
35507            maskTextClass,
35508            unmaskTextClass,
35509            maskTextSelector,
35510            unmaskTextSelector,
35511            inlineStylesheet,
35512            maskAllInputs: maskInputOptions,
35513            maskAttributeFn,
35514            maskInputFn,
35515            maskTextFn,
35516            slimDOM: slimDOMOptions,
35517            dataURLOptions,
35518            recordCanvas,
35519            inlineImages,
35520            onSerialize: (n) => {
35521                if (isSerializedIframe(n, mirror)) {
35522                    iframeManager.addIframe(n);
35523                }
35524                if (isSerializedStylesheet(n, mirror)) {
35525                    stylesheetManager.trackLinkElement(n);
35526                }
35527                if (hasShadowRoot(n)) {
35528                    shadowDomManager.addShadowRoot(n.shadowRoot, document);
35529                }
35530            },
35531            onIframeLoad: (iframe, childSn) => {
35532                iframeManager.attachIframe(iframe, childSn);
35533                shadowDomManager.observeAttachShadow(iframe);
35534            },
35535            onStylesheetLoad: (linkEl, childSn) => {
35536                stylesheetManager.attachLinkElement(linkEl, childSn);
35537            },
35538            keepIframeSrcFn,
35539        });
35540        if (!node) {
35541            return console.warn('Failed to snapshot the document');
35542        }
35543        wrappedEmit(wrapEvent({
35544            type: EventType.FullSnapshot,
35545            data: {
35546                node,
35547                initialOffset: getWindowScroll(window),
35548            },
35549        }));
35550        mutationBuffers.forEach((buf) => buf.unlock());
35551        if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)
35552            stylesheetManager.adoptStyleSheets(document.adoptedStyleSheets, mirror.getId(document));
35553    };
35554    _takeFullSnapshot = takeFullSnapshot;
35555    try {
35556        const handlers = [];
35557        const observe = (doc) => {
35558            return callbackWrapper(initObservers)({
35559                onMutation,
35560                mutationCb: wrappedMutationEmit,
35561                mousemoveCb: (positions, source) => wrappedEmit(wrapEvent({
35562                    type: EventType.IncrementalSnapshot,
35563                    data: {
35564                        source,
35565                        positions,
35566                    },
35567                })),
35568                mouseInteractionCb: (d) => wrappedEmit(wrapEvent({
35569                    type: EventType.IncrementalSnapshot,
35570                    data: {
35571                        source: IncrementalSource.MouseInteraction,
35572                        ...d,
35573                    },
35574                })),
35575                scrollCb: wrappedScrollEmit,
35576                viewportResizeCb: (d) => wrappedEmit(wrapEvent({
35577                    type: EventType.IncrementalSnapshot,
35578                    data: {
35579                        source: IncrementalSource.ViewportResize,
35580                        ...d,
35581                    },
35582                })),
35583                inputCb: (v) => wrappedEmit(wrapEvent({
35584                    type: EventType.IncrementalSnapshot,
35585                    data: {
35586                        source: IncrementalSource.Input,
35587                        ...v,
35588                    },
35589                })),
35590                mediaInteractionCb: (p) => wrappedEmit(wrapEvent({
35591                    type: EventType.IncrementalSnapshot,
35592                    data: {
35593                        source: IncrementalSource.MediaInteraction,
35594                        ...p,
35595                    },
35596                })),
35597                styleSheetRuleCb: (r) => wrappedEmit(wrapEvent({
35598                    type: EventType.IncrementalSnapshot,
35599                    data: {
35600                        source: IncrementalSource.StyleSheetRule,
35601                        ...r,
35602                    },
35603                })),
35604                styleDeclarationCb: (r) => wrappedEmit(wrapEvent({
35605                    type: EventType.IncrementalSnapshot,
35606                    data: {
35607                        source: IncrementalSource.StyleDeclaration,
35608                        ...r,
35609                    },
35610                })),
35611                canvasMutationCb: wrappedCanvasMutationEmit,
35612                fontCb: (p) => wrappedEmit(wrapEvent({
35613                    type: EventType.IncrementalSnapshot,
35614                    data: {
35615                        source: IncrementalSource.Font,
35616                        ...p,
35617                    },
35618                })),
35619                selectionCb: (p) => {
35620                    wrappedEmit(wrapEvent({
35621                        type: EventType.IncrementalSnapshot,
35622                        data: {
35623                            source: IncrementalSource.Selection,
35624                            ...p,
35625                        },
35626                    }));
35627                },
35628                customElementCb: (c) => {
35629                    wrappedEmit(wrapEvent({
35630                        type: EventType.IncrementalSnapshot,
35631                        data: {
35632                            source: IncrementalSource.CustomElement,
35633                            ...c,
35634                        },
35635                    }));
35636                },
35637                blockClass,
35638                ignoreClass,
35639                ignoreSelector,
35640                maskAllText,
35641                maskTextClass,
35642                unmaskTextClass,
35643                maskTextSelector,
35644                unmaskTextSelector,
35645                maskInputOptions,
35646                inlineStylesheet,
35647                sampling,
35648                recordCanvas,
35649                inlineImages,
35650                userTriggeredOnInput,
35651                collectFonts,
35652                doc,
35653                maskAttributeFn,
35654                maskInputFn,
35655                maskTextFn,
35656                keepIframeSrcFn,
35657                blockSelector,
35658                unblockSelector,
35659                slimDOMOptions,
35660                dataURLOptions,
35661                mirror,
35662                iframeManager,
35663                stylesheetManager,
35664                shadowDomManager,
35665                processedNodeManager,
35666                canvasManager,
35667                ignoreCSSAttributes,
35668                plugins: _optionalChain([plugins
35669, 'optionalAccess', _5 => _5.filter, 'call', _6 => _6((p) => p.observer)
35670, 'optionalAccess', _7 => _7.map, 'call', _8 => _8((p) => ({
35671                    observer: p.observer,
35672                    options: p.options,
35673                    callback: (payload) => wrappedEmit(wrapEvent({
35674                        type: EventType.Plugin,
35675                        data: {
35676                            plugin: p.name,
35677                            payload,
35678                        },
35679                    })),
35680                }))]) || [],
35681            }, {});
35682        };
35683        iframeManager.addLoadListener((iframeEl) => {
35684            try {
35685                handlers.push(observe(iframeEl.contentDocument));
35686            }
35687            catch (error) {
35688                console.warn(error);
35689            }
35690        });
35691        const init = () => {
35692            takeFullSnapshot();
35693            handlers.push(observe(document));
35694        };
35695        if (document.readyState === 'interactive' ||
35696            document.readyState === 'complete') {
35697            init();
35698        }
35699        else {
35700            handlers.push(on('DOMContentLoaded', () => {
35701                wrappedEmit(wrapEvent({
35702                    type: EventType.DomContentLoaded,
35703                    data: {},
35704                }));
35705                if (recordAfter === 'DOMContentLoaded')
35706                    init();
35707            }));
35708            handlers.push(on('load', () => {
35709                wrappedEmit(wrapEvent({
35710                    type: EventType.Load,
35711                    data: {},
35712                }));
35713                if (recordAfter === 'load')
35714                    init();
35715            }, window));
35716        }
35717        return () => {
35718            handlers.forEach((h) => h());
35719            processedNodeManager.destroy();
35720            _takeFullSnapshot = undefined;
35721            unregisterErrorHandler();
35722        };
35723    }
35724    catch (error) {
35725        console.warn(error);
35726    }
35727}
35728function takeFullSnapshot(isCheckout) {
35729    if (!_takeFullSnapshot) {
35730        throw new Error('please take full snapshot after start recording');
35731    }
35732    _takeFullSnapshot(isCheckout);
35733}
35734record.mirror = mirror;
35735record.takeFullSnapshot = takeFullSnapshot;
35736function _getCanvasManager(getCanvasManagerFn, options) {
35737    try {
35738        return getCanvasManagerFn
35739            ? getCanvasManagerFn(options)
35740            : new CanvasManagerNoop();
35741    }
35742    catch (e2) {
35743        console.warn('Unable to initialize CanvasManager');
35744        return new CanvasManagerNoop();
35745    }
35746}
35747
35748const ReplayEventTypeIncrementalSnapshot = 3;
35749const ReplayEventTypeCustom = 5;
35750
35751/**
35752 * Converts a timestamp to ms, if it was in s, or keeps it as ms.
35753 */
35754function timestampToMs(timestamp) {
35755  const isMs = timestamp > 9999999999;
35756  return isMs ? timestamp : timestamp * 1000;
35757}
35758
35759/**
35760 * Converts a timestamp to s, if it was in ms, or keeps it as s.
35761 */
35762function timestampToS(timestamp) {
35763  const isMs = timestamp > 9999999999;
35764  return isMs ? timestamp / 1000 : timestamp;
35765}
35766
35767/**
35768 * Add a breadcrumb event to replay.
35769 */
35770function addBreadcrumbEvent(replay, breadcrumb) {
35771  if (breadcrumb.category === 'sentry.transaction') {
35772    return;
35773  }
35774
35775  if (['ui.click', 'ui.input'].includes(breadcrumb.category )) {
35776    replay.triggerUserActivity();
35777  } else {
35778    replay.checkAndHandleExpiredSession();
35779  }
35780
35781  replay.addUpdate(() => {
35782    // This should never reject
35783    // eslint-disable-next-line @typescript-eslint/no-floating-promises
35784    replay.throttledAddEvent({
35785      type: EventType.Custom,
35786      // TODO: We were converting from ms to seconds for breadcrumbs, spans,
35787      // but maybe we should just keep them as milliseconds
35788      timestamp: (breadcrumb.timestamp || 0) * 1000,
35789      data: {
35790        tag: 'breadcrumb',
35791        // normalize to max. 10 depth and 1_000 properties per object
35792        payload: utils.normalize(breadcrumb, 10, 1000),
35793      },
35794    });
35795
35796    // Do not flush after console log messages
35797    return breadcrumb.category === 'console';
35798  });
35799}
35800
35801const INTERACTIVE_SELECTOR = 'button,a';
35802
35803/** Get the closest interactive parent element, or else return the given element. */
35804function getClosestInteractive(element) {
35805  const closestInteractive = element.closest(INTERACTIVE_SELECTOR);
35806  return closestInteractive || element;
35807}
35808
35809/**
35810 * For clicks, we check if the target is inside of a button or link
35811 * If so, we use this as the target instead
35812 * This is useful because if you click on the image in <button><img></button>,
35813 * The target will be the image, not the button, which we don't want here
35814 */
35815function getClickTargetNode(event) {
35816  const target = getTargetNode(event);
35817
35818  if (!target || !(target instanceof Element)) {
35819    return target;
35820  }
35821
35822  return getClosestInteractive(target);
35823}
35824
35825/** Get the event target node. */
35826function getTargetNode(event) {
35827  if (isEventWithTarget(event)) {
35828    return event.target ;
35829  }
35830
35831  return event;
35832}
35833
35834function isEventWithTarget(event) {
35835  return typeof event === 'object' && !!event && 'target' in event;
35836}
35837
35838let handlers;
35839
35840/**
35841 * Register a handler to be called when `window.open()` is called.
35842 * Returns a cleanup function.
35843 */
35844function onWindowOpen(cb) {
35845  // Ensure to only register this once
35846  if (!handlers) {
35847    handlers = [];
35848    monkeyPatchWindowOpen();
35849  }
35850
35851  handlers.push(cb);
35852
35853  return () => {
35854    const pos = handlers ? handlers.indexOf(cb) : -1;
35855    if (pos > -1) {
35856      (handlers ).splice(pos, 1);
35857    }
35858  };
35859}
35860
35861function monkeyPatchWindowOpen() {
35862  utils.fill(WINDOW, 'open', function (originalWindowOpen) {
35863    return function (...args) {
35864      if (handlers) {
35865        try {
35866          handlers.forEach(handler => handler());
35867        } catch (e) {
35868          // ignore errors in here
35869        }
35870      }
35871
35872      return originalWindowOpen.apply(WINDOW, args);
35873    };
35874  });
35875}
35876
35877/** Handle a click. */
35878function handleClick(clickDetector, clickBreadcrumb, node) {
35879  clickDetector.handleClick(clickBreadcrumb, node);
35880}
35881
35882/** A click detector class that can be used to detect slow or rage clicks on elements. */
35883class ClickDetector  {
35884  // protected for testing
35885
35886   constructor(
35887    replay,
35888    slowClickConfig,
35889    // Just for easier testing
35890    _addBreadcrumbEvent = addBreadcrumbEvent,
35891  ) {
35892    this._lastMutation = 0;
35893    this._lastScroll = 0;
35894    this._clicks = [];
35895
35896    // We want everything in s, but options are in ms
35897    this._timeout = slowClickConfig.timeout / 1000;
35898    this._threshold = slowClickConfig.threshold / 1000;
35899    this._scollTimeout = slowClickConfig.scrollTimeout / 1000;
35900    this._replay = replay;
35901    this._ignoreSelector = slowClickConfig.ignoreSelector;
35902    this._addBreadcrumbEvent = _addBreadcrumbEvent;
35903  }
35904
35905  /** Register click detection handlers on mutation or scroll. */
35906   addListeners() {
35907    const cleanupWindowOpen = onWindowOpen(() => {
35908      // Treat window.open as mutation
35909      this._lastMutation = nowInSeconds();
35910    });
35911
35912    this._teardown = () => {
35913      cleanupWindowOpen();
35914
35915      this._clicks = [];
35916      this._lastMutation = 0;
35917      this._lastScroll = 0;
35918    };
35919  }
35920
35921  /** Clean up listeners. */
35922   removeListeners() {
35923    if (this._teardown) {
35924      this._teardown();
35925    }
35926
35927    if (this._checkClickTimeout) {
35928      clearTimeout(this._checkClickTimeout);
35929    }
35930  }
35931
35932  /** @inheritDoc */
35933   handleClick(breadcrumb, node) {
35934    if (ignoreElement(node, this._ignoreSelector) || !isClickBreadcrumb(breadcrumb)) {
35935      return;
35936    }
35937
35938    const newClick = {
35939      timestamp: timestampToS(breadcrumb.timestamp),
35940      clickBreadcrumb: breadcrumb,
35941      // Set this to 0 so we know it originates from the click breadcrumb
35942      clickCount: 0,
35943      node,
35944    };
35945
35946    // If there was a click in the last 1s on the same element, ignore it - only keep a single reference per second
35947    if (
35948      this._clicks.some(click => click.node === newClick.node && Math.abs(click.timestamp - newClick.timestamp) < 1)
35949    ) {
35950      return;
35951    }
35952
35953    this._clicks.push(newClick);
35954
35955    // If this is the first new click, set a timeout to check for multi clicks
35956    if (this._clicks.length === 1) {
35957      this._scheduleCheckClicks();
35958    }
35959  }
35960
35961  /** @inheritDoc */
35962   registerMutation(timestamp = Date.now()) {
35963    this._lastMutation = timestampToS(timestamp);
35964  }
35965
35966  /** @inheritDoc */
35967   registerScroll(timestamp = Date.now()) {
35968    this._lastScroll = timestampToS(timestamp);
35969  }
35970
35971  /** @inheritDoc */
35972   registerClick(element) {
35973    const node = getClosestInteractive(element);
35974    this._handleMultiClick(node );
35975  }
35976
35977  /** Count multiple clicks on elements. */
35978   _handleMultiClick(node) {
35979    this._getClicks(node).forEach(click => {
35980      click.clickCount++;
35981    });
35982  }
35983
35984  /** Get all pending clicks for a given node. */
35985   _getClicks(node) {
35986    return this._clicks.filter(click => click.node === node);
35987  }
35988
35989  /** Check the clicks that happened. */
35990   _checkClicks() {
35991    const timedOutClicks = [];
35992
35993    const now = nowInSeconds();
35994
35995    this._clicks.forEach(click => {
35996      if (!click.mutationAfter && this._lastMutation) {
35997        click.mutationAfter = click.timestamp <= this._lastMutation ? this._lastMutation - click.timestamp : undefined;
35998      }
35999      if (!click.scrollAfter && this._lastScroll) {
36000        click.scrollAfter = click.timestamp <= this._lastScroll ? this._lastScroll - click.timestamp : undefined;
36001      }
36002
36003      // All of these are in seconds!
36004      if (click.timestamp + this._timeout <= now) {
36005        timedOutClicks.push(click);
36006      }
36007    });
36008
36009    // Remove "old" clicks
36010    for (const click of timedOutClicks) {
36011      const pos = this._clicks.indexOf(click);
36012
36013      if (pos > -1) {
36014        this._generateBreadcrumbs(click);
36015        this._clicks.splice(pos, 1);
36016      }
36017    }
36018
36019    // Trigger new check, unless no clicks left
36020    if (this._clicks.length) {
36021      this._scheduleCheckClicks();
36022    }
36023  }
36024
36025  /** Generate matching breadcrumb(s) for the click. */
36026   _generateBreadcrumbs(click) {
36027    const replay = this._replay;
36028    const hadScroll = click.scrollAfter && click.scrollAfter <= this._scollTimeout;
36029    const hadMutation = click.mutationAfter && click.mutationAfter <= this._threshold;
36030
36031    const isSlowClick = !hadScroll && !hadMutation;
36032    const { clickCount, clickBreadcrumb }
36032 = click;
36033
36034    // Slow click
36035    if (isSlowClick) {
36036      // If `mutationAfter` is set, it means a mutation happened after the threshold, but before the timeout
36037      // If not, it means we just timed out without scroll & mutation
36038      const timeAfterClickMs = Math.min(click.mutationAfter || this._timeout, this._timeout) * 1000;
36039      const endReason = timeAfterClickMs < this._timeout * 1000 ? 'mutation' : 'timeout';
36040
36041      const breadcrumb = {
36042        type: 'default',
36043        message: clickBreadcrumb.message,
36044        timestamp: clickBreadcrumb.timestamp,
36045        category: 'ui.slowClickDetected',
36046        data: {
36047          ...clickBreadcrumb.data,
36048          url: WINDOW.location.href,
36049          route: replay.getCurrentRoute(),
36050          timeAfterClickMs,
36051          endReason,
36052          // If clickCount === 0, it means multiClick was not correctly captured here
36053          // - we still want to send 1 in this case
36054          clickCount: clickCount || 1,
36055        },
36056      };
36057
36058      this._addBreadcrumbEvent(replay, breadcrumb);
36059      return;
36060    }
36061
36062    // Multi click
36063    if (clickCount > 1) {
36064      const breadcrumb = {
36065        type: 'default',
36066        message: clickBreadcrumb.message,
36067        timestamp: clickBreadcrumb.timestamp,
36068        category: 'ui.multiClick',
36069        data: {
36070          ...clickBreadcrumb.data,
36071          url: WINDOW.location.href,
36072          route: replay.getCurrentRoute(),
36073          clickCount,
36074          metric: true,
36075        },
36076      };
36077
36078      this._addBreadcrumbEvent(replay, breadcrumb);
36079    }
36080  }
36081
36082  /** Schedule to check current clicks. */
36083   _scheduleCheckClicks() {
36084    if (this._checkClickTimeout) {
36085      clearTimeout(this._checkClickTimeout);
36086    }
36087
36088    this._checkClickTimeout = setTimeout(() => this._checkClicks(), 1000);
36089  }
36090}
36091
36092const SLOW_CLICK_TAGS = ['A', 'BUTTON', 'INPUT'];
36093
36094/** exported for tests only */
36095function ignoreElement(node, ignoreSelector) {
36096  if (!SLOW_CLICK_TAGS.includes(node.tagName)) {
36097    return true;
36098  }
36099
36100  // If <input> tag, we only want to consider input[type='submit'] & input[type='button']
36101  if (node.tagName === 'INPUT' && !['submit', 'button'].includes(node.getAttribute('type') || '')) {
36102    return true;
36103  }
36104
36105  // If <a> tag, detect special variants that may not lead to an action
36106  // If target !== _self, we may open the link somewhere else, which would lead to no action
36107  // Also, when downloading a file, we may not leave the page, but still not trigger an action
36108  if (
36109    node.tagName === 'A' &&
36110    (node.hasAttribute('download') || (node.hasAttribute('target') && node.getAttribute('target') !== '_self'))
36111  ) {
36112    return true;
36113  }
36114
36115  if (ignoreSelector && node.matches(ignoreSelector)) {
36116    return true;
36117  }
36118
36119  return false;
36120}
36121
36122function isClickBreadcrumb(breadcrumb) {
36123  return !!(breadcrumb.data && typeof breadcrumb.data.nodeId === 'number' && breadcrumb.timestamp);
36124}
36125
36126// This is good enough for us, and is easier to test/mock than `timestampInSeconds`
36127function nowInSeconds() {
36128  return Date.now() / 1000;
36129}
36130
36131/** Update the click detector based on a recording event of rrweb. */
36132function updateClickDetectorForRecordingEvent(clickDetector, event) {
36133  try {
36134    // note: We only consider incremental snapshots here
36135    // This means that any full snapshot is ignored for mutation detection - the reason is that we simply cannot know if a mutation happened here.
36136    // E.g. think that we are buffering, an error happens and we take a full snapshot because we switched to session mode -
36137    // in this scenario, we would not know if a dead click happened because of the error, which is a key dead click scenario.
36138    // Instead, by ignoring full snapshots, we have the risk that we generate a false positive
36139    // (if a mutation _did_ happen but was "swallowed" by the full snapshot)
36140    // But this should be more unlikely as we'd generally capture the incremental snapshot right away
36141
36142    if (!isIncrementalEvent(event)) {
36143      return;
36144    }
36145
36146    const { source } = event.data;
36147    if (source === IncrementalSource.Mutation) {
36148      clickDetector.registerMutation(event.timestamp);
36149    }
36150
36151    if (source === IncrementalSource.Scroll) {
36152      clickDetector.registerScroll(event.timestamp);
36153    }
36154
36155    if (isIncrementalMouseInteraction(event)) {
36156      const { type, id } = event.data;
36157      const node = record.mirror.getNode(id);
36158
36159      if (node instanceof HTMLElement && type === MouseInteractions.Click) {
36160        clickDetector.registerClick(node);
36161      }
36162    }
36163  } catch (e) {
36164    // ignore errors here, e.g. if accessing something that does not exist
36165  }
36166}
36167
36168function isIncrementalEvent(event) {
36169  return event.type === ReplayEventTypeIncrementalSnapshot;
36170}
36171
36172function isIncrementalMouseInteraction(
36173  event,
36174) {
36175  return event.data.source === IncrementalSource.MouseInteraction;
36176}
36177
36178/**
36179 * Create a breadcrumb for a replay.
36180 */
36181function createBreadcrumb(
36182  breadcrumb,
36183) {
36184  return {
36185    timestamp: Date.now() / 1000,
36186    type: 'default',
36187    ...breadcrumb,
36188  };
36189}
36190
36191var NodeType;
36192(function (NodeType) {
36193    NodeType[NodeType["Document"] = 0] = "Document";
36194    NodeType[NodeType["DocumentType"] = 1] = "DocumentType";
36195    NodeType[NodeType["Element"] = 2] = "Element";
36196    NodeType[NodeType["Text"] = 3] = "Text";
36197    NodeType[NodeType["CDATA"] = 4] = "CDATA";
36198    NodeType[NodeType["Comment"] = 5] = "Comment";
36199})(NodeType || (NodeType = {}));
36200
36201// Note that these are the serialized attributes and not attributes directly on
36202// the DOM Node. Attributes we are interested in:
36203const ATTRIBUTES_TO_RECORD = new Set([
36204  'id',
36205  'class',
36206  'aria-label',
36207  'role',
36208  'name',
36209  'alt',
36210  'title',
36211  'data-test-id',
36212  'data-testid',
36213  'disabled',
36214  'aria-disabled',
36215  'data-sentry-component',
36216]);
36217
36218/**
36219 * Inclusion list of attributes that we want to record from the DOM element
36220 */
36221function getAttributesToRecord(attributes) {
36222  const obj = {};
36223  for (const key in attributes) {
36224    if (ATTRIBUTES_TO_RECORD.has(key)) {
36225      let normalizedKey = key;
36226
36227      if (key === 'data-testid' || key === 'data-test-id') {
36228        normalizedKey = 'testId';
36229      }
36230
36231      obj[normalizedKey] = attributes[key];
36232    }
36233  }
36234
36235  return obj;
36236}
36237
36238const handleDomListener = (
36239  replay,
36240) => {
36241  return (handlerData) => {
36242    if (!replay.isEnabled()) {
36243      return;
36244    }
36245
36246    const result = handleDom(handlerData);
36247
36248    if (!result) {
36249      return;
36250    }
36251
36252    const isClick = handlerData.name === 'click';
36253    const event = isClick ? (handlerData.event ) : undefined;
36254    // Ignore clicks if ctrl/alt/meta/shift keys are held down as they alter behavior of clicks (e.g. open in new tab)
36255    if (
36256      isClick &&
36257      replay.clickDetector &&
36258      event &&
36259      event.target &&
36260      !event.altKey &&
36261      !event.metaKey &&
36262      !event.ctrlKey &&
36263      !event.shiftKey
36264    ) {
36265      handleClick(
36266        replay.clickDetector,
36267        result ,
36268        getClickTargetNode(handlerData.event ) ,
36269      );
36270    }
36271
36272    addBreadcrumbEvent(replay, result);
36273  };
36274};
36275
36276/** Get the base DOM breadcrumb. */
36277function getBaseDomBreadcrumb(target, message) {
36278  const nodeId = record.mirror.getId(target);
36279  const node = nodeId && record.mirror.getNode(nodeId);
36280  const meta = node && record.mirror.getMeta(node);
36281  const element = meta && isElement(meta) ? meta : null;
36282
36283  return {
36284    message,
36285    data: element
36286      ? {
36287          nodeId,
36288          node: {
36289            id: nodeId,
36290            tagName: element.tagName,
36291            textContent: Array.from(element.childNodes)
36292              .map((node) => node.type === NodeType.Text && node.textContent)
36293              .filter(Boolean) // filter out empty values
36294              .map(text => (text ).trim())
36295              .join(''),
36296            attributes: getAttributesToRecord(element.attributes),
36297          },
36298        }
36299      : {},
36300  };
36301}
36302
36303/**
36304 * An event handler to react to DOM events.
36305 * Exported for tests.
36306 */
36307function handleDom(handlerData) {
36308  const { target, message } = getDomTarget(handlerData);
36309
36310  return createBreadcrumb({
36311    category: `ui.${handlerData.name}`,
36312    ...getBaseDomBreadcrumb(target, message),
36313  });
36314}
36315
36316function getDomTarget(handlerData) {
36317  const isClick = handlerData.name === 'click';
36318
36319  let message;
36320  let target = null;
36321
36322  // Accessing event.target can throw (see getsentry/raven-js#838, #768)
36323  try {
36324    target = isClick ? getClickTargetNode(handlerData.event ) : getTargetNode(handlerData.event );
36325    message = utils.htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';
36326  } catch (e) {
36327    message = '<unknown>';
36328  }
36329
36330  return { target, message };
36331}
36332
36333function isElement(node) {
36334  return node.type === NodeType.Element;
36335}
36336
36337/** Handle keyboard events & create breadcrumbs. */
36338function handleKeyboardEvent(replay, event) {
36339  if (!replay.isEnabled()) {
36340    return;
36341  }
36342
36343  // Update user activity, but do not restart recording as it can create
36344  // noisy/low-value replays (e.g. user comes back from idle, hits alt-tab, new
36345  // session with a single "keydown" breadcrumb is created)
36346  replay.updateUserActivity();
36347
36348  const breadcrumb = getKeyboardBreadcrumb(event);
36349
36350  if (!breadcrumb) {
36351    return;
36352  }
36353
36354  addBreadcrumbEvent(replay, breadcrumb);
36355}
36356
36357/** exported only for tests */
36358function getKeyboardBreadcrumb(event) {
36359  const { metaKey, shiftKey, ctrlKey, altKey, key, target } = event;
36360
36361  // never capture for input fields
36362  if (!target || isInputElement(target ) || !key) {
36363    return null;
36364  }
36365
36366  // Note: We do not consider shift here, as that means "uppercase"
36367  const hasModifierKey = metaKey || ctrlKey || altKey;
36368  const isCharacterKey = key.length === 1; // other keys like Escape, Tab, etc have a longer length
36369
36370  // Do not capture breadcrumb if only a word key is pressed
36371  // This could leak e.g. user input
36372  if (!hasModifierKey && isCharacterKey) {
36373    return null;
36374  }
36375
36376  const message = utils.htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';
36377  const baseBreadcrumb = getBaseDomBreadcrumb(target , message);
36378
36379  return createBreadcrumb({
36380    category: 'ui.keyDown',
36381    message,
36382    data: {
36383      ...baseBreadcrumb.data,
36384      metaKey,
36385      shiftKey,
36386      ctrlKey,
36387      altKey,
36388      key,
36389    },
36390  });
36391}
36392
36393function isInputElement(target) {
36394  return target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable;
36395}
36396
36397// Map entryType -> function to normalize data for event
36398const ENTRY_TYPES
36399
36400 = {
36401  // @ts-expect-error TODO: entry type does not fit the create* functions entry type
36402  resource: createResourceEntry,
36403  paint: createPaintEntry,
36404  // @ts-expect-error TODO: entry type does not fit the create* functions entry type
36405  navigation: createNavigationEntry,
36406};
36407
36408/**
36409 * Create replay performance entries from the browser performance entries.
36410 */
36411function createPerformanceEntries(
36412  entries,
36413) {
36414  return entries.map(createPerformanceEntry).filter(Boolean) ;
36415}
36416
36417function createPerformanceEntry(entry) {
36418  if (!ENTRY_TYPES[entry.entryType]) {
36419    return null;
36420  }
36421
36422  return ENTRY_TYPES[entry.entryType](entry);
36423}
36424
36425function getAbsoluteTime(time) {
36426  // browserPerformanceTimeOrigin can be undefined if `performance` or
36427  // `performance.now` doesn't exist, but this is already checked by this integration
36428  return ((utils.browserPerformanceTimeOrigin || WINDOW.performance.timeOrigin) + time) / 1000;
36429}
36430
36431function createPaintEntry(entry) {
36432  const { duration, entryType, name, startTime } = entry;
36433
36434  const start = getAbsoluteTime(startTime);
36435  return {
36436    type: entryType,
36437    name,
36438    start,
36439    end: start + duration,
36440    data: undefined,
36441  };
36442}
36443
36444function createNavigationEntry(entry) {
36445  const {
36446    entryType,
36447    name,
36448    decodedBodySize,
36449    duration,
36450    domComplete,
36451    encodedBodySize,
36452    domContentLoadedEventStart,
36453    domContentLoadedEventEnd,
36454    domInteractive,
36455    loadEventStart,
36456    loadEventEnd,
36457    redirectCount,
36458    startTime,
36459    transferSize,
36460    type,
36461  } = entry;
36462
36463  // Ignore entries with no duration, they do not seem to be useful and cause dupes
36464  if (duration === 0) {
36465    return null;
36466  }
36467
36468  return {
36469    type: `${entryType}.${type}`,
36470    start: getAbsoluteTime(startTime),
36471    end: getAbsoluteTime(domComplete),
36472    name,
36473    data: {
36474      size: transferSize,
36475      decodedBodySize,
36476      encodedBodySize,
36477      duration,
36478      domInteractive,
36479      domContentLoadedEventStart,
36480      domContentLoadedEventEnd,
36481      loadEventStart,
36482      loadEventEnd,
36483      domComplete,
36484      redirectCount,
36485    },
36486  };
36487}
36488
36489function createResourceEntry(
36490  entry,
36491) {
36492  const {
36493    entryType,
36494    initiatorType,
36495    name,
36496    responseEnd,
36497    startTime,
36498    decodedBodySize,
36499    encodedBodySize,
36500    responseStatus,
36501    transferSize,
36502  } = entry;
36503
36504  // Core SDK handles these
36505  if (['fetch', 'xmlhttprequest'].includes(initiatorType)) {
36506    return null;
36507  }
36508
36509  return {
36510    type: `${entryType}.${initiatorType}`,
36511    start: getAbsoluteTime(startTime),
36512    end: getAbsoluteTime(responseEnd),
36513    name,
36514    data: {
36515      size: transferSize,
36516      statusCode: responseStatus,
36517      decodedBodySize,
36518      encodedBodySize,
36519    },
36520  };
36521}
36522
36523/**
36524 * Add a LCP event to the replay based on an LCP metric.
36525 */
36526function getLargestContentfulPaint(metric
36527
36528) {
36529  const entries = metric.entries;
36530  const lastEntry = entries[entries.length - 1] ;
36531  const element = lastEntry ? lastEntry.element : undefined;
36532
36533  const value = metric.value;
36534
36535  const end = getAbsoluteTime(value);
36536
36537  const data = {
36538    type: 'largest-contentful-paint',
36539    name: 'largest-contentful-paint',
36540    start: end,
36541    end,
36542    data: {
36543      value,
36544      size: value,
36545      nodeId: element ? record.mirror.getId(element) : undefined,
36546    },
36547  };
36548
36549  return data;
36550}
36551
36552/**
36553 * Sets up a PerformanceObserver to listen to all performance entry types.
36554 * Returns a callback to stop observing.
36555 */
36556function setupPerformanceObserver(replay) {
36557  function addPerformanceEntry(entry) {
36558    // It is possible for entries to come up multiple times
36559    if (!replay.performanceEntries.includes(entry)) {
36560      replay.performanceEntries.push(entry);
36561    }
36562  }
36563
36564  function onEntries({ entries }) {
36565    entries.forEach(addPerformanceEntry);
36566  }
36567
36568  const clearCallbacks = [];
36569
36570  (['navigation', 'paint', 'resource'] ).forEach(type => {
36571    clearCallbacks.push(tracing.addPerformanceInstrumentationHandler(type, onEntries));
36572  });
36573
36574  clearCallbacks.push(
36575    tracing.addLcpInstrumentationHandler(({ metric }) => {
36576      replay.replayPerformanceEntries.push(getLargestContentfulPaint(metric));
36577    }),
36578  );
36579
36580  // A callback to cleanup all handlers
36581  return () => {
36582    clearCallbacks.forEach(clearCallback => clearCallback());
36583  };
36584}
36585
36586/**
36587 * 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.
36588 *
36589 * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
36590 */
36591const DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);
36592
36593const r = `var t=Uint8Array,n=Uint16Array,r=Int32Array,e=new t([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),i=new t([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),a=new t([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),s=function(t,e){for(var i=new n(31),a=0;a<31;++a)i[a]=e+=1<<t[a-1];var s=new r(i[30]);for(a=1;a<30;++a)for(var o=i[a];o<i[a+1];++o)s[o]=o-i[a]<<5|a;return{b:i,r:s}},o=s(e,2),f=o.b,h=o.r;f[28]=258,h[258]=28;for(var l=s(i,0).r,u=new n(32768),c=0;c<32768;++c){var v=(43690&c)>>1|(21845&c)<<1;v=(61680&(v=(52428&v)>>2|(13107&v)<<2))>>4|(3855&v)<<4,u[c]=((65280&v)>>8|(255&v)<<8)>>1}var d=function(t,r,e){for(var i=t.length,a=0,s=new n(r);a<i;++a)t[a]&&++s[t[a]-1];var o,f=new n(r);for(a=1;a<r;++a)f[a]=f[a-1]+s[a-1]<<1;if(e){o=new n(1<<r);var h=15-r;for(a=0;a<i;++a)if(t[a])for(var l=a<<4|t[a],c=r-t[a],v=f[t[a]-1]++<<c,d=v|(1<<c)-1;v<=d;++v)o[u[v]>>h]=l}else for(o=new n(i),a=0;a<i;++a)t[a]&&(o[a]=u[f[t[a]-1]++]>>15-t[a]);return o},g=new t(288);for(c=0;c<144;++c)g[c]=8;for(c=144;c<256;++c)g[c]=9;for(c=256;c<280;++c)g[c]=7;for(c=280;c<288;++c)g[c]=8;var w=new t(32);for(c=0;c<32;++c)w[c]=5;var p=d(g,9,0),y=d(w,5,0),m=function(t){return(t+7)/8|0},b=function(n,r,e){return(null==r||r<0)&&(r=0),(null==e||e>n.length)&&(e=n.length),new t(n.subarray(r,e))}
vendor: 4,465 bytes, line 36593
36593,M=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],E=function(t,n,r){var e=new Error(n||M[t]);if(e.code=t,Error.captureStackTrace&&Error.captureStackTrace(e,E),!r)throw e;return e},z=function(t,n,r){r<<=7&n;var e=n/8|0;t[e]|=r,t[e+1]|=r>>8},A=function(t,n,r){r<<=7&n;var e=n/8|0;t[e]|=r,t[e+1]|=r>>8,t[e+2]|=r>>16},_=function(r,e){for(var i=[],a=0;a<r.length;++a)r[a]&&i.push({s:a,f:r[a]});var s=i.length,o=i.slice();if(!s)return{t:F,l:0};if(1==s){var f=new t(i[0].s+1);return f[i[0].s]=1,{t:f,l:1}}i.sort((function(t,n){return t.f-n.f})),i.push({s:-1,f:25001});var h=i[0],l=i[1],u=0,c=1,v=2;for(i[0]={s:-1,f:h.f+l.f,l:h,r:l};c!=s-1;)h=i[i[u].f<i[v].f?u++:v++],l=i[u!=c&&i[u].f<i[v].f?u++:v++],i[c++]={s:-1,f:h.f+l.f,l:h,r:l};var d=o[0].s;for(a=1;a<s;++a)o[a].s>d&&(d=o[a].s);var g=new n(d+1),w=x(i[c-1],g,0);if(w>e){a=0;var p=0,y=w-e,m=1<<y;for(o.sort((function(t,n){return g[n.s]-g[t.s]||t.f-n.f}));a<s;++a){var b=o[a].s;if(!(g[b]>e))break;p+=m-(1<<w-g[b]),g[b]=e}for(p>>=y;p>0;){var M=o[a].s;g[M]<e?p-=1<<e-g[M]++-1:++a}for(;a>=0&&p;--a){var E=o[a].s;g[E]==e&&(--g[E],++p)}w=e}return{t:new t(g),l:w}},x=function(t,n,r){return-1==t.s?Math.max(x(t.l,n,r+1),x(t.r,n,r+1)):n[t.s]=r},D=function(t){for(var r=t.length;r&&!t[--r];);for(var e=new n(++r),i=0,a=t[0],s=1,o=function(t){e[i++]=t},f=1;f<=r;++f)if(t[f]==a&&f!=r)++s;else{if(!a&&s>2){for(;s>138;s-=138)o(32754);s>2&&(o(s>10?s-11<<5|28690:s-3<<5|12305),s=0)}else if(s>3){for(o(a),--s;s>6;s-=6)o(8304);s>2&&(o(s-3<<5|8208),s=0)}for(;s--;)o(a);s=1,a=t[f]}return{c:e.subarray(0,i),n:r}},T=function(t,n){for(var r=0,e=0;e<n.length;++e)r+=t[e]*n[e];return r},k=function(t,n,r){var e=r.length,i=m(n+2);t[i]=255&e,t[i+1]=e>>8,t[i+2]=255^t[i],t[i+3]=255^t[i+1];for(var a=0;a<e;++a)t[i+a+4]=r[a];return 8*(i+4+e)},C=function(t,r,s,o,f,h,l,u,c,v,m){z(r,m++,s),++f[256];for(var b=_(f,15),M=b.t,E=b.l,x=_(h,15),C=x.t,U=x.l,F=D(M),I=F.c,S=F.n,L=D(C),O=L.c,j=L.n,q=new n(19),B=0;B<I.length;++B)++q[31&I[B]];for(B=0;B<O.length;++B)++q[31&O[B]];for(var G=_(q,7),H=G.t,J=G.l,K=19;K>4&&!H[a[K-1]];--K);var N,P,Q,R,V=v+5<<3,W=T(f,g)+T(h,w)+l,X=T(f,M)+T(h,C)+l+14+3*K+T(q,H)+2*q[16]+3*q[17]+7*q[18];if(c>=0&&V<=W&&V<=X)return k(r,m,t.subarray(c,c+v));if(z(r,m,1+(X<W)),m+=2,X<W){N=d(M,E,0),P=M,Q=d(C,U,0),R=C;var Y=d(H,J,0);z(r,m,S-257),z(r,m+5,j-1),z(r,m+10,K-4),m+=14;for(B=0;B<K;++B)z(r,m+3*B,H[a[B]]);m+=3*K;for(var Z=[I,O],$=0;$<2;++$){var tt=Z[$];for(B=0;B<tt.length;++B){var nt=31&tt[B];z(r,m,Y[nt]),m+=H[nt],nt>15&&(z(r,m,tt[B]>>5&127),m+=tt[B]>>12)}}}else N=p,P=g,Q=y,R=w;for(B=0;B<u;++B){var rt=o[B];if(rt>255){A(r,m,N[(nt=rt>>18&31)+257]),m+=P[nt+257],nt>7&&(z(r,m,rt>>23&31),m+=e[nt]);var et=31&rt;A(r,m,Q[et]),m+=R[et],et>3&&(A(r,m,rt>>5&8191),m+=i[et])}else A(r,m,N[rt]),m+=P[rt]}return A(r,m,N[256]),m+P[256]},U=new r([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),F=new t(0),I=function(){for(var t=new Int32Array(256),n=0;n<256;++n){for(var r=n,e=9;--e;)r=(1&r&&-306674912)^r>>>1;t[n]=r}return t}(),S=function(){var t=1,n=0;return{p:function(r){for(var e=t,i=n,a=0|r.length,s=0;s!=a;){for(var o=Math.min(s+2655,a);s<o;++s)i+=e+=r[s];e=(65535&e)+15*(e>>16),i=(65535&i)+15*(i>>16)}t=e,n=i},d:function(){return(255&(t%=65521))<<24|(65280&t)<<8|(255&(n%=65521))<<8|n>>8}}},L=function(a,s,o,f,u){if(!u&&(u={l:1},s.dictionary)){var c=s.dictionary.subarray(-32768),v=new t(c.length+a.length);v.set(c),v.set(a,c.length),a=v,u.w=c.length}return function(a,s,o,f,u,c){var v=c.z||a.length,d=new t(f+v+5*(1+Math.ceil(v/7e3))+u),g=d.subarray(f,d.length-u),w=c.l,p=7&(c.r||0);if(s){p&&(g[0]=c.r>>3);for(var y=U[s-1],M=y>>13,E=8191&y,z=(1<<o)-1,A=c.p||new n(32768),_=c.h||new n(z+1),x=Math.ceil(o/3),D=2*x,T=function(t){return(a[t]^a[t+1]<<x^a[t+2]<<D)&z},F=new r(25e3),I=new n(288),S=new n(32),L=0,O=0,j=c.i||0,q=0,B=c.w||0,G=0;j+2<v;++j){var H=T(j),J=32767&j,K=_[H];if(A[J]=K,_[H]=J,B<=j){var N=v-j;if((L>7e3||q>24576)&&(N>423||!w)){p=C(a,g,0,F,I,S,O,q,G,j-G,p),q=L=O=0,G=j;for(var P=0;P<286;++P)I[P]=0;for(P=0;P<30;++P)S[P]=0}var Q=2,R=0,V=E,W=J-K&32767;if(N>2&&H==T(j-W))for(var X=Math.min(M,N)-1,Y=Math.min(32767,j),Z=Math.min(258,N);W<=Y&&--V&&J!=K;){if(a[j+Q]==a[j+Q-W]){for(var $=0;$<Z&&a[j+$]==a[j+$-W];++$);if($>Q){if(Q=$,R=W,$>X)break;var tt=Math.min(W,$-2),nt=0;for(P=0;P<tt;
36593++P){var rt=j-W+P&32767,et=rt-A[rt]&32767;et>nt&&(nt=et,K=rt)}}}W+=(J=K)-(K=A[J])&32767}if(R){F[q++]=268435456|h[Q]<<18|l[R];var it=31&h[Q],at=31&l[R];O+=e[it]+i[at],++I[257+it],++S[at],B=j+Q,++L}else F[q++]=a[j],++I[a[j]]}}for(j=Math.max(j,B);j<v;++j)F[q++]=a[j],++I[a[j]];p=C(a,g,w,F,I,S,O,q,G,j-G,p),w||(c.r=7&p|g[p/8|0]<<3,p-=7,c.h=_,c.p=A,c.i=j,c.w=B)}else{for(j=c.w||0;j<v+w;j+=65535){var st=j+65535;st>=v&&(g[p/8|0]=w,st=v),p=k(g,p+1,a.subarray(j,st))}c.i=v}return b(d,0,f+m(p)+u)}(a,null==s.level?6:s.level,null==s.mem?Math.ceil(1.5*Math.max(8,Math.min(13,Math.log(a.length)))):12+s.mem,o,f,u)},O=function(t,n,r){for(;r;++n)t[n]=r,r>>>=8},j=function(){function n(n,r){if("function"==typeof n&&(r=n,n={}),this.ondata=r,this.o=n||{},this.s={l:0,i:32768,w:32768,z:32768},this.b=new t(98304),this.o.dictionary){var e=this.o.dictionary.subarray(-32768);this.b.set(e,32768-e.length),this.s.i=32768-e.length}}return n.prototype.p=function(t,n){this.ondata(L(t,this.o,0,0,this.s),n)},n.prototype.push=function(n,r){this.ondata||E(5),this.s.l&&E(4);var e=n.length+this.s.z;if(e>this.b.length){if(e>2*this.b.length-32768){var i=new t(-32768&e);i.set(this.b.subarray(0,this.s.z)),this.b=i}var a=this.b.length-this.s.z;a&&(this.b.set(n.subarray(0,a),this.s.z),this.s.z=this.b.length,this.p(this.b,!1)),this.b.set(this.b.subarray(-32768)),this.b.set(n.subarray(a),32768),this.s.z=n.length-a+32768,this.s.i=32766,this.s.w=32768}else this.b.set(n,this.s.z),this.s.z+=n.length;this.s.l=1&r,(this.s.z>this.s.w+8191||r)&&(this.p(this.b,r||!1),this.s.w=this.s.i,this.s.i-=2)},n}();function q(t,n){n||(n={});var r=function(){var t=-1;return{p:function(n){for(var r=t,e=0;e<n.length;++e)r=I[255&r^n[e]]^r>>>8;t=r},d:function(){return~t}}}(),e=t.length;r.p(t);var i,a=L(t,n,10+((i=n).filename?i.filename.length+1:0),8),s=a.length;return function(t,n){var r=n.filename;if(t[0]=31,t[1]=139,t[2]=8,t[8]=n.level<2?4:9==n.level?2:0,t[9]=3,0!=n.mtime&&O(t,4,Math.floor(new Date(n.mtime||Date.now())/1e3)),r){t[3]=8;for(var e=0;e<=r.length;++e)t[e+10]=r.charCodeAt(e)}}(a,n),O(a,s-8,r.d()),O(a,s-4,e),a}var B=function(){function t(t,n){this.c=S(),this.v=1,j.call(this,t,n)}return t.prototype.push=function(t,n){this.c.p(t),j.prototype.push.call(this,t,n)},t.prototype.p=function(t,n){var r=L(t,this.o,this.v&&(this.o.dictionary?6:2),n&&4,this.s);this.v&&(function(t,n){var r=n.level,e=0==r?0:r<6?1:9==r?3:2;if(t[0]=120,t[1]=e<<6|(n.dictionary&&32),t[1]|=31-(t[0]<<8|t[1])%31,n.dictionary){var i=S();i.p(n.dictionary),O(t,2,i.d())}}(r,this.o),this.v=0),n&&O(r,r.length-4,this.c.d()),this.ondata(r,n)},t}(),G="undefined"!=typeof TextEncoder&&new TextEncoder,H="undefined"!=typeof TextDecoder&&new TextDecoder;try{H.decode(F,{stream:!0})}catch(t){}var J=function(){function t(t){this.ondata=t}return t.prototype.push=function(t,n){this.ondata||E(5),this.d&&E(4),this.ondata(K(t),this.d=n||!1)},t}();function K(n,r){if(r){for(var e=new t(n.length),i=0;i<n.length;++i)e[i]=n.charCodeAt(i);return e}if(G)return G.encode(n);var a=n.length,s=new t(n.length+(n.length>>1)),o=0,f=function(t){s[o++]=t};for(i=0;i<a;++i){if(o+5>s.length){var h=new t(o+8+(a-i<<1));h.set(s),s=h}var l=n.charCodeAt(i);l<128||r?f(l):l<2048?(f(192|l>>6),f(128|63&l)):l>55295&&l<57344?(f(240|(l=65536+(1047552&l)|1023&n.charCodeAt(++i))>>18),f(128|l>>12&63),f(128|l>>6&63),f(128|63&l)):(f(224|l>>12),f(128|l>>6&63),f(128|63&l))}return b(s,0,o)}const N=new class{constructor(){this._init()}clear(){this._init()}addEvent(t){if(!t)throw new Error("Adding invalid event");const n=this._hasEvents?",":"";this.stream.push(n+t),this._hasEvents=!0}finish(){this.stream.push("]",!0);const t=function(t){let n=0;for(let r=0,e=t.length;r<e;r++)n+=t[r].length;const r=new Uint8Array(n);for(let n=0,e=0,i=t.length;n<i;n++){const i=t[n];r.set(i,e),e+=i.length}return r}(this._deflatedData);return this._init(),t}_init(){this._hasEvents=!1,this._deflatedData=[],this.deflate=new B,this.deflate.ondata=(t,n)=>{this._deflatedData.push(t)},this.stream=new J(((t,n)=>{this.deflate.push(t,n)})),this.stream.push("[")}},P={clear:()=>{N.clear()},addEvent:t=>N.addEvent(t),finish:()=>N.finish(),compress:t=>function(t){return q(K(t))}(t)};addEventListener("message",(function(t){const n=t.data.method,r=t.data.id,e=t.data.arg;if(n in P&&"function"==typeof P[n])try{const t=P[n](e);postMessage({id:r,method:n,success:!0,response:t})}catch(t){postMessage({id:r,method:n,success:!1,response:t.message}),console.error(t)}})),postMessage({id:void 0,method:"init",success:!0,response:void 0});`;
36594
36595function e(){const e=new Blob([r]);return URL.createObjectURL(e)}
36596
36597/**
36598 * Log a message in debug mode, and add a breadcrumb when _experiment.traceInternals is enabled.
36599 */
36600function logInfo(message, shouldAddBreadcrumb) {
36601  if (!DEBUG_BUILD) {
36602    return;
36603  }
36604
36605  utils.logger.info(message);
36606
36607  if (shouldAddBreadcrumb) {
36608    addLogBreadcrumb(message);
36609  }
36610}
36611
36612/**
36613 * Log a message, and add a breadcrumb in the next tick.
36614 * This is necessary when the breadcrumb may be added before the replay is initialized.
36615 */
36616function logInfoNextTick(message, shouldAddBreadcrumb) {
36617  if (!DEBUG_BUILD) {
36618    return;
36619  }
36620
36621  utils.logger.info(message);
36622
36623  if (shouldAddBreadcrumb) {
36624    // Wait a tick here to avoid race conditions for some initial logs
36625    // which may be added before replay is initialized
36626    setTimeout(() => {
36627      addLogBreadcrumb(message);
36628    }, 0);
36629  }
36630}
36631
36632function addLogBreadcrumb(message) {
36633  core.addBreadcrumb(
36634    {
36635      category: 'console',
36636      data: {
36637        logger: 'replay',
36638      },
36639      level: 'info',
36640      message,
36641    },
36642    { level: 'info' },
36643  );
36644}
36645
36646/** This error indicates that the event buffer size exceeded the limit.. */
36647class EventBufferSizeExceededError extends Error {
36648   constructor() {
36649    super(`Event buffer exceeded maximum size of ${REPLAY_MAX_EVENT_BUFFER_SIZE}.`);
36650  }
36651}
36652
36653/**
36654 * A basic event buffer that does not do any compression.
36655 * Used as fallback if the compression worker cannot be loaded or is disabled.
36656 */
36657class EventBufferArray  {
36658  /** All the events that are buffered to be sent. */
36659
36660  /** @inheritdoc */
36661
36662   constructor() {
36663    this.events = [];
36664    this._totalSize = 0;
36665    this.hasCheckout = false;
36666  }
36667
36668  /** @inheritdoc */
36669   get hasEvents() {
36670    return this.events.length > 0;
36671  }
36672
36673  /** @inheritdoc */
36674   get type() {
36675    return 'sync';
36676  }
36677
36678  /** @inheritdoc */
36679   destroy() {
36680    this.events = [];
36681  }
36682
36683  /** @inheritdoc */
36684   async addEvent(event) {
36685    const eventSize = JSON.stringify(event).length;
36686    this._totalSize += eventSize;
36687    if (this._totalSize > REPLAY_MAX_EVENT_BUFFER_SIZE) {
36688      throw new EventBufferSizeExceededError();
36689    }
36690
36691    this.events.push(event);
36692  }
36693
36694  /** @inheritdoc */
36695   finish() {
36696    return new Promise(resolve => {
36697      // Make a copy of the events array reference and immediately clear the
36698      // events member so that we do not lose new events while uploading
36699      // attachment.
36700      const eventsRet = this.events;
36701      this.clear();
36702      resolve(JSON.stringify(eventsRet));
36703    });
36704  }
36705
36706  /** @inheritdoc */
36707   clear() {
36708    this.events = [];
36709    this._totalSize = 0;
36710    this.hasCheckout = false;
36711  }
36712
36713  /** @inheritdoc */
36714   getEarliestTimestamp() {
36715    const timestamp = this.events.map(event => event.timestamp).sort()[0];
36716
36717    if (!timestamp) {
36718      return null;
36719    }
36720
36721    return timestampToMs(timestamp);
36722  }
36723}
36724
36725/**
36726 * Event buffer that uses a web worker to compress events.
36727 * Exported only for testing.
36728 */
36729class WorkerHandler {
36730
36731   constructor(worker) {
36732    this._worker = worker;
36733    this._id = 0;
36734  }
36735
36736  /**
36737   * Ensure the worker is ready (or not).
36738   * This will either resolve when the worker is ready, or reject if an error occured.
36739   */
36740   ensureReady() {
36741    // Ensure we only check once
36742    if (this._ensureReadyPromise) {
36743      return this._ensureReadyPromise;
36744    }
36745
36746    this._ensureReadyPromise = new Promise((resolve, reject) => {
36747      this._worker.addEventListener(
36748        'message',
36749        ({ data }) => {
36750          if ((data ).success) {
36751            resolve();
36752          } else {
36753            reject();
36754          }
36755        },
36756        { once: true },
36757      );
36758
36759      this._worker.addEventListener(
36760        'error',
36761        error => {
36762          reject(error);
36763        },
36764        { once: true },
36765      );
36766    });
36767
36768    return this._ensureReadyPromise;
36769  }
36770
36771  /**
36772   * Destroy the worker.
36773   */
36774   destroy() {
36775    logInfo('[Replay] Destroying compression worker');
36776    this._worker.terminate();
36777  }
36778
36779  /**
36780   * Post message to worker and wait for response before resolving promise.
36781   */
36782   postMessage(method, arg) {
36783    const id = this._getAndIncrementId();
36784
36785    return new Promise((resolve, reject) => {
36786      const listener = ({ data }) => {
36787        const response = data ;
36788        if (response.method !== method) {
36789          return;
36790        }
36791
36792        // There can be multiple listeners for a single method, the id ensures
36793        // that the response matches the caller.
36794        if (response.id !== id) {
36795          return;
36796        }
36797
36798        // At this point, we'll always want to remove listener regardless of result status
36799        this._worker.removeEventListener('message', listener);
36800
36801        if (!response.success) {
36802          // TODO: Do some error handling, not sure what
36803          DEBUG_BUILD && utils.logger.error('[Replay]', response.response);
36804
36805          reject(new Error('Error in compression worker'));
36806          return;
36807        }
36808
36809        resolve(response.response );
36810      };
36811
36812      // Note: we can't use `once` option because it's possible it needs to
36813      // listen to multiple messages
36814      this._worker.addEventListener('message', listener);
36815      this._worker.postMessage({ id, method, arg });
36816    });
36817  }
36818
36819  /** Get the current ID and increment it for the next call. */
36820   _getAndIncrementId() {
36821    return this._id++;
36822  }
36823}
36824
36825/**
36826 * Event buffer that uses a web worker to compress events.
36827 * Exported only for testing.
36828 */
36829class EventBufferCompressionWorker  {
36830  /** @inheritdoc */
36831
vendor: 3,385 bytes, lines 36832-36982
36832   constructor(worker) {
36833    this._worker = new WorkerHandler(worker);
36834    this._earliestTimestamp = null;
36835    this._totalSize = 0;
36836    this.hasCheckout = false;
36837  }
36838
36839  /** @inheritdoc */
36840   get hasEvents() {
36841    return !!this._earliestTimestamp;
36842  }
36843
36844  /** @inheritdoc */
36845   get type() {
36846    return 'worker';
36847  }
36848
36849  /**
36850   * Ensure the worker is ready (or not).
36851   * This will either resolve when the worker is ready, or reject if an error occured.
36852   */
36853   ensureReady() {
36854    return this._worker.ensureReady();
36855  }
36856
36857  /**
36858   * Destroy the event buffer.
36859   */
36860   destroy() {
36861    this._worker.destroy();
36862  }
36863
36864  /**
36865   * Add an event to the event buffer.
36866   *
36867   * Returns true if event was successfuly received and processed by worker.
36868   */
36869   addEvent(event) {
36870    const timestamp = timestampToMs(event.timestamp);
36871    if (!this._earliestTimestamp || timestamp < this._earliestTimestamp) {
36872      this._earliestTimestamp = timestamp;
36873    }
36874
36875    const data = JSON.stringify(event);
36876    this._totalSize += data.length;
36877
36878    if (this._totalSize > REPLAY_MAX_EVENT_BUFFER_SIZE) {
36879      return Promise.reject(new EventBufferSizeExceededError());
36880    }
36881
36882    return this._sendEventToWorker(data);
36883  }
36884
36885  /**
36886   * Finish the event buffer and return the compressed data.
36887   */
36888   finish() {
36889    return this._finishRequest();
36890  }
36891
36892  /** @inheritdoc */
36893   clear() {
36894    this._earliestTimestamp = null;
36895    this._totalSize = 0;
36896    this.hasCheckout = false;
36897
36898    // We do not wait on this, as we assume the order of messages is consistent for the worker
36899    this._worker.postMessage('clear').then(null, e => {
36900      DEBUG_BUILD && utils.logger.warn('[Replay] Sending "clear" message to worker failed', e);
36901    });
36902  }
36903
36904  /** @inheritdoc */
36905   getEarliestTimestamp() {
36906    return this._earliestTimestamp;
36907  }
36908
36909  /**
36910   * Send the event to the worker.
36911   */
36912   _sendEventToWorker(data) {
36913    return this._worker.postMessage('addEvent', data);
36914  }
36915
36916  /**
36917   * Finish the request and return the compressed data from the worker.
36918   */
36919   async _finishRequest() {
36920    const response = await this._worker.postMessage('finish');
36921
36922    this._earliestTimestamp = null;
36923    this._totalSize = 0;
36924
36925    return response;
36926  }
36927}
36928
36929/**
36930 * This proxy will try to use the compression worker, and fall back to use the simple buffer if an error occurs there.
36931 * This can happen e.g. if the worker cannot be loaded.
36932 * Exported only for testing.
36933 */
36934class EventBufferProxy  {
36935
36936   constructor(worker) {
36937    this._fallback = new EventBufferArray();
36938    this._compression = new EventBufferCompressionWorker(worker);
36939    this._used = this._fallback;
36940
36941    this._ensureWorkerIsLoadedPromise = this._ensureWorkerIsLoaded();
36942  }
36943
36944  /** @inheritdoc */
36945   get type() {
36946    return this._used.type;
36947  }
36948
36949  /** @inheritDoc */
36950   get hasEvents() {
36951    return this._used.hasEvents;
36952  }
36953
36954  /** @inheritdoc */
36955   get hasCheckout() {
36956    return this._used.hasCheckout;
36957  }
36958  /** @inheritdoc */
36959   set hasCheckout(value) {
36960    this._used.hasCheckout = value;
36961  }
36962
36963  /** @inheritDoc */
36964   destroy() {
36965    this._fallback.destroy();
36966    this._compression.destroy();
36967  }
36968
36969  /** @inheritdoc */
36970   clear() {
36971    return this._used.clear();
36972  }
36973
36974  /** @inheritdoc */
36975   getEarliestTimestamp() {
36976    return this._used.getEarliestTimestamp();
36977  }
36978
36979  /**
36980   * Add an event to the event buffer.
36981   *
36982   * Returns true if event was successfully added.
36983   */
36984   addEvent(event) {
36985    return this._used.addEvent(event);
36986  }
36987
36988  /** @inheritDoc */
36989   async finish() {
36990    // Ensure the worker is loaded, so the sent event is compressed
36991    await this.ensureWorkerIsLoaded();
36992
36993    return this._used.finish();
36994  }
36995
36996  /** Ensure the worker has loaded. */
36997   ensureWorkerIsLoaded() {
36998    return this._ensureWorkerIsLoadedPromise;
36999  }
37000
37001  /** Actually check if the worker has been loaded. */
37002   async _ensureWorkerIsLoaded() {
37003    try {
37004      await this._compression.ensureReady();
37005    } catch (error) {
37006      // If the worker fails to load, we fall back to the simple buffer.
37007      // Nothing more to do from our side here
37008      logInfo('[Replay] Failed to load the compression worker, falling back to simple buffer');
37009      return;
37010    }
37011
37012    // Now we need to switch over the array buffer to the compression worker
37013    await this._switchToCompressionWorker();
37014  }
37015
37016  /** Switch the used buffer to the compression worker. */
37017   async _switchToCompressionWorker() {
37018    const { events, hasCheckout } = this._fallback;
37019
37020    const addEventPromises = [];
37021    for (const event of events) {
37022      addEventPromises.push(this._compression.addEvent(event));
37023    }
37024
37025    this._compression.hasCheckout = hasCheckout;
37026
37027    // We switch over to the new buffer immediately - any further events will be added
37028    // after the previously buffered ones
37029    this._used = this._compression;
37030
37031    // Wait for original events to be re-added before resolving
37032    try {
37033      await Promise.all(addEventPromises);
37034    } catch (error) {
37035      DEBUG_BUILD && utils.logger.warn('[Replay] Failed to add events when switching buffers.', error);
37036    }
37037  }
37038}
37039
37040/**
37041 * Create an event buffer for replays.
37042 */
37043function createEventBuffer({
37044  useCompression,
37045  workerUrl: customWorkerUrl,
37046}) {
37047  if (
37048    useCompression &&
37049    // eslint-disable-next-line no-restricted-globals
37050    window.Worker
37051  ) {
37052    const worker = _loadWorker(customWorkerUrl);
37053
37054    if (worker) {
37055      return worker;
37056    }
37057  }
37058
37059  logInfo('[Replay] Using simple buffer');
37060  return new EventBufferArray();
37061}
37062
37063function _loadWorker(customWorkerUrl) {
37064  try {
37065    const workerUrl = customWorkerUrl || _getWorkerUrl();
37066
37067    if (!workerUrl) {
37068      return;
37069    }
37070
37071    logInfo(`[Replay] Using compression worker${customWorkerUrl ? ` from ${customWorkerUrl}` : ''}`);
37072    const worker = new Worker(workerUrl);
37073    return new EventBufferProxy(worker);
37074  } catch (error) {
37075    logInfo('[Replay] Failed to create compression worker');
37076    // Fall back to use simple event buffer array
37077  }
37078}
37079
37080function _getWorkerUrl() {
37081  if (typeof __SENTRY_EXCLUDE_REPLAY_WORKER__ === 'undefined' || !__SENTRY_EXCLUDE_REPLAY_WORKER__) {
37082    return e();
37083  }
37084
37085  return '';
37086}
37087
37088/** If sessionStorage is available. */
37089function hasSessionStorage() {
37090  try {
37091    // This can throw, e.g. when being accessed in a sandboxed iframe
37092    return 'sessionStorage' in WINDOW && !!WINDOW.sessionStorage;
37093  } catch (e) {
37094    return false;
37095  }
37096}
37097
37098/**
37099 * Removes the session from Session Storage and unsets session in replay instance
37100 */
37101function clearSession(replay) {
37102  deleteSession();
37103  replay.session = undefined;
37104}
37105
37106/**
37107 * Deletes a session from storage
37108 */
37109function deleteSession() {
37110  if (!hasSessionStorage()) {
37111    return;
37112  }
37113
37114  try {
37115    WINDOW.sessionStorage.removeItem(REPLAY_SESSION_KEY);
37116  } catch (e) {
37117    // Ignore potential SecurityError exceptions
37118  }
37119}
37120
37121/**
37122 * Given a sample rate, returns true if replay should be sampled.
37123 *
37124 * 1.0 = 100% sampling
37125 * 0.0 = 0% sampling
37126 */
37127function isSampled(sampleRate) {
37128  if (sampleRate === undefined) {
37129    return false;
37130  }
37131
37132  // Math.random() returns a number in range of 0 to 1 (inclusive of 0, but not 1)
37133  return Math.random() < sampleRate;
37134}
37135
37136/**
37137 * Get a session with defaults & applied sampling.
37138 */
37139function makeSession(session) {
37140  const now = Date.now();
37141  const id = session.id || utils.uuid4();
37142  // Note that this means we cannot set a started/lastActivity of `0`, but this should not be relevant outside of tests.
37143  const started = session.started || now;
37144  const lastActivity = session.lastActivity || now;
37145  const segmentId = session.segmentId || 0;
37146  const sampled = session.sampled;
37147  const previousSessionId = session.previousSessionId;
37148
37149  return {
37150    id,
37151    started,
37152    lastActivity,
37153    segmentId,
37154    sampled,
37155    previousSessionId,
37156  };
37157}
37158
37159/**
37160 * Save a session to session storage.
37161 */
37162function saveSession(session) {
37163  if (!hasSessionStorage()) {
37164    return;
37165  }
37166
37167  try {
37168    WINDOW.sessionStorage.setItem(REPLAY_SESSION_KEY, JSON.stringify(session));
37169  } catch (e) {
37170    // Ignore potential SecurityError exceptions
37171  }
37172}
37173
37174/**
37175 * Get the sampled status for a session based on sample rates & current sampled status.
37176 */
37177function getSessionSampleType(sessionSampleRate, allowBuffering) {
37178  return isSampled(sessionSampleRate) ? 'session' : allowBuffering ? 'buffer' : false;
37179}
37180
37181/**
37182 * Create a new session, which in its current implementation is a Sentry event
37183 * that all replays will be saved to as attachments. Currently, we only expect
37184 * one of these Sentry events per "replay session".
37185 */
37186function createSession(
37187  { sessionSampleRate, allowBuffering, stickySession = false },
37188  { previousSessionId } = {},
37189) {
37190  const sampled = getSessionSampleType(sessionSampleRate, allowBuffering);
37191  const session = makeSession({
37192    sampled,
37193    previousSessionId,
37194  });
37195
37196  if (stickySession) {
37197    saveSession(session);
37198  }
37199
37200  return session;
37201}
37202
37203/**
37204 * Fetches a session from storage
37205 */
37206function fetchSession(traceInternals) {
37207  if (!hasSessionStorage()) {
37208    return null;
37209  }
37210
37211  try {
37212    // This can throw if cookies are disabled
37213    const sessionStringFromStorage = WINDOW.sessionStorage.getItem(REPLAY_SESSION_KEY);
37214
37215    if (!sessionStringFromStorage) {
37216      return null;
37217    }
37218
37219    const sessionObj = JSON.parse(sessionStringFromStorage) ;
37220
37221    logInfoNextTick('[Replay] Loading existing session', traceInternals);
37222
37223    return makeSession(sessionObj);
37224  } catch (e) {
37225    return null;
37226  }
37227}
37228
37229/**
37230 * Given an initial timestamp and an expiry duration, checks to see if current
37231 * time should be considered as expired.
37232 */
37233function isExpired(
37234  initialTime,
37235  expiry,
37236  targetTime = +new Date(),
37237) {
37238  // Always expired if < 0
37239  if (initialTime === null || expiry === undefined || expiry < 0) {
37240    return true;
37241  }
37242
37243  // Never expires if == 0
37244  if (expiry === 0) {
37245    return false;
37246  }
37247
37248  return initialTime + expiry <= targetTime;
37249}
37250
37251/**
37252 * Checks to see if session is expired
37253 */
37254function isSessionExpired(
37255  session,
37256  {
37257    maxReplayDuration,
37258    sessionIdleExpire,
37259    targetTime = Date.now(),
37260  },
37261) {
37262  return (
37263    // First, check that maximum session length has not been exceeded
37264    isExpired(session.started, maxReplayDuration, targetTime) ||
37265    // check that the idle timeout has not been exceeded (i.e. user has
37266    // performed an action within the last `sessionIdleExpire` ms)
37267    isExpired(session.lastActivity, sessionIdleExpire, targetTime)
37268  );
37269}
37270
37271/** If the session should be refreshed or not. */
37272function shouldRefreshSession(
37273  session,
37274  { sessionIdleExpire, maxReplayDuration },
37275) {
37276  // If not expired, all good, just keep the session
37277  if (!isSessionExpired(session, { sessionIdleExpire, maxReplayDuration })) {
37278    return false;
37279  }
37280
37281  // If we are buffering & haven't ever flushed yet, always continue
37282  if (session.sampled === 'buffer' && session.segmentId === 0) {
37283    return false;
37284  }
37285
37286  return true;
37287}
37288
37289/**
37290 * Get or create a session, when initializing the replay.
37291 * Returns a session that may be unsampled.
37292 */
37293function loadOrCreateSession(
37294  {
37295    traceInternals,
37296    sessionIdleExpire,
37297    maxReplayDuration,
37298    previousSessionId,
37299  }
37300
37301,
37302  sessionOptions,
37303) {
37304  const existingSession = sessionOptions.stickySession && fetchSession(traceInternals);
37305
37306  // No session exists yet, just create a new one
37307  if (!existingSession) {
37308    logInfoNextTick('[Replay] Creating new session', traceInternals);
37309    return createSession(sessionOptions, { previousSessionId });
37310  }
37311
37312  if (!shouldRefreshSession(existingSession, { sessionIdleExpire, maxReplayDuration })) {
37313    return existingSession;
37314  }
37315
37316  logInfoNextTick('[Replay] Session in sessionStorage is expired, creating new one...');
37317  return createSession(sessionOptions, { previousSessionId: existingSession.id });
37318}
37319
37320function isCustomEvent(event) {
37321  return event.type === EventType.Custom;
37322}
37323
37324/**
37325 * Add an event to the event buffer.
37326 * In contrast to `addEvent`, this does not return a promise & does not wait for the adding of the event to succeed/fail.
37327 * Instead this returns `true` if we tried to add the event, else false.
37328 * It returns `false` e.g. if we are paused, disabled, or out of the max replay duration.
37329 *
37330 * `isCheckout` is true if this is either the very first event, or an event triggered by `checkoutEveryNms`.
37331 */
37332function addEventSync(replay, event, isCheckout) {
37333  if (!shouldAddEvent(replay, event)) {
37334    return false;
37335  }
37336
37337  // This should never reject
37338  // eslint-disable-next-line @typescript-eslint/no-floating-promises
37339  _addEvent(replay, event, isCheckout);
37340
37341  return true;
37342}
37343
37344/**
37345 * Add an event to the event buffer.
37346 * Resolves to `null` if no event was added, else to `void`.
37347 *
37348 * `isCheckout` is true if this is either the very first event, or an event triggered by `checkoutEveryNms`.
37349 */
37350function addEvent(
37351  replay,
37352  event,
37353  isCheckout,
37354) {
37355  if (!shouldAddEvent(replay, event)) {
37356    return Promise.resolve(null);
37357  }
37358
37359  return _addEvent(replay, event, isCheckout);
37360}
37361
37362async function _addEvent(
37363  replay,
37364  event,
37365  isCheckout,
37366) {
37367  if (!replay.eventBuffer) {
37368    return null;
37369  }
37370
37371  try {
37372    if (isCheckout && replay.recordingMode === 'buffer') {
37373      replay.eventBuffer.clear();
37374    }
37375
37376    if (isCheckout) {
37377      replay.eventBuffer.hasCheckout = true;
37378    }
37379
37380    const replayOptions = replay.getOptions();
37381
37382    const eventAfterPossibleCallback = maybeApplyCallback(event, replayOptions.beforeAddRecordingEvent);
37383
37384    if (!eventAfterPossibleCallback) {
37385      return;
37386    }
37387
37388    return await replay.eventBuffer.addEvent(eventAfterPossibleCallback);
37389  } catch (error) {
37390    const reason = error && error instanceof EventBufferSizeExceededError ? 'addEventSizeExceeded' : 'addEvent';
37391
37392    DEBUG_BUILD && utils.logger.error(error);
37393    await replay.stop({ reason });
37394
37395    const client = core.getClient();
37396
37397    if (client) {
37398      client.recordDroppedEvent('internal_sdk_error', 'replay');
37399    }
37400  }
37401}
37402
37403/** Exported only for tests. */
37404function shouldAddEvent(replay, event) {
37405  if (!replay.eventBuffer || replay.isPaused() || !replay.isEnabled()) {
37406    return false;
37407  }
37408
37409  const timestampInMs = timestampToMs(event.timestamp);
37410
37411  // Throw out events that happen more than 5 minutes ago. This can happen if
37412  // page has been left open and idle for a long period of time and user
37413  // comes back to trigger a new session. The performance entries rely on
37414  // `performance.timeOrigin`, which is when the page first opened.
37415  if (timestampInMs + replay.timeouts.sessionIdlePause < Date.now()) {
37416    return false;
37417  }
37418
37419  // Throw out events that are +60min from the initial timestamp
37420  if (timestampInMs > replay.getContext().initialTimestamp + replay.getOptions().maxReplayDuration) {
37421    logInfo(
37422      `[Replay] Skipping event with timestamp ${timestampInMs} because it is after maxReplayDuration`,
37423      replay.getOptions()._experiments.traceInternals,
37424    );
37425    return false;
37426  }
37427
37428  return true;
37429}
37430
37431function maybeApplyCallback(
37432  event,
37433  callback,
37434) {
37435  try {
37436    if (typeof callback === 'function' && isCustomEvent(event)) {
37437      return callback(event);
37438    }
37439  } catch (error) {
37440    DEBUG_BUILD &&
37441      utils.logger.error('[Replay] An error occured in the `beforeAddRecordingEvent` callback, skipping the event...', error);
37442    return null;
37443  }
37444
37445  return event;
37446}
37447
37448/** If the event is an error event */
37449function isErrorEvent(event) {
37450  return !event.type;
37451}
37452
37453/** If the event is a transaction event */
37454function isTransactionEvent(event) {
37455  return event.type === 'transaction';
37456}
37457
37458/** If the event is an replay event */
37459function isReplayEvent(event) {
37460  return event.type === 'replay_event';
37461}
37462
37463/** If the event is a feedback event */
37464function isFeedbackEvent(event) {
37465  return event.type === 'feedback';
37466}
37467
37468/**
37469 * Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.
37470 */
37471function handleAfterSendEvent(replay) {
37472  // Custom transports may still be returning `Promise<void>`, which means we cannot expect the status code to be available there
37473  // TODO (v8): remove this check as it will no longer be necessary
37474  const enforceStatusCode = isBaseTransportSend();
37475
37476  return (event, sendResponse) => {
37477    if (!replay.isEnabled() || (!isErrorEvent(event) && !isTransactionEvent(event))) {
37478      return;
37479    }
37480
37481    const statusCode = sendResponse && sendResponse.statusCode;
37482
37483    // We only want to do stuff on successful error sending, otherwise you get error replays without errors attached
37484    // If not using the base transport, we allow `undefined` response (as a custom transport may not implement this correctly yet)
37485    // If we do use the base transport, we skip if we encountered an non-OK status code
37486    if (enforceStatusCode && (!statusCode || statusCode < 200 || statusCode >= 300)) {
37487      return;
37488    }
37489
37490    if (isTransactionEvent(event)) {
37491      handleTransactionEvent(replay, event);
37492      return;
37493    }
37494
37495    handleErrorEvent(replay, event);
37496  };
37497}
37498
37499function handleTransactionEvent(replay, event) {
37500  const replayContext = replay.getContext();
37501
37502  // Collect traceIds in _context regardless of `recordingMode`
37503  // In error mode, _context gets cleared on every checkout
37504  // We limit to max. 100 transactions linked
37505  if (event.contexts && event.contexts.trace && event.contexts.trace.trace_id && replayContext.traceIds.size < 100) {
37506    replayContext.traceIds.add(event.contexts.trace.trace_id );
37507  }
37508}
37509
37510function handleErrorEvent(replay, event) {
37511  const replayContext = replay.getContext();
37512
37513  // Add error to list of errorIds of replay. This is ok to do even if not
37514  // sampled because context will get reset at next checkout.
37515  // XXX: There is also a race condition where it's possible to capture an
37516  // error to Sentry before Replay SDK has loaded, but response returns after
37517  // it was loaded, and this gets called.
37518  // We limit to max. 100 errors linked
37519  if (event.event_id && replayContext.errorIds.size < 100) {
37520    replayContext.errorIds.add(event.event_id);
37521  }
37522
37523  // If error event is tagged with replay id it means it was sampled (when in buffer mode)
37524  // Need to be very careful that this does not cause an infinite loop
37525  if (replay.recordingMode !== 'buffer' || !event.tags || !event.tags.replayId) {
37526    return;
37527  }
37528
37529  const { beforeErrorSampling } = replay.getOptions();
37530  if (typeof beforeErrorSampling === 'function' && !beforeErrorSampling(event)) {
37531    return;
37532  }
37533
37534  setTimeout(() => {
37535    // Capture current event buffer as new replay
37536    // This should never reject
37537    // eslint-disable-next-line @typescript-eslint/no-floating-promises
37538    replay.sendBufferedReplayOrFlush();
37539  });
37540}
37541
37542function isBaseTransportSend() {
37543  const client = core.getClient();
37544  if (!client) {
37545    return false;
37546  }
37547
37548  const transport = client.getTransport();
37549  if (!transport) {
37550    return false;
37551  }
37552
37553  return (
37554    (transport.send ).__sentry__baseTransport__ || false
37555  );
37556}
37557
37558/**
37559 * Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.
37560 */
37561function handleBeforeSendEvent(replay) {
37562  return (event) => {
37563    if (!replay.isEnabled() || !isErrorEvent(event)) {
37564      return;
37565    }
37566
37567    handleHydrationError(replay, event);
37568  };
37569}
37570
37571function handleHydrationError(replay, event) {
37572  const exceptionValue = event.exception && event.exception.values && event.exception.values[0].value;
37573  if (typeof exceptionValue !== 'string') {
37574    return;
37575  }
37576
37577  if (
37578    // Only matches errors in production builds of react-dom
37579    // Example https://reactjs.org/docs/error-decoder.html?invariant=423
37580    exceptionValue.match(/reactjs\.org\/docs\/error-decoder\.html\?invariant=(418|419|422|423|425)/) ||
37581    // Development builds of react-dom
37582    // Error 1: Hydration failed because the initial UI does not match what was rendered on the server.
37583    // Error 2: Text content does not match server-rendered HTML. Warning: Text content did not match.
37584    exceptionValue.match(/(does not match server-rendered HTML|Hydration failed because)/i)
37585  ) {
37586    const breadcrumb = createBreadcrumb({
37587      category: 'replay.hydrate-error',
37588    });
37589    addBreadcrumbEvent(replay, breadcrumb);
37590  }
37591}
37592
37593/**
37594 * Returns true if we think the given event is an error originating inside of rrweb.
37595 */
37596function isRrwebError(event, hint) {
37597  if (event.type || !event.exception || !event.exception.values || !event.exception.values.length) {
37598    return false;
37599  }
37600
37601  // @ts-expect-error this may be set by rrweb when it finds errors
37602  if (hint.originalException && hint.originalException.__rrweb__) {
37603    return true;
37604  }
37605
37606  return false;
37607}
37608
37609/**
37610 * Add a feedback breadcrumb event to replay.
37611 */
37612function addFeedbackBreadcrumb(replay, event) {
37613  replay.triggerUserActivity();
37614  replay.addUpdate(() => {
37615    if (!event.timestamp) {
37616      // Ignore events that don't have timestamps (this shouldn't happen, more of a typing issue)
37617      // Return true here so that we don't flush
37618      return true;
37619    }
37620
37621    // This should never reject
37622    // eslint-disable-next-line @typescript-eslint/no-floating-promises
37623    replay.throttledAddEvent({
37624      type: EventType.Custom,
37625      timestamp: event.timestamp * 1000,
37626      data: {
37627        tag: 'breadcrumb',
37628        payload: {
37629          timestamp: event.timestamp,
37630          type: 'default',
37631          category: 'sentry.feedback',
37632          data: {
37633            feedbackId: event.event_id,
37634          },
37635        },
37636      },
37637    } );
37638
37639    return false;
37640  });
37641}
37642
37643/**
37644 * Determine if event should be sampled (only applies in buffer mode).
37645 * When an event is captured by `hanldleGlobalEvent`, when in buffer mode
37646 * we determine if we want to sample the error or not.
37647 */
37648function shouldSampleForBufferEvent(replay, event) {
37649  if (replay.recordingMode !== 'buffer') {
37650    return false;
37651  }
37652
37653  // ignore this error because otherwise we could loop indefinitely with
37654  // trying to capture replay and failing
37655  if (event.message === UNABLE_TO_SEND_REPLAY) {
37656    return false;
37657  }
37658
37659  // Require the event to be an error event & to have an exception
37660  if (!event.exception || event.type) {
37661    return false;
37662  }
37663
37664  return isSampled(replay.getOptions().errorSampleRate);
37665}
37666
37667/**
37668 * Returns a listener to be added to `addEventProcessor(listener)`.
37669 */
37670function handleGlobalEventListener(
37671  replay,
37672  includeAfterSendEventHandling = false,
37673) {
37674  const afterSendHandler = includeAfterSendEventHandling ? handleAfterSendEvent(replay) : undefined;
37675
37676  return Object.assign(
37677    (event, hint) => {
37678      // Do nothing if replay has been disabled
37679      if (!replay.isEnabled()) {
37680        return event;
37681      }
37682
37683      if (isReplayEvent(event)) {
37684        // Replays have separate set of breadcrumbs, do not include breadcrumbs
37685        // from core SDK
37686        delete event.breadcrumbs;
37687        return event;
37688      }
37689
37690      // We only want to handle errors, transactions, and feedbacks, nothing else
37691      if (!isErrorEvent(event) && !isTransactionEvent(event) && !isFeedbackEvent(event)) {
37692        return event;
37693      }
37694
37695      // Ensure we do not add replay_id if the session is expired
37696      const isSessionActive = replay.checkAndHandleExpiredSession();
37697      if (!isSessionActive) {
37698        return event;
37699      }
37700
37701      if (isFeedbackEvent(event)) {
37702        // This should never reject
37703        // eslint-disable-next-line @typescript-eslint/no-floating-promises
37704        replay.flush();
37705        event.contexts.feedback.replay_id = replay.getSessionId();
37706        // Add a replay breadcrumb for this piece of feedback
37707        addFeedbackBreadcrumb(replay, event);
37708        return event;
37709      }
37710
37711      // Unless `captureExceptions` is enabled, we want to ignore errors coming from rrweb
37712      // As there can be a bunch of stuff going wrong in internals there, that we don't want to bubble up to users
37713      if (isRrwebError(event, hint) && !replay.getOptions()._experiments.captureExceptions) {
37714        DEBUG_BUILD && utils.logger.log('[Replay] Ignoring error from rrweb internals', event);
37715        return null;
37716      }
37717
37718      // When in buffer mode, we decide to sample here.
37719      // Later, in `handleAfterSendEvent`, if the replayId is set, we know that we sampled
37720      // And convert the buffer session to a full session
37721      const isErrorEventSampled = shouldSampleForBufferEvent(replay, event);
37722
37723      // Tag errors if it has been sampled in buffer mode, or if it is session mode
37724      // Only tag transactions if in session mode
37725      const shouldTagReplayId = isErrorEventSampled || replay.recordingMode === 'session';
37726
37727      if (shouldTagReplayId) {
37728        event.tags = { ...event.tags, replayId: replay.getSessionId() };
37729      }
37730
37731      // In cases where a custom client is used that does not support the new hooks (yet),
37732      // we manually call this hook method here
37733      if (afterSendHandler) {
37734        // Pretend the error had a 200 response so we always capture it
37735        afterSendHandler(event, { statusCode: 200 });
37736      }
37737
37738      return event;
37739    },
37740    { id: 'Replay' },
37741  );
37742}
37743
37744/**
37745 * Create a "span" for each performance entry.
37746 */
37747function createPerformanceSpans(
37748  replay,
37749  entries,
37750) {
37751  return entries.map(({ type, start, end, name, data }) => {
37752    const response = replay.throttledAddEvent({
37753      type: EventType.Custom,
37754      timestamp: start,
37755      data: {
37756        tag: 'performanceSpan',
37757        payload: {
37758          op: type,
37759          description: name,
37760          startTimestamp: start,
37761          endTimestamp: end,
37762          data,
37763        },
37764      },
37765    });
37766
37767    // If response is a string, it means its either THROTTLED or SKIPPED
37768    return typeof response === 'string' ? Promise.resolve(null) : response;
37769  });
37770}
37771
37772function handleHistory(handlerData) {
37773  const { from, to } = handlerData;
37774
37775  const now = Date.now() / 1000;
37776
37777  return {
37778    type: 'navigation.push',
37779    start: now,
37780    end: now,
37781    name: to,
37782    data: {
37783      previous: from,
37784    },
37785  };
37786}
37787
37788/**
37789 * Returns a listener to be added to `addHistoryInstrumentationHandler(listener)`.
37790 */
37791function handleHistorySpanListener(replay) {
37792  return (handlerData) => {
37793    if (!replay.isEnabled()) {
37794      return;
37795    }
37796
37797    const result = handleHistory(handlerData);
37798
37799    if (result === null) {
37800      return;
37801    }
37802
37803    // Need to collect visited URLs
37804    replay.getContext().urls.push(result.name);
37805    replay.triggerUserActivity();
37806
37807    replay.addUpdate(() => {
37808      createPerformanceSpans(replay, [result]);
37809      // Returning false to flush
37810      return false;
37811    });
37812  };
37813}
37814
37815/**
37816 * Check whether a given request URL should be filtered out. This is so we
37817 * don't log Sentry ingest requests.
37818 */
37819function shouldFilterRequest(replay, url) {
37820  // If we enabled the `traceInternals` experiment, we want to trace everything
37821  if (DEBUG_BUILD && replay.getOptions()._experiments.traceInternals) {
37822    return false;
37823  }
37824
37825  return core.isSentryRequestUrl(url, core.getClient());
37826}
37827
37828/** Add a performance entry breadcrumb */
37829function addNetworkBreadcrumb(
37830  replay,
37831  result,
37832) {
37833  if (!replay.isEnabled()) {
37834    return;
37835  }
37836
37837  if (result === null) {
37838    return;
37839  }
37840
37841  if (shouldFilterRequest(replay, result.name)) {
37842    return;
37843  }
37844
37845  replay.addUpdate(() => {
37846    createPerformanceSpans(replay, [result]);
37847    // Returning true will cause `addUpdate` to not flush
37848    // We do not want network requests to cause a flush. This will prevent
37849    // recurring/polling requests from keeping the replay session alive.
37850    return true;
37851  });
37852}
37853
37854/** only exported for tests */
37855function handleFetch(handlerData) {
37856  const { startTimestamp, endTimestamp, fetchData, response } = handlerData;
37857
37858  if (!endTimestamp) {
37859    return null;
37860  }
37861
37862  // This is only used as a fallback, so we know the body sizes are never set here
37863  const { method, url } = fetchData;
37864
37865  return {
37866    type: 'resource.fetch',
37867    start: startTimestamp / 1000,
37868    end: endTimestamp / 1000,
37869    name: url,
37870    data: {
37871      method,
37872      statusCode: response ? (response ).status : undefined,
37873    },
37874  };
37875}
37876
37877/**
37878 * Returns a listener to be added to `addFetchInstrumentationHandler(listener)`.
37879 */
37880function handleFetchSpanListener(replay) {
37881  return (handlerData) => {
37882    if (!replay.isEnabled()) {
37883      return;
37884    }
37885
37886    const result = handleFetch(handlerData);
37887
37888    addNetworkBreadcrumb(replay, result);
37889  };
37890}
37891
37892/** only exported for tests */
37893function handleXhr(handlerData) {
37894  const { startTimestamp, endTimestamp, xhr } = handlerData;
37895
37896  const sentryXhrData = xhr[utils.SENTRY_XHR_DATA_KEY];
37897
37898  if (!startTimestamp || !endTimestamp || !sentryXhrData) {
37899    return null;
37900  }
37901
37902  // This is only used as a fallback, so we know the body sizes are never set here
37903  const { method, url, status_code: statusCode } = sentryXhrData;
37904
37905  if (url === undefined) {
37906    return null;
37907  }
37908
37909  return {
37910    type: 'resource.xhr',
37911    name: url,
37912    start: startTimestamp / 1000,
37913    end: endTimestamp / 1000,
37914    data: {
37915      method,
37916      statusCode,
37917    },
37918  };
37919}
37920
37921/**
37922 * Returns a listener to be added to `addXhrInstrumentationHandler(listener)`.
37923 */
37924function handleXhrSpanListener(replay) {
37925  return (handlerData) => {
37926    if (!replay.isEnabled()) {
37927      return;
37928    }
37929
37930    const result = handleXhr(handlerData);
37931
37932    addNetworkBreadcrumb(replay, result);
37933  };
37934}
37935
37936/** Get the size of a body. */
37937function getBodySize(
37938  body,
37939  textEncoder,
37940) {
37941  if (!body) {
37942    return undefined;
37943  }
37944
37945  try {
37946    if (typeof body === 'string') {
37947      return textEncoder.encode(body).length;
37948    }
37949
37950    if (body instanceof URLSearchParams) {
37951      return textEncoder.encode(body.toString()).length;
37952    }
37953
37954    if (body instanceof FormData) {
37955      const formDataStr = _serializeFormData(body);
37956      return textEncoder.encode(formDataStr).length;
37957    }
37958
37959    if (body instanceof Blob) {
37960      return body.size;
37961    }
37962
37963    if (body instanceof ArrayBuffer) {
37964      return body.byteLength;
37965    }
37966
37967    // Currently unhandled types: ArrayBufferView, ReadableStream
37968  } catch (e) {
37969    // just return undefined
37970  }
37971
37972  return undefined;
37973}
37974
37975/** Convert a Content-Length header to number/undefined.  */
37976function parseContentLengthHeader(header) {
37977  if (!header) {
37978    return undefined;
37979  }
37980
37981  const size = parseInt(header, 10);
37982  return isNaN(size) ? undefined : size;
37983}
37984
37985/** Get the string representation of a body. */
37986function getBodyString(body) {
37987  try {
37988    if (typeof body === 'string') {
37989      return [body];
37990    }
37991
37992    if (body instanceof URLSearchParams) {
37993      return [body.toString()];
37994    }
37995
37996    if (body instanceof FormData) {
37997      return [_serializeFormData(body)];
37998    }
37999
38000    if (!body) {
38001      return [undefined];
38002    }
38003  } catch (e2) {
38004    DEBUG_BUILD && utils.logger.warn('[Replay] Failed to serialize body', body);
38005    return [undefined, 'BODY_PARSE_ERROR'];
38006  }
38007
38008  DEBUG_BUILD && utils.logger.info('[Replay] Skipping network body because of body type', body);
38009
38010  return [undefined, 'UNPARSEABLE_BODY_TYPE'];
38011}
38012
38013/** Merge a warning into an existing network request/response. */
38014function mergeWarning(
38015  info,
38016  warning,
38017) {
38018  if (!info) {
38019    return {
38020      headers: {},
38021      size: undefined,
38022      _meta: {
38023        warnings: [warning],
38024      },
38025    };
38026  }
38027
38028  const newMeta = { ...info._meta };
38029  const existingWarnings = newMeta.warnings || [];
38030  newMeta.warnings = [...existingWarnings, warning];
38031
38032  info._meta = newMeta;
38033  return info;
38034}
38035
38036/** Convert ReplayNetworkRequestData to a PerformanceEntry. */
38037function makeNetworkReplayBreadcrumb(
38038  type,
38039  data,
38040) {
38041  if (!data) {
38042    return null;
38043  }
38044
38045  const { startTimestamp, endTimestamp, url, method, statusCode, request, response } = data;
38046
38047  const result = {
38048    type,
38049    start: startTimestamp / 1000,
38050    end: endTimestamp / 1000,
38051    name: url,
38052    data: utils.dropUndefinedKeys({
38053      method,
38054      statusCode,
38055      request,
38056      response,
38057    }),
38058  };
38059
38060  return result;
38061}
38062
38063/** Build the request or response part of a replay network breadcrumb that was skipped. */
38064function buildSkippedNetworkRequestOrResponse(bodySize) {
38065  return {
38066    headers: {},
38067    size: bodySize,
38068    _meta: {
38069      warnings: ['URL_SKIPPED'],
38070    },
38071  };
38072}
38073
38074/** Build the request or response part of a replay network breadcrumb. */
38075function buildNetworkRequestOrResponse(
38076  headers,
38077  bodySize,
38078  body,
38079) {
38080  if (!bodySize && Object.keys(headers).length === 0) {
38081    return undefined;
38082  }
38083
38084  if (!bodySize) {
38085    return {
38086      headers,
38087    };
38088  }
38089
38090  if (!body) {
38091    return {
38092      headers,
38093      size: bodySize,
38094    };
38095  }
38096
38097  const info = {
38098    headers,
38099    size: bodySize,
38100  };
38101
38102  const { body: normalizedBody, warnings } = normalizeNetworkBody(body);
38103  info.body = normalizedBody;
38104  if (warnings && warnings.length > 0) {
38105    info._meta = {
38106      warnings,
38107    };
38108  }
38109
38110  return info;
38111}
38112
38113/** Filter a set of headers */
38114function getAllowedHeaders(headers, allowedHeaders) {
38115  return Object.keys(headers).reduce((filteredHeaders, key) => {
38116    const normalizedKey = key.toLowerCase();
38117    // Avoid putting empty strings into the headers
38118    if (allowedHeaders.includes(normalizedKey) && headers[key]) {
38119      filteredHeaders[normalizedKey] = headers[key];
38120    }
38121    return filteredHeaders;
38122  }, {});
38123}
38124
38125function _serializeFormData(formData) {
38126  // This is a bit simplified, but gives us a decent estimate
38127  // This converts e.g. { name: 'Anne Smith', age: 13 } to 'name=Anne+Smith&age=13'
38128  // @ts-expect-error passing FormData to URLSearchParams actually works
38129  return new URLSearchParams(formData).toString();
38130}
38131
38132function normalizeNetworkBody(body)
38133
38134 {
38135  if (!body || typeof body !== 'string') {
38136    return {
38137      body,
38138    };
38139  }
38140
38141  const exceedsSizeLimit = body.length > NETWORK_BODY_MAX_SIZE;
38142  const isProbablyJson = _strIsProbablyJson(body);
38143
38144  if (exceedsSizeLimit) {
38145    const truncatedBody = body.slice(0, NETWORK_BODY_MAX_SIZE);
38146
38147    if (isProbablyJson) {
38148      return {
38149        body: truncatedBody,
38150        warnings: ['MAYBE_JSON_TRUNCATED'],
38151      };
38152    }
38153
38154    return {
38155      body: `${truncatedBody}…`,
38156      warnings: ['TEXT_TRUNCATED'],
38157    };
38158  }
38159
38160  if (isProbablyJson) {
38161    try {
38162      const jsonBody = JSON.parse(body);
38163      return {
38164        body: jsonBody,
38165      };
38166    } catch (e3) {
38167      // fall back to just send the body as string
38168    }
38169  }
38170
38171  return {
38172    body,
38173  };
38174}
38175
38176function _strIsProbablyJson(str) {
38177  const first = str[0];
38178  const last = str[str.length - 1];
38179
38180  // Simple check: If this does not start & end with {} or [], it's not JSON
38181  return (first === '[' && last === ']') || (first === '{' && last === '}');
38182}
38183
38184/** Match an URL against a list of strings/Regex. */
38185function urlMatches(url, urls) {
38186  const fullUrl = getFullUrl(url);
38187
38188  return utils.stringMatchesSomePattern(fullUrl, urls);
38189}
38190
38191/** exported for tests */
38192function getFullUrl(url, baseURI = WINDOW.document.baseURI) {
38193  // Short circuit for common cases:
38194  if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith(WINDOW.location.origin)) {
38195    return url;
38196  }
38197  const fixedUrl = new URL(url, baseURI);
38198
38199  // If these do not match, we are not dealing with a relative URL, so just return it
38200  if (fixedUrl.origin !== new URL(baseURI).origin) {
38201    return url;
38202  }
38203
38204  const fullUrl = fixedUrl.href;
38205
38206  // Remove trailing slashes, if they don't match the original URL
38207  if (!url.endsWith('/') && fullUrl.endsWith('/')) {
38208    return fullUrl.slice(0, -1);
38209  }
38210
38211  return fullUrl;
38212}
38213
38214/**
38215 * Capture a fetch breadcrumb to a replay.
38216 * This adds additional data (where approriate).
38217 */
38218async function captureFetchBreadcrumbToReplay(
38219  breadcrumb,
38220  hint,
38221  options
38222
38223,
38224) {
38225  try {
38226    const data = await _prepareFetchData(breadcrumb, hint, options);
38227
38228    // Create a replay performance entry from this breadcrumb
38229    const result = makeNetworkReplayBreadcrumb('resource.fetch', data);
38230    addNetworkBreadcrumb(options.replay, result);
38231  } catch (error) {
38232    DEBUG_BUILD && utils.logger.error('[Replay] Failed to capture fetch breadcrumb', error);
38233  }
38234}
38235
38236/**
38237 * Enrich a breadcrumb with additional data.
38238 * This has to be sync & mutate the given breadcrumb,
38239 * as the breadcrumb is afterwards consumed by other handlers.
38240 */
38241function enrichFetchBreadcrumb(
38242  breadcrumb,
38243  hint,
38244  options,
38245) {
38246  const { input, response } = hint;
38247
38248  const body = input ? _getFetchRequestArgBody(input) : undefined;
38249  const reqSize = getBodySize(body, options.textEncoder);
38250
38251  const resSize = response ? parseContentLengthHeader(response.headers.get('content-length')) : undefined;
38252
38253  if (reqSize !== undefined) {
38254    breadcrumb.data.request_body_size = reqSize;
38255  }
38256  if (resSize !== undefined) {
38257    breadcrumb.data.response_body_size = resSize;
38258  }
38259}
38260
38261async function _prepareFetchData(
38262  breadcrumb,
38263  hint,
38264  options
38265
38266,
38267) {
38268  const now = Date.now();
38269  const { startTimestamp = now, endTimestamp = now } = hint;
38270
38271  const {
38272    url,
38273    method,
38274    status_code: statusCode = 0,
38275    request_body_size: requestBodySize,
38276    response_body_size: responseBodySize,
38277  } = breadcrumb.data;
38278
38279  const captureDetails =
38280    urlMatches(url, options.networkDetailAllowUrls) && !urlMatches(url, options.networkDetailDenyUrls);
38281
38282  const request = captureDetails
38283    ? _getRequestInfo(options, hint.input, requestBodySize)
38284    : buildSkippedNetworkRequestOrResponse(requestBodySize);
38285  const response = await _getResponseInfo(captureDetails, options, hint.response, responseBodySize);
38286
38287  return {
38288    startTimestamp,
38289    endTimestamp,
38290    url,
38291    method,
38292    statusCode,
38293    request,
38294    response,
38295  };
38296}
38297
38298function _getRequestInfo(
38299  { networkCaptureBodies, networkRequestHeaders },
38300  input,
38301  requestBodySize,
38302) {
38303  const headers = input ? getRequestHeaders(input, networkRequestHeaders) : {};
38304
38305  if (!networkCaptureBodies) {
38306    return buildNetworkRequestOrResponse(headers, requestBodySize, undefined);
38307  }
38308
38309  // We only want to transmit string or string-like bodies
38310  const requestBody = _getFetchRequestArgBody(input);
38311  const [bodyStr, warning] = getBodyString(requestBody);
38312  const data = buildNetworkRequestOrResponse(headers, requestBodySize, bodyStr);
38313
38314  if (warning) {
38315    return mergeWarning(data, warning);
38316  }
38317
38318  return data;
38319}
38320
38321/** Exported only for tests. */
38322async function _getResponseInfo(
38323  captureDetails,
38324  {
38325    networkCaptureBodies,
38326    textEncoder,
38327    networkResponseHeaders,
38328  }
38329
38330,
38331  response,
38332  responseBodySize,
38333) {
38334  if (!captureDetails && responseBodySize !== undefined) {
38335    return buildSkippedNetworkRequestOrResponse(responseBodySize);
38336  }
38337
38338  const headers = response ? getAllHeaders(response.headers, networkResponseHeaders) : {};
38339
38340  if (!response || (!networkCaptureBodies && responseBodySize !== undefined)) {
38341    return buildNetworkRequestOrResponse(headers, responseBodySize, undefined);
38342  }
38343
38344  const [bodyText, warning] = await _parseFetchResponseBody(response);
38345  const result = getResponseData(bodyText, {
38346    networkCaptureBodies,
38347    textEncoder,
38348    responseBodySize,
38349    captureDetails,
38350    headers,
38351  });
38352
38353  if (warning) {
38354    return mergeWarning(result, warning);
38355  }
38356
38357  return result;
38358}
38359
38360function getResponseData(
38361  bodyText,
38362  {
38363    networkCaptureBodies,
38364    textEncoder,
38365    responseBodySize,
38366    captureDetails,
38367    headers,
38368  }
38369
38370,
38371) {
38372  try {
38373    const size =
38374      bodyText && bodyText.length && responseBodySize === undefined
38375        ? getBodySize(bodyText, textEncoder)
38376        : responseBodySize;
38377
38378    if (!captureDetails) {
38379      return buildSkippedNetworkRequestOrResponse(size);
38380    }
38381
38382    if (networkCaptureBodies) {
38383      return buildNetworkRequestOrResponse(headers, size, bodyText);
38384    }
38385
38386    return buildNetworkRequestOrResponse(headers, size, undefined);
38387  } catch (error) {
38388    DEBUG_BUILD && utils.logger.warn('[Replay] Failed to serialize response body', error);
38389    // fallback
38390    return buildNetworkRequestOrResponse(headers, responseBodySize, undefined);
38391  }
38392}
38393
38394async function _parseFetchResponseBody(response) {
38395  const res = _tryCloneResponse(response);
38396
38397  if (!res) {
38398    return [undefined, 'BODY_PARSE_ERROR'];
38399  }
38400
38401  try {
38402    const text = await _tryGetResponseText(res);
38403    return [text];
38404  } catch (error) {
38405    DEBUG_BUILD && utils.logger.warn('[Replay] Failed to get text body from response', error);
38406    return [undefined, 'BODY_PARSE_ERROR'];
38407  }
38408}
38409
38410function _getFetchRequestArgBody(fetchArgs = []) {
38411  // We only support getting the body from the fetch options
38412  if (fetchArgs.length !== 2 || typeof fetchArgs[1] !== 'object') {
38413    return undefined;
38414  }
38415
38416  return (fetchArgs[1] ).body;
38417}
38418
38419function getAllHeaders(headers, allowedHeaders) {
38420  const allHeaders = {};
38421
38422  allowedHeaders.forEach(header => {
38423    if (headers.get(header)) {
38424      allHeaders[header] = headers.get(header) ;
38425    }
38426  });
38427
38428  return allHeaders;
38429}
38430
38431function getRequestHeaders(fetchArgs, allowedHeaders) {
38432  if (fetchArgs.length === 1 && typeof fetchArgs[0] !== 'string') {
38433    return getHeadersFromOptions(fetchArgs[0] , allowedHeaders);
38434  }
38435
38436  if (fetchArgs.length === 2) {
38437    return getHeadersFromOptions(fetchArgs[1] , allowedHeaders);
38438  }
38439
38440  return {};
38441}
38442
38443function getHeadersFromOptions(
38444  input,
38445  allowedHeaders,
38446) {
38447  if (!input) {
38448    return {};
38449  }
38450
38451  const headers = input.headers;
38452
38453  if (!headers) {
38454    return {};
38455  }
38456
38457  if (headers instanceof Headers) {
38458    return getAllHeaders(headers, allowedHeaders);
38459  }
38460
38461  // We do not support this, as it is not really documented (anymore?)
38462  if (Array.isArray(headers)) {
38463    return {};
38464  }
38465
38466  return getAllowedHeaders(headers, allowedHeaders);
38467}
38468
38469function _tryCloneResponse(response) {
38470  try {
38471    // We have to clone this, as the body can only be read once
38472    return response.clone();
38473  } catch (error) {
38474    // this can throw if the response was already consumed before
38475    DEBUG_BUILD && utils.logger.warn('[Replay] Failed to clone response body', error);
38476  }
38477}
38478
38479/**
38480 * Get the response body of a fetch request, or timeout after 500ms.
38481 * Fetch can return a streaming body, that may not resolve (or not for a long time).
38482 * If that happens, we rather abort after a short time than keep waiting for this.
38483 */
38484function _tryGetResponseText(response) {
38485  return new Promise((resolve, reject) => {
38486    const timeout = setTimeout(() => reject(new Error('Timeout while trying to read response body')), 500);
38487
38488    _getResponseText(response)
38489      .then(
38490        txt => resolve(txt),
38491        reason => reject(reason),
38492      )
38493      .finally(() => clearTimeout(timeout));
38494  });
38495}
38496
38497async function _getResponseText(response) {
38498  // Force this to be a promise, just to be safe
38499  // eslint-disable-next-line no-return-await
38500  return await response.text();
38501}
38502
38503/**
38504 * Capture an XHR breadcrumb to a replay.
38505 * This adds additional data (where approriate).
38506 */
38507async function captureXhrBreadcrumbToReplay(
38508  breadcrumb,
38509  hint,
38510  options,
38511) {
38512  try {
38513    const data = _prepareXhrData(breadcrumb, hint, options);
38514
38515    // Create a replay performance entry from this breadcrumb
38516    const result = makeNetworkReplayBreadcrumb('resource.xhr', data);
38517    addNetworkBreadcrumb(options.replay, result);
38518  } catch (error) {
38519    DEBUG_BUILD && utils.logger.error('[Replay] Failed to capture xhr breadcrumb', error);
38520  }
38521}
38522
38523/**
38524 * Enrich a breadcrumb with additional data.
38525 * This has to be sync & mutate the given breadcrumb,
38526 * as the breadcrumb is afterwards consumed by other handlers.
38527 */
38528function enrichXhrBreadcrumb(
38529  breadcrumb,
38530  hint,
38531  options,
38532) {
38533  const { xhr, input } = hint;
38534
38535  if (!xhr) {
38536    return;
38537  }
38538
38539  const reqSize = getBodySize(input, options.textEncoder);
38540  const resSize = xhr.getResponseHeader('content-length')
38541    ? parseContentLengthHeader(xhr.getResponseHeader('content-length'))
38542    : _getBodySize(xhr.response, xhr.responseType, options.textEncoder);
38543
38544  if (reqSize !== undefined) {
38545    breadcrumb.data.request_body_size = reqSize;
38546  }
38547  if (resSize !== undefined) {
38548    breadcrumb.data.response_body_size = resSize;
38549  }
38550}
38551
38552function _prepareXhrData(
38553  breadcrumb,
38554  hint,
38555  options,
38556) {
38557  const now = Date.now();
38558  const { startTimestamp = now, endTimestamp = now, input, xhr } = hint;
38559
38560  const {
38561    url,
38562    method,
38563    status_code: statusCode = 0,
38564    request_body_size: requestBodySize,
38565    response_body_size: responseBodySize,
38566  } = breadcrumb.data;
38567
38568  if (!url) {
38569    return null;
38570  }
38571
38572  if (!xhr || !urlMatches(url, options.networkDetailAllowUrls) || urlMatches(url, options.networkDetailDenyUrls)) {
38573    const request = buildSkippedNetworkRequestOrResponse(requestBodySize);
38574    const response = buildSkippedNetworkRequestOrResponse(responseBodySize);
38575    return {
38576      startTimestamp,
38577      endTimestamp,
38578      url,
38579      method,
38580      statusCode,
38581      request,
38582      response,
38583    };
38584  }
38585
38586  const xhrInfo = xhr[utils.SENTRY_XHR_DATA_KEY];
38587  const networkRequestHeaders = xhrInfo
38588    ? getAllowedHeaders(xhrInfo.request_headers, options.networkRequestHeaders)
38589    : {};
38590  const networkResponseHeaders = getAllowedHeaders(getResponseHeaders(xhr), options.networkResponseHeaders);
38591
38592  const [requestBody, requestWarning] = options.networkCaptureBodies ? getBodyString(input) : [undefined];
38593  const [responseBody, responseWarning] = options.networkCaptureBodies ? _getXhrResponseBody(xhr) : [undefined];
38594
38595  const request = buildNetworkRequestOrResponse(networkRequestHeaders, requestBodySize, requestBody);
38596  const response = buildNetworkRequestOrResponse(networkResponseHeaders, responseBodySize, responseBody);
38597
38598  return {
38599    startTimestamp,
38600    endTimestamp,
38601    url,
38602    method,
38603    statusCode,
38604    request: requestWarning ? mergeWarning(request, requestWarning) : request,
38605    response: responseWarning ? mergeWarning(response, responseWarning) : response,
38606  };
38607}
38608
38609function getResponseHeaders(xhr) {
38610  const headers = xhr.getAllResponseHeaders();
38611
38612  if (!headers) {
38613    return {};
38614  }
38615
38616  return headers.split('\r\n').reduce((acc, line) => {
38617    const [key, value] = line.split(': ');
38618    acc[key.toLowerCase()] = value;
38619    return acc;
38620  }, {});
38621}
38622
38623function _getXhrResponseBody(xhr) {
38624  // We collect errors that happen, but only log them if we can't get any response body
38625  const errors = [];
38626
38627  try {
38628    return [xhr.responseText];
38629  } catch (e) {
38630    errors.push(e);
38631  }
38632
38633  // Try to manually parse the response body, if responseText fails
38634  try {
38635    return _parseXhrResponse(xhr.response, xhr.responseType);
38636  } catch (e) {
38637    errors.push(e);
38638  }
38639
38640  DEBUG_BUILD && utils.logger.warn('[Replay] Failed to get xhr response body', ...errors);
38641
38642  return [undefined];
38643}
38644
38645/**
38646 * Get the string representation of the XHR response.
38647 * Based on MDN, these are the possible types of the response:
38648 * string
38649 * ArrayBuffer
38650 * Blob
38651 * Document
38652 * POJO
38653 *
38654 * Exported only for tests.
38655 */
38656function _parseXhrResponse(
38657  body,
38658  responseType,
38659) {
38660  try {
38661    if (typeof body === 'string') {
38662      return [body];
38663    }
38664
38665    if (body instanceof Document) {
38666      return [body.body.outerHTML];
38667    }
38668
38669    if (responseType === 'json' && body && typeof body === 'object') {
38670      return [JSON.stringify(body)];
38671    }
38672
38673    if (!body) {
38674      return [undefined];
38675    }
38676  } catch (e2) {
38677    DEBUG_BUILD && utils.logger.warn('[Replay] Failed to serialize body', body);
38678    return [undefined, 'BODY_PARSE_ERROR'];
38679  }
38680
38681  DEBUG_BUILD && utils.logger.info('[Replay] Skipping network body because of body type', body);
38682
38683  return [undefined, 'UNPARSEABLE_BODY_TYPE'];
38684}
38685
38686function _getBodySize(
38687  body,
38688  responseType,
38689  textEncoder,
38690) {
38691  try {
38692    const bodyStr = responseType === 'json' && body && typeof body === 'object' ? JSON.stringify(body) : body;
38693    return getBodySize(bodyStr, textEncoder);
38694  } catch (e3) {
38695    return undefined;
38696  }
38697}
38698
38699/**
38700 * This method does two things:
38701 * - It enriches the regular XHR/fetch breadcrumbs with request/response size data
38702 * - It captures the XHR/fetch breadcrumbs to the replay
38703 *   (enriching it with further data that is _not_ added to the regular breadcrumbs)
38704 */
38705function handleNetworkBreadcrumbs(replay) {
38706  const client = core.getClient();
38707
38708  try {
38709    const textEncoder = new TextEncoder();
38710
38711    const {
38712      networkDetailAllowUrls,
38713      networkDetailDenyUrls,
38714      networkCaptureBodies,
38715      networkRequestHeaders,
38716      networkResponseHeaders,
38717    } = replay.getOptions();
38718
38719    const options = {
38720      replay,
38721      textEncoder,
38722      networkDetailAllowUrls,
38723      networkDetailDenyUrls,
38724      networkCaptureBodies,
38725      networkRequestHeaders,
38726      networkResponseHeaders,
38727    };
38728
38729    if (client && client.on) {
38730      client.on('beforeAddBreadcrumb', (breadcrumb, hint) => beforeAddNetworkBreadcrumb(options, breadcrumb, hint));
38731    } else {
38732      // Fallback behavior
38733      utils.addFetchInstrumentationHandler(handleFetchSpanListener(replay));
38734      utils.addXhrInstrumentationHandler(handleXhrSpanListener(replay));
38735    }
38736  } catch (e2) {
38737    // Do nothing
38738  }
38739}
38740
38741/** just exported for tests */
38742function beforeAddNetworkBreadcrumb(
38743  options,
38744  breadcrumb,
38745  hint,
38746) {
38747  if (!breadcrumb.data) {
38748    return;
38749  }
38750
38751  try {
38752    if (_isXhrBreadcrumb(breadcrumb) && _isXhrHint(hint)) {
38753      // This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
38754      // Because the hook runs synchronously, and the breadcrumb is afterwards passed on
38755      // So any async mutations to it will not be reflected in the final breadcrumb
38756      enrichXhrBreadcrumb(breadcrumb, hint, options);
38757
38758      // This call should not reject
38759      // eslint-disable-next-line @typescript-eslint/no-floating-promises
38760      captureXhrBreadcrumbToReplay(breadcrumb, hint, options);
38761    }
38762
38763    if (_isFetchBreadcrumb(breadcrumb) && _isFetchHint(hint)) {
38764      // This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
38765      // Because the hook runs synchronously, and the breadcrumb is afterwards passed on
38766      // So any async mutations to it will not be reflected in the final breadcrumb
38767      enrichFetchBreadcrumb(breadcrumb, hint, options);
38768
38769      // This call should not reject
38770      // eslint-disable-next-line @typescript-eslint/no-floating-promises
38771      captureFetchBreadcrumbToReplay(breadcrumb, hint, options);
38772    }
38773  } catch (e) {
38774    DEBUG_BUILD && utils.logger.warn('Error when enriching network breadcrumb');
38775  }
38776}
38777
38778function _isXhrBreadcrumb(breadcrumb) {
38779  return breadcrumb.category === 'xhr';
38780}
38781
38782function _isFetchBreadcrumb(breadcrumb) {
38783  return breadcrumb.category === 'fetch';
38784}
38785
38786function _isXhrHint(hint) {
38787  return hint && hint.xhr;
38788}
38789
38790function _isFetchHint(hint) {
38791  return hint && hint.response;
38792}
38793
38794let _LAST_BREADCRUMB = null;
38795
38796function isBreadcrumbWithCategory(breadcrumb) {
38797  return !!breadcrumb.category;
38798}
38799
38800const handleScopeListener =
38801  (replay) =>
38802  (scope) => {
38803    if (!replay.isEnabled()) {
38804      return;
38805    }
38806
38807    const result = handleScope(scope);
38808
38809    if (!result) {
38810      return;
38811    }
38812
38813    addBreadcrumbEvent(replay, result);
38814  };
38815
38816/**
38817 * An event handler to handle scope changes.
38818 */
38819function handleScope(scope) {
38820  // TODO (v8): Remove this guard. This was put in place because we introduced
38821  // Scope.getLastBreadcrumb mid-v7 which caused incompatibilities with older SDKs.
38822  // For now, we'll just return null if the method doesn't exist but we should eventually
38823  // get rid of this guard.
38824  const newBreadcrumb = scope.getLastBreadcrumb && scope.getLastBreadcrumb();
38825
38826  // Listener can be called when breadcrumbs have not changed, so we store the
38827  // reference to the last crumb and only return a crumb if it has changed
38828  if (_LAST_BREADCRUMB === newBreadcrumb || !newBreadcrumb) {
38829    return null;
38830  }
38831
38832  _LAST_BREADCRUMB = newBreadcrumb;
38833
38834  if (
38835    !isBreadcrumbWithCategory(newBreadcrumb) ||
38836    ['fetch', 'xhr', 'sentry.event', 'sentry.transaction'].includes(newBreadcrumb.category) ||
38837    newBreadcrumb.category.startsWith('ui.')
38838  ) {
38839    return null;
38840  }
38841
38842  if (newBreadcrumb.category === 'console') {
38843    return normalizeConsoleBreadcrumb(newBreadcrumb);
38844  }
38845
38846  return createBreadcrumb(newBreadcrumb);
38847}
38848
38849/** exported for tests only */
38850function normalizeConsoleBreadcrumb(
38851  breadcrumb,
38852) {
38853  const args = breadcrumb.data && breadcrumb.data.arguments;
38854
38855  if (!Array.isArray(args) || args.length === 0) {
38856    return createBreadcrumb(breadcrumb);
38857  }
38858
38859  let isTruncated = false;
38860
38861  // Avoid giant args captures
38862  const normalizedArgs = args.map(arg => {
38863    if (!arg) {
38864      return arg;
38865    }
38866    if (typeof arg === 'string') {
38867      if (arg.length > CONSOLE_ARG_MAX_SIZE) {
38868        isTruncated = true;
38869        return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
38870      }
38871
38872      return arg;
38873    }
38874    if (typeof arg === 'object') {
38875      try {
38876        const normalizedArg = utils.normalize(arg, 7);
38877        const stringified = JSON.stringify(normalizedArg);
38878        if (stringified.length > CONSOLE_ARG_MAX_SIZE) {
38879          isTruncated = true;
38880          // We use the pretty printed JSON string here as a base
38881          return `${JSON.stringify(normalizedArg, null, 2).slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
38882        }
38883        return normalizedArg;
38884      } catch (e) {
38885        // fall back to default
38886      }
38887    }
38888
38889    return arg;
38890  });
38891
38892  return createBreadcrumb({
38893    ...breadcrumb,
38894    data: {
38895      ...breadcrumb.data,
38896      arguments: normalizedArgs,
38897      ...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),
38898    },
38899  });
38900}
38901
38902/**
38903 * Add global listeners that cannot be removed.
38904 */
38905function addGlobalListeners(replay) {
38906  // Listeners from core SDK //
38907  const scope = core.getCurrentScope();
38908  const client = core.getClient();
38909
38910  scope.addScopeListener(handleScopeListener(replay));
38911  utils.addClickKeypressInstrumentationHandler(handleDomListener(replay));
38912  utils.addHistoryInstrumentationHandler(handleHistorySpanListener(replay));
38913  handleNetworkBreadcrumbs(replay);
38914
38915  // Tag all (non replay) events that get sent to Sentry with the current
38916  // replay ID so that we can reference them later in the UI
38917  const eventProcessor = handleGlobalEventListener(replay, !hasHooks(client));
38918  if (client && client.addEventProcessor) {
38919    client.addEventProcessor(eventProcessor);
38920  } else {
38921    core.addEventProcessor(eventProcessor);
38922  }
38923
38924  // If a custom client has no hooks yet, we continue to use the "old" implementation
38925  if (hasHooks(client)) {
38926    client.on('beforeSendEvent', handleBeforeSendEvent(replay));
38927    client.on('afterSendEvent', handleAfterSendEvent(replay));
38928    client.on('createDsc', (dsc) => {
38929      const replayId = replay.getSessionId();
38930      // We do not want to set the DSC when in buffer mode, as that means the replay has not been sent (yet)
38931      if (replayId && replay.isEnabled() && replay.recordingMode === 'session') {
38932        // Ensure to check that the session is still active - it could have expired in the meanwhile
38933        const isSessionActive = replay.checkAndHandleExpiredSession();
38934        if (isSessionActive) {
38935          dsc.replay_id = replayId;
38936        }
38937      }
38938    });
38939
38940    client.on('startTransaction', transaction => {
38941      replay.lastTransaction = transaction;
38942    });
38943
38944    // We may be missing the initial startTransaction due to timing issues,
38945    // so we capture it on finish again.
38946    client.on('finishTransaction', transaction => {
38947      replay.lastTransaction = transaction;
38948    });
38949
38950    // We want to flush replay
38951    client.on('beforeSendFeedback', (feedbackEvent, options) => {
38952      const replayId = replay.getSessionId();
38953      if (options && options.includeReplay && replay.isEnabled() && replayId) {
38954        // This should never reject
38955        if (feedbackEvent.contexts && feedbackEvent.contexts.feedback) {
38956          feedbackEvent.contexts.feedback.replay_id = replayId;
38957        }
38958      }
38959    });
38960  }
38961}
38962
38963// eslint-disable-next-line @typescript-eslint/no-explicit-any
38964function hasHooks(client) {
38965  return !!(client && client.on);
38966}
38967
38968/**
38969 * Create a "span" for the total amount of memory being used by JS objects
38970 * (including v8 internal objects).
38971 */
38972async function addMemoryEntry(replay) {
38973  // window.performance.memory is a non-standard API and doesn't work on all browsers, so we try-catch this
38974  try {
38975    return Promise.all(
38976      createPerformanceSpans(replay, [
38977        // @ts-expect-error memory doesn't exist on type Performance as the API is non-standard (we check that it exists above)
38978        createMemoryEntry(WINDOW.performance.memory),
38979      ]),
38980    );
38981  } catch (error) {
38982    // Do nothing
38983    return [];
38984  }
38985}
38986
38987function createMemoryEntry(memoryEntry) {
38988  const { jsHeapSizeLimit, totalJSHeapSize, usedJSHeapSize } = memoryEntry;
38989  // we don't want to use `getAbsoluteTime` because it adds the event time to the
38990  // time origin, so we get the current timestamp instead
38991  const time = Date.now() / 1000;
38992  return {
38993    type: 'memory',
38994    name: 'memory',
38995    start: time,
38996    end: time,
38997    data: {
38998      memory: {
38999        jsHeapSizeLimit,
39000        totalJSHeapSize,
39001        usedJSHeapSize,
39002      },
39003    },
39004  };
39005}
39006
39007/**
39008 * Heavily simplified debounce function based on lodash.debounce.
39009 *
39010 * This function takes a callback function (@param fun) and delays its invocation
39011 * by @param wait milliseconds. Optionally, a maxWait can be specified in @param options,
39012 * which ensures that the callback is invoked at least once after the specified max. wait time.
39013 *
39014 * @param func the function whose invocation is to be debounced
39015 * @param wait the minimum time until the function is invoked after it was called once
39016 * @param options the options object, which can contain the `maxWait` property
39017 *
39018 * @returns the debounced version of the function, which needs to be called at least once to start the
39019 *          debouncing process. Subsequent calls will reset the debouncing timer and, in case @paramfunc
39020 *          was already invoked in the meantime, return @param func's return value.
39021 *          The debounced function has two additional properties:
39022 *          - `flush`: Invokes the debounced function immediately and returns its return value
39023 *          - `cancel`: Cancels the debouncing process and resets the debouncing timer
39024 */
39025function debounce(func, wait, options) {
39026  let callbackReturnValue;
39027
39028  let timerId;
39029  let maxTimerId;
39030
39031  const maxWait = options && options.maxWait ? Math.max(options.maxWait, wait) : 0;
39032
39033  function invokeFunc() {
39034    cancelTimers();
39035    callbackReturnValue = func();
39036    return callbackReturnValue;
39037  }
39038
39039  function cancelTimers() {
39040    timerId !== undefined && clearTimeout(timerId);
39041    maxTimerId !== undefined && clearTimeout(maxTimerId);
39042    timerId = maxTimerId = undefined;
39043  }
39044
39045  function flush() {
39046    if (timerId !== undefined || maxTimerId !== undefined) {
39047      return invokeFunc();
39048    }
39049    return callbackReturnValue;
39050  }
39051
39052  function debounced() {
39053    if (timerId) {
39054      clearTimeout(timerId);
39055    }
39056    timerId = setTimeout(invokeFunc, wait);
39057
39058    if (maxWait && maxTimerId === undefined) {
39059      maxTimerId = setTimeout(invokeFunc, maxWait);
39060    }
39061
39062    return callbackReturnValue;
39063  }
39064
39065  debounced.cancel = cancelTimers;
39066  debounced.flush = flush;
39067  return debounced;
39068}
39069
39070/**
39071 * Handler for recording events.
39072 *
39073 * Adds to event buffer, and has varying flushing behaviors if the event was a checkout.
39074 */
39075function getHandleRecordingEmit(replay) {
39076  let hadFirstEvent = false;
39077
39078  return (event, _isCheckout) => {
39079    // If this is false, it means session is expired, create and a new session and wait for checkout
39080    if (!replay.checkAndHandleExpiredSession()) {
39081      DEBUG_BUILD && utils.logger.warn('[Replay] Received replay event after session expired.');
39082
39083      return;
39084    }
39085
39086    // `_isCheckout` is only set when the checkout is due to `checkoutEveryNms`
39087    // We also want to treat the first event as a checkout, so we handle this specifically here
39088    const isCheckout = _isCheckout || !hadFirstEvent;
39089    hadFirstEvent = true;
39090
39091    if (replay.clickDetector) {
39092      updateClickDetectorForRecordingEvent(replay.clickDetector, event);
39093    }
39094
39095    // The handler returns `true` if we do not want to trigger debounced flush, `false` if we want to debounce flush.
39096    replay.addUpdate(() => {
39097      // The session is always started immediately on pageload/init, but for
39098      // error-only replays, it should reflect the most recent checkout
39099      // when an error occurs. Clear any state that happens before this current
39100      // checkout. This needs to happen before `addEvent()` which updates state
39101      // dependent on this reset.
39102      if (replay.recordingMode === 'buffer' && isCheckout) {
39103        replay.setInitialState();
39104      }
39105
39106      // If the event is not added (e.g. due to being paused, disabled, or out of the max replay duration),
39107      // Skip all further steps
39108      if (!addEventSync(replay, event, isCheckout)) {
39109        // Return true to skip scheduling a debounced flush
39110        return true;
39111      }
39112
39113      // Different behavior for full snapshots (type=2), ignore other event types
39114      // See https://github.com/rrweb-io/rrweb/blob/d8f9290ca496712aa1e7d472549480c4e7876594/packages/rrweb/src/types.ts#L16
39115      if (!isCheckout) {
39116        return false;
39117      }
39118
39119      // Additionally, create a meta event that will capture certain SDK settings.
39120      // In order to handle buffer mode, this needs to either be done when we
39121      // receive checkout events or at flush time.
39122      //
39123      // `isCheckout` is always true, but want to be explicit that it should
39124      // only be added for checkouts
39125      addSettingsEvent(replay, isCheckout);
39126
39127      // If there is a previousSessionId after a full snapshot occurs, then
39128      // the replay session was started due to session expiration. The new session
39129      // is started before triggering a new checkout and contains the id
39130      // of the previous session. Do not immediately flush in this case
39131      // to avoid capturing only the checkout and instead the replay will
39132      // be captured if they perform any follow-up actions.
39133      if (replay.session && replay.session.previousSessionId) {
39134        return true;
39135      }
39136
39137      // When in buffer mode, make sure we adjust the session started date to the current earliest event of the buffer
39138      // this should usually be the timestamp of the checkout event, but to be safe...
39139      if (replay.recordingMode === 'buffer' && replay.session && replay.eventBuffer) {
39140        const earliestEvent = replay.eventBuffer.getEarliestTimestamp();
39141        if (earliestEvent) {
39142          logInfo(
39143            `[Replay] Updating session start time to earliest event in buffer to ${new Date(earliestEvent)}`,
39144            replay.getOptions()._experiments.traceInternals,
39145          );
39146
39147          replay.session.started = earliestEvent;
39148
39149          if (replay.getOptions().stickySession) {
39150            saveSession(replay.session);
39151          }
39152        }
39153      }
39154
39155      if (replay.recordingMode === 'session') {
39156        // If the full snapshot is due to an initial load, we will not have
39157        // a previous session ID. In this case, we want to buffer events
39158        // for a set amount of time before flushing. This can help avoid
39159        // capturing replays of users that immediately close the window.
39160
39161        // This should never reject
39162        // eslint-disable-next-line @typescript-eslint/no-floating-promises
39163        void replay.flush();
39164      }
39165
39166      return true;
39167    });
39168  };
39169}
39170
39171/**
39172 * Exported for tests
39173 */
39174function createOptionsEvent(replay) {
39175  const options = replay.getOptions();
39176  return {
39177    type: EventType.Custom,
39178    timestamp: Date.now(),
39179    data: {
39180      tag: 'options',
39181      payload: {
39182        shouldRecordCanvas: replay.isRecordingCanvas(),
39183        sessionSampleRate: options.sessionSampleRate,
39184        errorSampleRate: options.errorSampleRate,
39185        useCompressionOption: options.useCompression,
39186        blockAllMedia: options.blockAllMedia,
39187        maskAllText: options.maskAllText,
39188        maskAllInputs: options.maskAllInputs,
39189        useCompression: replay.eventBuffer ? replay.eventBuffer.type === 'worker' : false,
39190        networkDetailHasUrls: options.networkDetailAllowUrls.length > 0,
39191        networkCaptureBodies: options.networkCaptureBodies,
39192        networkRequestHasHeaders: options.networkRequestHeaders.length > 0,
39193        networkResponseHasHeaders: options.networkResponseHeaders.length > 0,
39194      },
39195    },
39196  };
39197}
39198
39199/**
39200 * Add a "meta" event that contains a simplified view on current configuration
39201 * options. This should only be included on the first segment of a recording.
39202 */
39203function addSettingsEvent(replay, isCheckout) {
39204  // Only need to add this event when sending the first segment
39205  if (!isCheckout || !replay.session || replay.session.segmentId !== 0) {
39206    return;
39207  }
39208
39209  addEventSync(replay, createOptionsEvent(replay), false);
39210}
39211
39212/**
39213 * Create a replay envelope ready to be sent.
39214 * This includes both the replay event, as well as the recording data.
39215 */
39216function createReplayEnvelope(
39217  replayEvent,
39218  recordingData,
39219  dsn,
39220  tunnel,
39221) {
39222  return utils.createEnvelope(
39223    utils.createEventEnvelopeHeaders(replayEvent, utils.getSdkMetadataForEnvelopeHeader(replayEvent), tunnel, dsn),
39224    [
39225      [{ type: 'replay_event' }, replayEvent],
39226      [
39227        {
39228          type: 'replay_recording',
39229          // If string then we need to encode to UTF8, otherwise will have
39230          // wrong size. TextEncoder has similar browser support to
39231          // MutationObserver, although it does not accept IE11.
39232          length:
39233            typeof recordingData === 'string' ? new TextEncoder().encode(recordingData).length : recordingData.length,
39234        },
39235        recordingData,
39236      ],
39237    ],
39238  );
39239}
39240
39241/**
39242 * Prepare the recording data ready to be sent.
39243 */
39244function prepareRecordingData({
39245  recordingData,
39246  headers,
39247}
39248
39249) {
39250  let payloadWithSequence;
39251
39252  // XXX: newline is needed to separate sequence id from events
39253  const replayHeaders = `${JSON.stringify(headers)}
39254`;
39255
39256  if (typeof recordingData === 'string') {
39257    payloadWithSequence = `${replayHeaders}${recordingData}`;
39258  } else {
39259    const enc = new TextEncoder();
39260    // XXX: newline is needed to separate sequence id from events
39261    const sequence = enc.encode(replayHeaders);
39262    // Merge the two Uint8Arrays
39263    payloadWithSequence = new Uint8Array(sequence.length + recordingData.length);
39264    payloadWithSequence.set(sequence);
39265    payloadWithSequence.set(recordingData, sequence.length);
39266  }
39267
39268  return payloadWithSequence;
39269}
39270
39271/**
39272 * Prepare a replay event & enrich it with the SDK metadata.
39273 */
39274async function prepareReplayEvent({
39275  client,
39276  scope,
39277  replayId: event_id,
39278  event,
39279}
39280
39281) {
39282  const integrations =
39283    typeof client._integrations === 'object' && client._integrations !== null && !Array.isArray(client._integrations)
39284      ? Object.keys(client._integrations)
39285      : undefined;
39286
39287  const eventHint = { event_id, integrations };
39288
39289  if (client.emit) {
39290    client.emit('preprocessEvent', event, eventHint);
39291  }
39292
39293  const preparedEvent = (await core.prepareEvent(
39294    client.getOptions(),
39295    event,
39296    eventHint,
39297    scope,
39298    client,
39299    core.getIsolationScope(),
39300  )) ;
39301
39302  // If e.g. a global event processor returned null
39303  if (!preparedEvent) {
39304    return null;
39305  }
39306
39307  // This normally happens in browser client "_prepareEvent"
39308  // but since we do not use this private method from the client, but rather the plain import
39309  // we need to do this manually.
39310  preparedEvent.platform = preparedEvent.platform || 'javascript';
39311
39312  // extract the SDK name because `client._prepareEvent` doesn't add it to the event
39313  const metadata = client.getSdkMetadata && client.getSdkMetadata();
39314  const { name, version } = (metadata && metadata.sdk) || {};
39315
39316  preparedEvent.sdk = {
39317    ...preparedEvent.sdk,
39318    name: name || 'sentry.javascript.unknown',
39319    version: version || '0.0.0',
39320  };
39321
39322  return preparedEvent;
39323}
39324
39325/**
39326 * Send replay attachment using `fetch()`
39327 */
39328async function sendReplayRequest({
39329  recordingData,
39330  replayId,
39331  segmentId: segment_id,
39332  eventContext,
39333  timestamp,
39334  session,
39335}) {
39336  const preparedRecordingData = prepareRecordingData({
39337    recordingData,
39338    headers: {
39339      segment_id,
39340    },
39341  });
39342
39343  const { urls, errorIds, traceIds, initialTimestamp } = eventContext;
39344
39345  const client = core.getClient();
39346  const scope = core.getCurrentScope();
39347  const transport = client && client.getTransport();
39348  const dsn = client && client.getDsn();
39349
39350  if (!client || !transport || !dsn || !session.sampled) {
39351    return;
39352  }
39353
39354  const baseEvent = {
39355    type: REPLAY_EVENT_NAME,
39356    replay_start_timestamp: initialTimestamp / 1000,
39357    timestamp: timestamp / 1000,
39358    error_ids: errorIds,
39359    trace_ids: traceIds,
39360    urls,
39361    replay_id: replayId,
39362    segment_id,
39363    replay_type: session.sampled,
39364  };
39365
39366  const replayEvent = await prepareReplayEvent({ scope, client, replayId, event: baseEvent });
39367
39368  if (!replayEvent) {
39369    // Taken from baseclient's `_processEvent` method, where this is handled for errors/transactions
39370    client.recordDroppedEvent('event_processor', 'replay', baseEvent);
39371    logInfo('An event processor returned `null`, will not send event.');
39372    return;
39373  }
39374
39375  /*
39376  For reference, the fully built event looks something like this:
39377  {
39378      "type": "replay_event",
39379      "timestamp": 1670837008.634,
39380      "error_ids": [
39381          "errorId"
39382      ],
39383      "trace_ids": [
39384          "traceId"
39385      ],
39386      "urls": [
39387          "https://example.com"
39388      ],
39389      "replay_id": "eventId",
39390      "segment_id": 3,
39391      "replay_type": "error",
39392      "platform": "javascript",
39393      "event_id": "eventId",
39394      "environment": "production",
39395      "sdk": {
39396          "integrations": [
39397              "BrowserTracing",
39398              "Replay"
39399          ],
39400          "name": "sentry.javascript.browser",
39401          "version": "7.25.0"
39402      },
39403      "sdkProcessingMetadata": {},
39404      "contexts": {
39405      },
39406  }
39407  */
39408
39409  // Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to
39410  // sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may
39411  // 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
39412  // of this `delete`, lest we miss putting it back in the next time the property is in use.)
39413  delete replayEvent.sdkProcessingMetadata;
39414
39415  const envelope = createReplayEnvelope(replayEvent, preparedRecordingData, dsn, client.getOptions().tunnel);
39416
39417  let response;
39418
39419  try {
39420    response = await transport.send(envelope);
39421  } catch (err) {
39422    const error = new Error(UNABLE_TO_SEND_REPLAY);
39423
39424    try {
39425      // In case browsers don't allow this property to be writable
39426      // @ts-expect-error This needs lib es2022 and newer
39427      error.cause = err;
39428    } catch (e) {
39429      // nothing to do
39430    }
39431    throw error;
39432  }
39433
39434  // TODO (v8): we can remove this guard once transport.send's type signature doesn't include void anymore
39435  if (!response) {
39436    return response;
39437  }
39438
39439  // If the status code is invalid, we want to immediately stop & not retry
39440  if (typeof response.statusCode === 'number' && (response.statusCode < 200 || response.statusCode >= 300)) {
39441    throw new TransportStatusCodeError(response.statusCode);
39442  }
39443
39444  const rateLimits = utils.updateRateLimits({}, response);
39445  if (utils.isRateLimited(rateLimits, 'replay')) {
39446    throw new RateLimitError(rateLimits);
39447  }
39448
39449  return response;
39450}
39451
39452/**
39453 * This error indicates that the transport returned an invalid status code.
39454 */
39455class TransportStatusCodeError extends Error {
39456   constructor(statusCode) {
39457    super(`Transport returned status code ${statusCode}`);
39458  }
39459}
39460
39461/**
39462 * This error indicates that we hit a rate limit API error.
39463 */
39464class RateLimitError extends Error {
39465
39466   constructor(rateLimits) {
39467    super('Rate limit hit');
39468    this.rateLimits = rateLimits;
39469  }
39470}
39471
39472/**
39473 * Finalize and send the current replay event to Sentry
39474 */
39475async function sendReplay(
39476  replayData,
39477  retryConfig = {
39478    count: 0,
39479    interval: RETRY_BASE_INTERVAL,
39480  },
39481) {
39482  const { recordingData, options } = replayData;
39483
39484  // short circuit if there's no events to upload (this shouldn't happen as _runFlush makes this check)
39485  if (!recordingData.length) {
39486    return;
39487  }
39488
39489  try {
39490    await sendReplayRequest(replayData);
39491    return true;
39492  } catch (err) {
39493    if (err instanceof TransportStatusCodeError || err instanceof RateLimitError) {
39494      throw err;
39495    }
39496
39497    // Capture error for every failed replay
39498    core.setContext('Replays', {
39499      _retryCount: retryConfig.count,
39500    });
39501
39502    if (DEBUG_BUILD && options._experiments && options._experiments.captureExceptions) {
39503      core.captureException(err);
39504    }
39505
39506    // If an error happened here, it's likely that uploading the attachment
39507    // failed, we'll can retry with the same events payload
39508    if (retryConfig.count >= RETRY_MAX_COUNT) {
39509      const error = new Error(`${UNABLE_TO_SEND_REPLAY} - max retries exceeded`);
39510
39511      try {
39512        // In case browsers don't allow this property to be writable
39513        // @ts-expect-error This needs lib es2022 and newer
39514        error.cause = err;
39515      } catch (e) {
39516        // nothing to do
39517      }
39518
39519      throw error;
39520    }
39521
39522    // will retry in intervals of 5, 10, 30
39523    retryConfig.interval *= ++retryConfig.count;
39524
39525    return new Promise((resolve, reject) => {
39526      setTimeout(async () => {
39527        try {
39528          await sendReplay(replayData, retryConfig);
39529          resolve(true);
39530        } catch (err) {
39531          reject(err);
39532        }
39533      }, retryConfig.interval);
39534    });
39535  }
39536}
39537
39538const THROTTLED = '__THROTTLED';
39539const SKIPPED = '__SKIPPED';
39540
39541/**
39542 * Create a throttled function off a given function.
39543 * When calling the throttled function, it will call the original function only
39544 * if it hasn't been called more than `maxCount` times in the last `durationSeconds`.
39545 *
39546 * Returns `THROTTLED` if throttled for the first time, after that `SKIPPED`,
39547 * or else the return value of the original function.
39548 */
39549// eslint-disable-next-line @typescript-eslint/no-explicit-any
39550function throttle(
39551  fn,
39552  maxCount,
39553  durationSeconds,
39554) {
39555  const counter = new Map();
39556
39557  const _cleanup = (now) => {
39558    const threshold = now - durationSeconds;
39559    counter.forEach((_value, key) => {
39560      if (key < threshold) {
39561        counter.delete(key);
39562      }
39563    });
39564  };
39565
39566  const _getTotalCount = () => {
39567    return [...counter.values()].reduce((a, b) => a + b, 0);
39568  };
39569
39570  let isThrottled = false;
39571
39572  return (...rest) => {
39573    // Date in second-precision, which we use as basis for the throttling
39574    const now = Math.floor(Date.now() / 1000);
39575
39576    // First, make sure to delete any old entries
39577    _cleanup(now);
39578
39579    // If already over limit, do nothing
39580    if (_getTotalCount() >= maxCount) {
39581      const wasThrottled = isThrottled;
39582      isThrottled = true;
39583      return wasThrottled ? SKIPPED : THROTTLED;
39584    }
39585
39586    isThrottled = false;
39587    const count = counter.get(now) || 0;
39588    counter.set(now, count + 1);
39589
39590    return fn(...rest);
39591  };
39592}
39593
39594/* eslint-disable max-lines */ // TODO: We might want to split this file up
39595
39596/**
39597 * The main replay container class, which holds all the state and methods for recording and sending replays.
39598 */
39599class ReplayContainer  {
39600
39601  /**
39602   * Recording can happen in one of three modes:
39603   *   - session: Record the whole session, sending it continuously
39604   *   - buffer: Always keep the last 60s of recording, requires:
39605   *     - having replaysOnErrorSampleRate > 0 to capture replay when an error occurs
39606   *     - or calling `flush()` to send the replay
39607   */
39608
39609  /**
39610   * The current or last active transcation.
39611   * This is only available when performance is enabled.
39612   */
39613
39614  /**
39615   * These are here so we can overwrite them in tests etc.
39616   * @hidden
39617   */
39618
39619  /**
39620   * Options to pass to `rrweb.record()`
39621   */
39622
39623  /**
39624   * Timestamp of the last user activity. This lives across sessions.
39625   */
39626
39627  /**
39628   * Is the integration currently active?
39629   */
39630
39631  /**
39632   * Paused is a state where:
39633   * - DOM Recording is not listening at all
39634   * - Nothing will be added to event buffer (e.g. core SDK events)
39635   */
39636
39637  /**
39638   * Have we attached listeners to the core SDK?
39639   * Note we have to track this as there is no way to remove instrumentation handlers.
39640   */
39641
39642  /**
39643   * Function to stop recording
39644   */
39645
39646  /**
39647   * Internal use for canvas recording options
39648   */
39649
39650   constructor({
39651    options,
39652    recordingOptions,
39653  }
39654
39655) {ReplayContainer.prototype.__init.call(this);ReplayContainer.prototype.__init2.call(this);ReplayContainer.prototype.__init3.call(this);ReplayContainer.prototype.__init4.call(this);ReplayContainer.prototype.__init5.call(this);ReplayContainer.prototype.__init6.call(this);
39656    this.eventBuffer = null;
39657    this.performanceEntries = [];
39658    this.replayPerformanceEntries = [];
39659    this.recordingMode = 'session';
39660    this.timeouts = {
39661      sessionIdlePause: SESSION_IDLE_PAUSE_DURATION,
39662      sessionIdleExpire: SESSION_IDLE_EXPIRE_DURATION,
39663    } ;
39664    this._lastActivity = Date.now();
39665    this._isEnabled = false;
39666    this._isPaused = false;
39667    this._hasInitializedCoreListeners = false;
39668    this._context = {
39669      errorIds: new Set(),
39670      traceIds: new Set(),
39671      urls: [],
39672      initialTimestamp: Date.now(),
39673      initialUrl: '',
39674    };
39675
39676    this._recordingOptions = recordingOptions;
39677    this._options = options;
39678
39679    this._debouncedFlush = debounce(() => this._flush(), this._options.flushMinDelay, {
39680      maxWait: this._options.flushMaxDelay,
39681    });
39682
39683    this._throttledAddEvent = throttle(
39684      (event, isCheckout) => addEvent(this, event, isCheckout),
39685      // Max 300 events...
39686      300,
39687      // ... per 5s
39688      5,
39689    );
39690
39691    const { slowClickTimeout, slowClickIgnoreSelectors } = this.getOptions();
39692
39693    const slowClickConfig = slowClickTimeout
39694      ? {
39695          threshold: Math.min(SLOW_CLICK_THRESHOLD, slowClickTimeout),
39696          timeout: slowClickTimeout,
39697          scrollTimeout: SLOW_CLICK_SCROLL_TIMEOUT,
39698          ignoreSelector: slowClickIgnoreSelectors ? slowClickIgnoreSelectors.join(',') : '',
39699        }
39700      : undefined;
39701
39702    if (slowClickConfig) {
39703      this.clickDetector = new ClickDetector(this, slowClickConfig);
39704    }
39705  }
39706
39707  /** Get the event context. */
39708   getContext() {
39709    return this._context;
39710  }
39711
39712  /** If recording is currently enabled. */
39713   isEnabled() {
39714    return this._isEnabled;
39715  }
39716
39717  /** If recording is currently paused. */
39718   isPaused() {
39719    return this._isPaused;
39720  }
39721
39722  /**
39723   * Determine if canvas recording is enabled
39724   */
39725   isRecordingCanvas() {
39726    return Boolean(this._canvas);
39727  }
39728
39729  /** Get the replay integration options. */
39730   getOptions() {
39731    return this._options;
39732  }
39733
39734  /**
39735   * Initializes the plugin based on sampling configuration. Should not be
39736   * called outside of constructor.
39737   */
39738   initializeSampling(previousSessionId) {
39739    const { errorSampleRate, sessionSampleRate } = this._options;
39740
39741    // If neither sample rate is > 0, then do nothing - user will need to call one of
39742    // `start()` or `startBuffering` themselves.
39743    if (errorSampleRate <= 0 && sessionSampleRate <= 0) {
39744      return;
39745    }
39746
39747    // Otherwise if there is _any_ sample rate set, try to load an existing
39748    // session, or create a new one.
39749    this._initializeSessionForSampling(previousSessionId);
39750
39751    if (!this.session) {
39752      // This should not happen, something wrong has occurred
39753      this._handleException(new Error('Unable to initialize and create session'));
39754      return;
39755    }
39756
39757    if (this.session.sampled === false) {
39758      // This should only occur if `errorSampleRate` is 0 and was unsampled for
39759      // session-based replay. In this case there is nothing to do.
39760      return;
39761    }
39762
39763    // If segmentId > 0, it means we've previously already captured this session
39764    // In this case, we still want to continue in `session` recording mode
39765    this.recordingMode = this.session.sampled === 'buffer' && this.session.segmentId === 0 ? 'buffer' : 'session';
39766
39767    logInfoNextTick(
39768      `[Replay] Starting replay in ${this.recordingMode} mode`,
39769      this._options._experiments.traceInternals,
39770    );
39771
39772    this._initializeRecording();
39773  }
39774
39775  /**
39776   * Start a replay regardless of sampling rate. Calling this will always
39777   * create a new session. Will throw an error if replay is already in progress.
39778   *
39779   * Creates or loads a session, attaches listeners to varying events (DOM,
39780   * _performanceObserver, Recording, Sentry SDK, etc)
39781   */
39782   start() {
39783    if (this._isEnabled && this.recordingMode === 'session') {
39784      throw new Error('Replay recording is already in progress');
39785    }
39786
39787    if (this._isEnabled && this.recordingMode === 'buffer') {
39788      throw new Error('Replay buffering is in progress, call `flush()` to save the replay');
39789    }
39790
39791    logInfoNextTick('[Replay] Starting replay in session mode', this._options._experiments.traceInternals);
39792
39793    const session = loadOrCreateSession(
39794      {
39795        maxReplayDuration: this._options.maxReplayDuration,
39796        sessionIdleExpire: this.timeouts.sessionIdleExpire,
39797        traceInternals: this._options._experiments.traceInternals,
39798      },
39799      {
39800        stickySession: this._options.stickySession,
39801        // This is intentional: create a new session-based replay when calling `start()`
39802        sessionSampleRate: 1,
39803        allowBuffering: false,
39804      },
39805    );
39806
39807    this.session = session;
39808
39809    this._initializeRecording();
39810  }
39811
39812  /**
39813   * Start replay buffering. Buffers until `flush()` is called or, if
39814   * `replaysOnErrorSampleRate` > 0, an error occurs.
39815   */
39816   startBuffering() {
39817    if (this._isEnabled) {
39818      throw new Error('Replay recording is already in progress');
39819    }
39820
39821    logInfoNextTick('[Replay] Starting replay in buffer mode', this._options._experiments.traceInternals);
39822
39823    const session = loadOrCreateSession(
39824      {
39825        sessionIdleExpire: this.timeouts.sessionIdleExpire,
39826        maxReplayDuration: this._options.maxReplayDuration,
39827        traceInternals: this._options._experiments.traceInternals,
39828      },
39829      {
39830        stickySession: this._options.stickySession,
39831        sessionSampleRate: 0,
39832        allowBuffering: true,
39833      },
39834    );
39835
39836    this.session = session;
39837
39838    this.recordingMode = 'buffer';
39839    this._initializeRecording();
39840  }
39841
39842  /**
39843   * Start recording.
39844   *
39845   * Note that this will cause a new DOM checkout
39846   */
39847   startRecording() {
39848    try {
39849      const canvasOptions = this._canvas;
39850
39851      this._stopRecording = record({
39852        ...this._recordingOptions,
39853        // When running in error sampling mode, we need to overwrite `checkoutEveryNms`
39854        // Without this, it would record forever, until an error happens, which we don't want
39855        // instead, we'll always keep the last 60 seconds of replay before an error happened
39856        ...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }),
39857        emit: getHandleRecordingEmit(this),
39858        onMutation: this._onMutationHandler,
39859        ...(canvasOptions
39860          ? {
39861              recordCanvas: canvasOptions.recordCanvas,
39862              getCanvasManager: canvasOptions.getCanvasManager,
39863              sampling: canvasOptions.sampling,
39864              dataURLOptions: canvasOptions.dataURLOptions,
39865            }
39866          : {}),
39867      });
39868    } catch (err) {
39869      this._handleException(err);
39870    }
39871  }
39872
39873  /**
39874   * Stops the recording, if it was running.
39875   *
39876   * Returns true if it was previously stopped, or is now stopped,
39877   * otherwise false.
39878   */
39879   stopRecording() {
39880    try {
39881      if (this._stopRecording) {
39882        this._stopRecording();
39883        this._stopRecording = undefined;
39884      }
39885
39886      return true;
39887    } catch (err) {
39888      this._handleException(err);
39889      return false;
39890    }
39891  }
39892
39893  /**
39894   * Currently, this needs to be manually called (e.g. for tests). Sentry SDK
39895   * does not support a teardown
39896   */
39897   async stop({ forceFlush = false, reason } = {}) {
39898    if (!this._isEnabled) {
39899      return;
39900    }
39901
39902    // We can't move `_isEnabled` after awaiting a flush, otherwise we can
39903    // enter into an infinite loop when `stop()` is called while flushing.
39904    this._isEnabled = false;
39905
39906    try {
39907      logInfo(
39908        `[Replay] Stopping Replay${reason ? ` triggered by ${reason}` : ''}`,
39909        this._options._experiments.traceInternals,
39910      );
39911
39912      this._removeListeners();
39913      this.stopRecording();
39914
39915      this._debouncedFlush.cancel();
39916      // See comment above re: `_isEnabled`, we "force" a flush, ignoring the
39917      // `_isEnabled` state of the plugin since it was disabled above.
39918      if (forceFlush) {
39919        await this._flush({ force: true });
39920      }
39921
39922      // After flush, destroy event buffer
39923      this.eventBuffer && this.eventBuffer.destroy();
39924      this.eventBuffer = null;
39925
39926      // Clear session from session storage, note this means if a new session
39927      // is started after, it will not have `previousSessionId`
39928      clearSession(this);
39929    } catch (err) {
39930      this._handleException(err);
39931    }
39932  }
39933
39934  /**
39935   * Pause some replay functionality. See comments for `_isPaused`.
39936   * This differs from stop as this only stops DOM recording, it is
39937   * not as thorough of a shutdown as `stop()`.
39938   */
39939   pause() {
39940    if (this._isPaused) {
39941      return;
39942    }
39943
39944    this._isPaused = true;
39945    this.stopRecording();
39946
39947    logInfo('[Replay] Pausing replay', this._options._experiments.traceInternals);
39948  }
39949
39950  /**
39951   * Resumes recording, see notes for `pause().
39952   *
39953   * Note that calling `startRecording()` here will cause a
39954   * new DOM checkout.`
39955   */
39956   resume() {
39957    if (!this._isPaused || !this._checkSession()) {
39958      return;
39959    }
39960
39961    this._isPaused = false;
39962    this.startRecording();
39963
39964    logInfo('[Replay] Resuming replay', this._options._experiments.traceInternals);
39965  }
39966
39967  /**
39968   * If not in "session" recording mode, flush event buffer which will create a new replay.
39969   * Unless `continueRecording` is false, the replay will continue to record and
39970   * behave as a "session"-based replay.
39971   *
39972   * Otherwise, queue up a flush.
39973   */
39974   async sendBufferedReplayOrFlush({ continueRecording = true } = {}) {
39975    if (this.recordingMode === 'session') {
39976      return this.flushImmediate();
39977    }
39978
39979    const activityTime = Date.now();
39980
39981    logInfo('[Replay] Converting buffer to session', this._options._experiments.traceInternals);
39982
39983    // Allow flush to complete before resuming as a session recording, otherwise
39984    // the checkout from `startRecording` may be included in the payload.
39985    // Prefer to keep the error replay as a separate (and smaller) segment
39986    // than the session replay.
39987    await this.flushImmediate();
39988
39989    const hasStoppedRecording = this.stopRecording();
39990
39991    if (!continueRecording || !hasStoppedRecording) {
39992      return;
39993    }
39994
39995    // To avoid race conditions where this is called multiple times, we check here again that we are still buffering
39996    if ((this.recordingMode ) === 'session') {
39997      return;
39998    }
39999
40000    // Re-start recording in session-mode
40001    this.recordingMode = 'session';
40002
40003    // Once this session ends, we do not want to refresh it
40004    if (this.session) {
40005      this._updateUserActivity(activityTime);
40006      this._updateSessionActivity(activityTime);
40007      this._maybeSaveSession();
40008    }
40009
40010    this.startRecording();
40011  }
40012
40013  /**
40014   * We want to batch uploads of replay events. Save events only if
40015   * `<flushMinDelay>` milliseconds have elapsed since the last event
40016   * *OR* if `<flushMaxDelay>` milliseconds have elapsed.
40017   *
40018   * Accepts a callback to perform side-effects and returns true to stop batch
40019   * processing and hand back control to caller.
40020   */
40021   addUpdate(cb) {
40022    // We need to always run `cb` (e.g. in the case of `this.recordingMode == 'buffer'`)
40023    const cbResult = cb();
40024
40025    // If this option is turned on then we will only want to call `flush`
40026    // explicitly
40027    if (this.recordingMode === 'buffer') {
40028      return;
40029    }
40030
40031    // If callback is true, we do not want to continue with flushing -- the
40032    // caller will need to handle it.
40033    if (cbResult === true) {
40034      return;
40035    }
40036
40037    // addUpdate is called quite frequently - use _debouncedFlush so that it
40038    // respects the flush delays and does not flush immediately
40039    this._debouncedFlush();
40040  }
40041
40042  /**
40043   * Updates the user activity timestamp and resumes recording. This should be
40044   * called in an event handler for a user action that we consider as the user
40045   * being "active" (e.g. a mouse click).
40046   */
40047   triggerUserActivity() {
40048    this._updateUserActivity();
40049
40050    // This case means that recording was once stopped due to inactivity.
40051    // Ensure that recording is resumed.
40052    if (!this._stopRecording) {
40053      // Create a new session, otherwise when the user action is flushed, it
40054      // will get rejected due to an expired session.
40055      if (!this._checkSession()) {
40056        return;
40057      }
40058
40059      // Note: This will cause a new DOM checkout
40060      this.resume();
40061      return;
40062    }
40063
40064    // Otherwise... recording was never suspended, continue as normalish
40065    this.checkAndHandleExpiredSession();
40066
40067    this._updateSessionActivity();
40068  }
40069
40070  /**
40071   * Updates the user activity timestamp *without* resuming
40072   * recording. Some user events (e.g. keydown) can be create
40073   * low-value replays that only contain the keypress as a
40074   * breadcrumb. Instead this would require other events to
40075   * create a new replay after a session has expired.
40076   */
40077   updateUserActivity() {
40078    this._updateUserActivity();
40079    this._updateSessionActivity();
40080  }
40081
40082  /**
40083   * Only flush if `this.recordingMode === 'session'`
40084   */
40085   conditionalFlush() {
40086    if (this.recordingMode === 'buffer') {
40087      return Promise.resolve();
40088    }
40089
40090    return this.flushImmediate();
40091  }
40092
40093  /**
40094   * Flush using debounce flush
40095   */
40096   flush() {
40097    return this._debouncedFlush() ;
40098  }
40099
40100  /**
40101   * Always flush via `_debouncedFlush` so that we do not have flushes triggered
40102   * from calling both `flush` and `_debouncedFlush`. Otherwise, there could be
40103   * cases of mulitple flushes happening closely together.
40104   */
40105   flushImmediate() {
40106    this._debouncedFlush();
40107    // `.flush` is provided by the debounced function, analogously to lodash.debounce
40108    return this._debouncedFlush.flush() ;
40109  }
40110
40111  /**
40112   * Cancels queued up flushes.
40113   */
40114   cancelFlush() {
40115    this._debouncedFlush.cancel();
40116  }
40117
40118  /** Get the current sesion (=replay) ID */
40119   getSessionId() {
40120    return this.session && this.session.id;
40121  }
40122
40123  /**
40124   * Checks if recording should be stopped due to user inactivity. Otherwise
40125   * check if session is expired and create a new session if so. Triggers a new
40126   * full snapshot on new session.
40127   *
40128   * Returns true if session is not expired, false otherwise.
40129   * @hidden
40130   */
40131   checkAndHandleExpiredSession() {
40132    // Prevent starting a new session if the last user activity is older than
40133    // SESSION_IDLE_PAUSE_DURATION. Otherwise non-user activity can trigger a new
40134    // session+recording. This creates noisy replays that do not have much
40135    // content in them.
40136    if (
40137      this._lastActivity &&
40138      isExpired(this._lastActivity, this.timeouts.sessionIdlePause) &&
40139      this.session &&
40140      this.session.sampled === 'session'
40141    ) {
40142      // Pause recording only for session-based replays. Otherwise, resuming
40143      // will create a new replay and will conflict with users who only choose
40144      // to record error-based replays only. (e.g. the resumed replay will not
40145      // contain a reference to an error)
40146      this.pause();
40147      return;
40148    }
40149
40150    // --- There is recent user activity --- //
40151    // This will create a new session if expired, based on expiry length
40152    if (!this._checkSession()) {
40153      // Check session handles the refreshing itself
40154      return false;
40155    }
40156
40157    return true;
40158  }
40159
40160  /**
40161   * Capture some initial state that can change throughout the lifespan of the
40162   * replay. This is required because otherwise they would be captured at the
40163   * first flush.
40164   */
40165   setInitialState() {
40166    const urlPath = `${WINDOW.location.pathname}${WINDOW.location.hash}${WINDOW.location.search}`;
40167    const url = `${WINDOW.location.origin}${urlPath}`;
40168
40169    this.performanceEntries = [];
40170    this.replayPerformanceEntries = [];
40171
40172    // Reset _context as well
40173    this._clearContext();
40174
40175    this._context.initialUrl = url;
40176    this._context.initialTimestamp = Date.now();
40177    this._context.urls.push(url);
40178  }
40179
40180  /**
40181   * Add a breadcrumb event, that may be throttled.
40182   * If it was throttled, we add a custom breadcrumb to indicate that.
40183   */
40184   throttledAddEvent(
40185    event,
40186    isCheckout,
40187  ) {
40188    const res = this._throttledAddEvent(event, isCheckout);
40189
40190    // If this is THROTTLED, it means we have throttled the event for the first time
40191    // In this case, we want to add a breadcrumb indicating that something was skipped
40192    if (res === THROTTLED) {
40193      const breadcrumb = createBreadcrumb({
40194        category: 'replay.throttled',
40195      });
40196
40197      this.addUpdate(() => {
40198        // Return `false` if the event _was_ added, as that means we schedule a flush
40199        return !addEventSync(this, {
40200          type: ReplayEventTypeCustom,
40201          timestamp: breadcrumb.timestamp || 0,
40202          data: {
40203            tag: 'breadcrumb',
40204            payload: breadcrumb,
40205            metric: true,
40206          },
40207        });
40208      });
40209    }
40210
40211    return res;
40212  }
40213
40214  /**
40215   * This will get the parametrized route name of the current page.
40216   * This is only available if performance is enabled, and if an instrumented router is used.
40217   */
40218   getCurrentRoute() {
40219    // eslint-disable-next-line deprecation/deprecation
40220    const lastTransaction = this.lastTransaction || core.getCurrentScope().getTransaction();
40221
40222    const attributes = (lastTransaction && core.spanToJSON(lastTransaction).data) || {};
40223    const source = attributes[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
40224    if (!lastTransaction || !source || !['route', 'custom'].includes(source)) {
40225      return undefined;
40226    }
40227
40228    return core.spanToJSON(lastTransaction).description;
40229  }
40230
40231  /**
40232   * Initialize and start all listeners to varying events (DOM,
40233   * Performance Observer, Recording, Sentry SDK, etc)
40234   */
40235   _initializeRecording() {
40236    this.setInitialState();
40237
40238    // this method is generally called on page load or manually - in both cases
40239    // we should treat it as an activity
40240    this._updateSessionActivity();
40241
40242    this.eventBuffer = createEventBuffer({
40243      useCompression: this._options.useCompression,
40244      workerUrl: this._options.workerUrl,
40245    });
40246
40247    this._removeListeners();
40248    this._addListeners();
40249
40250    // Need to set as enabled before we start recording, as `record()` can trigger a flush with a new checkout
40251    this._isEnabled = true;
40252    this._isPaused = false;
40253
40254    this.startRecording();
40255  }
40256
40257  /** A wrapper to conditionally capture exceptions. */
40258   _handleException(error) {
40259    DEBUG_BUILD && utils.logger.error('[Replay]', error);
40260
40261    if (DEBUG_BUILD && this._options._experiments && this._options._experiments.captureExceptions) {
40262      core.captureException(error);
40263    }
40264  }
40265
40266  /**
40267   * Loads (or refreshes) the current session.
40268   */
40269   _initializeSessionForSampling(previousSessionId) {
40270    // Whenever there is _any_ error sample rate, we always allow buffering
40271    // Because we decide on sampling when an error occurs, we need to buffer at all times if sampling for errors
40272    const allowBuffering = this._options.errorSampleRate > 0;
40273
40274    const session = loadOrCreateSession(
40275      {
40276        sessionIdleExpire: this.timeouts.sessionIdleExpire,
40277        maxReplayDuration: this._options.maxReplayDuration,
40278        traceInternals: this._options._experiments.traceInternals,
40279        previousSessionId,
40280      },
40281      {
40282        stickySession: this._options.stickySession,
40283        sessionSampleRate: this._options.sessionSampleRate,
40284        allowBuffering,
40285      },
40286    );
40287
40288    this.session = session;
40289  }
40290
40291  /**
40292   * Checks and potentially refreshes the current session.
40293   * Returns false if session is not recorded.
40294   */
40295   _checkSession() {
40296    // If there is no session yet, we do not want to refresh anything
40297    // This should generally not happen, but to be safe....
40298    if (!this.session) {
40299      return false;
40300    }
40301
40302    const currentSession = this.session;
40303
40304    if (
40305      shouldRefreshSession(currentSession, {
40306        sessionIdleExpire: this.timeouts.sessionIdleExpire,
40307        maxReplayDuration: this._options.maxReplayDuration,
40308      })
40309    ) {
40310      // This should never reject
40311      // eslint-disable-next-line @typescript-eslint/no-floating-promises
40312      this._refreshSession(currentSession);
40313      return false;
40314    }
40315
40316    return true;
40317  }
40318
40319  /**
40320   * Refresh a session with a new one.
40321   * This stops the current session (without forcing a flush, as that would never work since we are expired),
40322   * and then does a new sampling based on the refreshed session.
40323   */
40324   async _refreshSession(session) {
40325    if (!this._isEnabled) {
40326      return;
40327    }
40328    await this.stop({ reason: 'refresh session' });
40329    this.initializeSampling(session.id);
40330  }
40331
40332  /**
40333   * Adds listeners to record events for the replay
40334   */
40335   _addListeners() {
40336    try {
40337      WINDOW.document.addEventListener('visibilitychange', this._handleVisibilityChange);
40338      WINDOW.addEventListener('blur', this._handleWindowBlur);
40339      WINDOW.addEventListener('focus', this._handleWindowFocus);
40340      WINDOW.addEventListener('keydown', this._handleKeyboardEvent);
40341
40342      if (this.clickDetector) {
40343        this.clickDetector.addListeners();
40344      }
40345
40346      // There is no way to remove these listeners, so ensure they are only added once
40347      if (!this._hasInitializedCoreListeners) {
40348        addGlobalListeners(this);
40349
40350        this._hasInitializedCoreListeners = true;
40351      }
40352    } catch (err) {
40353      this._handleException(err);
40354    }
40355
40356    this._performanceCleanupCallback = setupPerformanceObserver(this);
40357  }
40358
40359  /**
40360   * Cleans up listeners that were created in `_addListeners`
40361   */
40362   _removeListeners() {
40363    try {
40364      WINDOW.document.removeEventListener('visibilitychange', this._handleVisibilityChange);
40365
40366      WINDOW.removeEventListener('blur', this._handleWindowBlur);
40367      WINDOW.removeEventListener('focus', this._handleWindowFocus);
40368      WINDOW.removeEventListener('keydown', this._handleKeyboardEvent);
40369
40370      if (this.clickDetector) {
40371        this.clickDetector.removeListeners();
40372      }
40373
40374      if (this._performanceCleanupCallback) {
40375        this._performanceCleanupCallback();
40376      }
40377    } catch (err) {
40378      this._handleException(err);
40379    }
40380  }
40381
40382  /**
40383   * Handle when visibility of the page content changes. Opening a new tab will
40384   * cause the state to change to hidden because of content of current page will
40385   * be hidden. Likewise, moving a different window to cover the contents of the
40386   * page will also trigger a change to a hidden state.
40387   */
40388   __init() {this._handleVisibilityChange = () => {
40389    if (WINDOW.document.visibilityState === 'visible') {
40390      this._doChangeToForegroundTasks();
40391    } else {
40392      this._doChangeToBackgroundTasks();
40393    }
40394  };}
40395
40396  /**
40397   * Handle when page is blurred
40398   */
40399   __init2() {this._handleWindowBlur = () => {
40400    const breadcrumb = createBreadcrumb({
40401      category: 'ui.blur',
40402    });
40403
40404    // Do not count blur as a user action -- it's part of the process of them
40405    // leaving the page
40406    this._doChangeToBackgroundTasks(breadcrumb);
40407  };}
40408
40409  /**
40410   * Handle when page is focused
40411   */
40412   __init3() {this._handleWindowFocus = () => {
40413    const breadcrumb = createBreadcrumb({
40414      category: 'ui.focus',
40415    });
40416
40417    // Do not count focus as a user action -- instead wait until they focus and
40418    // interactive with page
40419    this._doChangeToForegroundTasks(breadcrumb);
40420  };}
40421
40422  /** Ensure page remains active when a key is pressed. */
40423   __init4() {this._handleKeyboardEvent = (event) => {
40424    handleKeyboardEvent(this, event);
40425  };}
40426
40427  /**
40428   * Tasks to run when we consider a page to be hidden (via blurring and/or visibility)
40429   */
40430   _doChangeToBackgroundTasks(breadcrumb) {
40431    if (!this.session) {
40432      return;
40433    }
40434
40435    const expired = isSessionExpired(this.session, {
40436      maxReplayDuration: this._options.maxReplayDuration,
40437      sessionIdleExpire: this.timeouts.sessionIdleExpire,
40438    });
40439
40440    if (expired) {
40441      return;
40442    }
40443
40444    if (breadcrumb) {
40445      this._createCustomBreadcrumb(breadcrumb);
40446    }
40447
40448    // Send replay when the page/tab becomes hidden. There is no reason to send
40449    // replay if it becomes visible, since no actions we care about were done
40450    // while it was hidden
40451    // This should never reject
40452    // eslint-disable-next-line @typescript-eslint/no-floating-promises
40453    void this.conditionalFlush();
40454  }
40455
40456  /**
40457   * Tasks to run when we consider a page to be visible (via focus and/or visibility)
40458   */
40459   _doChangeToForegroundTasks(breadcrumb) {
40460    if (!this.session) {
40461      return;
40462    }
40463
40464    const isSessionActive = this.checkAndHandleExpiredSession();
40465
40466    if (!isSessionActive) {
40467      // If the user has come back to the page within SESSION_IDLE_PAUSE_DURATION
40468      // ms, we will re-use the existing session, otherwise create a new
40469      // session
40470      logInfo('[Replay] Document has become active, but session has expired');
40471      return;
40472    }
40473
40474    if (breadcrumb) {
40475      this._createCustomBreadcrumb(breadcrumb);
40476    }
40477  }
40478
40479  /**
40480   * Update user activity (across session lifespans)
40481   */
40482   _updateUserActivity(_lastActivity = Date.now()) {
40483    this._lastActivity = _lastActivity;
40484  }
40485
40486  /**
40487   * Updates the session's last activity timestamp
40488   */
40489   _updateSessionActivity(_lastActivity = Date.now()) {
40490    if (this.session) {
40491      this.session.lastActivity = _lastActivity;
40492      this._maybeSaveSession();
40493    }
40494  }
40495
40496  /**
40497   * Helper to create (and buffer) a replay breadcrumb from a core SDK breadcrumb
40498   */
40499   _createCustomBreadcrumb(breadcrumb) {
40500    this.addUpdate(() => {
40501      // This should never reject
40502      // eslint-disable-next-line @typescript-eslint/no-floating-promises
40503      this.throttledAddEvent({
40504        type: EventType.Custom,
40505        timestamp: breadcrumb.timestamp || 0,
40506        data: {
40507          tag: 'breadcrumb',
40508          payload: breadcrumb,
40509        },
40510      });
40511    });
40512  }
40513
40514  /**
40515   * Observed performance events are added to `this.performanceEntries`. These
40516   * are included in the replay event before it is finished and sent to Sentry.
40517   */
40518   _addPerformanceEntries() {
40519    const performanceEntries = createPerformanceEntries(this.performanceEntries).concat(this.replayPerformanceEntries);
40520
40521    this.performanceEntries = [];
40522    this.replayPerformanceEntries = [];
40523
40524    return Promise.all(createPerformanceSpans(this, performanceEntries));
40525  }
40526
40527  /**
40528   * Clear _context
40529   */
40530   _clearContext() {
40531    // XXX: `initialTimestamp` and `initialUrl` do not get cleared
40532    this._context.errorIds.clear();
40533    this._context.traceIds.clear();
40534    this._context.urls = [];
40535  }
40536
40537  /** Update the initial timestamp based on the buffer content. */
40538   _updateInitialTimestampFromEventBuffer() {
40539    const { session, eventBuffer } = this;
40540    if (!session || !eventBuffer) {
40541      return;
40542    }
40543
40544    // we only ever update this on the initial segment
40545    if (session.segmentId) {
40546      return;
40547    }
40548
40549    const earliestEvent = eventBuffer.getEarliestTimestamp();
40550    if (earliestEvent && earliestEvent < this._context.initialTimestamp) {
40551      this._context.initialTimestamp = earliestEvent;
40552    }
40553  }
40554
40555  /**
40556   * Return and clear _context
40557   */
40558   _popEventContext() {
40559    const _context = {
40560      initialTimestamp: this._context.initialTimestamp,
40561      initialUrl: this._context.initialUrl,
40562      errorIds: Array.from(this._context.errorIds),
40563      traceIds: Array.from(this._context.traceIds),
40564      urls: this._context.urls,
40565    };
40566
40567    this._clearContext();
40568
40569    return _context;
40570  }
40571
40572  /**
40573   * Flushes replay event buffer to Sentry.
40574   *
40575   * Performance events are only added right before flushing - this is
40576   * due to the buffered performance observer events.
40577   *
40578   * Should never be called directly, only by `flush`
40579   */
40580   async _runFlush() {
40581    const replayId = this.getSessionId();
40582
40583    if (!this.session || !this.eventBuffer || !replayId) {
40584      DEBUG_BUILD && utils.logger.error('[Replay] No session or eventBuffer found to flush.');
40585      return;
40586    }
40587
40588    await this._addPerformanceEntries();
40589
40590    // Check eventBuffer again, as it could have been stopped in the meanwhile
40591    if (!this.eventBuffer || !this.eventBuffer.hasEvents) {
40592      return;
40593    }
40594
40595    // Only attach memory event if eventBuffer is not empty
40596    await addMemoryEntry(this);
40597
40598    // Check eventBuffer again, as it could have been stopped in the meanwhile
40599    if (!this.eventBuffer) {
40600      return;
40601    }
40602
40603    // if this changed in the meanwhile, e.g. because the session was refreshed or similar, we abort here
40604    if (replayId !== this.getSessionId()) {
40605      return;
40606    }
40607
40608    try {
40609      // This uses the data from the eventBuffer, so we need to call this before `finish()
40610      this._updateInitialTimestampFromEventBuffer();
40611
40612      const timestamp = Date.now();
40613
40614      // Check total duration again, to avoid sending outdated stuff
40615      // We leave 30s wiggle room to accomodate late flushing etc.
40616      // This _could_ happen when the browser is suspended during flushing, in which case we just want to stop
40617      if (timestamp - this._context.initialTimestamp > this._options.maxReplayDuration + 30000) {
40618        throw new Error('Session is too long, not sending replay');
40619      }
40620
40621      const eventContext = this._popEventContext();
40622      // Always increment segmentId regardless of outcome of sending replay
40623      const segmentId = this.session.segmentId++;
40624      this._maybeSaveSession();
40625
40626      // Note this empties the event buffer regardless of outcome of sending replay
40627      const recordingData = await this.eventBuffer.finish();
40628
40629      await sendReplay({
40630        replayId,
40631        recordingData,
40632        segmentId,
40633        eventContext,
40634        session: this.session,
40635        options: this.getOptions(),
40636        timestamp,
40637      });
40638    } catch (err) {
40639      this._handleException(err);
40640
40641      // This means we retried 3 times and all of them failed,
40642      // or we ran into a problem we don't want to retry, like rate limiting.
40643      // In this case, we want to completely stop the replay - otherwise, we may get inconsistent segments
40644      // This should never reject
40645      // eslint-disable-next-line @typescript-eslint/no-floating-promises
40646      this.stop({ reason: 'sendReplay' });
40647
40648      const client = core.getClient();
40649
40650      if (client) {
40651        client.recordDroppedEvent('send_error', 'replay');
40652      }
40653    }
40654  }
40655
40656  /**
40657   * Flush recording data to Sentry. Creates a lock so that only a single flush
40658   * can be active at a time. Do not call this directly.
40659   */
40660   __init5() {this._flush = async ({
40661    force = false,
40662  }
40663
40664 = {}) => {
40665    if (!this._isEnabled && !force) {
40666      // This can happen if e.g. the replay was stopped because of exceeding the retry limit
40667      return;
40668    }
40669
40670    if (!this.checkAndHandleExpiredSession()) {
40671      DEBUG_BUILD && utils.logger.error('[Replay] Attempting to finish replay event after session expired.');
40672      return;
40673    }
40674
40675    if (!this.session) {
40676      // should never happen, as we would have bailed out before
40677      return;
40678    }
40679
40680    const start = this.session.started;
40681    const now = Date.now();
40682    const duration = now - start;
40683
40684    // A flush is about to happen, cancel any queued flushes
40685    this._debouncedFlush.cancel();
40686
40687    // If session is too short, or too long (allow some wiggle room over maxReplayDuration), do not send it
40688    // This _should_ not happen, but it may happen if flush is triggered due to a page activity change or similar
40689    const tooShort = duration < this._options.minReplayDuration;
40690    const tooLong = duration > this._options.maxReplayDuration + 5000;
40691    if (tooShort || tooLong) {
40692      logInfo(
40693        `[Replay] Session duration (${Math.floor(duration / 1000)}s) is too ${
40694          tooShort ? 'short' : 'long'
40695        }, not sending replay.`,
40696        this._options._experiments.traceInternals,
40697      );
40698
40699      if (tooShort) {
40700        this._debouncedFlush();
40701      }
40702      return;
40703    }
40704
40705    const eventBuffer = this.eventBuffer;
40706    if (eventBuffer && this.session.segmentId === 0 && !eventBuffer.hasCheckout) {
40707      logInfo('[Replay] Flushing initial segment without checkout.', this._options._experiments.traceInternals);
40708      // TODO FN: Evaluate if we want to stop here, or remove this again?
40709    }
40710
40711    // this._flushLock acts as a lock so that future calls to `_flush()`
40712    // will be blocked until this promise resolves
40713    if (!this._flushLock) {
40714      this._flushLock = this._runFlush();
40715      await this._flushLock;
40716      this._flushLock = undefined;
40717      return;
40718    }
40719
40720    // Wait for previous flush to finish, then call the debounced `_flush()`.
40721    // It's possible there are other flush requests queued and waiting for it
40722    // to resolve. We want to reduce all outstanding requests (as well as any
40723    // new flush requests that occur within a second of the locked flush
40724    // completing) into a single flush.
40725
40726    try {
40727      await this._flushLock;
40728    } catch (err) {
40729      DEBUG_BUILD && utils.logger.error(err);
40730    } finally {
40731      this._debouncedFlush();
40732    }
40733  };}
40734
40735  /** Save the session, if it is sticky */
40736   _maybeSaveSession() {
40737    if (this.session && this._options.stickySession) {
40738      saveSession(this.session);
40739    }
40740  }
40741
40742  /** Handler for rrweb.record.onMutation */
40743   __init6() {this._onMutationHandler = (mutations) => {
40744    const count = mutations.length;
40745
40746    const mutationLimit = this._options.mutationLimit;
40747    const mutationBreadcrumbLimit = this._options.mutationBreadcrumbLimit;
40748    const overMutationLimit = mutationLimit && count > mutationLimit;
40749
40750    // Create a breadcrumb if a lot of mutations happen at the same time
40751    // We can show this in the UI as an information with potential performance improvements
40752    if (count > mutationBreadcrumbLimit || overMutationLimit) {
40753      const breadcrumb = createBreadcrumb({
40754        category: 'replay.mutations',
40755        data: {
40756          count,
40757          limit: overMutationLimit,
40758        },
40759      });
40760      this._createCustomBreadcrumb(breadcrumb);
40761    }
40762
40763    // Stop replay if over the mutation limit
40764    if (overMutationLimit) {
40765      // This should never reject
40766      // eslint-disable-next-line @typescript-eslint/no-floating-promises
40767      this.stop({ reason: 'mutationLimit', forceFlush: this.recordingMode === 'session' });
40768      return false;
40769    }
40770
40771    // `true` means we use the regular mutation handling by rrweb
40772    return true;
40773  };}
40774}
40775
40776function getOption(
40777  selectors,
40778  defaultSelectors,
40779  deprecatedClassOption,
40780  deprecatedSelectorOption,
40781) {
40782  const deprecatedSelectors = typeof deprecatedSelectorOption === 'string' ? deprecatedSelectorOption.split(',') : [];
40783
40784  const allSelectors = [
40785    ...selectors,
40786    // @deprecated
40787    ...deprecatedSelectors,
40788
40789    // sentry defaults
40790    ...defaultSelectors,
40791  ];
40792
40793  // @deprecated
40794  if (typeof deprecatedClassOption !== 'undefined') {
40795    // NOTE: No support for RegExp
40796    if (typeof deprecatedClassOption === 'string') {
40797      allSelectors.push(`.${deprecatedClassOption}`);
40798    }
40799
40800    utils.consoleSandbox(() => {
40801      // eslint-disable-next-line no-console
40802      console.warn(
40803        '[Replay] You are using a deprecated configuration item for privacy. Read the documentation on how to use the new privacy configuration.',
40804      );
40805    });
40806  }
40807
40808  return allSelectors.join(',');
40809}
40810
40811/**
40812 * Returns privacy related configuration for use in rrweb
40813 */
40814function getPrivacyOptions({
40815  mask,
40816  unmask,
40817  block,
40818  unblock,
40819  ignore,
40820
40821  // eslint-disable-next-line deprecation/deprecation
40822  blockClass,
40823  // eslint-disable-next-line deprecation/deprecation
40824  blockSelector,
40825  // eslint-disable-next-line deprecation/deprecation
40826  maskTextClass,
40827  // eslint-disable-next-line deprecation/deprecation
40828  maskTextSelector,
40829  // eslint-disable-next-line deprecation/deprecation
40830  ignoreClass,
40831}) {
40832  const defaultBlockedElements = ['base[href="/"]'];
40833
40834  const maskSelector = getOption(mask, ['.sentry-mask', '[data-sentry-mask]'], maskTextClass, maskTextSelector);
40835  const unmaskSelector = getOption(unmask, ['.sentry-unmask', '[data-sentry-unmask]']);
40836
40837  const options = {
40838    // We are making the decision to make text and input selectors the same
40839    maskTextSelector: maskSelector,
40840    unmaskTextSelector: unmaskSelector,
40841
40842    blockSelector: getOption(
40843      block,
40844      ['.sentry-block', '[data-sentry-block]', ...defaultBlockedElements],
40845      blockClass,
40846      blockSelector,
40847    ),
40848    unblockSelector: getOption(unblock, ['.sentry-unblock', '[data-sentry-unblock]']),
40849    ignoreSelector: getOption(ignore, ['.sentry-ignore', '[data-sentry-ignore]', 'input[type="file"]'], ignoreClass),
40850  };
40851
40852  if (blockClass instanceof RegExp) {
40853    options.blockClass = blockClass;
40854  }
40855
40856  if (maskTextClass instanceof RegExp) {
40857    options.maskTextClass = maskTextClass;
40858  }
40859
40860  return options;
40861}
40862
40863/**
40864 * Masks an attribute if necessary, otherwise return attribute value as-is.
40865 */
40866function maskAttribute({
40867  el,
40868  key,
40869  maskAttributes,
40870  maskAllText,
40871  privacyOptions,
40872  value,
40873}) {
40874  // We only mask attributes if `maskAllText` is true
40875  if (!maskAllText) {
40876    return value;
40877  }
40878
40879  // unmaskTextSelector takes precendence
40880  if (privacyOptions.unmaskTextSelector && el.matches(privacyOptions.unmaskTextSelector)) {
40881    return value;
40882  }
40883
40884  if (
40885    maskAttributes.includes(key) ||
40886    // Need to mask `value` attribute for `<input>` if it's a button-like
40887    // type
40888    (key === 'value' && el.tagName === 'INPUT' && ['submit', 'button'].includes(el.getAttribute('type') || ''))
40889  ) {
40890    return value.replace(/[\S]/g, '*');
40891  }
40892
40893  return value;
40894}
40895
40896const MEDIA_SELECTORS =
40897  'img,image,svg,video,object,picture,embed,map,audio,link[rel="icon"],link[rel="apple-touch-icon"]';
40898
40899const DEFAULT_NETWORK_HEADERS = ['content-length', 'content-type', 'accept'];
40900
40901let _initialized = false;
40902
40903const replayIntegration = ((options) => {
40904  // eslint-disable-next-line deprecation/deprecation
40905  return new Replay(options);
40906}) ;
40907
40908/**
40909 * The main replay integration class, to be passed to `init({  integrations: [] })`.
40910 * @deprecated Use `replayIntegration()` instead.
40911 */
40912class Replay  {
40913  /**
40914   * @inheritDoc
40915   */
40916   static __initStatic() {this.id = 'Replay';}
40917
40918  /**
40919   * @inheritDoc
40920   */
40921
40922  /**
40923   * Options to pass to `rrweb.record()`
40924   */
40925
40926  /**
40927   * Initial options passed to the replay integration, merged with default values.
40928   * Note: `sessionSampleRate` and `errorSampleRate` are not required here, as they
40929   * can only be finally set when setupOnce() is called.
40930   *
40931   * @private
40932   */
40933
40934   constructor({
40935    flushMinDelay = DEFAULT_FLUSH_MIN_DELAY,
40936    flushMaxDelay = DEFAULT_FLUSH_MAX_DELAY,
40937    minReplayDuration = MIN_REPLAY_DURATION,
40938    maxReplayDuration = MAX_REPLAY_DURATION,
40939    stickySession = true,
40940    useCompression = true,
40941    workerUrl,
40942    _experiments = {},
40943    sessionSampleRate,
40944    errorSampleRate,
40945    maskAllText = true,
40946    maskAllInputs = true,
40947    blockAllMedia = true,
40948
40949    mutationBreadcrumbLimit = 750,
40950    mutationLimit = 10000,
40951
40952    slowClickTimeout = 7000,
40953    slowClickIgnoreSelectors = [],
40954
40955    networkDetailAllowUrls = [],
40956    networkDetailDenyUrls = [],
40957    networkCaptureBodies = true,
40958    networkRequestHeaders = [],
40959    networkResponseHeaders = [],
40960
40961    mask = [],
40962    maskAttributes = ['title', 'placeholder'],
40963    unmask = [],
40964    block = [],
40965    unblock = [],
40966    ignore = [],
40967    maskFn,
40968
40969    beforeAddRecordingEvent,
40970    beforeErrorSampling,
40971
40972    // eslint-disable-next-line deprecation/deprecation
40973    blockClass,
40974    // eslint-disable-next-line deprecation/deprecation
40975    blockSelector,
40976    // eslint-disable-next-line deprecation/deprecation
40977    maskInputOptions,
40978    // eslint-disable-next-line deprecation/deprecation
40979    maskTextClass,
40980    // eslint-disable-next-line deprecation/deprecation
40981    maskTextSelector,
40982    // eslint-disable-next-line deprecation/deprecation
40983    ignoreClass,
40984  } = {}) {
40985    // eslint-disable-next-line deprecation/deprecation
40986    this.name = Replay.id;
40987
40988    const privacyOptions = getPrivacyOptions({
40989      mask,
40990      unmask,
40991      block,
40992      unblock,
40993      ignore,
40994      blockClass,
40995      blockSelector,
40996      maskTextClass,
40997      maskTextSelector,
40998      ignoreClass,
40999    });
41000
41001    this._recordingOptions = {
41002      maskAllInputs,
41003      maskAllText,
41004      maskInputOptions: { ...(maskInputOptions || {}), password: true },
41005      maskTextFn: maskFn,
41006      maskInputFn: maskFn,
41007      maskAttributeFn: (key, value, el) =>
41008        maskAttribute({
41009          maskAttributes,
41010          maskAllText,
41011          privacyOptions,
41012          key,
41013          value,
41014          el,
41015        }),
41016
41017      ...privacyOptions,
41018
41019      // Our defaults
41020      slimDOMOptions: 'all',
41021      inlineStylesheet: true,
41022      // Disable inline images as it will increase segment/replay size
41023      inlineImages: false,
41024      // collect fonts, but be aware that `sentry.io` needs to be an allowed
41025      // origin for playback
41026      collectFonts: true,
41027      errorHandler: (err) => {
41028        try {
41029          err.__rrweb__ = true;
41030        } catch (error) {
41031          // ignore errors here
41032          // this can happen if the error is frozen or does not allow mutation for other reasons
41033        }
41034      },
41035    };
41036
41037    this._initialOptions = {
41038      flushMinDelay,
41039      flushMaxDelay,
41040      minReplayDuration: Math.min(minReplayDuration, MIN_REPLAY_DURATION_LIMIT),
41041      maxReplayDuration: Math.min(maxReplayDuration, MAX_REPLAY_DURATION),
41042      stickySession,
41043      sessionSampleRate,
41044      errorSampleRate,
41045      useCompression,
41046      workerUrl,
41047      blockAllMedia,
41048      maskAllInputs,
41049      maskAllText,
41050      mutationBreadcrumbLimit,
41051      mutationLimit,
41052      slowClickTimeout,
41053      slowClickIgnoreSelectors,
41054      networkDetailAllowUrls,
41055      networkDetailDenyUrls,
41056      networkCaptureBodies,
41057      networkRequestHeaders: _getMergedNetworkHeaders(networkRequestHeaders),
41058      networkResponseHeaders: _getMergedNetworkHeaders(networkResponseHeaders),
41059      beforeAddRecordingEvent,
41060      beforeErrorSampling,
41061
41062      _experiments,
41063    };
41064
41065    if (typeof sessionSampleRate === 'number') {
41066      // eslint-disable-next-line
41067      console.warn(
41068        `[Replay] You are passing \`sessionSampleRate\` to the Replay integration.
41069This option is deprecated and will be removed soon.
41070Instead, configure \`replaysSessionSampleRate\` directly in the SDK init options, e.g.:
41071Sentry.init({ replaysSessionSampleRate: ${sessionSampleRate} })`,
41072      );
41073
41074      this._initialOptions.sessionSampleRate = sessionSampleRate;
41075    }
41076
41077    if (typeof errorSampleRate === 'number') {
41078      // eslint-disable-next-line
41079      console.warn(
41080        `[Replay] You are passing \`errorSampleRate\` to the Replay integration.
41081This option is deprecated and will be removed soon.
41082Instead, configure \`replaysOnErrorSampleRate\` directly in the SDK init options, e.g.:
41083Sentry.init({ replaysOnErrorSampleRate: ${errorSampleRate} })`,
41084      );
41085
41086      this._initialOptions.errorSampleRate = errorSampleRate;
41087    }
41088
41089    if (this._initialOptions.blockAllMedia) {
41090      // `blockAllMedia` is a more user friendly option to configure blocking
41091      // embedded media elements
41092      this._recordingOptions.blockSelector = !this._recordingOptions.blockSelector
41093        ? MEDIA_SELECTORS
41094        : `${this._recordingOptions.blockSelector},${MEDIA_SELECTORS}`;
41095    }
41096
41097    if (this._isInitialized && utils.isBrowser()) {
41098      throw new Error('Multiple Sentry Session Replay instances are not supported');
41099    }
41100
41101    this._isInitialized = true;
41102  }
41103
41104  /** If replay has already been initialized */
41105   get _isInitialized() {
41106    return _initialized;
41107  }
41108
41109  /** Update _isInitialized */
41110   set _isInitialized(value) {
41111    _initialized = value;
41112  }
41113
41114  /**
41115   * Setup and initialize replay container
41116   */
41117   setupOnce() {
41118    if (!utils.isBrowser()) {
41119      return;
41120    }
41121
41122    this._setup();
41123
41124    // Once upon a time, we tried to create a transaction in `setupOnce` and it would
41125    // potentially create a transaction before some native SDK integrations have run
41126    // and applied their own global event processor. An example is:
41127    // https://github.com/getsentry/sentry-javascript/blob/b47ceafbdac7f8b99093ce6023726ad4687edc48/packages/browser/src/integrations/useragent.ts
41128    //
41129    // So we call `this._initialize()` in next event loop as a workaround to wait for other
41130    // global event processors to finish. This is no longer needed, but keeping it
41131    // here to avoid any future issues.
41132    setTimeout(() => this._initialize());
41133  }
41134
41135  /**
41136   * Start a replay regardless of sampling rate. Calling this will always
41137   * create a new session. Will throw an error if replay is already in progress.
41138   *
41139   * Creates or loads a session, attaches listeners to varying events (DOM,
41140   * PerformanceObserver, Recording, Sentry SDK, etc)
41141   */
41142   start() {
41143    if (!this._replay) {
41144      return;
41145    }
41146
41147    this._replay.start();
41148  }
41149
41150  /**
41151   * Start replay buffering. Buffers until `flush()` is called or, if
41152   * `replaysOnErrorSampleRate` > 0, until an error occurs.
41153   */
41154   startBuffering() {
41155    if (!this._replay) {
41156      return;
41157    }
41158
41159    this._replay.startBuffering();
41160  }
41161
41162  /**
41163   * Currently, this needs to be manually called (e.g. for tests). Sentry SDK
41164   * does not support a teardown
41165   */
41166   stop() {
41167    if (!this._replay) {
41168      return Promise.resolve();
41169    }
41170
41171    return this._replay.stop({ forceFlush: this._replay.recordingMode === 'session' });
41172  }
41173
41174  /**
41175   * If not in "session" recording mode, flush event buffer which will create a new replay.
41176   * Unless `continueRecording` is false, the replay will continue to record and
41177   * behave as a "session"-based replay.
41178   *
41179   * Otherwise, queue up a flush.
41180   */
41181   flush(options) {
41182    if (!this._replay || !this._replay.isEnabled()) {
41183      return Promise.resolve();
41184    }
41185
41186    return this._replay.sendBufferedReplayOrFlush(options);
41187  }
41188
41189  /**
41190   * Get the current session ID.
41191   */
41192   getReplayId() {
41193    if (!this._replay || !this._replay.isEnabled()) {
41194      return;
41195    }
41196
41197    return this._replay.getSessionId();
41198  }
41199
41200  /**
41201   * Initializes replay.
41202   */
41203   _initialize() {
41204    if (!this._replay) {
41205      return;
41206    }
41207
41208    // We have to run this in _initialize, because this runs in setTimeout
41209    // So when this runs all integrations have been added
41210    // Before this, we cannot access integrations on the client,
41211    // so we need to mutate the options here
41212    this._maybeLoadFromReplayCanvasIntegration();
41213
41214    this._replay.initializeSampling();
41215  }
41216
41217  /** Setup the integration. */
41218   _setup() {
41219    // Client is not available in constructor, so we need to wait until setupOnce
41220    const finalOptions = loadReplayOptionsFromClient(this._initialOptions);
41221
41222    this._replay = new ReplayContainer({
41223      options: finalOptions,
41224      recordingOptions: this._recordingOptions,
41225    });
41226  }
41227
41228  /** Get canvas options from ReplayCanvas integration, if it is also added. */
41229   _maybeLoadFromReplayCanvasIntegration() {
41230    // To save bundle size, we skip checking for stuff here
41231    // and instead just try-catch everything - as generally this should all be defined
41232    /* eslint-disable @typescript-eslint/no-non-null-assertion */
41233    try {
41234      const client = core.getClient();
41235      const canvasIntegration = client.getIntegrationByName('ReplayCanvas')
41236
41237;
41238      if (!canvasIntegration) {
41239        return;
41240      }
41241
41242      this._replay['_canvas'] = canvasIntegration.getOptions();
41243    } catch (e) {
41244      // ignore errors here
41245    }
41246    /* eslint-enable @typescript-eslint/no-non-null-assertion */
41247  }
41248}Replay.__initStatic();
41249
41250/** Parse Replay-related options from SDK options */
41251function loadReplayOptionsFromClient(initialOptions) {
41252  const client = core.getClient();
41253  const opt = client && (client.getOptions() );
41254
41255  const finalOptions = { sessionSampleRate: 0, errorSampleRate: 0, ...utils.dropUndefinedKeys(initialOptions) };
41256
41257  if (!opt) {
41258    utils.consoleSandbox(() => {
41259      // eslint-disable-next-line no-console
41260      console.warn('SDK client is not available.');
41261    });
41262    return finalOptions;
41263  }
41264
41265  if (
41266    initialOptions.sessionSampleRate == null && // TODO remove once deprecated rates are removed
41267    initialOptions.errorSampleRate == null && // TODO remove once deprecated rates are removed
41268    opt.replaysSessionSampleRate == null &&
41269    opt.replaysOnErrorSampleRate == null
41270  ) {
41271    utils.consoleSandbox(() => {
41272      // eslint-disable-next-line no-console
41273      console.warn(
41274        'Replay is disabled because neither `replaysSessionSampleRate` nor `replaysOnErrorSampleRate` are set.',
41275      );
41276    });
41277  }
41278
41279  if (typeof opt.replaysSessionSampleRate === 'number') {
41280    finalOptions.sessionSampleRate = opt.replaysSessionSampleRate;
41281  }
41282
41283  if (typeof opt.replaysOnErrorSampleRate === 'number') {
41284    finalOptions.errorSampleRate = opt.replaysOnErrorSampleRate;
41285  }
41286
41287  return finalOptions;
41288}
41289
41290function _getMergedNetworkHeaders(headers) {
41291  return [...DEFAULT_NETWORK_HEADERS, ...headers.map(header => header.toLowerCase())];
41292}
41293
41294/**
41295 * This is a small utility to get a type-safe instance of the Replay integration.
41296 */
41297// eslint-disable-next-line deprecation/deprecation
41298function getReplay() {
41299  const client = core.getClient();
41300  return (
41301    client && client.getIntegrationByName && client.getIntegrationByName('Replay')
41302  );
41303}
41304
41305exports.Replay = Replay;
41306exports.getReplay = getReplay;
41307exports.replayIntegration = replayIntegration;
41308
41309
41310},{"@sentry-internal/tracing":209,"@sentry/core":250,"@sentry/utils":319}],300:[function(require,module,exports){
41311Object.defineProperty(exports, '__esModule', { value: true });
41312
41313const is = require('./is.js');
41314const string = require('./string.js');
41315
41316/**
41317 * Creates exceptions inside `event.exception.values` for errors that are nested on properties based on the `key` parameter.
41318 */
41319function applyAggregateErrorsToEvent(
41320  exceptionFromErrorImplementation,
41321  parser,
41322  maxValueLimit = 250,
41323  key,
41324  limit,
41325  event,
41326  hint,
41327) {
41328  if (!event.exception || !event.exception.values || !hint || !is.isInstanceOf(hint.originalException, Error)) {
41329    return;
41330  }
41331
41332  // Generally speaking the last item in `event.exception.values` is the exception originating from the original Error
41333  const originalException =
41334    event.exception.values.length > 0 ? event.exception.values[event.exception.values.length - 1] : undefined;
41335
41336  // We only create exception grouping if there is an exception in the event.
41337  if (originalException) {
41338    event.exception.values = truncateAggregateExceptions(
41339      aggregateExceptionsFromError(
41340        exceptionFromErrorImplementation,
41341        parser,
41342        limit,
41343        hint.originalException ,
41344        key,
41345        event.exception.values,
41346        originalException,
41347        0,
41348      ),
41349      maxValueLimit,
41350    );
41351  }
41352}
41353
41354function aggregateExceptionsFromError(
41355  exceptionFromErrorImplementation,
41356  parser,
41357  limit,
41358  error,
41359  key,
41360  prevExceptions,
41361  exception,
41362  exceptionId,
41363) {
41364  if (prevExceptions.length >= limit + 1) {
41365    return prevExceptions;
41366  }
41367
41368  let newExceptions = [...prevExceptions];
41369
41370  // Recursively call this function in order to walk down a chain of errors
41371  if (is.isInstanceOf(error[key], Error)) {
41372    applyExceptionGroupFieldsForParentException(exception, exceptionId);
41373    const newException = exceptionFromErrorImplementation(parser, error[key]);
41374    const newExceptionId = newExceptions.length;
41375    applyExceptionGroupFieldsForChildException(newException, key, newExceptionId, exceptionId);
41376    newExceptions = aggregateExceptionsFromError(
41377      exceptionFromErrorImplementation,
41378      parser,
41379      limit,
41380      error[key],
41381      key,
41382      [newException, ...newExceptions],
41383      newException,
41384      newExceptionId,
41385    );
41386  }
41387
41388  // This will create exception grouping for AggregateErrors
41389  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError
41390  if (Array.isArray(error.errors)) {
41391    error.errors.forEach((childError, i) => {
41392      if (is.isInstanceOf(childError, Error)) {
41393        applyExceptionGroupFieldsForParentException(exception, exceptionId);
41394        const newException = exceptionFromErrorImplementation(parser, childError);
41395        const newExceptionId = newExceptions.length;
41396        applyExceptionGroupFieldsForChildException(newException, `errors[${i}]`, newExceptionId, exceptionId);
41397        newExceptions = aggregateExceptionsFromError(
41398          exceptionFromErrorImplementation,
41399          parser,
41400          limit,
41401          childError,
41402          key,
41403          [newException, ...newExceptions],
41404          newException,
41405          newExceptionId,
41406        );
41407      }
41408    });
41409  }
41410
41411  return newExceptions;
41412}
41413
41414function applyExceptionGroupFieldsForParentException(exception, exceptionId) {
41415  // Don't know if this default makes sense. The protocol requires us to set these values so we pick *some* default.
41416  exception.mechanism = exception.mechanism || { type: 'generic', handled: true };
41417
41418  exception.mechanism = {
41419    ...exception.mechanism,
41420    ...(exception.type === 'AggregateError' && { is_exception_group: true }),
41421    exception_id: exceptionId,
41422  };
41423}
41424
41425function applyExceptionGroupFieldsForChildException(
41426  exception,
41427  source,
41428  exceptionId,
41429  parentId,
41430) {
41431  // Don't know if this default makes sense. The protocol requires us to set these values so we pick *some* default.
41432  exception.mechanism = exception.mechanism || { type: 'generic', handled: true };
41433
41434  exception.mechanism = {
41435    ...exception.mechanism,
41436    type: 'chained',
41437    source,
41438    exception_id: exceptionId,
41439    parent_id: parentId,
41440  };
41441}
41442
41443/**
41444 * Truncate the message (exception.value) of all exceptions in the event.
41445 * Because this event processor is ran after `applyClientOptions`,
41446 * we need to truncate the message of the added exceptions here.
41447 */
41448function truncateAggregateExceptions(exceptions, maxValueLength) {
41449  return exceptions.map(exception => {
41450    if (exception.value) {
41451      exception.value = string.truncate(exception.value, maxValueLength);
41452    }
41453    return exception;
41454  });
41455}
41456
41457exports.applyAggregateErrorsToEvent = applyAggregateErrorsToEvent;
41458
41459
41460},{"./is.js":329,"./string.js":345}],301:[function(require,module,exports){
41461Object.defineProperty(exports, '__esModule', { value: true });
41462
41463const object = require('./object.js');
41464const nodeStackTrace = require('./node-stack-trace.js');
41465
41466/**
41467 * A node.js watchdog timer
41468 * @param pollInterval The interval that we expect to get polled at
41469 * @param anrThreshold The threshold for when we consider ANR
41470 * @param callback The callback to call for ANR
41471 * @returns An object with `poll` and `enabled` functions {@link WatchdogReturn}
41472 */
41473function watchdogTimer(
41474  createTimer,
41475  pollInterval,
41476  anrThreshold,
41477  callback,
41478) {
41479  const timer = createTimer();
41480  let triggered = false;
41481  let enabled = true;
41482
41483  setInterval(() => {
41484    const diffMs = timer.getTimeMs();
41485
41486    if (triggered === false && diffMs > pollInterval + anrThreshold) {
41487      triggered = true;
41488      if (enabled) {
41489        callback();
41490      }
41491    }
41492
41493    if (diffMs < pollInterval + anrThreshold) {
41494      triggered = false;
41495    }
41496  }, 20);
41497
41498  return {
41499    poll: () => {
41500      timer.reset();
41501    },
41502    enabled: (state) => {
41503      enabled = state;
41504    },
41505  };
41506}
41507
41508// types copied from inspector.d.ts
41509
41510/**
41511 * Converts Debugger.CallFrame to Sentry StackFrame
41512 */
41513function callFrameToStackFrame(
41514  frame,
41515  url,
41516  getModuleFromFilename,
41517) {
41518  const filename = url ? url.replace(/^file:\/\//, '') : undefined;
41519
41520  // CallFrame row/col are 0 based, whereas StackFrame are 1 based
41521  const colno = frame.location.columnNumber ? frame.location.columnNumber + 1 : undefined;
41522  const lineno = frame.location.lineNumber ? frame.location.lineNumber + 1 : undefined;
41523
41524  return object.dropUndefinedKeys({
41525    filename,
41526    module: getModuleFromFilename(filename),
41527    function: frame.functionName || '?',
41528    colno,
41529    lineno,
41530    in_app: filename ? nodeStackTrace.filenameIsInApp(filename) : undefined,
41531  });
41532}
41533
41534exports.callFrameToStackFrame = callFrameToStackFrame;
41535exports.watchdogTimer = watchdogTimer;
41536
41537
41538},{"./node-stack-trace.js":335,"./object.js":338}],302:[function(require,module,exports){
41539Object.defineProperty(exports, '__esModule', { value: true });
41540
41541const debugBuild = require('./debug-build.js');
41542const is = require('./is.js');
41543const logger = require('./logger.js');
41544
41545const BAGGAGE_HEADER_NAME = 'baggage';
41546
41547const SENTRY_BAGGAGE_KEY_PREFIX = 'sentry-';
41548
41549const SENTRY_BAGGAGE_KEY_PREFIX_REGEX = /^sentry-/;
41550
41551/**
vendor: 5,343 bytes, lines 41552-41690
41552 * Max length of a serialized baggage string
41553 *
41554 * https://www.w3.org/TR/baggage/#limits
41555 */
41556const MAX_BAGGAGE_STRING_LENGTH = 8192;
41557
41558/**
41559 * Takes a baggage header and turns it into Dynamic Sampling Context, by extracting all the "sentry-" prefixed values
41560 * from it.
41561 *
41562 * @param baggageHeader A very bread definition of a baggage header as it might appear in various frameworks.
41563 * @returns The Dynamic Sampling Context that was found on `baggageHeader`, if there was any, `undefined` otherwise.
41564 */
41565function baggageHeaderToDynamicSamplingContext(
41566  // Very liberal definition of what any incoming header might look like
41567  baggageHeader,
41568) {
41569  if (!is.isString(baggageHeader) && !Array.isArray(baggageHeader)) {
41570    return undefined;
41571  }
41572
41573  // Intermediary object to store baggage key value pairs of incoming baggage headers on.
41574  // It is later used to read Sentry-DSC-values from.
41575  let baggageObject = {};
41576
41577  if (Array.isArray(baggageHeader)) {
41578    // Combine all baggage headers into one object containing the baggage values so we can later read the Sentry-DSC-values from it
41579    baggageObject = baggageHeader.reduce((acc, curr) => {
41580      const currBaggageObject = baggageHeaderToObject(curr);
41581      for (const key of Object.keys(currBaggageObject)) {
41582        acc[key] = currBaggageObject[key];
41583      }
41584      return acc;
41585    }, {});
41586  } else {
41587    // Return undefined if baggage header is an empty string (technically an empty baggage header is not spec conform but
41588    // this is how we choose to handle it)
41589    if (!baggageHeader) {
41590      return undefined;
41591    }
41592
41593    baggageObject = baggageHeaderToObject(baggageHeader);
41594  }
41595
41596  // Read all "sentry-" prefixed values out of the baggage object and put it onto a dynamic sampling context object.
41597  const dynamicSamplingContext = Object.entries(baggageObject).reduce((acc, [key, value]) => {
41598    if (key.match(SENTRY_BAGGAGE_KEY_PREFIX_REGEX)) {
41599      const nonPrefixedKey = key.slice(SENTRY_BAGGAGE_KEY_PREFIX.length);
41600      acc[nonPrefixedKey] = value;
41601    }
41602    return acc;
41603  }, {});
41604
41605  // Only return a dynamic sampling context object if there are keys in it.
41606  // A keyless object means there were no sentry values on the header, which means that there is no DSC.
41607  if (Object.keys(dynamicSamplingContext).length > 0) {
41608    return dynamicSamplingContext ;
41609  } else {
41610    return undefined;
41611  }
41612}
41613
41614/**
41615 * Turns a Dynamic Sampling Object into a baggage header by prefixing all the keys on the object with "sentry-".
41616 *
41617 * @param dynamicSamplingContext The Dynamic Sampling Context to turn into a header. For convenience and compatibility
41618 * with the `getDynamicSamplingContext` method on the Transaction class ,this argument can also be `undefined`. If it is
41619 * `undefined` the function will return `undefined`.
41620 * @returns a baggage header, created from `dynamicSamplingContext`, or `undefined` either if `dynamicSamplingContext`
41621 * was `undefined`, or if `dynamicSamplingContext` didn't contain any values.
41622 */
41623function dynamicSamplingContextToSentryBaggageHeader(
41624  // this also takes undefined for convenience and bundle size in other places
41625  dynamicSamplingContext,
41626) {
41627  if (!dynamicSamplingContext) {
41628    return undefined;
41629  }
41630
41631  // Prefix all DSC keys with "sentry-" and put them into a new object
41632  const sentryPrefixedDSC = Object.entries(dynamicSamplingContext).reduce(
41633    (acc, [dscKey, dscValue]) => {
41634      if (dscValue) {
41635        acc[`${SENTRY_BAGGAGE_KEY_PREFIX}${dscKey}`] = dscValue;
41636      }
41637      return acc;
41638    },
41639    {},
41640  );
41641
41642  return objectToBaggageHeader(sentryPrefixedDSC);
41643}
41644
41645/**
41646 * Will parse a baggage header, which is a simple key-value map, into a flat object.
41647 *
41648 * @param baggageHeader The baggage header to parse.
41649 * @returns a flat object containing all the key-value pairs from `baggageHeader`.
41650 */
41651function baggageHeaderToObject(baggageHeader) {
41652  return baggageHeader
41653    .split(',')
41654    .map(baggageEntry => baggageEntry.split('=').map(keyOrValue => decodeURIComponent(keyOrValue.trim())))
41655    .reduce((acc, [key, value]) => {
41656      acc[key] = value;
41657      return acc;
41658    }, {});
41659}
41660
41661/**
41662 * Turns a flat object (key-value pairs) into a baggage header, which is also just key-value pairs.
41663 *
41664 * @param object The object to turn into a baggage header.
41665 * @returns a baggage header string, or `undefined` if the object didn't have any values, since an empty baggage header
41666 * is not spec compliant.
41667 */
41668function objectToBaggageHeader(object) {
41669  if (Object.keys(object).length === 0) {
41670    // An empty baggage header is not spec compliant: We return undefined.
41671    return undefined;
41672  }
41673
41674  return Object.entries(object).reduce((baggageHeader, [objectKey, objectValue], currentIndex) => {
41675    const baggageEntry = `${encodeURIComponent(objectKey)}=${encodeURIComponent(objectValue)}`;
41676    const newBaggageHeader = currentIndex === 0 ? baggageEntry : `${baggageHeader},${baggageEntry}`;
41677    if (newBaggageHeader.length > MAX_BAGGAGE_STRING_LENGTH) {
41678      debugBuild.DEBUG_BUILD &&
41679        logger.logger.warn(
41680          `Not adding key: ${objectKey} with val: ${objectValue} to baggage header due to exceeding baggage size limits.`,
41681        );
41682      return baggageHeader;
41683    } else {
41684      return newBaggageHeader;
41685    }
41686  }, '');
41687}
41688
41689exports.BAGGAGE_HEADER_NAME = BAGGAGE_HEADER_NAME;
41690exports.MAX_BAGGAGE_STRING_LENGTH = MAX_BAGGAGE_STRING_LENGTH;
41691exports.SENTRY_BAGGAGE_KEY_PREFIX = SENTRY_BAGGAGE_KEY_PREFIX;
41692exports.SENTRY_BAGGAGE_KEY_PREFIX_REGEX = SENTRY_BAGGAGE_KEY_PREFIX_REGEX;
41693exports.baggageHeaderToDynamicSamplingContext = baggageHeaderToDynamicSamplingContext;
41694exports.dynamicSamplingContextToSentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader;
41695
41696
41697},{"./debug-build.js":313,"./is.js":329,"./logger.js":331}],303:[function(require,module,exports){
41698Object.defineProperty(exports, '__esModule', { value: true });
41699
41700const is = require('./is.js');
41701const worldwide = require('./worldwide.js');
41702
41703// eslint-disable-next-line deprecation/deprecation
41704const WINDOW = worldwide.getGlobalObject();
41705
41706const DEFAULT_MAX_STRING_LENGTH = 80;
41707
41708/**
41709 * Given a child DOM element, returns a query-selector statement describing that
41710 * and its ancestors
41711 * e.g. [HTMLElement] => body > div > input#foo.btn[name=baz]
41712 * @returns generated DOM path
41713 */
41714function htmlTreeAsString(
41715  elem,
41716  options = {},
41717) {
41718  if (!elem) {
41719    return '<unknown>';
41720  }
41721
41722  // try/catch both:
41723  // - accessing event.target (see getsentry/raven-js#838, #768)
41724  // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly
41725  // - can throw an exception in some circumstances.
41726  try {
vendor: 5,405 bytes, lines 41727-41907
41727    let currentElem = elem ;
41728    const MAX_TRAVERSE_HEIGHT = 5;
41729    const out = [];
41730    let height = 0;
41731    let len = 0;
41732    const separator = ' > ';
41733    const sepLength = separator.length;
41734    let nextStr;
41735    const keyAttrs = Array.isArray(options) ? options : options.keyAttrs;
41736    const maxStringLength = (!Array.isArray(options) && options.maxStringLength) || DEFAULT_MAX_STRING_LENGTH;
41737
41738    while (currentElem && height++ < MAX_TRAVERSE_HEIGHT) {
41739      nextStr = _htmlElementAsString(currentElem, keyAttrs);
41740      // bail out if
41741      // - nextStr is the 'html' element
41742      // - the length of the string that would be created exceeds maxStringLength
41743      //   (ignore this limit if we are on the first iteration)
41744      if (nextStr === 'html' || (height > 1 && len + out.length * sepLength + nextStr.length >= maxStringLength)) {
41745        break;
41746      }
41747
41748      out.push(nextStr);
41749
41750      len += nextStr.length;
41751      currentElem = currentElem.parentNode;
41752    }
41753
41754    return out.reverse().join(separator);
41755  } catch (_oO) {
41756    return '<unknown>';
41757  }
41758}
41759
41760/**
41761 * Returns a simple, query-selector representation of a DOM element
41762 * e.g. [HTMLElement] => input#foo.btn[name=baz]
41763 * @returns generated DOM path
41764 */
41765function _htmlElementAsString(el, keyAttrs) {
41766  const elem = el
41767
41768;
41769
41770  const out = [];
41771  let className;
41772  let classes;
41773  let key;
41774  let attr;
41775  let i;
41776
41777  if (!elem || !elem.tagName) {
41778    return '';
41779  }
41780
41781  // @ts-expect-error WINDOW has HTMLElement
41782  if (WINDOW.HTMLElement) {
41783    // If using the component name annotation plugin, this value may be available on the DOM node
41784    if (elem instanceof HTMLElement && elem.dataset && elem.dataset['sentryComponent']) {
41785      return elem.dataset['sentryComponent'];
41786    }
41787  }
41788
41789  out.push(elem.tagName.toLowerCase());
41790
41791  // Pairs of attribute keys defined in `serializeAttribute` and their values on element.
41792  const keyAttrPairs =
41793    keyAttrs && keyAttrs.length
41794      ? keyAttrs.filter(keyAttr => elem.getAttribute(keyAttr)).map(keyAttr => [keyAttr, elem.getAttribute(keyAttr)])
41795      : null;
41796
41797  if (keyAttrPairs && keyAttrPairs.length) {
41798    keyAttrPairs.forEach(keyAttrPair => {
41799      out.push(`[${keyAttrPair[0]}="${keyAttrPair[1]}"]`);
41800    });
41801  } else {
41802    if (elem.id) {
41803      out.push(`#${elem.id}`);
41804    }
41805
41806    // eslint-disable-next-line prefer-const
41807    className = elem.className;
41808    if (className && is.isString(className)) {
41809      classes = className.split(/\s+/);
41810      for (i = 0; i < classes.length; i++) {
41811        out.push(`.${classes[i]}`);
41812      }
41813    }
41814  }
41815  const allowedAttrs = ['aria-label', 'type', 'name', 'title', 'alt'];
41816  for (i = 0; i < allowedAttrs.length; i++) {
41817    key = allowedAttrs[i];
41818    attr = elem.getAttribute(key);
41819    if (attr) {
41820      out.push(`[${key}="${attr}"]`);
41821    }
41822  }
41823  return out.join('');
41824}
41825
41826/**
41827 * A safe form of location.href
41828 */
41829function getLocationHref() {
41830  try {
41831    return WINDOW.document.location.href;
41832  } catch (oO) {
41833    return '';
41834  }
41835}
41836
41837/**
41838 * Gets a DOM element by using document.querySelector.
41839 *
41840 * This wrapper will first check for the existance of the function before
41841 * actually calling it so that we don't have to take care of this check,
41842 * every time we want to access the DOM.
41843 *
41844 * Reason: DOM/querySelector is not available in all environments.
41845 *
41846 * We have to cast to any because utils can be consumed by a variety of environments,
41847 * and we don't want to break TS users. If you know what element will be selected by
41848 * `document.querySelector`, specify it as part of the generic call. For example,
41849 * `const element = getDomElement<Element>('selector');`
41850 *
41851 * @param selector the selector string passed on to document.querySelector
41852 */
41853// eslint-disable-next-line @typescript-eslint/no-explicit-any
41854function getDomElement(selector) {
41855  if (WINDOW.document && WINDOW.document.querySelector) {
41856    return WINDOW.document.querySelector(selector) ;
41857  }
41858  return null;
41859}
41860
41861/**
41862 * Given a DOM element, traverses up the tree until it finds the first ancestor node
41863 * that has the `data-sentry-component` attribute. This attribute is added at build-time
41864 * by projects that have the component name annotation plugin installed.
41865 *
41866 * @returns a string representation of the component for the provided DOM element, or `null` if not found
41867 */
41868function getComponentName(elem) {
41869  // @ts-expect-error WINDOW has HTMLElement
41870  if (!WINDOW.HTMLElement) {
41871    return null;
41872  }
41873
41874  let currentElem = elem ;
41875  const MAX_TRAVERSE_HEIGHT = 5;
41876  for (let i = 0; i < MAX_TRAVERSE_HEIGHT; i++) {
41877    if (!currentElem) {
41878      return null;
41879    }
41880
41881    if (currentElem instanceof HTMLElement && currentElem.dataset['sentryComponent']) {
41882      return currentElem.dataset['sentryComponent'];
41883    }
41884
41885    currentElem = currentElem.parentNode;
41886  }
41887
41888  return null;
41889}
41890
41891exports.getComponentName = getComponentName;
41892exports.getDomElement = getDomElement;
41893exports.getLocationHref = getLocationHref;
41894exports.htmlTreeAsString = htmlTreeAsString;
41895
41896
41897},{"./is.js":329,"./worldwide.js":354}],304:[function(require,module,exports){
41898Object.defineProperty(exports, '__esModule', { value: true });
41899
41900const _nullishCoalesce = require('./_nullishCoalesce.js');
41901
41902// https://github.com/alangpierce/sucrase/tree/265887868966917f3b924ce38dfad01fbab1329f
41903
41904/**
41905 * Polyfill for the nullish coalescing operator (`??`), when used in situations where at least one of the values is the
41906 * result of an async operation.
41907 *
41908 * Note that the RHS is wrapped in a function so that if it's a computed value, that evaluation won't happen unless the
41909 * LHS evaluates to a nullish value, to mimic the operator's short-circuiting behavior.
41910 *
41911 * Adapted from Sucrase (https://github.com/alangpierce/sucrase)
41912 *
41913 * @param lhs The value of the expression to the left of the `??`
41914 * @param rhsFn A function returning the value of the expression to the right of the `??`
41915 * @returns The LHS value, unless it's `null` or `undefined`, in which case, the RHS value
41916 */
41917async function _asyncNullishCoalesce(lhs, rhsFn) {
41918  return _nullishCoalesce._nullishCoalesce(lhs, rhsFn);
41919}
41920
41921// Sucrase version:
41922// async function _asyncNullishCoalesce(lhs, rhsFn) {
41923//   if (lhs != null) {
41924//     return lhs;
41925//   } else {
41926//     return await rhsFn();
41927//   }
41928// }
41929
41930exports._asyncNullishCoalesce = _asyncNullishCoalesce;
41931
41932
41933},{"./_nullishCoalesce.js":307}],305:[function(require,module,exports){
41934Object.defineProperty(exports, '__esModule', { value: true });
41935
41936/**
41937 * Polyfill for the optional chain operator, `?.`, given previous conversion of the expression into an array of values,
41938 * descriptors, and functions, for situations in which at least one part of the expression is async.
41939 *
41940 * Adapted from Sucrase (https://github.com/alangpierce/sucrase) See
41941 * https://github.com/alangpierce/sucrase/blob/265887868966917f3b924ce38dfad01fbab1329f/src/transformers/OptionalChainingNullishTransformer.ts#L15
41942 *
41943 * @param ops Array result of expression conversion
41944 * @returns The value of the expression
41945 */
41946async function _asyncOptionalChain(ops) {
41947  let lastAccessLHS = undefined;
41948  let value = ops[0];
41949  let i = 1;
41950  while (i < ops.length) {
41951    const op = ops[i] ;
41952    const fn = ops[i + 1] ;
41953    i += 2;
41954    // by checking for loose equality to `null`, we catch both `null` and `undefined`
41955    if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
41956      // really we're meaning to return `undefined` as an actual value here, but it saves bytes not to write it
41957      return;
41958    }
41959    if (op === 'access' || op === 'optionalAccess') {
41960      lastAccessLHS = value;
41961      value = await fn(value);
41962    } else if (op === 'call' || op === 'optionalCall') {
41963      value = await fn((...args) => (value ).call(lastAccessLHS, ...args));
41964      lastAccessLHS = undefined;
41965    }
41966  }
41967  return value;
41968}
41969
41970// Sucrase version:
41971// async function _asyncOptionalChain(ops) {
41972//   let lastAccessLHS = undefined;
41973//   let value = ops[0];
41974//   let i = 1;
41975//   while (i < ops.length) {
41976//     const op = ops[i];
41977//     const fn = ops[i + 1];
41978//     i += 2;
41979//     if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
41980//       return undefined;
41981//     }
41982//     if (op === 'access' || op === 'optionalAccess') {
41983//       lastAccessLHS = value;
41984//       value = await fn(value);
41985//     } else if (op === 'call' || op === 'optionalCall') {
41986//       value = await fn((...args) => value.call(lastAccessLHS, ...args));
41987//       lastAccessLHS = undefined;
41988//     }
41989//   }
41990//   return value;
41991// }
41992
41993exports._asyncOptionalChain = _asyncOptionalChain;
41994
41995
41996},{}],306:[function(require,module,exports){
41997Object.defineProperty(exports, '__esModule', { value: true });
41998
41999const _asyncOptionalChain = require('./_asyncOptionalChain.js');
42000
42001// https://github.com/alangpierce/sucrase/tree/265887868966917f3b924ce38dfad01fbab1329f
42002
42003/**
42004 * Polyfill for the optional chain operator, `?.`, given previous conversion of the expression into an array of values,
42005 * descriptors, and functions, in cases where the value of the expression is to be deleted.
42006 *
42007 * Adapted from Sucrase (https://github.com/alangpierce/sucrase) See
42008 * https://github.com/alangpierce/sucrase/blob/265887868966917f3b924ce38dfad01fbab1329f/src/transformers/OptionalChainingNullishTransformer.ts#L15
42009 *
42010 * @param ops Array result of expression conversion
42011 * @returns The return value of the `delete` operator: `true`, unless the deletion target is an own, non-configurable
42012 * property (one which can't be deleted or turned into an accessor, and whose enumerability can't be changed), in which
42013 * case `false`.
42014 */
42015async function _asyncOptionalChainDelete(ops) {
42016  const result = (await _asyncOptionalChain._asyncOptionalChain(ops)) ;
42017  // If `result` is `null`, it means we didn't get to the end of the chain and so nothing was deleted (in which case,
42018  // return `true` since that's what `delete` does when it no-ops). If it's non-null, we know the delete happened, in
42019  // which case we return whatever the `delete` returned, which will be a boolean.
42020  return result == null ? true : (result );
42021}
42022
42023// Sucrase version:
42024// async function asyncOptionalChainDelete(ops) {
42025//   const result = await ASYNC_OPTIONAL_CHAIN_NAME(ops);
42026//   return result == null ? true : result;
42027// }
42028
42029exports._asyncOptionalChainDelete = _asyncOptionalChainDelete;
42030
42031
42032},{"./_asyncOptionalChain.js":305}],307:[function(require,module,exports){
42033Object.defineProperty(exports, '__esModule', { value: true });
42034
42035// https://github.com/alangpierce/sucrase/tree/265887868966917f3b924ce38dfad01fbab1329f
42036//
42037// The MIT License (MIT)
42038//
42039// Copyright (c) 2012-2018 various contributors (see AUTHORS)
42040//
42041// Permission is hereby granted, free of charge, to any person obtaining a copy
42042// of this software and associated documentation files (the "Software"), to deal
42043// in the Software without restriction, including without limitation the rights
42044// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42045// copies of the Software, and to permit persons to whom the Software is
42046// furnished to do so, subject to the following conditions:
42047//
42048// The above copyright notice and this permission notice shall be included in all
42049// copies or substantial portions of the Software.
42050//
42051// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42052// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42053// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42054// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42055// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42056// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
42057// SOFTWARE.
42058
42059/**
42060 * Polyfill for the nullish coalescing operator (`??`).
42061 *
42062 * Note that the RHS is wrapped in a function so that if it's a computed value, that evaluation won't happen unless the
42063 * LHS evaluates to a nullish value, to mimic the operator's short-circuiting behavior.
42064 *
42065 * Adapted from Sucrase (https://github.com/alangpierce/sucrase)
42066 *
42067 * @param lhs The value of the expression to the left of the `??`
42068 * @param rhsFn A function returning the value of the expression to the right of the `??`
42069 * @returns The LHS value, unless it's `null` or `undefined`, in which case, the RHS value
42070 */
42071function _nullishCoalesce(lhs, rhsFn) {
42072  // by checking for loose equality to `null`, we catch both `null` and `undefined`
42073  return lhs != null ? lhs : rhsFn();
42074}
42075
42076// Sucrase version:
42077// function _nullishCoalesce(lhs, rhsFn) {
42078//   if (lhs != null) {
42079//     return lhs;
42080//   } else {
42081//     return rhsFn();
42082//   }
42083// }
42084
42085exports._nullishCoalesce = _nullishCoalesce;
42086
42087
42088},{}],308:[function(require,module,exports){
42089Object.defineProperty(exports, '__esModule', { value: true });
42090
42091/**
42092 * Polyfill for the optional chain operator, `?.`, given previous conversion of the expression into an array of values,
42093 * descriptors, and functions.
42094 *
42095 * Adapted from Sucrase (https://github.com/alangpierce/sucrase)
42096 * See https://github.com/alangpierce/sucrase/blob/265887868966917f3b924ce38dfad01fbab1329f/src/transformers/OptionalChainingNullishTransformer.ts#L15
42097 *
42098 * @param ops Array result of expression conversion
42099 * @returns The value of the expression
42100 */
42101function _optionalChain(ops) {
42102  let lastAccessLHS = undefined;
42103  let value = ops[0];
42104  let i = 1;
42105  while (i < ops.length) {
42106    const op = ops[i] ;
42107    const fn = ops[i + 1] ;
42108    i += 2;
42109    // by checking for loose equality to `null`, we catch both `null` and `undefined`
42110    if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
42111      // really we're meaning to return `undefined` as an actual value here, but it saves bytes not to write it
42112      return;
42113    }
42114    if (op === 'access' || op === 'optionalAccess') {
42115      lastAccessLHS = value;
42116      value = fn(value);
42117    } else if (op === 'call' || op === 'optionalCall') {
42118      value = fn((...args) => (value ).call(lastAccessLHS, ...args));
42119      lastAccessLHS = undefined;
42120    }
42121  }
42122  return value;
42123}
42124
42125// Sucrase version
42126// function _optionalChain(ops) {
42127//   let lastAccessLHS = undefined;
42128//   let value = ops[0];
42129//   let i = 1;
42130//   while (i < ops.length) {
42131//     const op = ops[i];
42132//     const fn = ops[i + 1];
42133//     i += 2;
42134//     if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
42135//       return undefined;
42136//     }
42137//     if (op === 'access' || op === 'optionalAccess') {
42138//       lastAccessLHS = value;
42139//       value = fn(value);
42140//     } else if (op === 'call' || op === 'optionalCall') {
42141//       value = fn((...args) => value.call(lastAccessLHS, ...args));
42142//       lastAccessLHS = undefined;
42143//     }
42144//   }
42145//   return value;
42146// }
42147
42148exports._optionalChain = _optionalChain;
42149
42150
42151},{}],309:[function(require,module,exports){
42152Object.defineProperty(exports, '__esModule', { value: true });
42153
42154const _optionalChain = require('./_optionalChain.js');
42155
42156// https://github.com/alangpierce/sucrase/tree/265887868966917f3b924ce38dfad01fbab1329f
42157
42158/**
42159 * Polyfill for the optional chain operator, `?.`, given previous conversion of the expression into an array of values,
42160 * descriptors, and functions, in cases where the value of the expression is to be deleted.
42161 *
42162 * Adapted from Sucrase (https://github.com/alangpierce/sucrase) See
42163 * https://github.com/alangpierce/sucrase/blob/265887868966917f3b924ce38dfad01fbab1329f/src/transformers/OptionalChainingNullishTransformer.ts#L15
42164 *
42165 * @param ops Array result of expression conversion
42166 * @returns The return value of the `delete` operator: `true`, unless the deletion target is an own, non-configurable
42167 * property (one which can't be deleted or turned into an accessor, and whose enumerability can't be changed), in which
42168 * case `false`.
42169 */
42170function _optionalChainDelete(ops) {
42171  const result = _optionalChain._optionalChain(ops) ;
42172  // If `result` is `null`, it means we didn't get to the end of the chain and so nothing was deleted (in which case,
42173  // return `true` since that's what `delete` does when it no-ops). If it's non-null, we know the delete happened, in
42174  // which case we return whatever the `delete` returned, which will be a boolean.
42175  return result == null ? true : result;
42176}
42177
42178// Sucrase version:
42179// function _optionalChainDelete(ops) {
42180//   const result = _optionalChain(ops);
42181//   // by checking for loose equality to `null`, we catch both `null` and `undefined`
42182//   return result == null ? true : result;
42183// }
42184
42185exports._optionalChainDelete = _optionalChainDelete;
42186
42187
42188},{"./_optionalChain.js":308}],310:[function(require,module,exports){
42189Object.defineProperty(exports, '__esModule', { value: true });
42190
42191/**
42192 * Creates a cache that evicts keys in fifo order
42193 * @param size {Number}
42194 */
42195function makeFifoCache(
42196  size,
42197)
42198
42199 {
42200  // Maintain a fifo queue of keys, we cannot rely on Object.keys as the browser may not support it.
42201  let evictionOrder = [];
42202  let cache = {};
42203
42204  return {
42205    add(key, value) {
42206      while (evictionOrder.length >= size) {
42207        // shift is O(n) but this is small size and only happens if we are
42208        // exceeding the cache size so it should be fine.
42209        const evictCandidate = evictionOrder.shift();
42210
42211        if (evictCandidate !== undefined) {
42212          // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
42213          delete cache[evictCandidate];
42214        }
42215      }
42216
42217      // in case we have a collision, delete the old key.
42218      if (cache[key]) {
42219        this.delete(key);
42220      }
42221
42222      evictionOrder.push(key);
42223      cache[key] = value;
42224    },
42225    clear() {
42226      cache = {};
42227      evictionOrder = [];
42228    },
42229    get(key) {
42230      return cache[key];
42231    },
42232    size() {
42233      return evictionOrder.length;
42234    },
42235    // Delete cache key and return true if it existed, false otherwise.
42236    delete(key) {
42237      if (!cache[key]) {
42238        return false;
42239      }
42240
42241      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
42242      delete cache[key];
42243
42244      for (let i = 0; i < evictionOrder.length; i++) {
42245        if (evictionOrder[i] === key) {
42246          evictionOrder.splice(i, 1);
42247          break;
42248        }
42249      }
42250
42251      return true;
42252    },
42253  };
42254}
42255
42256exports.makeFifoCache = makeFifoCache;
42257
42258
42259},{}],311:[function(require,module,exports){
42260Object.defineProperty(exports, '__esModule', { value: true });
42261
42262const envelope = require('./envelope.js');
42263const time = require('./time.js');
42264
42265/**
42266 * Creates client report envelope
42267 * @param discarded_events An array of discard events
42268 * @param dsn A DSN that can be set on the header. Optional.
42269 */
42270function createClientReportEnvelope(
42271  discarded_events,
42272  dsn,
42273  timestamp,
42274) {
42275  const clientReportItem = [
42276    { type: 'client_report' },
42277    {
42278      timestamp: timestamp || time.dateTimestampInSeconds(),
42279      discarded_events,
42280    },
42281  ];
42282  return envelope.createEnvelope(dsn ? { dsn } : {}, [clientReportItem]);
42283}
42284
42285exports.createClientReportEnvelope = createClientReportEnvelope;
42286
42287
42288},{"./envelope.js":316,"./time.js":348}],312:[function(require,module,exports){
42289Object.defineProperty(exports, '__esModule', { value: true });
42290
42291/**
42292 * This code was originally copied from the 'cookie` module at v0.5.0 and was simplified for our use case.
42293 * https://github.com/jshttp/cookie/blob/a0c84147aab6266bdb3996cf4062e93907c0b0fc/index.js
42294 * It had the following license:
42295 *
42296 * (The MIT License)
42297 *
42298 * Copyright (c) 2012-2014 Roman Shtylman <[email protected]>
42299 * Copyright (c) 2015 Douglas Christopher Wilson <[email protected]>
42300 *
42301 * Permission is hereby granted, free of charge, to any person obtaining
42302 * a copy of this software and associated documentation files (the
42303 * 'Software'), to deal in the Software without restriction, including
42304 * without limitation the rights to use, copy, modify, merge, publish,
42305 * distribute, sublicense, and/or sell copies of the Software, and to
42306 * permit persons to whom the Software is furnished to do so, subject to
42307 * the following conditions:
42308 *
42309 * The above copyright notice and this permission notice shall be
42310 * included in all copies or substantial portions of the Software.
42311 *
42312 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
42313 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
42314 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
42315 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
42316 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
42317 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
42318 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42319 */
42320
42321/**
42322 * Parses a cookie string
42323 */
42324function parseCookie(str) {
42325  const obj = {};
42326  let index = 0;
42327
42328  while (index < str.length) {
42329    const eqIdx = str.indexOf('=', index);
42330
42331    // no more cookie pairs
42332    if (eqIdx === -1) {
42333      break;
42334    }
42335
42336    let endIdx = str.indexOf(';', index);
42337
42338    if (endIdx === -1) {
42339      endIdx = str.length;
42340    } else if (endIdx < eqIdx) {
42341      // backtrack on prior semicolon
42342      index = str.lastIndexOf(';', eqIdx - 1) + 1;
42343      continue;
42344    }
42345
42346    const key = str.slice(index, eqIdx).trim();
42347
42348    // only assign once
42349    if (undefined === obj[key]) {
42350      let val = str.slice(eqIdx + 1, endIdx).trim();
42351
42352      // quoted values
42353      if (val.charCodeAt(0) === 0x22) {
42354        val = val.slice(1, -1);
42355      }
42356
42357      try {
42358        obj[key] = val.indexOf('%') !== -1 ? decodeURIComponent(val) : val;
42359      } catch (e) {
42360        obj[key] = val;
42361      }
42362    }
42363
42364    index = endIdx + 1;
42365  }
42366
42367  return obj;
42368}
42369
42370exports.parseCookie = parseCookie;
42371
42372
42373},{}],313:[function(require,module,exports){
42374arguments[4][206][0].apply(exports,arguments)
42375},{"dup":206}],314:[function(require,module,exports){
42376Object.defineProperty(exports, '__esModule', { value: true });
42377
42378const debugBuild = require('./debug-build.js');
42379const logger = require('./logger.js');
42380
42381/** Regular expression used to parse a Dsn. */
42382const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+)?)?@)([\w.-]+)(?::(\d+))?\/(.+)/;
42383
42384function isValidProtocol(protocol) {
42385  return protocol === 'http' || protocol === 'https';
42386}
42387
42388/**
42389 * Renders the string representation of this Dsn.
42390 *
42391 * By default, this will render the public representation without the password
42392 * component. To get the deprecated private representation, set `withPassword`
42393 * to true.
42394 *
42395 * @param withPassword When set to true, the password will be included.
42396 */
42397function dsnToString(dsn, withPassword = false) {
42398  const { host, path, pass, port, projectId, protocol, publicKey } = dsn;
42399  return (
42400    `${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` +
42401    `@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`
42402  );
42403}
42404
42405/**
42406 * Parses a Dsn from a given string.
42407 *
42408 * @param str A Dsn as string
42409 * @returns Dsn as DsnComponents or undefined if @param str is not a valid DSN string
42410 */
42411function dsnFromString(str) {
42412  const match = DSN_REGEX.exec(str);
42413
42414  if (!match) {
42415    // This should be logged to the console
42416    logger.consoleSandbox(() => {
42417      // eslint-disable-next-line no-console
42418      console.error(`Invalid Sentry Dsn: ${str}`);
42419    });
42420    return undefined;
42421  }
42422
42423  const [protocol, publicKey, pass = '', host, port = '', lastPath] = match.slice(1);
42424  let path = '';
42425  let projectId = lastPath;
42426
42427  const split = projectId.split('/');
42428  if (split.length > 1) {
42429    path = split.slice(0, -1).join('/');
42430    projectId = split.pop() ;
42431  }
42432
42433  if (projectId) {
42434    const projectMatch = projectId.match(/^\d+/);
42435    if (projectMatch) {
42436      projectId = projectMatch[0];
42437    }
42438  }
42439
42440  return dsnFromComponents({ host, pass, path, projectId, port, protocol: protocol , publicKey });
42441}
42442
42443function dsnFromComponents(components) {
42444  return {
42445    protocol: components.protocol,
42446    publicKey: components.publicKey || '',
42447    pass: components.pass || '',
42448    host: components.host,
42449    port: components.port || '',
42450    path: components.path || '',
42451    projectId: components.projectId,
42452  };
42453}
42454
42455function validateDsn(dsn) {
42456  if (!debugBuild.DEBUG_BUILD) {
42457    return true;
42458  }
42459
42460  const { port, projectId, protocol }
42460 = dsn;
42461
42462  const requiredComponents = ['protocol', 'publicKey', 'host', 'projectId'];
42463  const hasMissingRequiredComponent = requiredComponents.find(component => {
42464    if (!dsn[component]) {
42465      logger.logger.error(`Invalid Sentry Dsn: ${component} missing`);
42466      return true;
42467    }
42468    return false;
42469  });
42470
42471  if (hasMissingRequiredComponent) {
42472    return false;
42473  }
42474
42475  if (!projectId.match(/^\d+$/)) {
42476    logger.logger.error(`Invalid Sentry Dsn: Invalid projectId ${projectId}`);
42477    return false;
42478  }
42479
42480  if (!isValidProtocol(protocol)) {
42481    logger.logger.error(`Invalid Sentry Dsn: Invalid protocol ${protocol}`);
42482    return false;
42483  }
42484
42485  if (port && isNaN(parseInt(port, 10))) {
42486    logger.logger.error(`Invalid Sentry Dsn: Invalid port ${port}`);
42487    return false;
42488  }
42489
42490  return true;
42491}
42492
42493/**
42494 * Creates a valid Sentry Dsn object, identifying a Sentry instance and project.
42495 * @returns a valid DsnComponents object or `undefined` if @param from is an invalid DSN source
42496 */
42497function makeDsn(from) {
42498  const components = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from);
42499  if (!components || !validateDsn(components)) {
42500    return undefined;
42501  }
42502  return components;
42503}
42504
42505exports.dsnFromString = dsnFromString;
42506exports.dsnToString = dsnToString;
42507exports.makeDsn = makeDsn;
42508
42509
42510},{"./debug-build.js":313,"./logger.js":331}],315:[function(require,module,exports){
42511Object.defineProperty(exports, '__esModule', { value: true });
42512
42513/*
42514 * This module exists for optimizations in the build process through rollup and terser.  We define some global
42515 * constants, which can be overridden during build. By guarding certain pieces of code with functions that return these
42516 * constants, we can control whether or not they appear in the final bundle. (Any code guarded by a false condition will
42517 * never run, and will hence be dropped during treeshaking.) The two primary uses for this are stripping out calls to
42518 * `logger` and preventing node-related code from appearing in browser bundles.
42519 *
42520 * Attention:
42521 * This file should not be used to define constants/flags that are intended to be used for tree-shaking conducted by
42522 * users. These flags should live in their respective packages, as we identified user tooling (specifically webpack)
42523 * having issues tree-shaking these constants across package boundaries.
42524 * An example for this is the __SENTRY_DEBUG__ constant. It is declared in each package individually because we want
42525 * users to be able to shake away expressions that it guards.
42526 */
42527
42528/**
42529 * Figures out if we're building a browser bundle.
42530 *
42531 * @returns true if this is a browser bundle build.
42532 */
42533function isBrowserBundle() {
42534  return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__;
42535}
42536
42537/**
42538 * Get source of SDK.
42539 */
42540function getSDKSource() {
42541  // @ts-expect-error "npm" is injected by rollup during build process
42542  return "npm";
42543}
42544
42545exports.getSDKSource = getSDKSource;
42546exports.isBrowserBundle = isBrowserBundle;
42547
42548
42549},{}],316:[function(require,module,exports){
42550Object.defineProperty(exports, '__esModule', { value: true });
42551
42552const dsn = require('./dsn.js');
42553const normalize = require('./normalize.js');
42554const object = require('./object.js');
42555
42556/**
42557 * Creates an envelope.
42558 * Make sure to always explicitly provide the generic to this function
42559 * so that the envelope types resolve correctly.
42560 */
42561function createEnvelope(headers, items = []) {
42562  return [headers, items] ;
42563}
42564
42565/**
42566 * Add an item to an envelope.
42567 * Make sure to always explicitly provide the generic to this function
42568 * so that the envelope types resolve correctly.
42569 */
42570function addItemToEnvelope(envelope, newItem) {
42571  const [headers, items] = envelope;
42572  return [headers, [...items, newItem]] ;
42573}
42574
42575/**
42576 * Convenience function to loop through the items and item types of an envelope.
42577 * (This function was mostly created because working with envelope types is painful at the moment)
42578 *
42579 * If the callback returns true, the rest of the items will be skipped.
42580 */
42581function forEachEnvelopeItem(
42582  envelope,
42583  callback,
42584) {
42585  const envelopeItems = envelope[1];
42586
42587  for (const envelopeItem of envelopeItems) {
42588    const envelopeItemType = envelopeItem[0].type;
42589    const result = callback(envelopeItem, envelopeItemType);
42590
42591    if (result) {
42592      return true;
42593    }
42594  }
42595
42596  return false;
vendor: 4,200 bytes, lines 42597-42751
42597}
42598
42599/**
42600 * Returns true if the envelope contains any of the given envelope item types
42601 */
42602function envelopeContainsItemType(envelope, types) {
42603  return forEachEnvelopeItem(envelope, (_, type) => types.includes(type));
42604}
42605
42606/**
42607 * Encode a string to UTF8.
42608 */
42609function encodeUTF8(input, textEncoder) {
42610  const utf8 = textEncoder || new TextEncoder();
42611  return utf8.encode(input);
42612}
42613
42614/**
42615 * Serializes an envelope.
42616 */
42617function serializeEnvelope(envelope, textEncoder) {
42618  const [envHeaders, items] = envelope;
42619
42620  // Initially we construct our envelope as a string and only convert to binary chunks if we encounter binary data
42621  let parts = JSON.stringify(envHeaders);
42622
42623  function append(next) {
42624    if (typeof parts === 'string') {
42625      parts = typeof next === 'string' ? parts + next : [encodeUTF8(parts, textEncoder), next];
42626    } else {
42627      parts.push(typeof next === 'string' ? encodeUTF8(next, textEncoder) : next);
42628    }
42629  }
42630
42631  for (const item of items) {
42632    const [itemHeaders, payload] = item;
42633
42634    append(`\n${JSON.stringify(itemHeaders)}\n`);
42635
42636    if (typeof payload === 'string' || payload instanceof Uint8Array) {
42637      append(payload);
42638    } else {
42639      let stringifiedPayload;
42640      try {
42641        stringifiedPayload = JSON.stringify(payload);
42642      } catch (e) {
42643        // In case, despite all our efforts to keep `payload` circular-dependency-free, `JSON.strinify()` still
42644        // fails, we try again after normalizing it again with infinite normalization depth. This of course has a
42645        // performance impact but in this case a performance hit is better than throwing.
42646        stringifiedPayload = JSON.stringify(normalize.normalize(payload));
42647      }
42648      append(stringifiedPayload);
42649    }
42650  }
42651
42652  return typeof parts === 'string' ? parts : concatBuffers(parts);
42653}
42654
42655function concatBuffers(buffers) {
42656  const totalLength = buffers.reduce((acc, buf) => acc + buf.length, 0);
42657
42658  const merged = new Uint8Array(totalLength);
42659  let offset = 0;
42660  for (const buffer of buffers) {
42661    merged.set(buffer, offset);
42662    offset += buffer.length;
42663  }
42664
42665  return merged;
42666}
42667
42668/**
42669 * Parses an envelope
42670 */
42671function parseEnvelope(
42672  env,
42673  textEncoder,
42674  textDecoder,
42675) {
42676  let buffer = typeof env === 'string' ? textEncoder.encode(env) : env;
42677
42678  function readBinary(length) {
42679    const bin = buffer.subarray(0, length);
42680    // Replace the buffer with the remaining data excluding trailing newline
42681    buffer = buffer.subarray(length + 1);
42682    return bin;
42683  }
42684
42685  function readJson() {
42686    let i = buffer.indexOf(0xa);
42687    // If we couldn't find a newline, we must have found the end of the buffer
42688    if (i < 0) {
42689      i = buffer.length;
42690    }
42691
42692    return JSON.parse(textDecoder.decode(readBinary(i))) ;
42693  }
42694
42695  const envelopeHeader = readJson();
42696  // eslint-disable-next-line @typescript-eslint/no-explicit-any
42697  const items = [];
42698
42699  while (buffer.length) {
42700    const itemHeader = readJson();
42701    const binaryLength = typeof itemHeader.length === 'number' ? itemHeader.length : undefined;
42702
42703    items.push([itemHeader, binaryLength ? readBinary(binaryLength) : readJson()]);
42704  }
42705
42706  return [envelopeHeader, items];
42707}
42708
42709/**
42710 * Creates attachment envelope items
42711 */
42712function createAttachmentEnvelopeItem(
42713  attachment,
42714  textEncoder,
42715) {
42716  const buffer = typeof attachment.data === 'string' ? encodeUTF8(attachment.data, textEncoder) : attachment.data;
42717
42718  return [
42719    object.dropUndefinedKeys({
42720      type: 'attachment',
42721      length: buffer.length,
42722      filename: attachment.filename,
42723      content_type: attachment.contentType,
42724      attachment_type: attachment.attachmentType,
42725    }),
42726    buffer,
42727  ];
42728}
42729
42730const ITEM_TYPE_TO_DATA_CATEGORY_MAP = {
42731  session: 'session',
42732  sessions: 'session',
42733  attachment: 'attachment',
42734  transaction: 'transaction',
42735  event: 'error',
42736  client_report: 'internal',
42737  user_report: 'default',
42738  profile: 'profile',
42739  replay_event: 'replay',
42740  replay_recording: 'replay',
42741  check_in: 'monitor',
42742  feedback: 'feedback',
42743  span: 'span',
42744  // TODO: This is a temporary workaround until we have a proper data category for metrics
42745  statsd: 'unknown',
42746};
42747
42748/**
42749 * Maps the type of an envelope item to a data category.
42750 */
42751function envelopeItemTypeToDataCategory(type) {
42752  return ITEM_TYPE_TO_DATA_CATEGORY_MAP[type];
42753}
42754
42755/** Extracts the minimal SDK info from from the metadata or an events */
42756function getSdkMetadataForEnvelopeHeader(metadataOrEvent) {
42757  if (!metadataOrEvent || !metadataOrEvent.sdk) {
42758    return;
42759  }
42760  const { name, version } = metadataOrEvent.sdk;
42761  return { name, version };
42762}
42763
42764/**
42765 * Creates event envelope headers, based on event, sdk info and tunnel
42766 * Note: This function was extracted from the core package to make it available in Replay
42767 */
42768function createEventEnvelopeHeaders(
42769  event,
42770  sdkInfo,
42771  tunnel,
42772  dsn$1,
42773) {
42774  const dynamicSamplingContext = event.sdkProcessingMetadata && event.sdkProcessingMetadata.dynamicSamplingContext;
42775  return {
42776    event_id: event.event_id ,
42777    sent_at: new Date().toISOString(),
42778    ...(sdkInfo && { sdk: sdkInfo }),
42779    ...(!!tunnel && dsn$1 && { dsn: dsn.dsnToString(dsn$1) }),
42780    ...(dynamicSamplingContext && {
42781      trace: object.dropUndefinedKeys({ ...dynamicSamplingContext }),
42782    }),
42783  };
42784}
42785
42786exports.addItemToEnvelope = addItemToEnvelope;
42787exports.createAttachmentEnvelopeItem = createAttachmentEnvelopeItem;
42788exports.createEnvelope = createEnvelope;
42789exports.createEventEnvelopeHeaders = createEventEnvelopeHeaders;
42790exports.envelopeContainsItemType = envelopeContainsItemType;
42791exports.envelopeItemTypeToDataCategory = envelopeItemTypeToDataCategory;
42792exports.forEachEnvelopeItem = forEachEnvelopeItem;
42793exports.getSdkMetadataForEnvelopeHeader = getSdkMetadataForEnvelopeHeader;
42794exports.parseEnvelope = parseEnvelope;
42795exports.serializeEnvelope = serializeEnvelope;
42796
42797
42798},{"./dsn.js":314,"./normalize.js":337,"./object.js":338}],317:[function(require,module,exports){
42799Object.defineProperty(exports, '__esModule', { value: true });
42800
42801/** An error emitted by Sentry SDKs and related utilities. */
42802class SentryError extends Error {
42803  /** Display name of this error instance. */
42804
42805   constructor( message, logLevel = 'warn') {
42806    super(message);this.message = message;
42807    this.name = new.target.prototype.constructor.name;
42808    // This sets the prototype to be `Error`, not `SentryError`. It's unclear why we do this, but commenting this line
42809    // out causes various (seemingly totally unrelated) playwright tests consistently time out. FYI, this makes
42810    // instances of `SentryError` fail `obj instanceof SentryError` checks.
42811    Object.setPrototypeOf(this, new.target.prototype);
42812    this.logLevel = logLevel;
42813  }
42814}
42815
42816exports.SentryError = SentryError;
42817
42818
42819},{}],318:[function(require,module,exports){
42820Object.defineProperty(exports, '__esModule', { value: true });
42821
42822const is = require('./is.js');
42823const misc = require('./misc.js');
42824const normalize = require('./normalize.js');
42825const object = require('./object.js');
42826
42827/**
42828 * Extracts stack frames from the error.stack string
42829 */
42830function parseStackFrames(stackParser, error) {
42831  return stackParser(error.stack || '', 1);
42832}
42833
42834/**
42835 * Extracts stack frames from the error and builds a Sentry Exception
42836 */
42837function exceptionFromError(stackParser, error) {
42838  const exception = {
42839    type: error.name || error.constructor.name,
42840    value: error.message,
42841  };
42842
42843  const frames = parseStackFrames(stackParser, error);
42844  if (frames.length) {
42845    exception.stacktrace = { frames };
42846  }
42847
42848  return exception;
42849}
42850
42851function getMessageForObject(exception) {
42852  if ('name' in exception && typeof exception.name === 'string') {
42853    let message = `'${exception.name}' captured as exception`;
42854
42855    if ('message' in exception && typeof exception.message === 'string') {
42856      message += ` with message '${exception.message}'`;
42857    }
42858
42859    return message;
42860  } else if ('message' in exception && typeof exception.message === 'string') {
42861    return exception.message;
42862  } else {
42863    // This will allow us to group events based on top-level keys
42864    // which is much better than creating new group when any key/value change
42865    return `Object captured as exception with keys: ${object.extractExceptionKeysForMessage(
42866      exception ,
42867    )}`;
42868  }
42869}
42870
42871/**
42872 * Builds and Event from a Exception
42873 *
42874 * TODO(v8): Remove getHub fallback
42875 * @hidden
42876 */
42877function eventFromUnknownInput(
42878  getHubOrClient,
42879  stackParser,
42880  exception,
42881  hint,
42882) {
42883  const client =
42884    typeof getHubOrClient === 'function'
42885      ? // eslint-disable-next-line deprecation/deprecation
42886        getHubOrClient().getClient()
42887      : getHubOrClient;
42888
42889  let ex = exception;
42890  const providedMechanism =
42891    hint && hint.data && (hint.data ).mechanism;
42892  const mechanism = providedMechanism || {
42893    handled: true,
42894    type: 'generic',
42895  };
42896
42897  let extras;
42898
42899  if (!is.isError(exception)) {
42900    if (is.isPlainObject(exception)) {
42901      const normalizeDepth = client && client.getOptions().normalizeDepth;
42902      extras = { ['__serialized__']: normalize.normalizeToSize(exception , normalizeDepth) };
42903
42904      const message = getMessageForObject(exception);
42905      ex = (hint && hint.syntheticException) || new Error(message);
42906      (ex ).message = message;
42907    } else {
42908      // This handles when someone does: `throw "something awesome";`
42909      // We use synthesized Error here so we can extract a (rough) stack trace.
42910      ex = (hint && hint.syntheticException) || new Error(exception );
42911      (ex ).message = exception ;
42912    }
42913    mechanism.synthetic = true;
42914  }
42915
42916  const event = {
42917    exception: {
42918      values: [exceptionFromError(stackParser, ex )],
42919    },
42920  };
42921
42922  if (extras) {
42923    event.extra = extras;
42924  }
42925
42926  misc.addExceptionTypeValue(event, undefined, undefined);
42927  misc.addExceptionMechanism(event, mechanism);
42928
42929  return {
42930    ...event,
42931    event_id: hint && hint.event_id,
42932  };
42933}
42934
42935/**
42936 * Builds and Event from a Message
42937 * @hidden
42938 */
42939function eventFromMessage(
42940  stackParser,
42941  message,
42942  // eslint-disable-next-line deprecation/deprecation
42943  level = 'info',
42944  hint,
42945  attachStacktrace,
42946) {
42947  const event = {
42948    event_id: hint && hint.event_id,
42949    level,
42950  };
42951
42952  if (attachStacktrace && hint && hint.syntheticException) {
42953    const frames = parseStackFrames(stackParser, hint.syntheticException);
42954    if (frames.length) {
42955      event.exception = {
42956        values: [
42957          {
42958            value: message,
42959            stacktrace: { frames },
42960          },
42961        ],
42962      };
42963    }
42964  }
42965
42966  if (is.isParameterizedString(message)) {
42967    const { __sentry_template_string__, __sentry_template_values__ } = message;
42968
42969    event.logentry = {
42970      message: __sentry_template_string__,
42971      params: __sentry_template_values__,
42972    };
42973    return event;
42974  }
42975
42976  event.message = message;
42977  return event;
42978}
42979
42980exports.eventFromMessage = eventFromMessage;
42981exports.eventFromUnknownInput = eventFromUnknownInput;
42982exports.exceptionFromError = exceptionFromError;
42983exports.parseStackFrames = parseStackFrames;
42984
42985
42986},{"./is.js":329,"./misc.js":334,"./normalize.js":337,"./object.js":338}],319:[function(require,module,exports){
42987Object.defineProperty(exports, '__esModule', { value: true });
42988
42989const aggregateErrors = require('./aggregate-errors.js');
42990const browser = require('./browser.js');
42991const dsn = require('./dsn.js');
42992const error = require('./error.js');
42993const worldwide = require('./worldwide.js');
42994const index = require('./instrument/index.js');
42995const is = require('./is.js');
42996const isBrowser = require('./isBrowser.js');
42997const logger = require('./logger.js');
42998const memo = require('./memo.js');
42999const misc = require('./misc.js');
43000const node = require('./node.js');
43001const normalize = require('./normalize.js');
43002const object = require('./object.js');
43003const path = require('./path.js');
43004const promisebuffer = require('./promisebuffer.js');
43005const requestdata = require('./requestdata.js');
43006const severity = require('./severity.js');
43007const stacktrace = require('./stacktrace.js');
43008const string = require('./string.js');
43009const supports = require('./supports.js');
43010const syncpromise = require('./syncpromise.js');
43011const time = require('./time.js');
43012const tracing = require('./tracing.js');
43013const env = require('./env.js');
43014const envelope = require('./envelope.js');
43015const clientreport = require('./clientreport.js');
43016const ratelimit = require('./ratelimit.js');
43017const baggage = require('./baggage.js');
43018const url = require('./url.js');
43019const userIntegrations = require('./userIntegrations.js');
43020const cache = require('./cache.js');
43021const eventbuilder = require('./eventbuilder.js');
43022const anr = require('./anr.js');
43023const lru = require('./lru.js');
43024const _asyncNullishCoalesce = require('./buildPolyfills/_asyncNullishCoalesce.js');
43025const _asyncOptionalChain = require('./buildPolyfills/_asyncOptionalChain.js');
43026const _asyncOptionalChainDelete = require('./buildPolyfills/_asyncOptionalChainDelete.js');
43027const _nullishCoalesce = require('./buildPolyfills/_nullishCoalesce.js');
43028const _optionalChain = require('./buildPolyfills/_optionalChain.js');
43029const _optionalChainDelete = require('./buildPolyfills/_optionalChainDelete.js');
43030const console = require('./instrument/console.js');
43031const dom = require('./instrument/dom.js');
43032const xhr = require('./instrument/xhr.js');
43033const fetch = require('./instrument/fetch.js');
43034const history = require('./instrument/history.js');
43035const globalError = require('./instrument/globalError.js');
43036const globalUnhandledRejection = require('./instrument/globalUnhandledRejection.js');
43037const _handlers = require('./instrument/_handlers.js');
43038const nodeStackTrace = require('./node-stack-trace.js');
43039const escapeStringForRegex = require('./vendor/escapeStringForRegex.js');
43040const supportsHistory = require('./vendor/supportsHistory.js');
43041
43042
43043
43044exports.applyAggregateErrorsToEvent = aggregateErrors.applyAggregateErrorsToEvent;
43045exports.getComponentName = browser.getComponentName;
43046exports.getDomElement = browser.getDomElement;
43047exports.getLocationHref = browser.getLocationHref;
43048exports.htmlTreeAsString = browser.htmlTreeAsString;
43049exports.dsnFromString = dsn.dsnFromString;
43050exports.dsnToString = dsn.dsnToString;
43051exports.makeDsn = dsn.makeDsn;
43052exports.SentryError = error.SentryError;
43053exports.GLOBAL_OBJ = worldwide.GLOBAL_OBJ;
43054exports.getGlobalObject = worldwide.getGlobalObject;
43055exports.getGlobalSingleton = worldwide.getGlobalSingleton;
43056exports.addInstrumentationHandler = index.addInstrumentationHandler;
43057exports.isDOMError = is.isDOMError;
43058exports.isDOMException = is.isDOMException;
43059exports.isElement = is.isElement;
43060exports.isError = is.isError;
43061exports.isErrorEvent = is.isErrorEvent;
43062exports.isEvent = is.isEvent;
43063exports.isInstanceOf = is.isInstanceOf;
43064exports.isNaN = is.isNaN;
43065exports.isParameterizedString = is.isParameterizedString;
43066exports.isPlainObject = is.isPlainObject;
43067exports.isPrimitive = is.isPrimitive;
43068exports.isRegExp = is.isRegExp;
43069exports.isString = is.isString;
43070exports.isSyntheticEvent = is.isSyntheticEvent;
43071exports.isThenable = is.isThenable;
43072exports.isVueViewModel = is.isVueViewModel;
43073exports.isBrowser = isBrowser.isBrowser;
43074exports.CONSOLE_LEVELS = logger.CONSOLE_LEVELS;
43075exports.consoleSandbox = logger.consoleSandbox;
43076exports.logger = logger.logger;
43077exports.originalConsoleMethods = logger.originalConsoleMethods;
43078exports.memoBuilder = memo.memoBuilder;
43079exports.addContextToFrame = misc.addContextToFrame;
43080exports.addExceptionMechanism = misc.addExceptionMechanism;
43081exports.addExceptionTypeValue = misc.addExceptionTypeValue;
43082exports.arrayify = misc.arrayify;
43083exports.checkOrSetAlreadyCaught = misc.checkOrSetAlreadyCaught;
43084exports.getEventDescription = misc.getEventDescription;
43085exports.parseSemver = misc.parseSemver;
43086exports.uuid4 = misc.uuid4;
43087exports.dynamicRequire = node.dynamicRequire;
43088exports.isNodeEnv = node.isNodeEnv;
43089exports.loadModule = node.loadModule;
43090exports.normalize = normalize.normalize;
43091exports.normalizeToSize = normalize.normalizeToSize;
43092exports.normalizeUrlToBase = normalize.normalizeUrlToBase;
43093exports.walk = normalize.walk;
43094exports.addNonEnumerableProperty = object.addNonEnumerableProperty;
43095exports.convertToPlainObject = object.convertToPlainObject;
43096exports.dropUndefinedKeys = object.dropUndefinedKeys;
43097exports.extractExceptionKeysForMessage = object.extractExceptionKeysForMessage;
43098exports.fill = object.fill;
43099exports.getOriginalFunction = object.getOriginalFunction;
43100exports.markFunctionWrapped = object.markFunctionWrapped;
43101exports.objectify = object.objectify;
43102exports.urlEncode = object.urlEncode;
43103exports.basename = path.basename;
43104exports.dirname = path.dirname;
43105exports.isAbsolute = path.isAbsolute;
43106exports.join = path.join;
43107exports.normalizePath = path.normalizePath;
43108exports.relative = path.relative;
43109exports.resolve = path.resolve;
43110exports.makePromiseBuffer = promisebuffer.makePromiseBuffer;
43111exports.DEFAULT_USER_INCLUDES = requestdata.DEFAULT_USER_INCLUDES;
43112exports.addRequestDataToEvent = requestdata.addRequestDataToEvent;
43113exports.addRequestDataToTransaction = requestdata.addRequestDataToTransaction;
43114exports.extractPathForTransaction = requestdata.extractPathForTransaction;
43115exports.extractRequestData = requestdata.extractRequestData;
43116exports.winterCGHeadersToDict = requestdata.winterCGHeadersToDict;
43117exports.winterCGRequestToRequestData = requestdata.winterCGRequestToRequestData;
43118exports.severityFromString = severity.severityFromString;
43119exports.severityLevelFromString = severity.severityLevelFromString;
43120exports.validSeverityLevels = severity.validSeverityLevels;
43121exports.createStackParser = stacktrace.createStackParser;
43122exports.getFunctionName = stacktrace.getFunctionName;
43123exports.nodeStackLineParser = stacktrace.nodeStackLineParser;
43124exports.stackParserFromStackParserOptions = stacktrace.stackParserFromStackParserOptions;
43125exports.stripSentryFramesAndReverse = stacktrace.stripSentryFramesAndReverse;
43126exports.isMatchingPattern = string.isMatchingPattern;
43127exports.safeJoin = string.safeJoin;
43128exports.snipLine = string.snipLine;
43129exports.stringMatchesSomePattern = string.stringMatchesSomePattern;
43130exports.truncate = string.truncate;
43131exports.isNativeFetch = supports.isNativeFetch;
43132exports.supportsDOMError = supports.supportsDOMError;
43133exports.supportsDOMException = supports.supportsDOMException;
43134exports.supportsErrorEvent = supports.supportsErrorEvent;
43135exports.supportsFetch = supports.supportsFetch;
43136exports.supportsNativeFetch = supports.supportsNativeFetch;
43137exports.supportsReferrerPolicy = supports.supportsReferrerPolicy;
43138exports.supportsReportingObserver = supports.supportsReportingObserver;
43139exports.SyncPromise = syncpromise.SyncPromise;
43140exports.rejectedSyncPromise = syncpromise.rejectedSyncPromise;
43141exports.resolvedSyncPromise = syncpromise.resolvedSyncPromise;
43142Object.defineProperty(exports, '_browserPerformanceTimeOriginMode', {
43143	enumerable: true,
43144	get: () => time._browserPerformanceTimeOriginMode
43145});
43146exports.browserPerformanceTimeOrigin = time.browserPerformanceTimeOrigin;
43147exports.dateTimestampInSeconds = time.dateTimestampInSeconds;
43148exports.timestampInSeconds = time.timestampInSeconds;
43149exports.timestampWithMs = time.timestampWithMs;
43150exports.TRACEPARENT_REGEXP = tracing.TRACEPARENT_REGEXP;
43151exports.extractTraceparentData = tracing.extractTraceparentData;
43152exports.generateSentryTraceHeader = tracing.generateSentryTraceHeader;
43153exports.propagationContextFromHeaders = tracing.propagationContextFromHeaders;
43154exports.tracingContextFromHeaders = tracing.tracingContextFromHeaders;
43155exports.getSDKSource = env.getSDKSource;
43156exports.isBrowserBundle = env.isBrowserBundle;
43157exports.addItemToEnvelope = envelope.addItemToEnvelope;
43158exports.createAttachmentEnvelopeItem = envelope.createAttachmentEnvelopeItem;
43159exports.createEnvelope = envelope.createEnvelope;
43160exports.createEventEnvelopeHeaders = envelope.createEventEnvelopeHeaders;
43161exports.envelopeContainsItemType = envelope.envelopeContainsItemType;
43162exports.envelopeItemTypeToDataCategory = envelope.envelopeItemTypeToDataCategory;
43163exports.forEachEnvelopeItem = envelope.forEachEnvelopeItem;
43164exports.getSdkMetadataForEnvelopeHeader = envelope.getSdkMetadataForEnvelopeHeader;
43165exports.parseEnvelope = envelope.parseEnvelope;
43166exports.serializeEnvelope = envelope.serializeEnvelope;
43167exports.createClientReportEnvelope = clientreport.createClientReportEnvelope;
43168exports.DEFAULT_RETRY_AFTER = ratelimit.DEFAULT_RETRY_AFTER;
43169exports.disabledUntil = ratelimit.disabledUntil;
43170exports.isRateLimited = ratelimit.isRateLimited;
43171exports.parseRetryAfterHeader = ratelimit.parseRetryAfterHeader;
43172exports.updateRateLimits = ratelimit.updateRateLimits;
43173exports.BAGGAGE_HEADER_NAME = baggage.BAGGAGE_HEADER_NAME;
43174exports.MAX_BAGGAGE_STRING_LENGTH = baggage.MAX_BAGGAGE_STRING_LENGTH;
43175exports.SENTRY_BAGGAGE_KEY_PREFIX = baggage.SENTRY_BAGGAGE_KEY_PREFIX;
43176exports.SENTRY_BAGGAGE_KEY_PREFIX_REGEX = baggage.SENTRY_BAGGAGE_KEY_PREFIX_REGEX;
43177exports.baggageHeaderToDynamicSamplingContext = baggage.baggageHeaderToDynamicSamplingContext;
43178exports.dynamicSamplingContextToSentryBaggageHeader = baggage.dynamicSamplingContextToSentryBaggageHeader;
43179exports.getNumberOfUrlSegments = url.getNumberOfUrlSegments;
43180exports.getSanitizedUrlString = url.getSanitizedUrlString;
43181exports.parseUrl = url.parseUrl;
43182exports.stripUrlQueryAndFragment = url.stripUrlQueryAndFragment;
43183exports.addOrUpdateIntegration = userIntegrations.addOrUpdateIntegration;
43184exports.makeFifoCache = cache.makeFifoCache;
43185exports.eventFromMessage = eventbuilder.eventFromMessage;
43186exports.eventFromUnknownInput = eventbuilder.eventFromUnknownInput;
43187exports.exceptionFromError = eventbuilder.exceptionFromError;
43188exports.parseStackFrames = eventbuilder.parseStackFrames;
43189exports.callFrameToStackFrame = anr.callFrameToStackFrame;
43190exports.watchdogTimer = anr.watchdogTimer;
43191exports.LRUMap = lru.LRUMap;
43192exports._asyncNullishCoalesce = _asyncNullishCoalesce._asyncNullishCoalesce;
43193exports._asyncOptionalChain = _asyncOptionalChain._asyncOptionalChain;
43194exports._asyncOptionalChainDelete = _asyncOptionalChainDelete._asyncOptionalChainDelete;
43195exports._nullishCoalesce = _nullishCoalesce._nullishCoalesce;
43196exports._optionalChain = _optionalChain._optionalChain;
43197exports._optionalChainDelete = _optionalChainDelete._optionalChainDelete;
43198exports.addConsoleInstrumentationHandler = console.addConsoleInstrumentationHandler;
43199exports.addClickKeypressInstrumentationHandler = dom.addClickKeypressInstrumentationHandler;
43200exports.SENTRY_XHR_DATA_KEY = xhr.SENTRY_XHR_DATA_KEY;
43201exports.addXhrInstrumentationHandler = xhr.addXhrInstrumentationHandler;
43202exports.addFetchInstrumentationHandler = fetch.addFetchInstrumentationHandler;
43203exports.addHistoryInstrumentationHandler = history.addHistoryInstrumentationHandler;
43204exports.addGlobalErrorInstrumentationHandler = globalError.addGlobalErrorInstrumentationHandler;
43205exports.addGlobalUnhandledRejectionInstrumentationHandler = globalUnhandledRejection.addGlobalUnhandledRejectionInstrumentationHandler;
43206exports.resetInstrumentationHandlers = _handlers.resetInstrumentationHandlers;
43207exports.filenameIsInApp = nodeStackTrace.filenameIsInApp;
43208exports.escapeStringForRegex = escapeStringForRegex.escapeStringForRegex;
43209exports.supportsHistory = supportsHistory.supportsHistory;
43210
43211
43212},{"./aggregate-errors.js":300,"./anr.js":301,"./baggage.js":302,"./browser.js":303,"./buildPolyfills/_asyncNullishCoalesce.js":304,"./buildPolyfills/_asyncOptionalChain.js":305,"./buildPolyfills/_asyncOptionalChainDelete.js":306,"./buildPolyfills/_nullishCoalesce.js":307,"./buildPolyfills/_optionalChain.js":308,"./buildPolyfills/_optionalChainDelete.js":309,"./cache.js":310,"./clientreport.js":311,"./dsn.js":314,"./env.js":315,"./envelope.js":316,"./error.js":317,"./eventbuilder.js":318,"./instrument/_handlers.js":320,"./instrument/console.js":321,"./instrument/dom.js":322,"./instrument/fetch.js":323,"./instrument/globalError.js":324,"./instrument/globalUnhandledRejection.js":325,"./instrument/history.js":326,"./instrument/index.js":327,"./instrument/xhr.js":328,"./is.js":329,"./isBrowser.js":330,"./logger.js":331,"./lru.js":332,"./memo.js":333,"./misc.js":334,"./node-stack-trace.js":335,"./node.js":336,"./normalize.js":337,"./object.js":338,"./path.js":339,"./promisebuffer.js":340,"./ratelimit.js":341,"./requestdata.js":342,"./severity.js":343,"./stacktrace.js":344,"./string.js":345,"./supports.js":346,"./syncpromise.js":347,"./time.js":348,"./tracing.js":349,"./url.js":350,"./userIntegrations.js":351,"./vendor/escapeStringForRegex.js":352,"./vendor/supportsHistory.js":353,"./worldwide.js":354}],320:[function(require,module,exports){
43213Object.defineProperty(exports, '__esModule', { value: true });
43214
43215const debugBuild = require('../debug-build.js');
43216const logger = require('../logger.js');
43217const stacktrace = require('../stacktrace.js');
43218
43219// We keep the handlers globally
43220const handlers = {};
43221const instrumented = {};
43222
43223/** Add a handler function. */
43224function addHandler(type, handler) {
43225  handlers[type] = handlers[type] || [];
43226  (handlers[type] ).push(handler);
43227}
43228
43229/**
43230 * Reset all instrumentation handlers.
43231 * This can be used by tests to ensure we have a clean slate of instrumentation handlers.
43232 */
43233function resetInstrumentationHandlers() {
43234  Object.keys(handlers).forEach(key => {
43235    handlers[key ] = undefined;
43236  });
43237}
43238
43239/** Maybe run an instrumentation function, unless it was already called. */
43240function maybeInstrument(type, instrumentFn) {
43241  if (!instrumented[type]) {
43242    instrumentFn();
43243    instrumented[type] = true;
43244  }
43245}
43246
43247/** Trigger handlers for a given instrumentation type. */
43248function triggerHandlers(type, data) {
43249  const typeHandlers = type && handlers[type];
43250  if (!typeHandlers) {
43251    return;
43252  }
43253
43254  for (const handler of typeHandlers) {
43255    try {
43256      handler(data);
43257    } catch (e) {
43258      debugBuild.DEBUG_BUILD &&
43259        logger.logger.error(
43260          `Error while triggering instrumentation handler.\nType: ${type}\nName: ${stacktrace.getFunctionName(handler)}\nError:`,
43261          e,
43262        );
43263    }
43264  }
43265}
43266
43267exports.addHandler = addHandler;
43268exports.maybeInstrument = maybeInstrument;
43269exports.resetInstrumentationHandlers = resetInstrumentationHandlers;
43270exports.triggerHandlers = triggerHandlers;
43271
43272
43273},{"../debug-build.js":313,"../logger.js":331,"../stacktrace.js":344}],321:[function(require,module,exports){
43274Object.defineProperty(exports, '__esModule', { value: true });
43275
43276const logger = require('../logger.js');
43277const object = require('../object.js');
43278const worldwide = require('../worldwide.js');
43279const _handlers = require('./_handlers.js');
43280
43281/**
43282 * Add an instrumentation handler for when a console.xxx method is called.
43283 *
43284 * Use at your own risk, this might break without changelog notice, only used internally.
43285 * @hidden
43286 */
43287function addConsoleInstrumentationHandler(handler) {
43288  const type = 'console';
43289  _handlers.addHandler(type, handler);
43290  _handlers.maybeInstrument(type, instrumentConsole);
43291}
43292
43293function instrumentConsole() {
43294  if (!('console' in worldwide.GLOBAL_OBJ)) {
43295    return;
43296  }
43297
43298  logger.CONSOLE_LEVELS.forEach(function (level) {
43299    if (!(level in worldwide.GLOBAL_OBJ.console)) {
43300      return;
43301    }
43302
43303    object.fill(worldwide.GLOBAL_OBJ.console, level, function (originalConsoleMethod) {
43304      logger.originalConsoleMethods[level] = originalConsoleMethod;
43305
43306      return function (...args) {
43307        const handlerData = { args, level };
43308        _handlers.triggerHandlers('console', handlerData);
43309
43310        const log = logger.originalConsoleMethods[level];
43311        log && log.apply(worldwide.GLOBAL_OBJ.console, args);
43312      };
43313    });
43314  });
43315}
43316
43317exports.addConsoleInstrumentationHandler = addConsoleInstrumentationHandler;
43318
43319
43320},{"../logger.js":331,"../object.js":338,"../worldwide.js":354,"./_handlers.js":320}],322:[function(require,module,exports){
43321Object.defineProperty(exports, '__esModule', { value: true });
43322
43323const misc = require('../misc.js');
43324const object = require('../object.js');
43325const worldwide = require('../worldwide.js');
43326const _handlers = require('./_handlers.js');
43327
43328const WINDOW = worldwide.GLOBAL_OBJ ;
43329const DEBOUNCE_DURATION = 1000;
43330
43331let debounceTimerID;
43332let lastCapturedEventType;
43333let lastCapturedEventTargetId;
43334
43335/**
43336 * Add an instrumentation handler for when a click or a keypress happens.
43337 *
43338 * Use at your own risk, this might break without changelog notice, only used internally.
43339 * @hidden
43340 */
43341function addClickKeypressInstrumentationHandler(handler) {
43342  const type = 'dom';
43343  _handlers.addHandler(type, handler);
43344  _handlers.maybeInstrument(type, instrumentDOM);
43345}
43346
43347/** Exported for tests only. */
43348function instrumentDOM() {
43349  if (!WINDOW.document) {
43350    return;
43351  }
43352
43353  // Make it so that any click or keypress that is unhandled / bubbled up all the way to the document triggers our dom
43354  // handlers. (Normally we have only one, which captures a breadcrumb for each click or keypress.) Do this before
43355  // we instrument `addEventListener` so that we don't end up attaching this handler twice.
43356  const triggerDOMHandler = _handlers.triggerHandlers.bind(null, 'dom');
43357  const globalDOMEventHandler = makeDOMEventHandler(triggerDOMHandler, true);
43358  WINDOW.document.addEventListener('click', globalDOMEventHandler, false);
43359  WINDOW.document.addEventListener('keypress', globalDOMEventHandler, false);
43360
43361  // After hooking into click and keypress events bubbled up to `document`, we also hook into user-handled
43362  // clicks & keypresses, by adding an event listener of our own to any element to which they add a listener. That
43363  // way, whenever one of their handlers is triggered, ours will be, too. (This is needed because their handler
43364  // could potentially prevent the event from bubbling up to our global listeners. This way, our handler are still
43365  // guaranteed to fire at least once.)
43366  ['EventTarget', 'Node'].forEach((target) => {
43367    // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
43368    const proto = (WINDOW )[target] && (WINDOW )[target].prototype;
43369    // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
43370    if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
43371      return;
43372    }
43373
43374    object.fill(proto, 'addEventListener', function (originalAddEventListener) {
43375      return function (
43376
43377        type,
43378        listener,
43379        options,
43380      ) {
43381        if (type === 'click' || type == 'keypress') {
43382          try {
43383            const el = this ;
43384            const handlers = (el.__sentry_instrumentation_handlers__ = el.__sentry_instrumentation_handlers__ || {});
43385            const handlerForType = (handlers[type] = handlers[type] || { refCount: 0 });
43386
43387            if (!handlerForType.handler) {
43388              const handler = makeDOMEventHandler(triggerDOMHandler);
43389              handlerForType.handler = handler;
43390              originalAddEventListener.call(this, type, handler, options);
43391            }
43392
43393            handlerForType.refCount++;
43394          } catch (e) {
43395            // Accessing dom properties is always fragile.
43396            // Also allows us to skip `addEventListenrs` calls with no proper `this` context.
43397          }
43398        }
43399
43400        return originalAddEventListener.call(this, type, listener, options);
43401      };
43402    });
43403
43404    object.fill(
43405      proto,
43406      'removeEventListener',
43407      function (originalRemoveEventListener) {
43408        return function (
43409
43410          type,
43411          listener,
43412          options,
43413        ) {
43414          if (type === 'click' || type == 'keypress') {
43415            try {
43416              const el = this ;
43417              const handlers = el.__sentry_instrumentation_handlers__ || {};
43418              const handlerForType = handlers[type];
43419
43420              if (handlerForType) {
43421                handlerForType.refCount--;
43422                // If there are no longer any custom handlers of the current type on this element, we can remove ours, too.
43423                if (handlerForType.refCount <= 0) {
43424                  originalRemoveEventListener.call(this, type, handlerForType.handler, options);
43425                  handlerForType.handler = undefined;
43426                  delete handlers[type]; // eslint-disable-line @typescript-eslint/no-dynamic-delete
43427                }
43428
43429                // If there are no longer any custom handlers of any type on this element, cleanup everything.
43430                if (Object.keys(handlers).length === 0) {
43431                  delete el.__sentry_instrumentation_handlers__;
43432                }
43433              }
43434            } catch (e) {
43435              // Accessing dom properties is always fragile.
43436              // Also allows us to skip `addEventListenrs` calls with no proper `this` context.
43437            }
43438          }
43439
43440          return originalRemoveEventListener.call(this, type, listener, options);
43441        };
43442      },
43443    );
43444  });
43445}
43446
43447/**
43448 * Check whether the event is similar to the last captured one. For example, two click events on the same button.
43449 */
43450function isSimilarToLastCapturedEvent(event) {
43451  // If both events have different type, then user definitely performed two separate actions. e.g. click + keypress.
43452  if (event.type !== lastCapturedEventType) {
43453    return false;
43454  }
43455
43456  try {
43457    // If both events have the same type, it's still possible that actions were performed on different targets.
43458    // e.g. 2 clicks on different buttons.
43459    if (!event.target || (event.target )._sentryId !== lastCapturedEventTargetId) {
43460      return false;
43461    }
43462  } catch (e) {
43463    // just accessing `target` property can throw an exception in some rare circumstances
43464    // see: https://github.com/getsentry/sentry-javascript/issues/838
43465  }
43466
43467  // If both events have the same type _and_ same `target` (an element which triggered an event, _not necessarily_
43468  // to which an event listener was attached), we treat them as the same action, as we want to capture
43469  // only one breadcrumb. e.g. multiple clicks on the same button, or typing inside a user input box.
43470  return true;
43471}
43472
43473/**
43474 * Decide whether an event should be captured.
43475 * @param event event to be captured
43476 */
43477function shouldSkipDOMEvent(eventType, target) {
43478  // We are only interested in filtering `keypress` events for now.
43479  if (eventType !== 'keypress') {
43480    return false;
43481  }
43482
43483  if (!target || !target.tagName) {
43484    return true;
43485  }
43486
43487  // Only consider keypress events on actual input elements. This will disregard keypresses targeting body
43488  // e.g.tabbing through elements, hotkeys, etc.
43489  if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
43490    return false;
43491  }
43492
43493  return true;
43494}
43495
43496/**
43497 * Wraps addEventListener to capture UI breadcrumbs
43498 */
43499function makeDOMEventHandler(
43500  handler,
43501  globalListener = false,
43502) {
43503  return (event) => {
43504    // It's possible this handler might trigger multiple times for the same
43505    // event (e.g. event propagation through node ancestors).
43506    // Ignore if we've already captured that event.
43507    if (!event || event['_sentryCaptured']) {
43508      return;
43509    }
43510
43511    const target = getEventTarget(event);
43512
43513    // We always want to skip _some_ events.
43514    if (shouldSkipDOMEvent(event.type, target)) {
43515      return;
43516    }
43517
43518    // Mark event as "seen"
43519    object.addNonEnumerableProperty(event, '_sentryCaptured', true);
43520
43521    if (target && !target._sentryId) {
43522      // Add UUID to event target so we can identify if
43523      object.addNonEnumerableProperty(target, '_sentryId', misc.uuid4());
43524    }
43525
43526    const name = event.type === 'keypress' ? 'input' : event.type;
43527
43528    // If there is no last captured event, it means that we can safely capture the new event and store it for future comparisons.
43529    // If there is a last captured event, see if the new event is different enough to treat it as a unique one.
43530    // If that's the case, emit the previous event and store locally the newly-captured DOM event.
43531    if (!isSimilarToLastCapturedEvent(event)) {
43532      const handlerData = { event, name, global: globalListener };
43533      handler(handlerData);
43534      lastCapturedEventType = event.type;
43535      lastCapturedEventTargetId = target ? target._sentryId : undefined;
43536    }
43537
43538    // Start a new debounce timer that will prevent us from capturing multiple events that should be grouped together.
43539    clearTimeout(debounceTimerID);
43540    debounceTimerID = WINDOW.setTimeout(() => {
43541      lastCapturedEventTargetId = undefined;
43542      lastCapturedEventType = undefined;
43543    }, DEBOUNCE_DURATION);
43544  };
43545}
43546
43547function getEventTarget(event) {
43548  try {
43549    return event.target ;
43550  } catch (e) {
43551    // just accessing `target` property can throw an exception in some rare circumstances
43552    // see: https://github.com/getsentry/sentry-javascript/issues/838
43553    return null;
43554  }
43555}
43556
43557exports.addClickKeypressInstrumentationHandler = addClickKeypressInstrumentationHandler;
43558exports.instrumentDOM = instrumentDOM;
43559
43560
43561},{"../misc.js":334,"../object.js":338,"../worldwide.js":354,"./_handlers.js":320}],323:[function(require,module,exports){
43562Object.defineProperty(exports, '__esModule', { value: true });
43563
43564const object = require('../object.js');
43565const supports = require('../supports.js');
43566const worldwide = require('../worldwide.js');
43567const _handlers = require('./_handlers.js');
43568
43569/**
43570 * Add an instrumentation handler for when a fetch request happens.
43571 * The handler function is called once when the request starts and once when it ends,
43572 * which can be identified by checking if it has an `endTimestamp`.
43573 *
43574 * Use at your own risk, this might break without changelog notice, only used internally.
43575 * @hidden
43576 */
43577function addFetchInstrumentationHandler(handler) {
43578  const type = 'fetch';
43579  _handlers.addHandler(type, handler);
43580  _handlers.maybeInstrument(type, instrumentFetch);
43581}
43582
43583function instrumentFetch() {
43584  if (!supports.supportsNativeFetch()) {
43585    return;
43586  }
43587
43588  object.fill(worldwide.GLOBAL_OBJ, 'fetch', function (originalFetch) {
43589    return function (...args) {
43590      const { method, url } = parseFetchArgs(args);
43591
43592      const handlerData = {
43593        args,
43594        fetchData: {
43595          method,
43596          url,
43597        },
43598        startTimestamp: Date.now(),
43599      };
43600
43601      _handlers.triggerHandlers('fetch', {
43602        ...handlerData,
43603      });
43604
43605      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
43606      return originalFetch.apply(worldwide.GLOBAL_OBJ, args).then(
43607        (response) => {
43608          const finishedHandlerData = {
43609            ...handlerData,
43610            endTimestamp: Date.now(),
43611            response,
43612          };
43613
43614          _handlers.triggerHandlers('fetch', finishedHandlerData);
43615          return response;
43616        },
43617        (error) => {
43618          const erroredHandlerData = {
43619            ...handlerData,
43620            endTimestamp: Date.now(),
43621            error,
43622          };
43623
43624          _handlers.triggerHandlers('fetch', erroredHandlerData);
43625          // NOTE: If you are a Sentry user, and you are seeing this stack frame,
43626          //       it means the sentry.javascript SDK caught an error invoking your application code.
43627          //       This is expected behavior and NOT indicative of a bug with sentry.javascript.
43628          throw error;
43629        },
43630      );
43631    };
43632  });
43633}
43634
43635function hasProp(obj, prop) {
43636  return !!obj && typeof obj === 'object' && !!(obj )[prop];
43637}
43638
43639function getUrlFromResource(resource) {
43640  if (typeof resource === 'string') {
43641    return resource;
43642  }
43643
43644  if (!resource) {
43645    return '';
43646  }
43647
43648  if (hasProp(resource, 'url')) {
43649    return resource.url;
43650  }
43651
43652  if (resource.toString) {
43653    return resource.toString();
43654  }
43655
43656  return '';
43657}
43658
43659/**
43660 * Parses the fetch arguments to find the used Http method and the url of the request.
43661 * Exported for tests only.
43662 */
43663function parseFetchArgs(fetchArgs) {
43664  if (fetchArgs.length === 0) {
43665    return { method: 'GET', url: '' };
43666  }
43667
43668  if (fetchArgs.length === 2) {
43669    const [url, options] = fetchArgs ;
43670
43671    return {
43672      url: getUrlFromResource(url),
43673      method: hasProp(options, 'method') ? String(options.method).toUpperCase() : 'GET',
43674    };
43675  }
43676
43677  const arg = fetchArgs[0];
43678  return {
43679    url: getUrlFromResource(arg ),
43680    method: hasProp(arg, 'method') ? String(arg.method).toUpperCase() : 'GET',
43681  };
43682}
43683
43684exports.addFetchInstrumentationHandler = addFetchInstrumentationHandler;
43685exports.parseFetchArgs = parseFetchArgs;
43686
43687
43688},{"../object.js":338,"../supports.js":346,"../worldwide.js":354,"./_handlers.js":320}],324:[function(require,module,exports){
43689Object.defineProperty(exports, '__esModule', { value: true });
43690
43691const worldwide = require('../worldwide.js');
43692const _handlers = require('./_handlers.js');
43693
43694let _oldOnErrorHandler = null;
43695
43696/**
43697 * Add an instrumentation handler for when an error is captured by the global error handler.
43698 *
43699 * Use at your own risk, this might break without changelog notice, only used internally.
43700 * @hidden
43701 */
43702function addGlobalErrorInstrumentationHandler(handler) {
43703  const type = 'error';
43704  _handlers.addHandler(type, handler);
43705  _handlers.maybeInstrument(type, instrumentError);
43706}
43707
43708function instrumentError() {
43709  _oldOnErrorHandler = worldwide.GLOBAL_OBJ.onerror;
43710
43711  worldwide.GLOBAL_OBJ.onerror = function (
43712    msg,
43713    url,
43714    line,
43715    column,
43716    error,
43717  ) {
43718    const handlerData = {
43719      column,
43720      error,
43721      line,
43722      msg,
43723      url,
43724    };
43725    _handlers.triggerHandlers('error', handlerData);
43726
43727    if (_oldOnErrorHandler && !_oldOnErrorHandler.__SENTRY_LOADER__) {
43728      // eslint-disable-next-line prefer-rest-params
43729      return _oldOnErrorHandler.apply(this, arguments);
43730    }
43731
43732    return false;
43733  };
43734
43735  worldwide.GLOBAL_OBJ.onerror.__SENTRY_INSTRUMENTED__ = true;
43736}
43737
43738exports.addGlobalErrorInstrumentationHandler = addGlobalErrorInstrumentationHandler;
43739
43740
43741},{"../worldwide.js":354,"./_handlers.js":320}],325:[function(require,module,exports){
43742Object.defineProperty(exports, '__esModule', { value: true });
43743
43744const worldwide = require('../worldwide.js');
43745const _handlers = require('./_handlers.js');
43746
43747let _oldOnUnhandledRejectionHandler = null;
43748
43749/**
43750 * Add an instrumentation handler for when an unhandled promise rejection is captured.
43751 *
43752 * Use at your own risk, this might break without changelog notice, only used internally.
43753 * @hidden
43754 */
43755function addGlobalUnhandledRejectionInstrumentationHandler(
43756  handler,
43757) {
43758  const type = 'unhandledrejection';
43759  _handlers.addHandler(type, handler);
43760  _handlers.maybeInstrument(type, instrumentUnhandledRejection);
43761}
43762
43763function instrumentUnhandledRejection() {
43764  _oldOnUnhandledRejectionHandler = worldwide.GLOBAL_OBJ.onunhandledrejection;
43765
43766  worldwide.GLOBAL_OBJ.onunhandledrejection = function (e) {
43767    const handlerData = e;
43768    _handlers.triggerHandlers('unhandledrejection', handlerData);
43769
43770    if (_oldOnUnhandledRejectionHandler && !_oldOnUnhandledRejectionHandler.__SENTRY_LOADER__) {
43771      // eslint-disable-next-line prefer-rest-params
43772      return _oldOnUnhandledRejectionHandler.apply(this, arguments);
43773    }
43774
43775    return true;
43776  };
43777
43778  worldwide.GLOBAL_OBJ.onunhandledrejection.__SENTRY_INSTRUMENTED__ = true;
43779}
43780
43781exports.addGlobalUnhandledRejectionInstrumentationHandler = addGlobalUnhandledRejectionInstrumentationHandler;
43782
43783
43784},{"../worldwide.js":354,"./_handlers.js":320}],326:[function(require,module,exports){
43785Object.defineProperty(exports, '__esModule', { value: true });
43786
43787const object = require('../object.js');
43788require('../debug-build.js');
43789require('../logger.js');
43790const worldwide = require('../worldwide.js');
43791const supportsHistory = require('../vendor/supportsHistory.js');
43792const _handlers = require('./_handlers.js');
43793
43794const WINDOW = worldwide.GLOBAL_OBJ ;
43795
43796let lastHref;
43797
43798/**
43799 * Add an instrumentation handler for when a fetch request happens.
43800 * The handler function is called once when the request starts and once when it ends,
43801 * which can be identified by checking if it has an `endTimestamp`.
43802 *
43803 * Use at your own risk, this might break without changelog notice, only used internally.
43804 * @hidden
43805 */
43806function addHistoryInstrumentationHandler(handler) {
43807  const type = 'history';
43808  _handlers.addHandler(type, handler);
43809  _handlers.maybeInstrument(type, instrumentHistory);
43810}
43811
43812function instrumentHistory() {
43813  if (!supportsHistory.supportsHistory()) {
43814    return;
43815  }
43816
43817  const oldOnPopState = WINDOW.onpopstate;
43818  WINDOW.onpopstate = function ( ...args) {
43819    const to = WINDOW.location.href;
43820    // keep track of the current URL state, as we always receive only the updated state
43821    const from = lastHref;
43822    lastHref = to;
43823    const handlerData = { from, to };
43824    _handlers.triggerHandlers('history', handlerData);
43825    if (oldOnPopState) {
43826      // Apparently this can throw in Firefox when incorrectly implemented plugin is installed.
43827      // https://github.com/getsentry/sentry-javascript/issues/3344
43828      // https://github.com/bugsnag/bugsnag-js/issues/469
43829      try {
43830        return oldOnPopState.apply(this, args);
43831      } catch (_oO) {
43832        // no-empty
43833      }
43834    }
43835  };
43836
43837  function historyReplacementFunction(originalHistoryFunction) {
43838    return function ( ...args) {
43839      const url = args.length > 2 ? args[2] : undefined;
43840      if (url) {
43841        // coerce to string (this is what pushState does)
43842        const from = lastHref;
43843        const to = String(url);
43844        // keep track of the current URL state, as we always receive only the updated state
43845        lastHref = to;
43846        const handlerData = { from, to };
43847        _handlers.triggerHandlers('history', handlerData);
43848      }
43849      return originalHistoryFunction.apply(this, args);
43850    };
43851  }
43852
43853  object.fill(WINDOW.history, 'pushState', historyReplacementFunction);
43854  object.fill(WINDOW.history, 'replaceState', historyReplacementFunction);
43855}
43856
43857exports.addHistoryInstrumentationHandler = addHistoryInstrumentationHandler;
43858
43859
43860},{"../debug-build.js":313,"../logger.js":331,"../object.js":338,"../vendor/supportsHistory.js":353,"../worldwide.js":354,"./_handlers.js":320}],327:[function(require,module,exports){
43861Object.defineProperty(exports, '__esModule', { value: true });
43862
43863const debugBuild = require('../debug-build.js');
43864const logger = require('../logger.js');
43865const console = require('./console.js');
43866const dom = require('./dom.js');
43867const fetch = require('./fetch.js');
43868const globalError = require('./globalError.js');
43869const globalUnhandledRejection = require('./globalUnhandledRejection.js');
43870const history = require('./history.js');
43871const xhr = require('./xhr.js');
43872
43873// TODO(v8): Consider moving this file (or at least parts of it) into the browser package. The registered handlers are mostly non-generic and we risk leaking runtime specific code into generic packages.
43874
43875/**
43876 * Add handler that will be called when given type of instrumentation triggers.
43877 * Use at your own risk, this might break without changelog notice, only used internally.
43878 * @hidden
43879 * @deprecated Use the proper function per instrumentation type instead!
43880 */
43881function addInstrumentationHandler(type, callback) {
43882  switch (type) {
43883    case 'console':
43884      return console.addConsoleInstrumentationHandler(callback);
43885    case 'dom':
43886      return dom.addClickKeypressInstrumentationHandler(callback);
43887    case 'xhr':
43888      return xhr.addXhrInstrumentationHandler(callback);
43889    case 'fetch':
43890      return fetch.addFetchInstrumentationHandler(callback);
43891    case 'history':
43892      return history.addHistoryInstrumentationHandler(callback);
43893    case 'error':
43894      return globalError.addGlobalErrorInstrumentationHandler(callback);
43895    case 'unhandledrejection':
43896      return globalUnhandledRejection.addGlobalUnhandledRejectionInstrumentationHandler(callback);
43897    default:
43898      debugBuild.DEBUG_BUILD && logger.logger.warn('unknown instrumentation type:', type);
43899  }
43900}
43901
43902exports.addConsoleInstrumentationHandler = console.addConsoleInstrumentationHandler;
43903exports.addClickKeypressInstrumentationHandler = dom.addClickKeypressInstrumentationHandler;
43904exports.addFetchInstrumentationHandler = fetch.addFetchInstrumentationHandler;
43905exports.addGlobalErrorInstrumentationHandler = globalError.addGlobalErrorInstrumentationHandler;
43906exports.addGlobalUnhandledRejectionInstrumentationHandler = globalUnhandledRejection.addGlobalUnhandledRejectionInstrumentationHandler;
43907exports.addHistoryInstrumentationHandler = history.addHistoryInstrumentationHandler;
43908exports.SENTRY_XHR_DATA_KEY = xhr.SENTRY_XHR_DATA_KEY;
43909exports.addXhrInstrumentationHandler = xhr.addXhrInstrumentationHandler;
43910exports.addInstrumentationHandler = addInstrumentationHandler;
43911
43912
43913},{"../debug-build.js":313,"../logger.js":331,"./console.js":321,"./dom.js":322,"./fetch.js":323,"./globalError.js":324,"./globalUnhandledRejection.js":325,"./history.js":326,"./xhr.js":328}],328:[function(require,module,exports){
43914Object.defineProperty(exports, '__esModule', { value: true });
43915
43916const is = require('../is.js');
43917const object = require('../object.js');
43918const worldwide = require('../worldwide.js');
43919const _handlers = require('./_handlers.js');
43920
43921const WINDOW = worldwide.GLOBAL_OBJ ;
43922
43923const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__';
43924
43925/**
43926 * Add an instrumentation handler for when an XHR request happens.
43927 * The handler function is called once when the request starts and once when it ends,
43928 * which can be identified by checking if it has an `endTimestamp`.
43929 *
43930 * Use at your own risk, this might break without changelog notice, only used internally.
43931 * @hidden
43932 */
43933function addXhrInstrumentationHandler(handler) {
43934  const type = 'xhr';
43935  _handlers.addHandler(type, handler);
43936  _handlers.maybeInstrument(type, instrumentXHR);
43937}
43938
43939/** Exported only for tests. */
43940function instrumentXHR() {
43941  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
43942  if (!(WINDOW ).XMLHttpRequest) {
43943    return;
43944  }
43945
43946  const xhrproto = XMLHttpRequest.prototype;
43947
43948  object.fill(xhrproto, 'open', function (originalOpen) {
43949    return function ( ...args) {
43950      const startTimestamp = Date.now();
43951
43952      // open() should always be called with two or more arguments
43953      // But to be on the safe side, we actually validate this and bail out if we don't have a method & url
43954      const method = is.isString(args[0]) ? args[0].toUpperCase() : undefined;
43955      const url = parseUrl(args[1]);
43956
43957      if (!method || !url) {
43958        return originalOpen.apply(this, args);
43959      }
43960
43961      this[SENTRY_XHR_DATA_KEY] = {
43962        method,
43963        url,
43964        request_headers: {},
43965      };
43966
43967      // if Sentry key appears in URL, don't capture it as a request
43968      if (method === 'POST' && url.match(/sentry_key/)) {
43969        this.__sentry_own_request__ = true;
43970      }
43971
43972      const onreadystatechangeHandler = () => {
43973        // For whatever reason, this is not the same instance here as from the outer method
43974        const xhrInfo = this[SENTRY_XHR_DATA_KEY];
43975
43976        if (!xhrInfo) {
43977          return;
43978        }
43979
43980        if (this.readyState === 4) {
43981          try {
43982            // touching statusCode in some platforms throws
43983            // an exception
43984            xhrInfo.status_code = this.status;
43985          } catch (e) {
43986            /* do nothing */
43987          }
43988
43989          const handlerData = {
43990            args: [method, url],
43991            endTimestamp: Date.now(),
43992            startTimestamp,
43993            xhr: this,
43994          };
43995          _handlers.triggerHandlers('xhr', handlerData);
43996        }
43997      };
43998
43999      if ('onreadystatechange' in this && typeof this.onreadystatechange === 'function') {
44000        object.fill(this, 'onreadystatechange', function (original) {
44001          return function ( ...readyStateArgs) {
44002            onreadystatechangeHandler();
44003            return original.apply(this, readyStateArgs);
44004          };
44005        });
44006      } else {
44007        this.addEventListener('readystatechange', onreadystatechangeHandler);
44008      }
44009
44010      // Intercepting `setRequestHeader` to access the request headers of XHR instance.
44011      // This will only work for user/library defined headers, not for the default/browser-assigned headers.
44012      // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.
44013      object.fill(this, 'setRequestHeader', function (original) {
44014        return function ( ...setRequestHeaderArgs) {
44015          const [header, value] = setRequestHeaderArgs;
44016
44017          const xhrInfo = this[SENTRY_XHR_DATA_KEY];
44018
44019          if (xhrInfo && is.isString(header) && is.isString(value)) {
44020            xhrInfo.request_headers[header.toLowerCase()] = value;
44021          }
44022
44023          return original.apply(this, setRequestHeaderArgs);
44024        };
44025      });
44026
44027      return originalOpen.apply(this, args);
44028    };
44029  });
44030
44031  object.fill(xhrproto, 'send', function (originalSend) {
44032    return function ( ...args) {
44033      const sentryXhrData = this[SENTRY_XHR_DATA_KEY];
44034
44035      if (!sentryXhrData) {
44036        return originalSend.apply(this, args);
44037      }
44038
44039      if (args[0] !== undefined) {
44040        sentryXhrData.body = args[0];
44041      }
44042
44043      const handlerData = {
44044        args: [sentryXhrData.method, sentryXhrData.url],
44045        startTimestamp: Date.now(),
44046        xhr: this,
44047      };
44048      _handlers.triggerHandlers('xhr', handlerData);
44049
44050      return originalSend.apply(this, args);
44051    };
44052  });
44053}
44054
44055function parseUrl(url) {
44056  if (is.isString(url)) {
44057    return url;
44058  }
44059
44060  try {
44061    // url can be a string or URL
44062    // but since URL is not available in IE11, we do not check for it,
44063    // but simply assume it is an URL and return `toString()` from it (which returns the full URL)
44064    // If that fails, we just return undefined
44065    return (url ).toString();
44066  } catch (e2) {} // eslint-disable-line no-empty
44067
44068  return undefined;
44069}
44070
44071exports.SENTRY_XHR_DATA_KEY = SENTRY_XHR_DATA_KEY;
44072exports.addXhrInstrumentationHandler = addXhrInstrumentationHandler;
44073exports.instrumentXHR = instrumentXHR;
44074
44075
44076},{"../is.js":329,"../object.js":338,"../worldwide.js":354,"./_handlers.js":320}],329:[function(require,module,exports){
44077Object.defineProperty(exports, '__esModule', { value: true });
44078
44079// eslint-disable-next-line @typescript-eslint/unbound-method
44080const objectToString = Object.prototype.toString;
44081
44082/**
44083 * Checks whether given value's type is one of a few Error or Error-like
44084 * {@link isError}.
44085 *
44086 * @param wat A value to be checked.
44087 * @returns A boolean representing the result.
44088 */
44089function isError(wat) {
44090  switch (objectToString.call(wat)) {
44091    case '[object Error]':
44092    case '[object Exception]':
44093    case '[object DOMException]':
44094      return true;
44095    default:
44096      return isInstanceOf(wat, Error);
44097  }
44098}
44099/**
44100 * Checks whether given value is an instance of the given built-in class.
44101 *
44102 * @param wat The value to be checked
44103 * @param className
44104 * @returns A boolean representing the result.
44105 */
44106function isBuiltin(wat, className) {
44107  return objectToString.call(wat) === `[object ${className}]`;
44108}
44109
44110/**
44111 * Checks whether given value's type is ErrorEvent
44112 * {@link isErrorEvent}.
44113 *
44114 * @param wat A value to be checked.
44115 * @returns A boolean representing the result.
44116 */
44117function isErrorEvent(wat) {
44118  return isBuiltin(wat, 'ErrorEvent');
44119}
44120
44121/**
44122 * Checks whether given value's type is DOMError
44123 * {@link isDOMError}.
44124 *
44125 * @param wat A value to be checked.
44126 * @returns A boolean representing the result.
44127 */
44128function isDOMError(wat) {
44129  return isBuiltin(wat, 'DOMError');
44130}
44131
44132/**
44133 * Checks whether given value's type is DOMException
44134 * {@link isDOMException}.
44135 *
44136 * @param wat A value to be checked.
44137 * @returns A boolean representing the result.
44138 */
44139function isDOMException(wat) {
44140  return isBuiltin(wat, 'DOMException');
44141}
44142
44143/**
44144 * Checks whether given value's type is a string
44145 * {@link isString}.
44146 *
44147 * @param wat A value to be checked.
44148 * @returns A boolean representing the result.
44149 */
44150function isString(wat) {
44151  return isBuiltin(wat, 'String');
44152}
44153
44154/**
44155 * Checks whether given string is parameterized
44156 * {@link isParameterizedString}.
44157 *
44158 * @param wat A value to be checked.
44159 * @returns A boolean representing the result.
44160 */
44161function isParameterizedString(wat) {
44162  return (
44163    typeof wat === 'object' &&
44164    wat !== null &&
44165    '__sentry_template_string__' in wat &&
44166    '__sentry_template_values__' in wat
44167  );
44168}
44169
44170/**
44171 * Checks whether given value is a primitive (undefined, null, number, boolean, string, bigint, symbol)
44172 * {@link isPrimitive}.
44173 *
44174 * @param wat A value to be checked.
44175 * @returns A boolean representing the result.
44176 */
44177function isPrimitive(wat) {
44178  return wat === null || isParameterizedString(wat) || (typeof wat !== 'object' && typeof wat !== 'function');
44179}
44180
44181/**
44182 * Checks whether given value's type is an object literal, or a class instance.
44183 * {@link isPlainObject}.
44184 *
44185 * @param wat A value to be checked.
44186 * @returns A boolean representing the result.
44187 */
44188function isPlainObject(wat) {
44189  return isBuiltin(wat, 'Object');
44190}
44191
44192/**
44193 * Checks whether given value's type is an Event instance
44194 * {@link isEvent}.
44195 *
44196 * @param wat A value to be checked.
44197 * @returns A boolean representing the result.
44198 */
44199function isEvent(wat) {
44200  return typeof Event !== 'undefined' && isInstanceOf(wat, Event);
44201}
44202
44203/**
44204 * Checks whether given value's type is an Element instance
44205 * {@link isElement}.
44206 *
44207 * @param wat A value to be checked.
44208 * @returns A boolean representing the result.
44209 */
44210function isElement(wat) {
44211  return typeof Element !== 'undefined' && isInstanceOf(wat, Element);
44212}
44213
44214/**
44215 * Checks whether given value's type is an regexp
44216 * {@link isRegExp}.
44217 *
44218 * @param wat A value to be checked.
44219 * @returns A boolean representing the result.
44220 */
44221function isRegExp(wat) {
44222  return isBuiltin(wat, 'RegExp');
44223}
44224
44225/**
44226 * Checks whether given value has a then function.
44227 * @param wat A value to be checked.
44228 */
44229function isThenable(wat) {
44230  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
44231  return Boolean(wat && wat.then && typeof wat.then === 'function');
44232}
44233
44234/**
44235 * Checks whether given value's type is a SyntheticEvent
44236 * {@link isSyntheticEvent}.
44237 *
44238 * @param wat A value to be checked.
44239 * @returns A boolean representing the result.
44240 */
44241function isSyntheticEvent(wat) {
44242  return isPlainObject(wat) && 'nativeEvent' in wat && 'preventDefault' in wat && 'stopPropagation' in wat;
44243}
44244
44245/**
44246 * Checks whether given value is NaN
44247 * {@link isNaN}.
44248 *
44249 * @param wat A value to be checked.
44250 * @returns A boolean representing the result.
44251 */
44252function isNaN(wat) {
44253  return typeof wat === 'number' && wat !== wat;
44254}
44255
44256/**
44257 * Checks whether given value's type is an instance of provided constructor.
44258 * {@link isInstanceOf}.
44259 *
44260 * @param wat A value to be checked.
44261 * @param base A constructor to be used in a check.
44262 * @returns A boolean representing the result.
44263 */
44264function isInstanceOf(wat, base) {
44265  try {
44266    return wat instanceof base;
44267  } catch (_e) {
44268    return false;
44269  }
44270}
44271
44272/**
44273 * Checks whether given value's type is a Vue ViewModel.
44274 *
44275 * @param wat A value to be checked.
44276 * @returns A boolean representing the result.
44277 */
44278function isVueViewModel(wat) {
44279  // Not using Object.prototype.toString because in Vue 3 it would read the instance's Symbol(Symbol.toStringTag) property.
44280  return !!(typeof wat === 'object' && wat !== null && ((wat ).__isVue || (wat )._isVue));
44281}
44282
44283exports.isDOMError = isDOMError;
44284exports.isDOMException = isDOMException;
44285exports.isElement = isElement;
44286exports.isError = isError;
44287exports.isErrorEvent = isErrorEvent;
44288exports.isEvent = isEvent;
44289exports.isInstanceOf = isInstanceOf;
44290exports.isNaN = isNaN;
44291exports.isParameterizedString = isParameterizedString;
44292exports.isPlainObject = isPlainObject;
44293exports.isPrimitive = isPrimitive;
44294exports.isRegExp = isRegExp;
44295exports.isString = isString;
44296exports.isSyntheticEvent = isSyntheticEvent;
44297exports.isThenable = isThenable;
44298exports.isVueViewModel = isVueViewModel;
44299
44300
44301},{}],330:[function(require,module,exports){
44302Object.defineProperty(exports, '__esModule', { value: true });
44303
44304const node = require('./node.js');
44305const worldwide = require('./worldwide.js');
44306
44307/**
44308 * Returns true if we are in the browser.
44309 */
44310function isBrowser() {
44311  // eslint-disable-next-line no-restricted-globals
44312  return typeof window !== 'undefined' && (!node.isNodeEnv() || isElectronNodeRenderer());
44313}
44314
44315// Electron renderers with nodeIntegration enabled are detected as Node.js so we specifically test for them
44316function isElectronNodeRenderer() {
44317  return (
44318    // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
44319    (worldwide.GLOBAL_OBJ ).process !== undefined && ((worldwide.GLOBAL_OBJ ).process ).t
44319ype === 'renderer'
44320  );
44321}
44322
44323exports.isBrowser = isBrowser;
44324
44325
44326},{"./node.js":336,"./worldwide.js":354}],331:[function(require,module,exports){
44327Object.defineProperty(exports, '__esModule', { value: true });
44328
44329const debugBuild = require('./debug-build.js');
44330const worldwide = require('./worldwide.js');
44331
44332/** Prefix for logging strings */
44333const PREFIX = 'Sentry Logger ';
44334
44335const CONSOLE_LEVELS = [
44336  'debug',
44337  'info',
44338  'warn',
44339  'error',
44340  'log',
44341  'assert',
44342  'trace',
44343] ;
44344
44345/** This may be mutated by the console instrumentation. */
44346const originalConsoleMethods
44347
44348 = {};
44349
44350/** JSDoc */
44351
44352/**
44353 * Temporarily disable sentry console instrumentations.
44354 *
44355 * @param callback The function to run against the original `console` messages
44356 * @returns The results of the callback
44357 */
44358function consoleSandbox(callback) {
44359  if (!('console' in worldwide.GLOBAL_OBJ)) {
44360    return callback();
44361  }
44362
44363  const console = worldwide.GLOBAL_OBJ.console ;
44364  const wrappedFuncs = {};
44365
44366  const wrappedLevels = Object.keys(originalConsoleMethods) ;
44367
44368  // Restore all wrapped console methods
44369  wrappedLevels.forEach(level => {
44370    const originalConsoleMethod = originalConsoleMethods[level] ;
44371    wrappedFuncs[level] = console[level] ;
44372    console[level] = originalConsoleMethod;
44373  });
44374
44375  try {
44376    return callback();
44377  } finally {
44378    // Revert restoration to wrapped state
44379    wrappedLevels.forEach(level => {
44380      console[level] = wrappedFuncs[level] ;
44381    });
44382  }
44383}
44384
44385function makeLogger() {
44386  let enabled = false;
44387  const logger = {
44388    enable: () => {
44389      enabled = true;
44390    },
44391    disable: () => {
44392      enabled = false;
44393    },
44394    isEnabled: () => enabled,
44395  };
44396
44397  if (debugBuild.DEBUG_BUILD) {
44398    CONSOLE_LEVELS.forEach(name => {
44399      // eslint-disable-next-line @typescript-eslint/no-explicit-any
44400      logger[name] = (...args) => {
44401        if (enabled) {
44402          consoleSandbox(() => {
44403            worldwide.GLOBAL_OBJ.console[name](`${PREFIX}[${name}]:`, ...args);
44404          });
44405        }
44406      };
44407    });
44408  } else {
44409    CONSOLE_LEVELS.forEach(name => {
44410      logger[name] = () => undefined;
44411    });
44412  }
44413
44414  return logger ;
44415}
44416
44417const logger = makeLogger();
44418
44419exports.CONSOLE_LEVELS = CONSOLE_LEVELS;
44420exports.consoleSandbox = consoleSandbox;
44421exports.logger = logger;
44422exports.originalConsoleMethods = originalConsoleMethods;
44423
44424
44425},{"./debug-build.js":313,"./worldwide.js":354}],332:[function(require,module,exports){
44426Object.defineProperty(exports, '__esModule', { value: true });
44427
44428/** A simple Least Recently Used map */
44429class LRUMap {
44430
44431   constructor(  _maxSize) {this._maxSize = _maxSize;
44432    this._cache = new Map();
44433  }
44434
44435  /** Get the current size of the cache */
44436   get size() {
44437    return this._cache.size;
44438  }
44439
44440  /** Get an entry or undefined if it was not in the cache. Re-inserts to update the recently used order */
44441   get(key) {
44442    const value = this._cache.get(key);
44443    if (value === undefined) {
44444      return undefined;
44445    }
44446    // Remove and re-insert to update the order
44447    this._cache.delete(key);
44448    this._cache.set(key, value);
44449    return value;
44450  }
44451
44452  /** Insert an entry and evict an older entry if we've reached maxSize */
44453   set(key, value) {
44454    if (this._cache.size >= this._maxSize) {
44455      // keys() returns an iterator in insertion order so keys().next() gives us the oldest key
44456      this._cache.delete(this._cache.keys().next().value);
44457    }
44458    this._cache.set(key, value);
44459  }
44460
44461  /** Remove an entry and return the entry if it was in the cache */
44462   remove(key) {
44463    const value = this._cache.get(key);
44464    if (value) {
44465      this._cache.delete(key);
44466    }
44467    return value;
44468  }
44469
44470  /** Clear all entries */
44471   clear() {
44472    this._cache.clear();
44473  }
44474
44475  /** Get all the keys */
44476   keys() {
44477    return Array.from(this._cache.keys());
44478  }
44479
44480  /** Get all the values */
44481   values() {
44482    const values = [];
44483    this._cache.forEach(value => values.push(value));
44484    return values;
44485  }
44486}
44487
44488exports.LRUMap = LRUMap;
44489
44490
44491},{}],333:[function(require,module,exports){
44492Object.defineProperty(exports, '__esModule', { value: true });
44493
44494/* eslint-disable @typescript-eslint/no-unsafe-member-access */
44495/* eslint-disable @typescript-eslint/no-explicit-any */
44496
44497/**
44498 * Helper to decycle json objects
44499 */
44500function memoBuilder() {
44501  const hasWeakSet = typeof WeakSet === 'function';
44502  const inner = hasWeakSet ? new WeakSet() : [];
44503  function memoize(obj) {
44504    if (hasWeakSet) {
44505      if (inner.has(obj)) {
44506        return true;
44507      }
44508      inner.add(obj);
44509      return false;
44510    }
44511    // eslint-disable-next-line @typescript-eslint/prefer-for-of
44512    for (let i = 0; i < inner.length; i++) {
44513      const value = inner[i];
44514      if (value === obj) {
44515        return true;
44516      }
44517    }
44518    inner.push(obj);
44519    return false;
44520  }
44521
44522  function unmemoize(obj) {
44523    if (hasWeakSet) {
44524      inner.delete(obj);
44525    } else {
44526      for (let i = 0; i < inner.length; i++) {
44527        if (inner[i] === obj) {
44528          inner.splice(i, 1);
44529          break;
44530        }
44531      }
44532    }
44533  }
44534  return [memoize, unmemoize];
44535}
44536
44537exports.memoBuilder = memoBuilder;
44538
44539
44540},{}],334:[function(require,module,exports){
44541Object.defineProperty(exports, '__esModule', { value: true });
44542
44543const object = require('./object.js');
44544const string = require('./string.js');
44545const worldwide = require('./worldwide.js');
44546
44547/**
44548 * UUID4 generator
44549 *
44550 * @returns string Generated UUID4.
44551 */
44552function uuid4() {
44553  const gbl = worldwide.GLOBAL_OBJ ;
44554  const crypto = gbl.crypto || gbl.msCrypto;
44555
44556  let getRandomByte = () => Math.random() * 16;
44557  try {
44558    if (crypto && crypto.randomUUID) {
44559      return crypto.randomUUID().replace(/-/g, '');
44560    }
44561    if (crypto && crypto.getRandomValues) {
44562      getRandomByte = () => {
44563        // crypto.getRandomValues might return undefined instead of the typed array
44564        // in old Chromium versions (e.g. 23.0.1235.0 (151422))
vendor: 5,656 bytes, lines 44565-44715
44565        // However, `typedArray` is still filled in-place.
44566        // @see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#typedarray
44567        const typedArray = new Uint8Array(1);
44568        crypto.getRandomValues(typedArray);
44569        return typedArray[0];
44570      };
44571    }
44572  } catch (_) {
44573    // some runtimes can crash invoking crypto
44574    // https://github.com/getsentry/sentry-javascript/issues/8935
44575  }
44576
44577  // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
44578  // Concatenating the following numbers as strings results in '10000000100040008000100000000000'
44579  return (([1e7] ) + 1e3 + 4e3 + 8e3 + 1e11).replace(/[018]/g, c =>
44580    // eslint-disable-next-line no-bitwise
44581    ((c ) ^ ((getRandomByte() & 15) >> ((c ) / 4))).toString(16),
44582  );
44583}
44584
44585function getFirstException(event) {
44586  return event.exception && event.exception.values ? event.exception.values[0] : undefined;
44587}
44588
44589/**
44590 * Extracts either message or type+value from an event that can be used for user-facing logs
44591 * @returns event's description
44592 */
44593function getEventDescription(event) {
44594  const { message, event_id: eventId } = event;
44595  if (message) {
44596    return message;
44597  }
44598
44599  const firstException = getFirstException(event);
44600  if (firstException) {
44601    if (firstException.type && firstException.value) {
44602      return `${firstException.type}: ${firstException.value}`;
44603    }
44604    return firstException.type || firstException.value || eventId || '<unknown>';
44605  }
44606  return eventId || '<unknown>';
44607}
44608
44609/**
44610 * Adds exception values, type and value to an synthetic Exception.
44611 * @param event The event to modify.
44612 * @param value Value of the exception.
44613 * @param type Type of the exception.
44614 * @hidden
44615 */
44616function addExceptionTypeValue(event, value, type) {
44617  const exception = (event.exception = event.exception || {});
44618  const values = (exception.values = exception.values || []);
44619  const firstException = (values[0] = values[0] || {});
44620  if (!firstException.value) {
44621    firstException.value = value || '';
44622  }
44623  if (!firstException.type) {
44624    firstException.type = type || 'Error';
44625  }
44626}
44627
44628/**
44629 * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
44630 *
44631 * @param event The event to modify.
44632 * @param newMechanism Mechanism data to add to the event.
44633 * @hidden
44634 */
44635function addExceptionMechanism(event, newMechanism) {
44636  const firstException = getFirstException(event);
44637  if (!firstException) {
44638    return;
44639  }
44640
44641  const defaultMechanism = { type: 'generic', handled: true };
44642  const currentMechanism = firstException.mechanism;
44643  firstException.mechanism = { ...defaultMechanism, ...currentMechanism, ...newMechanism };
44644
44645  if (newMechanism && 'data' in newMechanism) {
44646    const mergedData = { ...(currentMechanism && currentMechanism.data), ...newMechanism.data };
44647    firstException.mechanism.data = mergedData;
44648  }
44649}
44650
44651// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
44652const SEMVER_REGEXP =
44653  /^(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-]+)*))?$/;
44654
44655/**
44656 * Represents Semantic Versioning object
44657 */
44658
44659/**
44660 * Parses input into a SemVer interface
44661 * @param input string representation of a semver version
44662 */
44663function parseSemver(input) {
44664  const match = input.match(SEMVER_REGEXP) || [];
44665  const major = parseInt(match[1], 10);
44666  const minor = parseInt(match[2], 10);
44667  const patch = parseInt(match[3], 10);
44668  return {
44669    buildmetadata: match[5],
44670    major: isNaN(major) ? undefined : major,
44671    minor: isNaN(minor) ? undefined : minor,
44672    patch: isNaN(patch) ? undefined : patch,
44673    prerelease: match[4],
44674  };
44675}
44676
44677/**
44678 * This function adds context (pre/post/line) lines to the provided frame
44679 *
44680 * @param lines string[] containing all lines
44681 * @param frame StackFrame that will be mutated
44682 * @param linesOfContext number of context lines we want to add pre/post
44683 */
44684function addContextToFrame(lines, frame, linesOfContext = 5) {
44685  // When there is no line number in the frame, attaching context is nonsensical and will even break grouping
44686  if (frame.lineno === undefined) {
44687    return;
44688  }
44689
44690  const maxLines = lines.length;
44691  const sourceLine = Math.max(Math.min(maxLines - 1, frame.lineno - 1), 0);
44692
44693  frame.pre_context = lines
44694    .slice(Math.max(0, sourceLine - linesOfContext), sourceLine)
44695    .map((line) => string.snipLine(line, 0));
44696
44697  frame.context_line = string.snipLine(lines[Math.min(maxLines - 1, sourceLine)], frame.colno || 0);
44698
44699  frame.post_context = lines
44700    .slice(Math.min(sourceLine + 1, maxLines), sourceLine + 1 + linesOfContext)
44701    .map((line) => string.snipLine(line, 0));
44702}
44703
44704/**
44705 * Checks whether or not we've already captured the given exception (note: not an identical exception - the very object
44706 * in question), and marks it captured if not.
44707 *
44708 * This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and
44709 * record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so
44710 * that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because
44711 * the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not
44712 * caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This
44713 * function helps us ensure that even if we encounter the same error more than once, we only record it the first time we
44714 * see it.
44715 *
44716 * Note: It will ignore primitives (always return `false` and not mark them as seen), as properties can't be set on
44717 * them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent
44718 * object wrapper forms so that this check will always work. However, because we need to flag the exact object which
44719 * will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification
44720 * must be done before the exception captured.
44721 *
44722 * @param A thrown exception to check or flag as having been seen
44723 * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
44724 */
44725function checkOrSetAlreadyCaught(exception) {
44726  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
44727  if (exception && (exception ).__sentry_captured__) {
44728    return true;
44729  }
44730
44731  try {
44732    // set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
44733    // `ExtraErrorData` integration
44734    object.addNonEnumerableProperty(exception , '__sentry_captured__', true);
44735  } catch (err) {
44736    // `exception` is a primitive, so we can't mark it seen
44737  }
44738
44739  return false;
44740}
44741
44742/**
44743 * Checks whether the given input is already an array, and if it isn't, wraps it in one.
44744 *
44745 * @param maybeArray Input to turn into an array, if necessary
44746 * @returns The input, if already an array, or an array with the input as the only element, if not
44747 */
44748function arrayify(maybeArray) {
44749  return Array.isArray(maybeArray) ? maybeArray : [maybeArray];
44750}
44751
44752exports.addContextToFrame = addContextToFrame;
44753exports.addExceptionMechanism = addExceptionMechanism;
44754exports.addExceptionTypeValue = addExceptionTypeValue;
44755exports.arrayify = arrayify;
44756exports.checkOrSetAlreadyCaught = checkOrSetAlreadyCaught;
44757exports.getEventDescription = getEventDescription;
44758exports.parseSemver = parseSemver;
44759exports.uuid4 = uuid4;
44760
44761
44762},{"./object.js":338,"./string.js":345,"./worldwide.js":354}],335:[function(require,module,exports){
44763Object.defineProperty(exports, '__esModule', { value: true });
44764
44765/**
44766 * Does this filename look like it's part of the app code?
44767 */
44768function filenameIsInApp(filename, isNative = false) {
44769  const isInternal =
44770    isNative ||
44771    (filename &&
44772      // It's not internal if it's an absolute linux path
44773      !filename.startsWith('/') &&
44774      // It's not internal if it's an absolute windows path
44775      !filename.match(/^[A-Z]:/) &&
44776      // It's not internal if the path is starting with a dot
44777      !filename.startsWith('.') &&
44778      // It's not internal if the frame has a protocol. In node, this is usually the case if the file got pre-processed with a bundler like webpack
44779      !filename.match(/^[a-zA-Z]([a-zA-Z0-9.\-+])*:\/\//)); // Schema from: https://stackoverflow.com/a/3641782
44780
44781  // in_app is all that's not an internal Node function or a module within node_modules
44782  // note that isNative appears to return true even for node core libraries
44783  // see https://github.com/getsentry/raven-node/issues/176
44784
44785  return !isInternal && filename !== undefined && !filename.includes('node_modules/');
44786}
44787
44788/** Node Stack line parser */
44789// eslint-disable-next-line complexity
44790function node(getModule) {
44791  const FILENAME_MATCH = /^\s*[-]{4,}$/;
44792  const FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
44793
44794  // eslint-disable-next-line complexity
44795  return (line) => {
44796    const lineMatch = line.match(FULL_MATCH);
44797
44798    if (lineMatch) {
44799      let object;
44800      let method;
44801      let functionName;
44802      let typeName;
44803      let methodName;
44804
44805      if (lineMatch[1]) {
44806        functionName = lineMatch[1];
44807
44808        let methodStart = functionName.lastIndexOf('.');
44809        if (functionName[methodStart - 1] === '.') {
44810          methodStart--;
44811        }
44812
44813        if (methodStart > 0) {
44814          object = functionName.slice(0, methodStart);
44815          method = functionName.slice(methodStart + 1);
44816          const objectEnd = object.indexOf('.Module');
44817          if (objectEnd > 0) {
44818            functionName = functionName.slice(objectEnd + 1);
44819            object = object.slice(0, objectEnd);
44820          }
44821        }
44822        typeName = undefined;
44823      }
44824
44825      if (method) {
44826        typeName = object;
44827        methodName = method;
44828      }
44829
44830      if (method === '<anonymous>') {
44831        methodName = undefined;
44832        functionName = undefined;
44833      }
44834
44835      if (functionName === undefined) {
44836        methodName = methodName || '<anonymous>';
44837        functionName = typeName ? `${typeName}.${methodName}` : methodName;
44838      }
44839
44840      let filename = lineMatch[2] && lineMatch[2].startsWith('file://') ? lineMatch[2].slice(7) : lineMatch[2];
44841      const isNative = lineMatch[5] === 'native';
44842
44843      // If it's a Windows path, trim the leading slash so that `/C:/foo` becomes `C:/foo`
44844      if (filename && filename.match(/\/[A-Z]:/)) {
44845        filename = filename.slice(1);
44846      }
44847
44848      if (!filename && lineMatch[5] && !isNative) {
44849        filename = lineMatch[5];
44850      }
44851
44852      return {
44853        filename,
44854        module: getModule ? getModule(filename) : undefined,
44855        function: functionName,
44856        lineno: parseInt(lineMatch[3], 10) || undefined,
44857        colno: parseInt(lineMatch[4], 10) || undefined,
44858        in_app: filenameIsInApp(filename, isNative),
44859      };
44860    }
44861
44862    if (line.match(FILENAME_MATCH)) {
44863      return {
44864        filename: line,
44865      };
44866    }
44867
44868    return undefined;
44869  };
44870}
44871
44872exports.filenameIsInApp = filenameIsInApp;
44873exports.node = node;
44874
44875
44876},{}],336:[function(require,module,exports){
44877(function (process){(function (){
44878Object.defineProperty(exports, '__esModule', { value: true });
44879
44880const env = require('./env.js');
44881
44882/**
44883 * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
44884 * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
44885 */
44886
44887/**
44888 * Checks whether we're in the Node.js or Browser environment
44889 *
44890 * @returns Answer to given question
44891 */
44892function isNodeEnv() {
44893  // explicitly check for browser bundles as those can be optimized statically
44894  // by terser/rollup.
44895  return (
44896    !env.isBrowserBundle() &&
44897    Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]'
44898  );
44899}
44900
44901/**
44902 * Requires a module which is protected against bundler minification.
44903 *
44904 * @param request The module path to resolve
44905 */
44906// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
44907function dynamicRequire(mod, request) {
44908  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
44909  return mod.require(request);
44910}
44911
44912/**
44913 * Helper for dynamically loading module that should work with linked dependencies.
44914 * The problem is that we _should_ be using `require(require.resolve(moduleName, { paths: [cwd()] }))`
44915 * However it's _not possible_ to do that with Webpack, as it has to know all the dependencies during
44916 * build time. `require.resolve` is also not available in any other way, so we cannot create,
44917 * a fake helper like we do with `dynamicRequire`.
44918 *
44919 * We always prefer to use local package, thus the value is not returned early from each `try/catch` block.
44920 * That is to mimic the behavior of `require.resolve` exactly.
44921 *
44922 * @param moduleName module name to require
44923 * @returns possibly required module
44924 */
44925function loadModule(moduleName) {
44926  let mod;
44927
44928  try {
44929    mod = dynamicRequire(module, moduleName);
44930  } catch (e) {
44931    // no-empty
44932  }
44933
44934  try {
44935    const { cwd } = dynamicRequire(module, 'process');
44936    mod = dynamicRequire(module, `${cwd()}/node_modules/${moduleName}`) ;
44937  } catch (e) {
44938    // no-empty
44939  }
44940
44941  return mod;
44942}
44943
44944exports.dynamicRequire = dynamicRequire;
44945exports.isNodeEnv = isNodeEnv;
44946exports.loadModule = loadModule;
44947
44948
44949}).call(this)}).call(this,require('_process'))
44950},{"./env.js":315,"_process":365}],337:[function(require,module,exports){
44951(function (global){(function (){
44952Object.defineProperty(exports, '__esModule', { value: true });
44953
44954const is = require('./is.js');
44955const memo = require('./memo.js');
44956const object = require('./object.js');
44957const stacktrace = require('./stacktrace.js');
44958
44959/**
44960 * Recursively normalizes the given object.
44961 *
44962 * - Creates a copy to prevent original input mutation
44963 * - Skips non-enumerable properties
44964 * - When stringifying, calls `toJSON` if implemented
44965 * - Removes circular references
44966 * - Translates non-serializable values (`undefined`/`NaN`/functions) to serializable format
44967 * - Translates known global objects/classes to a string representations
44968 * - Takes care of `Error` object serialization
44969 * - Optionally limits depth of final output
44970 * - Optionally limits number of properties/elements included in any single object/array
44971 *
44972 * @param input The object to be normalized.
44973 * @param depth The max depth to which to normalize the object. (Anything deeper stringified whole.)
44974 * @param maxProperties The max number of elements or properties to be included in any single array or
44975 * object in the normallized output.
44976 * @returns A normalized version of the object, or `"**non-serializable**"` if any errors are thrown during normalization.
44977 */
44978// eslint-disable-next-line @typescript-eslint/no-explicit-any
44979function normalize(input, depth = 100, maxProperties = +Infinity) {
44980  try {
44981    // since we're at the outermost level, we don't provide a key
44982    return visit('', input, depth, maxProperties);
44983  } catch (err) {
44984    return { ERROR: `**non-serializable** (${err})` };
44985  }
44986}
44987
44988/** JSDoc */
44989function normalizeToSize(
44990  // eslint-disable-next-line @typescript-eslint/no-explicit-any
44991  object,
44992  // Default Node.js REPL depth
44993  depth = 3,
44994  // 100kB, as 200kB is max payload size, so half sounds reasonable
44995  maxSize = 100 * 1024,
44996) {
44997  const normalized = normalize(object, depth);
44998
44999  if (jsonSize(normalized) > maxSize) {
45000    return normalizeToSize(object, depth - 1, maxSize);
45001  }
45002
45003  return normalized ;
45004}
45005
45006/**
45007 * Visits a node to perform normalization on it
45008 *
45009 * @param key The key corresponding to the given node
45010 * @param value The node to be visited
45011 * @param depth Optional number indicating the maximum recursion depth
45012 * @param maxProperties Optional maximum number of properties/elements included in any single object/array
45013 * @param memo Optional Memo class handling decycling
45014 */
45015function visit(
45016  key,
45017  value,
45018  depth = +Infinity,
45019  maxProperties = +Infinity,
45020  memo$1 = memo.memoBuilder(),
45021) {
45022  const [memoize, unmemoize] = memo$1;
45023
45024  // Get the simple cases out of the way first
45025  if (
45026    value == null || // this matches null and undefined -> eqeq not eqeqeq
45027    (['number', 'boolean', 'string'].includes(typeof value) && !is.isNaN(value))
45028  ) {
45029    return value ;
45030  }
45031
45032  const stringified = stringifyValue(key, value);
45033
45034  // Anything we could potentially dig into more (objects or arrays) will have come back as `"[object XXXX]"`.
45035  // Everything else will have already been serialized, so if we don't see that pattern, we're done.
45036  if (!stringified.startsWith('[object ')) {
45037    return stringified;
45038  }
45039
45040  // From here on, we can assert that `value` is either an object or an array.
vendor: 6,568 bytes, lines 45041-45224
45041
45042  // Do not normalize objects that we know have already been normalized. As a general rule, the
45043  // "__sentry_skip_normalization__" property should only be used sparingly and only should only be set on objects that
45044  // have already been normalized.
45045  if ((value )['__sentry_skip_normalization__']) {
45046    return value ;
45047  }
45048
45049  // We can set `__sentry_override_normalization_depth__` on an object to ensure that from there
45050  // We keep a certain amount of depth.
45051  // This should be used sparingly, e.g. we use it for the redux integration to ensure we get a certain amount of state.
45052  const remainingDepth =
45053    typeof (value )['__sentry_override_normalization_depth__'] === 'number'
45054      ? ((value )['__sentry_override_normalization_depth__'] )
45055      : depth;
45056
45057  // We're also done if we've reached the max depth
45058  if (remainingDepth === 0) {
45059    // At this point we know `serialized` is a string of the form `"[object XXXX]"`. Clean it up so it's just `"[XXXX]"`.
45060    return stringified.replace('object ', '');
45061  }
45062
45063  // If we've already visited this branch, bail out, as it's circular reference. If not, note that we're seeing it now.
45064  if (memoize(value)) {
45065    return '[Circular ~]';
45066  }
45067
45068  // If the value has a `toJSON` method, we call it to extract more information
45069  const valueWithToJSON = value ;
45070  if (valueWithToJSON && typeof valueWithToJSON.toJSON === 'function') {
45071    try {
45072      const jsonValue = valueWithToJSON.toJSON();
45073      // We need to normalize the return value of `.toJSON()` in case it has circular references
45074      return visit('', jsonValue, remainingDepth - 1, maxProperties, memo$1);
45075    } catch (err) {
45076      // pass (The built-in `toJSON` failed, but we can still try to do it ourselves)
45077    }
45078  }
45079
45080  // 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
45081  // because we haven't yet reached the max depth. Create an accumulator to hold the results of visiting each
45082  // property/entry, and keep track of the number of items we add to it.
45083  const normalized = (Array.isArray(value) ? [] : {}) ;
45084  let numAdded = 0;
45085
45086  // Before we begin, convert`Error` and`Event` instances into plain objects, since some of each of their relevant
45087  // properties are non-enumerable and otherwise would get missed.
45088  const visitable = object.convertToPlainObject(value );
45089
45090  for (const visitKey in visitable) {
45091    // Avoid iterating over fields in the prototype if they've somehow been exposed to enumeration.
45092    if (!Object.prototype.hasOwnProperty.call(visitable, visitKey)) {
45093      continue;
45094    }
45095
45096    if (numAdded >= maxProperties) {
45097      normalized[visitKey] = '[MaxProperties ~]';
45098      break;
45099    }
45100
45101    // Recursively visit all the child nodes
45102    const visitValue = visitable[visitKey];
45103    normalized[visitKey] = visit(visitKey, visitValue, remainingDepth - 1, maxProperties, memo$1);
45104
45105    numAdded++;
45106  }
45107
45108  // Once we've visited all the branches, remove the parent from memo storage
45109  unmemoize(value);
45110
45111  // Return accumulated values
45112  return normalized;
45113}
45114
45115/* eslint-disable complexity */
45116/**
45117 * Stringify the given value. Handles various known special values and types.
45118 *
45119 * Not meant to be used on simple primitives which already have a string representation, as it will, for example, turn
45120 * the number 1231 into "[Object Number]", nor on `null`, as it will throw.
45121 *
45122 * @param value The value to stringify
45123 * @returns A stringified representation of the given value
45124 */
45125function stringifyValue(
45126  key,
45127  // this type is a tiny bit of a cheat, since this function does handle NaN (which is technically a number), but for
45128  // our internal use, it'll do
45129  value,
45130) {
45131  try {
45132    if (key === 'domain' && value && typeof value === 'object' && (value )._events) {
45133      return '[Domain]';
45134    }
45135
45136    if (key === 'domainEmitter') {
45137      return '[DomainEmitter]';
45138    }
45139
45140    // It's safe to use `global`, `window`, and `document` here in this manner, as we are asserting using `typeof` first
45141    // which won't throw if they are not present.
45142
45143    if (typeof global !== 'undefined' && value === global) {
45144      return '[Global]';
45145    }
45146
45147    // eslint-disable-next-line no-restricted-globals
45148    if (typeof window !== 'undefined' && value === window) {
45149      return '[Window]';
45150    }
45151
45152    // eslint-disable-next-line no-restricted-globals
45153    if (typeof document !== 'undefined' && value === document) {
45154      return '[Document]';
45155    }
45156
45157    if (is.isVueViewModel(value)) {
45158      return '[VueViewModel]';
45159    }
45160
45161    // React's SyntheticEvent thingy
45162    if (is.isSyntheticEvent(value)) {
45163      return '[SyntheticEvent]';
45164    }
45165
45166    if (typeof value === 'number' && value !== value) {
45167      return '[NaN]';
45168    }
45169
45170    if (typeof value === 'function') {
45171      return `[Function: ${stacktrace.getFunctionName(value)}]`;
45172    }
45173
45174    if (typeof value === 'symbol') {
45175      return `[${String(value)}]`;
45176    }
45177
45178    // stringified BigInts are indistinguishable from regular numbers, so we need to label them to avoid confusion
45179    if (typeof value === 'bigint') {
45180      return `[BigInt: ${String(value)}]`;
45181    }
45182
45183    // Now that we've knocked out all the special cases and the primitives, all we have left are objects. Simply casting
45184    // them to strings means that instances of classes which haven't defined their `toStringTag` will just come out as
45185    // `"[object Object]"`. If we instead look at the constructor's name (which is the same as the name of the class),
45186    // we can make sure that only plain objects come out that way.
45187    const objName = getConstructorName(value);
45188
45189    // Handle HTML Elements
45190    if (/^HTML(\w*)Element$/.test(objName)) {
45191      return `[HTMLElement: ${objName}]`;
45192    }
45193
45194    return `[object ${objName}]`;
45195  } catch (err) {
45196    return `**non-serializable** (${err})`;
45197  }
45198}
45199/* eslint-enable complexity */
45200
45201function getConstructorName(value) {
45202  const prototype = Object.getPrototypeOf(value);
45203
45204  return prototype ? prototype.constructor.name : 'null prototype';
45205}
45206
45207/** Calculates bytes size of input string */
45208function utf8Length(value) {
45209  // eslint-disable-next-line no-bitwise
45210  return ~-encodeURI(value).split(/%..|./).length;
45211}
45212
45213/** Calculates bytes size of input object */
45214// eslint-disable-next-line @typescript-eslint/no-explicit-any
45215function jsonSize(value) {
45216  return utf8Length(JSON.stringify(value));
45217}
45218
45219/**
45220 * Normalizes URLs in exceptions and stacktraces to a base path so Sentry can fingerprint
45221 * across platforms and working directory.
45222 *
45223 * @param url The URL to be normalized.
45224 * @param basePath The application base path.
45225 * @returns The normalized URL.
45226 */
45227function normalizeUrlToBase(url, basePath) {
45228  const escapedBase = basePath
45229    // Backslash to forward
45230    .replace(/\\/g, '/')
45231    // Escape RegExp special characters
45232    .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
45233
45234  let newUrl = url;
45235  try {
45236    newUrl = decodeURI(url);
45237  } catch (_Oo) {
45238    // Sometime this breaks
45239  }
45240  return (
45241    newUrl
45242      .replace(/\\/g, '/')
45243      .replace(/webpack:\/?/g, '') // Remove intermediate base path
45244      // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor
45245      .replace(new RegExp(`(file://)?/*${escapedBase}/*`, 'ig'), 'app:///')
45246  );
45247}
45248
45249exports.normalize = normalize;
45250exports.normalizeToSize = normalizeToSize;
45251exports.normalizeUrlToBase = normalizeUrlToBase;
45252exports.walk = visit;
45253
45254
45255}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
45256},{"./is.js":329,"./memo.js":333,"./object.js":338,"./stacktrace.js":344}],338:[function(require,module,exports){
45257Object.defineProperty(exports, '__esModule', { value: true });
45258
45259const browser = require('./browser.js');
45260const debugBuild = require('./debug-build.js');
45261const is = require('./is.js');
45262const logger = require('./logger.js');
45263const string = require('./string.js');
45264
45265/**
45266 * Replace a method in an object with a wrapped version of itself.
45267 *
45268 * @param source An object that contains a method to be wrapped.
45269 * @param name The name of the method to be wrapped.
45270 * @param replacementFactory A higher-order function that takes the original version of the given method and returns a
45271 * wrapped version. Note: The function returned by `replacementFactory` needs to be a non-arrow function, in order to
45272 * preserve the correct value of `this`, and the original method must be called using `origMethod.call(this, <other
45273 * args>)` or `origMethod.apply(this, [<other args>])` (rather than being called directly), again to preserve `this`.
45274 * @returns void
45275 */
45276function fill(source, name, replacementFactory) {
45277  if (!(name in source)) {
45278    return;
45279  }
45280
45281  const original = source[name] ;
45282  const wrapped = replacementFactory(original) ;
45283
45284  // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work
45285  // otherwise it'll throw "TypeError: Object.defineProperties called on non-object"
45286  if (typeof wrapped === 'function') {
45287    markFunctionWrapped(wrapped, original);
45288  }
45289
45290  source[name] = wrapped;
45291}
45292
45293/**
45294 * Defines a non-enumerable property on the given object.
45295 *
45296 * @param obj The object on which to set the property
45297 * @param name The name of the property to be set
45298 * @param value The value to which to set the property
45299 */
45300function addNonEnumerableProperty(obj, name, value) {
45301  try {
45302    Object.defineProperty(obj, name, {
45303      // enumerable: false, // the default, so we can save on bundle size by not explicitly setting it
45304      value: value,
45305      writable: true,
45306      configurable: true,
45307    });
45308  } catch (o_O) {
45309    debugBuild.DEBUG_BUILD && logger.logger.log(`Failed to add non-enumerable property "${name}" to object`, obj);
45310  }
45311}
45312
45313/**
45314 * Remembers the original function on the wrapped function and
45315 * patches up the prototype.
45316 *
45317 * @param wrapped the wrapper function
45318 * @param original the original function that gets wrapped
45319 */
45320function markFunctionWrapped(wrapped, original) {
45321  try {
45322    const proto = original.prototype || {};
45323    wrapped.prototype = original.prototype = proto;
45324    addNonEnumerableProperty(wrapped, '__sentry_original__', original);
45325  } catch (o_O) {} // eslint-disable-line no-empty
45326}
45327
45328/**
45329 * This extracts the original function if available.  See
45330 * `markFunctionWrapped` for more information.
45331 *
45332 * @param func the function to unwrap
45333 * @returns the unwrapped version of the function if available.
45334 */
45335function getOriginalFunction(func) {
45336  return func.__sentry_original__;
45337}
45338
45339/**
45340 * Encodes given object into url-friendly format
45341 *
45342 * @param object An object that contains serializable values
45343 * @returns string Encoded
45344 */
45345function urlEncode(object) {
45346  return Object.keys(object)
45347    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(object[key])}`)
45348    .join('&');
45349}
45350
45351/**
45352 * Transforms any `Error` or `Event` into a plain object with all of their enumerable properties, and some of their
45353 * non-enumerable properties attached.
45354 *
45355 * @param value Initial source that we have to transform in order for it to be usable by the serializer
45356 * @returns An Event or Error turned into an object - or the value argurment itself, when value is neither an Event nor
45357 *  an Error.
45358 */
45359function convertToPlainObject(
45360  value,
45361)
45362
45363 {
45364  if (is.isError(value)) {
45365    return {
45366      message: value.message,
45367      name: value.name,
45368      stack: value.stack,
45369      ...getOwnProperties(value),
45370    };
45371  } else if (is.isEvent(value)) {
45372    const newObj
45373
45374 = {
45375      type: value.type,
45376      target: serializeEventTarget(value.target),
45377      currentTarget: serializeEventTarget(value.currentTarget),
45378      ...getOwnProperties(value),
45379    };
45380
45381    if (typeof CustomEvent !== 'undefined' && is.isInstanceOf(value, CustomEvent)) {
45382      newObj.detail = value.detail;
45383    }
45384
45385    return newObj;
45386  } else {
45387    return value;
45388  }
45389}
45390
45391/** Creates a string representation of the target of an `Event` object */
45392function serializeEventTarget(target) {
45393  try {
45394    return is.isElement(target) ? browser.htmlTreeAsString(target) : Object.prototype.toString.call(target);
45395  } catch (_oO) {
45396    return '<unknown>';
45397  }
45398}
45399
45400/** Filters out all but an object's own properties */
45401function getOwnProperties(obj) {
45402  if (typeof obj === 'object' && obj !== null) {
45403    const extractedProps = {};
45404    for (const property in obj) {
45405      if (Object.prototype.hasOwnProperty.call(obj, property)) {
45406        extractedProps[property] = (obj )[property];
45407      }
45408    }
45409    return extractedProps;
45410  } else {
45411    return {};
45412  }
45413}
45414
45415/**
45416 * Given any captured exception, extract its keys and create a sorted
45417 * and truncated list that will be used inside the event message.
45418 * eg. `Non-error exception captured with keys: foo, bar, baz`
45419 */
45420function extractExceptionKeysForMessage(exception, maxLength = 40) {
45421  const keys = Object.keys(convertToPlainObject(exception));
45422  keys.sort();
45423
45424  if (!keys.length) {
45425    return '[object has no keys]';
45426  }
45427
45428  if (keys[0].length >= maxLength) {
45429    return string.truncate(keys[0], maxLength);
45430  }
45431
45432  for (let includedKeys = keys.length; includedKeys > 0; includedKeys--) {
45433    const serialized = keys.slice(0, includedKeys).join(', ');
45434    if (serialized.length > maxLength) {
45435      continue;
45436    }
45437    if (includedKeys === keys.length) {
45438      return serialized;
45439    }
45440    return string.truncate(serialized, maxLength);
45441  }
45442
45443  return '';
45444}
45445
45446/**
45447 * Given any object, return a new object having removed all fields whose value was `undefined`.
45448 * Works recursively on objects and arrays.
45449 *
45450 * Attention: This function keeps circular references in the returned object.
45451 */
45452function dropUndefinedKeys(inputValue) {
45453  // This map keeps track of what already visited nodes map to.
45454  // Our Set - based memoBuilder doesn't work here because we want to the output object to have the same circular
45455  // references as the input object.
45456  const memoizationMap = new Map();
45457
45458  // This function just proxies `_dropUndefinedKeys` to keep the `memoBuilder` out of this function's API
45459  return _dropUndefinedKeys(inputValue, memoizationMap);
45460}
45461
45462function _dropUndefinedKeys(inputValue, memoizationMap) {
45463  if (isPojo(inputValue)) {
45464    // If this node has already been visited due to a circular reference, return the object it was mapped to in the new object
45465    const memoVal = memoizationMap.get(inputValue);
45466    if (memoVal !== undefined) {
45467      return memoVal ;
45468    }
45469
45470    const returnValue = {};
45471    // Store the mapping of this value in case we visit it again, in case of circular data
45472    memoizationMap.set(inputValue, returnValue);
45473
45474    for (const key of Object.keys(inputValue)) {
45475      if (typeof inputValue[key] !== 'undefined') {
45476        returnValue[key] = _dropUndefinedKeys(inputValue[key], memoizationMap);
45477      }
45478    }
45479
45480    return returnValue ;
45481  }
45482
45483  if (Array.isArray(inputValue)) {
45484    // If this node has already been visited due to a circular reference, return the array it was mapped to in the new object
45485    const memoVal = memoizationMap.get(inputValue);
45486    if (memoVal !== undefined) {
45487      return memoVal ;
45488    }
45489
45490    const returnValue = [];
45491    // Store the mapping of this value in case we visit it again, in case of circular data
45492    memoizationMap.set(inputValue, returnValue);
45493
45494    inputValue.forEach((item) => {
45495      returnValue.push(_dropUndefinedKeys(item, memoizationMap));
45496    });
45497
45498    return returnValue ;
45499  }
45500
45501  return inputValue;
45502}
45503
45504function isPojo(input) {
45505  if (!is.isPlainObject(input)) {
45506    return false;
45507  }
45508
45509  try {
45510    const name = (Object.getPrototypeOf(input) ).constructor.name;
45511    return !name || name === 'Object';
45512  } catch (e) {
45513    return true;
45514  }
45515}
45516
45517/**
45518 * Ensure that something is an object.
45519 *
45520 * Turns `undefined` and `null` into `String`s and all other primitives into instances of their respective wrapper
45521 * classes (String, Boolean, Number, etc.). Acts as the identity function on non-primitives.
45522 *
45523 * @param wat The subject of the objectification
45524 * @returns A version of `wat` which can safely be used with `Object` class methods
45525 */
45526function objectify(wat) {
45527  let objectified;
45528  switch (true) {
45529    case wat === undefined || wat === null:
45530      objectified = new String(wat);
45531      break;
45532
45533    // Though symbols and bigints do have wrapper classes (`Symbol` and `BigInt`, respectively), for whatever reason
45534    // those classes don't have constructors which can be used with the `new` keyword. We therefore need to cast each as
45535    // an object in order to wrap it.
45536    case typeof wat === 'symbol' || typeof wat === 'bigint':
45537      objectified = Object(wat);
45538      break;
45539
45540    // this will catch the remaining primitives: `String`, `Number`, and `Boolean`
45541    case is.isPrimitive(wat):
45542      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
45543      objectified = new (wat ).constructor(wat);
45544      break;
45545
45546    // by process of elimination, at this point we know that `wat` must already be an object
45547    default:
45548      objectified = wat;
45549      break;
45550  }
45551  return objectified;
45552}
45553
45554exports.addNonEnumerableProperty = addNonEnumerableProperty;
45555exports.convertToPlainObject = convertToPlainObject;
45556exports.dropUndefinedKeys = dropUndefinedKeys;
45557exports.extractExceptionKeysForMessage = extractExceptionKeysForMessage;
45558exports.fill = fill;
45559exports.getOriginalFunction = getOriginalFunction;
45560exports.markFunctionWrapped = markFunctionWrapped;
45561exports.objectify = objectify;
45562exports.urlEncode = urlEncode;
45563
45564
45565},{"./browser.js":303,"./debug-build.js":313,"./is.js":329,"./logger.js":331,"./string.js":345}],339:[function(require,module,exports){
45566Object.defineProperty(exports, '__esModule', { value: true });
45567
45568// Slightly modified (no IE8 support, ES6) and transcribed to TypeScript
45569// https://github.com/calvinmetcalf/rollup-plugin-node-builtins/blob/63ab8aacd013767445ca299e468d9a60a95328d7/src/es6/path.js
45570//
45571// Copyright Joyent, Inc.and other Node contributors.
45572//
45573// Permission is hereby granted, free of charge, to any person obtaining a
45574// copy of this software and associated documentation files (the
45575// "Software"), to deal in the Software without restriction, including
45576// without limitation the rights to use, copy, modify, merge, publish,
45577// distribute, sublicense, and/or sell copies of the Software, and to permit
45578// persons to whom the Software is furnished to do so, subject to the
45579// following conditions:
45580//
45581// The above copyright notice and this permission notice shall be included
45582// in all copies or substantial portions of the Software.
45583//
45584// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
45585// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
45586// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
45587// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
45588// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
45589// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
45590// USE OR OTHER DEALINGS IN THE SOFTWARE.
45591
45592/** JSDoc */
45593function normalizeArray(parts, allowAboveRoot) {
45594  // if the path tries to go above the root, `up` ends up > 0
45595  let up = 0;
45596  for (let i = parts.length - 1; i >= 0; i--) {
45597    const last = parts[i];
45598    if (last === '.') {
45599      parts.splice(i, 1);
45600    } else if (last === '..') {
45601      parts.splice(i, 1);
45602      up++;
45603    } else if (up) {
45604      parts.splice(i, 1);
45605      up--;
45606    }
45607  }
45608
45609  // if the path is allowed to go above the root, restore leading ..s
45610  if (allowAboveRoot) {
45611    for (; up--; up) {
45612      parts.unshift('..');
45613    }
45614  }
45615
45616  return parts;
45617}
45618
45619// Split a filename into [root, dir, basename, ext], unix version
45620// 'root' is just a slash, or nothing.
45621const splitPathRe = /^(\S+:\\|\/?)([\s\S]*?)((?:\.{1,2}|[^/\\]+?|)(\.[^./\\]*|))(?:[/\\]*)$/;
45622/** JSDoc */
45623function splitPath(filename) {
45624  // Truncate files names greater than 1024 characters to avoid regex dos
45625  // https://github.com/getsentry/sentry-javascript/pull/8737#discussion_r1285719172
45626  const truncated = filename.length > 1024 ? `<truncated>${filename.slice(-1024)}` : filename;
45627  const parts = splitPathRe.exec(truncated);
45628  return parts ? parts.slice(1) : [];
45629}
45630
45631// path.resolve([from ...], to)
45632// posix version
45633/** JSDoc */
45634function resolve(...args) {
45635  let resolvedPath = '';
45636  let resolvedAbsolute = false;
vendor: 5,354 bytes, lines 45637-45841
45637
45638  for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
45639    const path = i >= 0 ? args[i] : '/';
45640
45641    // Skip empty entries
45642    if (!path) {
45643      continue;
45644    }
45645
45646    resolvedPath = `${path}/${resolvedPath}`;
45647    resolvedAbsolute = path.charAt(0) === '/';
45648  }
45649
45650  // At this point the path should be resolved to a full absolute path, but
45651  // handle relative paths to be safe (might happen when process.cwd() fails)
45652
45653  // Normalize the path
45654  resolvedPath = normalizeArray(
45655    resolvedPath.split('/').filter(p => !!p),
45656    !resolvedAbsolute,
45657  ).join('/');
45658
45659  return (resolvedAbsolute ? '/' : '') + resolvedPath || '.';
45660}
45661
45662/** JSDoc */
45663function trim(arr) {
45664  let start = 0;
45665  for (; start < arr.length; start++) {
45666    if (arr[start] !== '') {
45667      break;
45668    }
45669  }
45670
45671  let end = arr.length - 1;
45672  for (; end >= 0; end--) {
45673    if (arr[end] !== '') {
45674      break;
45675    }
45676  }
45677
45678  if (start > end) {
45679    return [];
45680  }
45681  return arr.slice(start, end - start + 1);
45682}
45683
45684// path.relative(from, to)
45685// posix version
45686/** JSDoc */
45687function relative(from, to) {
45688  /* eslint-disable no-param-reassign */
45689  from = resolve(from).slice(1);
45690  to = resolve(to).slice(1);
45691  /* eslint-enable no-param-reassign */
45692
45693  const fromParts = trim(from.split('/'));
45694  const toParts = trim(to.split('/'));
45695
45696  const length = Math.min(fromParts.length, toParts.length);
45697  let samePartsLength = length;
45698  for (let i = 0; i < length; i++) {
45699    if (fromParts[i] !== toParts[i]) {
45700      samePartsLength = i;
45701      break;
45702    }
45703  }
45704
45705  let outputParts = [];
45706  for (let i = samePartsLength; i < fromParts.length; i++) {
45707    outputParts.push('..');
45708  }
45709
45710  outputParts = outputParts.concat(toParts.slice(samePartsLength));
45711
45712  return outputParts.join('/');
45713}
45714
45715// path.normalize(path)
45716// posix version
45717/** JSDoc */
45718function normalizePath(path) {
45719  const isPathAbsolute = isAbsolute(path);
45720  const trailingSlash = path.slice(-1) === '/';
45721
45722  // Normalize the path
45723  let normalizedPath = normalizeArray(
45724    path.split('/').filter(p => !!p),
45725    !isPathAbsolute,
45726  ).join('/');
45727
45728  if (!normalizedPath && !isPathAbsolute) {
45729    normalizedPath = '.';
45730  }
45731  if (normalizedPath && trailingSlash) {
45732    normalizedPath += '/';
45733  }
45734
45735  return (isPathAbsolute ? '/' : '') + normalizedPath;
45736}
45737
45738// posix version
45739/** JSDoc */
45740function isAbsolute(path) {
45741  return path.charAt(0) === '/';
45742}
45743
45744// posix version
45745/** JSDoc */
45746function join(...args) {
45747  return normalizePath(args.join('/'));
45748}
45749
45750/** JSDoc */
45751function dirname(path) {
45752  const result = splitPath(path);
45753  const root = result[0];
45754  let dir = result[1];
45755
45756  if (!root && !dir) {
45757    // No dirname whatsoever
45758    return '.';
45759  }
45760
45761  if (dir) {
45762    // It has a dirname, strip trailing slash
45763    dir = dir.slice(0, dir.length - 1);
45764  }
45765
45766  return root + dir;
45767}
45768
45769/** JSDoc */
45770function basename(path, ext) {
45771  let f = splitPath(path)[2];
45772  if (ext && f.slice(ext.length * -1) === ext) {
45773    f = f.slice(0, f.length - ext.length);
45774  }
45775  return f;
45776}
45777
45778exports.basename = basename;
45779exports.dirname = dirname;
45780exports.isAbsolute = isAbsolute;
45781exports.join = join;
45782exports.normalizePath = normalizePath;
45783exports.relative = relative;
45784exports.resolve = resolve;
45785
45786
45787},{}],340:[function(require,module,exports){
45788Object.defineProperty(exports, '__esModule', { value: true });
45789
45790const error = require('./error.js');
45791const syncpromise = require('./syncpromise.js');
45792
45793/**
45794 * Creates an new PromiseBuffer object with the specified limit
45795 * @param limit max number of promises that can be stored in the buffer
45796 */
45797function makePromiseBuffer(limit) {
45798  const buffer = [];
45799
45800  function isReady() {
45801    return limit === undefined || buffer.length < limit;
45802  }
45803
45804  /**
45805   * Remove a promise from the queue.
45806   *
45807   * @param task Can be any PromiseLike<T>
45808   * @returns Removed promise.
45809   */
45810  function remove(task) {
45811    return buffer.splice(buffer.indexOf(task), 1)[0];
45812  }
45813
45814  /**
45815   * Add a promise (representing an in-flight action) to the queue, and set it to remove itself on fulfillment.
45816   *
45817   * @param taskProducer A function producing any PromiseLike<T>; In previous versions this used to be `task:
45818   *        PromiseLike<T>`, but under that model, Promises were instantly created on the call-site and their executor
45819   *        functions therefore ran immediately. Thus, even if the buffer was full, the action still happened. By
45820   *        requiring the promise to be wrapped in a function, we can defer promise creation until after the buffer
45821   *        limit check.
45822   * @returns The original promise.
45823   */
45824  function add(taskProducer) {
45825    if (!isReady()) {
45826      return syncpromise.rejectedSyncPromise(new error.SentryError('Not adding Promise because buffer limit was reached.'));
45827    }
45828
45829    // start the task and add its promise to the queue
45830    const task = taskProducer();
45831    if (buffer.indexOf(task) === -1) {
45832      buffer.push(task);
45833    }
45834    void task
45835      .then(() => remove(task))
45836      // Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike`
45837      // rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't
45838      // have promises, so TS has to polyfill when down-compiling.)
45839      .then(null, () =>
45840        remove(task).then(null, () => {
45841          // We have to add another catch here because `remove()` starts a new promise chain.
45842        }),
45843      );
45844    return task;
45845  }
45846
45847  /**
45848   * Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.
45849   *
45850   * @param timeout The time, in ms, after which to resolve to `false` if the queue is still non-empty. Passing `0` (or
45851   * not passing anything) will make the promise wait as long as it takes for the queue to drain before resolving to
45852   * `true`.
45853   * @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and
45854   * `false` otherwise
45855   */
45856  function drain(timeout) {
45857    return new syncpromise.SyncPromise((resolve, reject) => {
45858      let counter = buffer.length;
45859
45860      if (!counter) {
45861        return resolve(true);
45862      }
45863
45864      // wait for `timeout` ms and then resolve to `false` (if not cancelled first)
45865      const capturedSetTimeout = setTimeout(() => {
45866        if (timeout && timeout > 0) {
45867          resolve(false);
45868        }
45869      }, timeout);
45870
45871      // if all promises resolve in time, cancel the timer and resolve to `true`
45872      buffer.forEach(item => {
45873        void syncpromise.resolvedSyncPromise(item).then(() => {
45874          if (!--counter) {
45875            clearTimeout(capturedSetTimeout);
45876            resolve(true);
45877          }
45878        }, reject);
45879      });
45880    });
45881  }
45882
45883  return {
45884    $: buffer,
45885    add,
45886    drain,
45887  };
45888}
45889
45890exports.makePromiseBuffer = makePromiseBuffer;
45891
45892
45893},{"./error.js":317,"./syncpromise.js":347}],341:[function(require,module,exports){
45894Object.defineProperty(exports, '__esModule', { value: true });
45895
45896// Intentionally keeping the key broad, as we don't know for sure what rate limit headers get returned from backend
45897
45898const DEFAULT_RETRY_AFTER = 60 * 1000; // 60 seconds
45899
45900/**
45901 * Extracts Retry-After value from the request header or returns default value
45902 * @param header string representation of 'Retry-After' header
45903 * @param now current unix timestamp
45904 *
45905 */
45906function parseRetryAfterHeader(header, now = Date.now()) {
45907  const headerDelay = parseInt(`${header}`, 10);
45908  if (!isNaN(headerDelay)) {
45909    return headerDelay * 1000;
45910  }
45911
45912  const headerDate = Date.parse(`${header}`);
45913  if (!isNaN(headerDate)) {
45914    return headerDate - now;
45915  }
45916
45917  return DEFAULT_RETRY_AFTER;
45918}
45919
45920/**
45921 * Gets the time that the given category is disabled until for rate limiting.
45922 * In case no category-specific limit is set but a general rate limit across all categories is active,
45923 * that time is returned.
45924 *
45925 * @return the time in ms that the category is disabled until or 0 if there's no active rate limit.
45926 */
45927function disabledUntil(limits, category) {
45928  return limits[category] || limits.all || 0;
45929}
45930
45931/**
45932 * Checks if a category is rate limited
45933 */
45934function isRateLimited(limits, category, now = Date.now()) {
45935  return disabledUntil(limits, category) > now;
45936}
45937
45938/**
45939 * Update ratelimits from incoming headers.
45940 *
45941 * @return the updated RateLimits object.
45942 */
45943function updateRateLimits(
45944  limits,
45945  { statusCode, headers },
45946  now = Date.now(),
45947) {
45948  const updatedRateLimits = {
45949    ...limits,
45950  };
45951
45952  // "The name is case-insensitive."
45953  // https://developer.mozilla.org/en-US/docs/Web/API/Headers/get
45954  const rateLimitHeader = headers && headers['x-sentry-rate-limits'];
45955  const retryAfterHeader = headers && headers['retry-after'];
45956
45957  if (rateLimitHeader) {
45958    /**
45959     * rate limit headers are of the form
45960     *     <header>,<header>,..
45961     * where each <header> is of the form
45962     *     <retry_after>: <categories>: <scope>: <reason_code>
45963     * where
45964     *     <retry_after> is a delay in seconds
45965     *     <categories> is the event type(s) (error, transaction, etc) being rate limited and is of the form
45966     *         <category>;<category>;...
45967     *     <scope> is what's being limited (org, project, or key) - ignored by SDK
45968     *     <reason_code> is an arbitrary string like "org_quota" - ignored by SDK
45969     */
45970    for (const limit of rateLimitHeader.trim().split(',')) {
45971      const [retryAfter, categories] = limit.split(':', 2);
45972      const headerDelay = parseInt(retryAfter, 10);
45973      const delay = (!isNaN(headerDelay) ? headerDelay : 60) * 1000; // 60sec default
45974      if (!categories) {
45975        updatedRateLimits.all = now + delay;
45976      } else {
45977        for (const category of categories.split(';')) {
45978          updatedRateLimits[category] = now + delay;
45979        }
45980      }
45981    }
45982  } else if (retryAfterHeader) {
45983    updatedRateLimits.all = now + parseRetryAfterHeader(retryAfterHeader, now);
45984  } else if (statusCode === 429) {
45985    updatedRateLimits.all = now + 60 * 1000;
45986  }
45987
45988  return updatedRateLimits;
45989}
45990
45991exports.DEFAULT_RETRY_AFTER = DEFAULT_RETRY_AFTER;
45992exports.disabledUntil = disabledUntil;
45993exports.isRateLimited = isRateLimited;
45994exports.parseRetryAfterHeader = parseRetryAfterHeader;
45995exports.updateRateLimits = updateRateLimits;
45996
45997
45998},{}],342:[function(require,module,exports){
45999Object.defineProperty(exports, '__esModule', { value: true });
46000
46001const cookie = require('./cookie.js');
46002const debugBuild = require('./debug-build.js');
46003const is = require('./is.js');
46004const logger = require('./logger.js');
46005const normalize = require('./normalize.js');
46006const url = require('./url.js');
46007
46008const DEFAULT_INCLUDES = {
46009  ip: false,
46010  request: true,
46011  transaction: true,
46012  user: true,
46013};
46014const DEFAULT_REQUEST_INCLUDES = ['cookies', 'data', 'headers', 'method', 'query_string', 'url'];
46015const DEFAULT_USER_INCLUDES = ['id', 'username', 'email'];
46016
46017/**
46018 * Sets parameterized route as transaction name e.g.: `GET /users/:id`
46019 * Also adds more context data on the transaction from the request
46020 */
46021function addRequestDataToTransaction(
46022  transaction,
46023  req,
46024  deps,
46025) {
46026  if (!transaction) return;
46027  // eslint-disable-next-line deprecation/deprecation
46028  if (!transaction.metadata.source || transaction.metadata.source === 'url') {
46029    // Attempt to grab a parameterized route off of the request
46030    const [name, source] = extractPathForTransaction(req, { path: true, method: true });
46031    transaction.updateName(name);
46032    // TODO: SEMANTIC_ATTRIBUTE_SENTRY_SOURCE is in core, align this once we merge utils & core
46033    // eslint-disable-next-line deprecation/deprecation
46034    transaction.setMetadata({ source });
46035  }
46036  transaction.setAttribute('url', req.originalUrl || req.url);
46037  if (req.baseUrl) {
46038    transaction.setAttribute('baseUrl', req.baseUrl);
46039  }
46040  // TODO: We need to rewrite this to a flat format?
46041  // eslint-disable-next-line deprecation/deprecation
46042  transaction.setData('query', extractQueryParams(req, deps));
46043}
46044
46045/**
46046 * Extracts a complete and parameterized path from the request object and uses it to construct transaction name.
46047 * If the parameterized transaction name cannot be extracted, we fall back to the raw URL.
46048 *
46049 * Additionally, this function determines and returns the transaction name source
46050 *
vendor: 7,800 bytes, lines 46051-46315
46051 * eg. GET /mountpoint/user/:id
46052 *
46053 * @param req A request object
46054 * @param options What to include in the transaction name (method, path, or a custom route name to be
46055 *                used instead of the request's route)
46056 *
46057 * @returns A tuple of the fully constructed transaction name [0] and its source [1] (can be either 'route' or 'url')
46058 */
46059function extractPathForTransaction(
46060  req,
46061  options = {},
46062) {
46063  const method = req.method && req.method.toUpperCase();
46064
46065  let path = '';
46066  let source = 'url';
46067
46068  // Check to see if there's a parameterized route we can use (as there is in Express)
46069  if (options.customRoute || req.route) {
46070    path = options.customRoute || `${req.baseUrl || ''}${req.route && req.route.path}`;
46071    source = 'route';
46072  }
46073
46074  // Otherwise, just take the original URL
46075  else if (req.originalUrl || req.url) {
46076    path = url.stripUrlQueryAndFragment(req.originalUrl || req.url || '');
46077  }
46078
46079  let name = '';
46080  if (options.method && method) {
46081    name += method;
46082  }
46083  if (options.method && options.path) {
46084    name += ' ';
46085  }
46086  if (options.path && path) {
46087    name += path;
46088  }
46089
46090  return [name, source];
46091}
46092
46093/** JSDoc */
46094function extractTransaction(req, type) {
46095  switch (type) {
46096    case 'path': {
46097      return extractPathForTransaction(req, { path: true })[0];
46098    }
46099    case 'handler': {
46100      return (req.route && req.route.stack && req.route.stack[0] && req.route.stack[0].name) || '<anonymous>';
46101    }
46102    case 'methodPath':
46103    default: {
46104      // if exist _reconstructedRoute return that path instead of route.path
46105      const customRoute = req._reconstructedRoute ? req._reconstructedRoute : undefined;
46106      return extractPathForTransaction(req, { path: true, method: true, customRoute })[0];
46107    }
46108  }
46109}
46110
46111/** JSDoc */
46112function extractUserData(
46113  user
46114
46115,
46116  keys,
46117) {
46118  const extractedUser = {};
46119  const attributes = Array.isArray(keys) ? keys : DEFAULT_USER_INCLUDES;
46120
46121  attributes.forEach(key => {
46122    if (user && key in user) {
46123      extractedUser[key] = user[key];
46124    }
46125  });
46126
46127  return extractedUser;
46128}
46129
46130/**
46131 * Normalize data from the request object, accounting for framework differences.
46132 *
46133 * @param req The request object from which to extract data
46134 * @param options.include An optional array of keys to include in the normalized data. Defaults to
46135 * DEFAULT_REQUEST_INCLUDES if not provided.
46136 * @param options.deps Injected, platform-specific dependencies
46137 * @returns An object containing normalized request data
46138 */
46139function extractRequestData(
46140  req,
46141  options
46142
46143,
46144) {
46145  const { include = DEFAULT_REQUEST_INCLUDES, deps } = options || {};
46146  // eslint-disable-next-line @typescript-eslint/no-explicit-any
46147  const requestData = {};
46148
46149  // headers:
46150  //   node, express, koa, nextjs: req.headers
46151  const headers = (req.headers || {})
46152
46153;
46154  // method:
46155  //   node, express, koa, nextjs: req.method
46156  const method = req.method;
46157  // host:
46158  //   express: req.hostname in > 4 and req.host in < 4
46159  //   koa: req.host
46160  //   node, nextjs: req.headers.host
46161  // Express 4 mistakenly strips off port number from req.host / req.hostname so we can't rely on them
46162  // See: https://github.com/expressjs/express/issues/3047#issuecomment-236653223
46163  // Also: https://github.com/getsentry/sentry-javascript/issues/1917
46164  const host = headers.host || req.hostname || req.host || '<no host>';
46165  // protocol:
46166  //   node, nextjs: <n/a>
46167  //   express, koa: req.protocol
46168  const protocol = req.protocol === 'https' || (req.socket && req.socket.encrypted) ? 'https' : 'http';
46169  // url (including path and query string):
46170  //   node, express: req.originalUrl
46171  //   koa, nextjs: req.url
46172  const originalUrl = req.originalUrl || req.url || '';
46173  // absolute url
46174  const absoluteUrl = originalUrl.startsWith(protocol) ? originalUrl : `${protocol}://${host}${originalUrl}`;
46175  include.forEach(key => {
46176    switch (key) {
46177      case 'headers': {
46178        requestData.headers = headers;
46179
46180        // Remove the Cookie header in case cookie data should not be included in the event
46181        if (!include.includes('cookies')) {
46182          delete (requestData.headers ).cookie;
46183        }
46184
46185        break;
46186      }
46187      case 'method': {
46188        requestData.method = method;
46189        break;
46190      }
46191      case 'url': {
46192        requestData.url = absoluteUrl;
46193        break;
46194      }
46195      case 'cookies': {
46196        // cookies:
46197        //   node, express, koa: req.headers.cookie
46198        //   vercel, sails.js, express (w/ cookie middleware), nextjs: req.cookies
46199        requestData.cookies =
46200          // TODO (v8 / #5257): We're only sending the empty object for backwards compatibility, so the last bit can
46201          // come off in v8
46202          req.cookies || (headers.cookie && cookie.parseCookie(headers.cookie)) || {};
46203        break;
46204      }
46205      case 'query_string': {
46206        // query string:
46207        //   node: req.url (raw)
46208        //   express, koa, nextjs: req.query
46209        // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
46210        requestData.query_string = extractQueryParams(req, deps);
46211        break;
46212      }
46213      case 'data': {
46214        if (method === 'GET' || method === 'HEAD') {
46215          break;
46216        }
46217        // body data:
46218        //   express, koa, nextjs: req.body
46219        //
46220        //   when using node by itself, you have to read the incoming stream(see
46221        //   https://nodejs.dev/learn/get-http-request-body-data-using-nodejs); if a user is doing that, we can't know
46222        //   where they're going to store the final result, so they'll have to capture this data themselves
46223        if (req.body !== undefined) {
46224          requestData.data = is.isString(req.body) ? req.body : JSON.stringify(normalize.normalize(req.body));
46225        }
46226        break;
46227      }
46228      default: {
46229        if ({}.hasOwnProperty.call(req, key)) {
46230          requestData[key] = (req )[key];
46231        }
46232      }
46233    }
46234  });
46235
46236  return requestData;
46237}
46238
46239/**
46240 * Add data from the given request to the given event
46241 *
46242 * @param event The event to which the request data will be added
46243 * @param req Request object
46244 * @param options.include Flags to control what data is included
46245 * @param options.deps Injected platform-specific dependencies
46246 * @returns The mutated `Event` object
46247 */
46248function addRequestDataToEvent(
46249  event,
46250  req,
46251  options,
46252) {
46253  const include = {
46254    ...DEFAULT_INCLUDES,
46255    ...(options && options.include),
46256  };
46257
46258  if (include.request) {
46259    const extractedRequestData = Array.isArray(include.request)
46260      ? extractRequestData(req, { include: include.request, deps: options && options.deps })
46261      : extractRequestData(req, { deps: options && options.deps });
46262
46263    event.request = {
46264      ...event.request,
46265      ...extractedRequestData,
46266    };
46267  }
46268
46269  if (include.user) {
46270    const extractedUser = req.user && is.isPlainObject(req.user) ? extractUserData(req.user, include.user) : {};
46271
46272    if (Object.keys(extractedUser).length) {
46273      event.user = {
46274        ...event.user,
46275        ...extractedUser,
46276      };
46277    }
46278  }
46279
46280  // client ip:
46281  //   node, nextjs: req.socket.remoteAddress
46282  //   express, koa: req.ip
46283  if (include.ip) {
46284    const ip = req.ip || (req.socket && req.socket.remoteAddress);
46285    if (ip) {
46286      event.user = {
46287        ...event.user,
46288        ip_address: ip,
46289      };
46290    }
46291  }
46292
46293  if (include.transaction && !event.transaction) {
46294    // TODO do we even need this anymore?
46295    // TODO make this work for nextjs
46296    event.transaction = extractTransaction(req, include.transaction);
46297  }
46298
46299  return event;
46300}
46301
46302function extractQueryParams(
46303  req,
46304  deps,
46305) {
46306  // url (including path and query string):
46307  //   node, express: req.originalUrl
46308  //   koa, nextjs: req.url
46309  let originalUrl = req.originalUrl || req.url || '';
46310
46311  if (!originalUrl) {
46312    return;
46313  }
46314
46315  // The `URL` constructor can't handle internal URLs of the form `/some/p
46315ath/here`, so stick a dummy protocol and
46316  // hostname on the beginning. Since the point here is just to grab the query string, it doesn't matter what we use.
46317  if (originalUrl.startsWith('/')) {
46318    originalUrl = `http://dogs.are.great${originalUrl}`;
46319  }
46320
46321  try {
46322    return (
46323      req.query ||
46324      (typeof URL !== 'undefined' && new URL(originalUrl).search.slice(1)) ||
46325      // In Node 8, `URL` isn't in the global scope, so we have to use the built-in module from Node
46326      (deps && deps.url && deps.url.parse(originalUrl).query) ||
46327      undefined
46328    );
46329  } catch (e2) {
46330    return undefined;
46331  }
46332}
46333
46334/**
46335 * 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.
46336 * The header keys will be lower case: e.g. A "Content-Type" header will be stored as "content-type".
46337 */
46338// TODO(v8): Make this function return undefined when the extraction fails.
46339function winterCGHeadersToDict(winterCGHeaders) {
46340  const headers = {};
46341  try {
46342    winterCGHeaders.forEach((value, key) => {
46343      if (typeof value === 'string') {
46344        // We check that value is a string even though it might be redundant to make sure prototype pollution is not possible.
46345        headers[key] = value;
46346      }
46347    });
46348  } catch (e) {
46349    debugBuild.DEBUG_BUILD &&
46350      logger.logger.warn('Sentry failed extracting headers from a request object. If you see this, please file an issue.');
46351  }
46352
46353  return headers;
46354}
46355
46356/**
46357 * 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.
46358 */
46359function winterCGRequestToRequestData(req) {
46360  const headers = winterCGHeadersToDict(req.headers);
46361  return {
46362    method: req.method,
46363    url: req.url,
46364    headers,
46365  };
46366}
46367
46368exports.DEFAULT_USER_INCLUDES = DEFAULT_USER_INCLUDES;
46369exports.addRequestDataToEvent = addRequestDataToEvent;
46370exports.addRequestDataToTransaction = addRequestDataToTransaction;
46371exports.extractPathForTransaction = extractPathForTransaction;
46372exports.extractRequestData = extractRequestData;
46373exports.winterCGHeadersToDict = winterCGHeadersToDict;
46374exports.winterCGRequestToRequestData = winterCGRequestToRequestData;
46375
46376
46377},{"./cookie.js":312,"./debug-build.js":313,"./is.js":329,"./logger.js":331,"./normalize.js":337,"./url.js":350}],343:[function(require,module,exports){
46378Object.defineProperty(exports, '__esModule', { value: true });
46379
46380// Note: Ideally the `SeverityLevel` type would be derived from `validSeverityLevels`, but that would mean either
46381//
46382// a) moving `validSeverityLevels` to `@sentry/types`,
46383// b) moving the`SeverityLevel` type here, or
46384// c) importing `validSeverityLevels` from here into `@sentry/types`.
46385//
46386// Option A would make `@sentry/types` a runtime dependency of `@sentry/utils` (not good), and options B and C would
46387// create a circular dependency between `@sentry/types` and `@sentry/utils` (also not good). So a TODO accompanying the
46388// type, reminding anyone who changes it to change this list also, will have to do.
46389
46390const validSeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'];
46391
46392/**
46393 * Converts a string-based level into a member of the deprecated {@link Severity} enum.
46394 *
46395 * @deprecated `severityFromString` is deprecated. Please use `severityLevelFromString` instead.
46396 *
46397 * @param level String representation of Severity
46398 * @returns Severity
46399 */
46400function severityFromString(level) {
46401  return severityLevelFromString(level) ;
46402}
46403
46404/**
46405 * Converts a string-based level into a `SeverityLevel`, normalizing it along the way.
46406 *
46407 * @param level String representation of desired `SeverityLevel`.
46408 * @returns The `SeverityLevel` corresponding to the given string, or 'log' if the string isn't a valid level.
46409 */
46410function severityLevelFromString(level) {
46411  return (level === 'warn' ? 'warning' : validSeverityLevels.includes(level) ? level : 'log') ;
46412}
46413
46414exports.severityFromString = severityFromString;
46415exports.severityLevelFromString = severityLevelFromString;
46416exports.validSeverityLevels = validSeverityLevels;
46417
46418
46419},{}],344:[function(require,module,exports){
46420Object.defineProperty(exports, '__esModule', { value: true });
46421
46422const nodeStackTrace = require('./node-stack-trace.js');
46423
46424const STACKTRACE_FRAME_LIMIT = 50;
46425// Used to sanitize webpack (error: *) wrapped stack errors
46426const WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
46427const STRIP_FRAME_REGEXP = /captureMessage|captureException/;
46428
46429/**
46430 * Creates a stack parser with the supplied line parsers
46431 *
46432 * StackFrames are returned in the correct order for Sentry Exception
46433 * frames and with Sentry SDK internal frames removed from the top and bottom
46434 *
46435 */
46436function createStackParser(...parsers) {
46437  const sortedParsers = parsers.sort((a, b) => a[0] - b[0]).map(p => p[1]);
46438
46439  return (stack, skipFirst = 0) => {
46440    const frames = [];
46441    const lines = stack.split('\n');
46442
46443    for (let i = skipFirst; i < lines.length; i++) {
46444      const line = lines[i];
46445      // Ignore lines over 1kb as they are unlikely to be stack frames.
46446      // Many of the regular expressions use backtracking which results in run time that increases exponentially with
46447      // input size. Huge strings can result in hangs/Denial of Service:
46448      // https://github.com/getsentry/sentry-javascript/issues/2286
46449      if (line.length > 1024) {
46450        continue;
46451      }
46452
46453      // https://github.com/getsentry/sentry-javascript/issues/5459
46454      // Remove webpack (error: *) wrappers
46455      const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;
46456
46457      // https://github.com/getsentry/sentry-javascript/issues/7813
46458      // Skip Error: lines
46459      if (cleanedLine.match(/\S*Error: /)) {
46460        continue;
46461      }
46462
46463      for (const parser of sortedParsers) {
46464        const frame = parser(cleanedLine);
46465
46466        if (frame) {
46467          frames.push(frame);
46468          break;
46469        }
46470      }
46471
46472      if (frames.length >= STACKTRACE_FRAME_LIMIT) {
46473        break;
46474      }
46475    }
46476
46477    return stripSentryFramesAndReverse(frames);
46478  };
46479}
46480
46481/**
46482 * Gets a stack parser implementation from Options.stackParser
46483 * @see Options
46484 *
46485 * If options contains an array of line parsers, it is converted into a parser
46486 */
46487function stackParserFromStackParserOptions(stackParser) {
46488  if (Array.isArray(stackParser)) {
46489    return createStackParser(...stackParser);
46490  }
46491  return stackParser;
46492}
46493
46494/**
46495 * Removes Sentry frames from the top and bottom of the stack if present and enforces a limit of max number of frames.
46496 * Assumes stack input is ordered from top to bottom and returns the reverse representation so call site of the
46497 * function that caused the crash is the last frame in the array.
46498 * @hidden
46499 */
46500function stripSentryFramesAndReverse(stack) {
46501  if (!stack.length) {
46502    return [];
46503  }
46504
46505  const localStack = Array.from(stack);
46506
46507  // If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)
46508  if (/sentryWrapped/.test(localStack[localStack.length - 1].function || '')) {
46509    localStack.pop();
46510  }
46511
46512  // Reversing in the middle of the procedure allows us to just pop the values off the stack
46513  localStack.reverse();
46514
46515  // 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)
46516  if (STRIP_FRAME_REGEXP.test(localStack[localStack.length - 1].function || '')) {
46517    localStack.pop();
46518
46519    // When using synthetic events, we will have a 2 levels deep stack, as `new Error('Sentry syntheticException')`
46520    // is produced within the hub itself, making it:
46521    //
46522    //   Sentry.captureException()
46523    //   getCurrentHub().captureException()
46524    //
46525    // instead of just the top `Sentry` call itself.
46526    // This forces us to possibly strip an additional frame in the exact same was as above.
46527    if (STRIP_FRAME_REGEXP.test(localStack[localStack.length - 1].function || '')) {
46528      localStack.pop();
46529    }
46530  }
46531
46532  return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map(frame => ({
46533    ...frame,
46534    filename: frame.filename || localStack[localStack.length - 1].filename,
46535    function: frame.function || '?',
46536  }));
46537}
46538
46539const defaultFunctionName = '<anonymous>';
46540
46541/**
46542 * Safely extract function name from itself
46543 */
46544function getFunctionName(fn) {
46545  try {
46546    if (!fn || typeof fn !== 'function') {
46547      return defaultFunctionName;
46548    }
46549    return fn.name || defaultFunctionName;
46550  } catch (e) {
46551    // Just accessing custom props in some Selenium environments
46552    // can cause a "Permission denied" exception (see raven-js#495).
46553    return defaultFunctionName;
46554  }
46555}
46556
46557/**
46558 * Node.js stack line parser
46559 *
46560 * This is in @sentry/utils so it can be used from the Electron SDK in the browser for when `nodeIntegration == true`.
46561 * This allows it to be used without referencing or importing any node specific code which causes bundlers to complain
46562 */
46563function nodeStackLineParser(getModule) {
46564  return [90, nodeStackTrace.node(getModule)];
46565}
46566
46567exports.filenameIsInApp = nodeStackTrace.filenameIsInApp;
46568exports.createStackParser = createStackParser;
46569exports.getFunctionName = getFunctionName;
46570exports.nodeStackLineParser = nodeStackLineParser;
46571exports.stackParserFromStackParserOptions = stackParserFromStackParserOptions;
46572exports.stripSentryFramesAndReverse = stripSentryFramesAndReverse;
46573
46574
46575},{"./node-stack-trace.js":335}],345:[function(require,module,exports){
46576Object.defineProperty(exports, '__esModule', { value: true });
46577
46578const is = require('./is.js');
46579
46580/**
46581 * Truncates given string to the maximum characters count
46582 *
46583 * @param str An object that contains serializable values
46584 * @param max Maximum number of characters in truncated string (0 = unlimited)
46585 * @returns string Encoded
46586 */
46587function truncate(str, max = 0) {
46588  if (typeof str !== 'string' || max === 0) {
46589    return str;
46590  }
46591  return str.length <= max ? str : `${str.slice(0, max)}...`;
46592}
46593
46594/**
46595 * This is basically just `trim_line` from
46596 * https://github.com/getsentry/sentry/blob/master/src/sentry/lang/javascript/processor.py#L67
46597 *
46598 * @param str An object that contains serializable values
46599 * @param max Maximum number of characters in truncated string
46600 * @returns string Encoded
46601 */
46602function snipLine(line, colno) {
46603  let newLine = line;
46604  const lineLength = newLine.length;
46605  if (lineLength <= 150) {
46606    return newLine;
46607  }
46608  if (colno > lineLength) {
46609    // eslint-disable-next-line no-param-reassign
46610    colno = lineLength;
46611  }
46612
46613  let start = Math.max(colno - 60, 0);
46614  if (start < 5) {
46615    start = 0;
46616  }
46617
46618  let end = Math.min(start + 140, lineLength);
46619  if (end > lineLength - 5) {
46620    end = lineLength;
46621  }
46622  if (end === lineLength) {
46623    start = Math.max(end - 140, 0);
46624  }
46625
46626  newLine = newLine.slice(start, end);
46627  if (start > 0) {
46628    newLine = `'{snip} ${newLine}`;
46629  }
46630  if (end < lineLength) {
46631    newLine += ' {snip}';
46632  }
46633
46634  return newLine;
46635}
46636
46637/**
46638 * Join values in array
46639 * @param input array of values to be joined together
46640 * @param delimiter string to be placed in-between values
46641 * @returns Joined values
46642 */
46643// eslint-disable-next-line @typescript-eslint/no-explicit-any
46644function safeJoin(input, delimiter) {
46645  if (!Array.isArray(input)) {
46646    return '';
46647  }
46648
46649  const output = [];
46650  // eslint-disable-next-line @typescript-eslint/prefer-for-of
46651  for (let i = 0; i < input.length; i++) {
46652    const value = input[i];
46653    try {
46654      // This is a hack to fix a Vue3-specific bug that causes an infinite loop of
46655      // console warnings. This happens when a Vue template is rendered with
46656      // an undeclared variable, which we try to stringify, ultimately causing
46657      // Vue to issue another warning which repeats indefinitely.
46658      // see: https://github.com/getsentry/sentry-javascript/pull/8981
46659      if (is.isVueViewModel(value)) {
46660        output.push('[VueViewModel]');
46661      } else {
46662        output.push(String(value));
46663      }
46664    } catch (e) {
46665      output.push('[value cannot be serialized]');
46666    }
46667  }
46668
46669  return output.join(delimiter);
46670}
46671
46672/**
46673 * Checks if the given value matches a regex or string
46674 *
46675 * @param value The string to test
46676 * @param pattern Either a regex or a string against which `value` will be matched
46677 * @param requireExactStringMatch If true, `value` must match `pattern` exactly. If false, `value` will match
46678 * `pattern` if it contains `pattern`. Only applies to string-type patterns.
46679 */
46680function isMatchingPattern(
46681  value,
46682  pattern,
46683  requireExactStringMatch = false,
46684) {
46685  if (!is.isString(value)) {
46686    return false;
46687  }
46688
46689  if (is.isRegExp(pattern)) {
46690    return pattern.test(value);
46691  }
46692  if (is.isString(pattern)) {
46693    return requireExactStringMatch ? value === pattern : value.includes(pattern);
46694  }
46695
46696  return false;
46697}
46698
46699/**
46700 * Test the given string against an array of strings and regexes. By default, string matching is done on a
46701 * substring-inclusion basis rather than a strict equality basis
46702 *
46703 * @param testString The string to test
46704 * @param patterns The patterns against which to test the string
46705 * @param requireExactStringMatch If true, `testString` must match one of the given string patterns exactly in order to
46706 * count. If false, `testString` will match a string pattern if it contains that pattern.
46707 * @returns
46708 */
46709function stringMatchesSomePattern(
46710  testString,
46711  patterns = [],
46712  requireExactStringMatch = false,
46713) {
46714  return patterns.some(pattern => isMatchingPattern(testString, pattern, requireExactStringMatch));
46715}
46716
46717exports.isMatchingPattern = isMatchingPattern;
46718exports.safeJoin = safeJoin;
46719exports.snipLine = snipLine;
46720exports.stringMatchesSomePattern = stringMatchesSomePattern;
46721exports.truncate = truncate;
46722
46723
46724},{"./is.js":329}],346:[function(require,module,exports){
46725Object.defineProperty(exports, '__esModule', { value: true });
46726
46727const debugBuild = require('./debug-build.js');
46728const logger = require('./logger.js');
46729const worldwide = require('./worldwide.js');
46730
46731// eslint-disable-next-line deprecation/deprecation
46732const WINDOW = worldwide.getGlobalObject
vendor: 2,843 bytes, lines 46732-46847
46732();
46733
46734/**
46735 * Tells whether current environment supports ErrorEvent objects
46736 * {@link supportsErrorEvent}.
46737 *
46738 * @returns Answer to the given question.
46739 */
46740function supportsErrorEvent() {
46741  try {
46742    new ErrorEvent('');
46743    return true;
46744  } catch (e) {
46745    return false;
46746  }
46747}
46748
46749/**
46750 * Tells whether current environment supports DOMError objects
46751 * {@link supportsDOMError}.
46752 *
46753 * @returns Answer to the given question.
46754 */
46755function supportsDOMError() {
46756  try {
46757    // Chrome: VM89:1 Uncaught TypeError: Failed to construct 'DOMError':
46758    // 1 argument required, but only 0 present.
46759    // @ts-expect-error It really needs 1 argument, not 0.
46760    new DOMError('');
46761    return true;
46762  } catch (e) {
46763    return false;
46764  }
46765}
46766
46767/**
46768 * Tells whether current environment supports DOMException objects
46769 * {@link supportsDOMException}.
46770 *
46771 * @returns Answer to the given question.
46772 */
46773function supportsDOMException() {
46774  try {
46775    new DOMException('');
46776    return true;
46777  } catch (e) {
46778    return false;
46779  }
46780}
46781
46782/**
46783 * Tells whether current environment supports Fetch API
46784 * {@link supportsFetch}.
46785 *
46786 * @returns Answer to the given question.
46787 */
46788function supportsFetch() {
46789  if (!('fetch' in WINDOW)) {
46790    return false;
46791  }
46792
46793  try {
46794    new Headers();
46795    new Request('http://www.example.com');
46796    new Response();
46797    return true;
46798  } catch (e) {
46799    return false;
46800  }
46801}
46802/**
46803 * isNativeFetch checks if the given function is a native implementation of fetch()
46804 */
46805// eslint-disable-next-line @typescript-eslint/ban-types
46806function isNativeFetch(func) {
46807  return func && /^function fetch\(\)\s+\{\s+\[native code\]\s+\}$/.test(func.toString());
46808}
46809
46810/**
46811 * Tells whether current environment supports Fetch API natively
46812 * {@link supportsNativeFetch}.
46813 *
46814 * @returns true if `window.fetch` is natively implemented, false otherwise
46815 */
46816function supportsNativeFetch() {
46817  if (typeof EdgeRuntime === 'string') {
46818    return true;
46819  }
46820
46821  if (!supportsFetch()) {
46822    return false;
46823  }
46824
46825  // Fast path to avoid DOM I/O
46826  // eslint-disable-next-line @typescript-eslint/unbound-method
46827  if (isNativeFetch(WINDOW.fetch)) {
46828    return true;
46829  }
46830
46831  // window.fetch is implemented, but is polyfilled or already wrapped (e.g: by a chrome extension)
46832  // so create a "pure" iframe to see if that has native fetch
46833  let result = false;
46834  const doc = WINDOW.document;
46835  // eslint-disable-next-line deprecation/deprecation
46836  if (doc && typeof (doc.createElement ) === 'function') {
46837    try {
46838      const sandbox = doc.createElement('iframe');
46839      sandbox.hidden = true;
46840      doc.head.appendChild(sandbox);
46841      if (sandbox.contentWindow && sandbox.contentWindow.fetch) {
46842        // eslint-disable-next-line @typescript-eslint/unbound-method
46843        result = isNativeFetch(sandbox.contentWindow.fetch);
46844      }
46845      doc.head.removeChild(sandbox);
46846    } catch (err) {
46847      
vendor: 4,300 bytes, lines 46847-47015
46847debugBuild.DEBUG_BUILD &&
46848        logger.logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);
46849    }
46850  }
46851
46852  return result;
46853}
46854
46855/**
46856 * Tells whether current environment supports ReportingObserver API
46857 * {@link supportsReportingObserver}.
46858 *
46859 * @returns Answer to the given question.
46860 */
46861function supportsReportingObserver() {
46862  return 'ReportingObserver' in WINDOW;
46863}
46864
46865/**
46866 * Tells whether current environment supports Referrer Policy API
46867 * {@link supportsReferrerPolicy}.
46868 *
46869 * @returns Answer to the given question.
46870 */
46871function supportsReferrerPolicy() {
46872  // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default'
46873  // (see https://caniuse.com/#feat=referrer-policy),
46874  // it doesn't. And it throws an exception instead of ignoring this parameter...
46875  // REF: https://github.com/getsentry/raven-js/issues/1233
46876
46877  if (!supportsFetch()) {
46878    return false;
46879  }
46880
46881  try {
46882    new Request('_', {
46883      referrerPolicy: 'origin' ,
46884    });
46885    return true;
46886  } catch (e) {
46887    return false;
46888  }
46889}
46890
46891exports.isNativeFetch = isNativeFetch;
46892exports.supportsDOMError = supportsDOMError;
46893exports.supportsDOMException = supportsDOMException;
46894exports.supportsErrorEvent = supportsErrorEvent;
46895exports.supportsFetch = supportsFetch;
46896exports.supportsNativeFetch = supportsNativeFetch;
46897exports.supportsReferrerPolicy = supportsReferrerPolicy;
46898exports.supportsReportingObserver = supportsReportingObserver;
46899
46900
46901},{"./debug-build.js":313,"./logger.js":331,"./worldwide.js":354}],347:[function(require,module,exports){
46902Object.defineProperty(exports, '__esModule', { value: true });
46903
46904const is = require('./is.js');
46905
46906/* eslint-disable @typescript-eslint/explicit-function-return-type */
46907
46908/** SyncPromise internal states */
46909var States; (function (States) {
46910  /** Pending */
46911  const PENDING = 0; States[States["PENDING"] = PENDING] = "PENDING";
46912  /** Resolved / OK */
46913  const RESOLVED = 1; States[States["RESOLVED"] = RESOLVED] = "RESOLVED";
46914  /** Rejected / Error */
46915  const REJECTED = 2; States[States["REJECTED"] = REJECTED] = "REJECTED";
46916})(States || (States = {}));
46917
46918// Overloads so we can call resolvedSyncPromise without arguments and generic argument
46919
46920/**
46921 * Creates a resolved sync promise.
46922 *
46923 * @param value the value to resolve the promise with
46924 * @returns the resolved sync promise
46925 */
46926function resolvedSyncPromise(value) {
46927  return new SyncPromise(resolve => {
46928    resolve(value);
46929  });
46930}
46931
46932/**
46933 * Creates a rejected sync promise.
46934 *
46935 * @param value the value to reject the promise with
46936 * @returns the rejected sync promise
46937 */
46938function rejectedSyncPromise(reason) {
46939  return new SyncPromise((_, reject) => {
46940    reject(reason);
46941  });
46942}
46943
46944/**
46945 * Thenable class that behaves like a Promise and follows it's interface
46946 * but is not async internally
46947 */
46948class SyncPromise {
46949
46950   constructor(
46951    executor,
46952  ) {SyncPromise.prototype.__init.call(this);SyncPromise.prototype.__init2.call(this);SyncPromise.prototype.__init3.call(this);SyncPromise.prototype.__init4.call(this);
46953    this._state = States.PENDING;
46954    this._handlers = [];
46955
46956    try {
46957      executor(this._resolve, this._reject);
46958    } catch (e) {
46959      this._reject(e);
46960    }
46961  }
46962
46963  /** JSDoc */
46964   then(
46965    onfulfilled,
46966    onrejected,
46967  ) {
46968    return new SyncPromise((resolve, reject) => {
46969      this._handlers.push([
46970        false,
46971        result => {
46972          if (!onfulfilled) {
46973            // TODO: ¯\_(ツ)_/¯
46974            // TODO: FIXME
46975            resolve(result );
46976          } else {
46977            try {
46978              resolve(onfulfilled(result));
46979            } catch (e) {
46980              reject(e);
46981            }
46982          }
46983        },
46984        reason => {
46985          if (!onrejected) {
46986            reject(reason);
46987          } else {
46988            try {
46989              resolve(onrejected(reason));
46990            } catch (e) {
46991              reject(e);
46992            }
46993          }
46994        },
46995      ]);
46996      this._executeHandlers();
46997    });
46998  }
46999
47000  /** JSDoc */
47001   catch(
47002    onrejected,
47003  ) {
47004    return this.then(val => val, onrejected);
47005  }
47006
47007  /** JSDoc */
47008   finally(onfinally) {
47009    return new SyncPromise((resolve, reject) => {
47010      let val;
47011      let isRejected;
47012
47013      return this.then(
47014        value => {
47015          isRejected = false;
47016          val = value;
47017          if (onfinally) {
47018            onfinally();
47019          }
47020        },
47021        reason => {
47022          isRejected = true;
47023          val = reason;
47024          if (onfinally) {
47025            onfinally();
47026          }
47027        },
47028      ).then(() => {
47029        if (isRejected) {
47030          reject(val);
47031          return;
47032        }
47033
47034        resolve(val );
47035      });
47036    });
47037  }
47038
47039  /** JSDoc */
47040    __init() {this._resolve = (value) => {
47041    this._setResult(States.RESOLVED, value);
47042  };}
47043
47044  /** JSDoc */
47045    __init2() {this._reject = (reason) => {
47046    this._setResult(States.REJECTED, reason);
47047  };}
47048
47049  /** JSDoc */
47050    __init3() {this._setResult = (state, value) => {
47051    if (this._state !== States.PENDING) {
47052      return;
47053    }
47054
47055    if (is.isThenable(value)) {
47056      void (value ).then(this._resolve, this._reject);
47057      return;
47058    }
47059
47060    this._state = state;
47061    this._value = value;
47062
47063    this._executeHandlers();
47064  };}
47065
47066  /** JSDoc */
47067    __init4() {this._executeHandlers = () => {
47068    if (this._state === States.PENDING) {
47069      return;
47070    }
47071
47072    const cachedHandlers = this._handlers.slice();
47073    this._handlers = [];
47074
47075    cachedHandlers.forEach(handler => {
47076      if (handler[0]) {
47077        return;
47078      }
47079
47080      if (this._state === States.RESOLVED) {
47081        // eslint-disable-next-line @typescript-eslint/no-floating-promises
47082        handler[1](this._value );
47083      }
47084
47085      if (this._state === States.REJECTED) {
47086        handler[2](this._value);
47087      }
47088
47089      handler[0] = true;
47090    });
47091  };}
47092}
47093
47094exports.SyncPromise = SyncPromise;
47095exports.rejectedSyncPromise = rejectedSyncPromise;
47096exports.resolvedSyncPromise = resolvedSyncPromise;
47097
47098
47099},{"./is.js":329}],348:[function(require,module,exports){
47100Object.defineProperty(exports, '__esModule', { value: true });
47101
47102const worldwide = require('./worldwide.js');
47103
47104const ONE_SECOND_IN_MS = 1000;
47105
47106/**
47107 * A partial definition of the [Performance Web API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Performance}
47108 * for accessing a high-resolution monotonic clock.
47109 */
47110
47111/**
47112 * Returns a timestamp in seconds since the UNIX epoch using the Date API.
47113 *
47114 * TODO(v8): Return type should be rounded.
47115 */
47116function dateTimestampInSeconds() {
47117  return Date.now() / ONE_SECOND_IN_MS;
47118}
47119
47120/**
47121 * Returns a wrapper around the native Performance API browser implementation, or undefined for browsers that do not
47122 * support the API.
47123 *
47124 * Wrapping the native API works around differences in behavior from different browsers.
47125 */
47126function createUnixTimestampInSecondsFunc() {
47127  const { performance } = worldwide.GLOBAL_OBJ ;
47128  if (!performance || !performance.now) {
47129    return dateTimestampInSeconds;
47130  }
47131
47132  // Some browser and environments don't have a timeOrigin, so we fallback to
47133  // using Date.now() to compute the starting time.
47134  const approxStartingTimeOrigin = Date.now() - performance.now();
47135  const timeOrigin = performance.timeOrigin == undefined ? approxStartingTimeOrigin : performance.timeOrigin;
47136
47137  // performance.now() is a monotonic clock, which means it starts at 0 when the process begins. To get the current
47138  // wall clock time (actual UNIX timestamp), we need to add the starting time origin and the current time elapsed.
47139  //
47140  // TODO: This does not account for the case where the monotonic clock that powers performance.now() drifts from the
47141  // wall clock time, which causes the returned timestamp to be inaccurate. We should investigate how to detect and
47142  // correct for this.
47143  // See: https://github.com/getsentry/sentry-javascript/issues/2590
47144  // See: https://github.com/mdn/content/issues/4713
47145  // See: https://dev.to/noamr/when-a-millisecond-is-not-a-millisecond-3h6
47146  return () => {
47147    return (timeOrigin + performance.now()) / ONE_SECOND_IN_MS;
47148  };
47149}
47150
47151/**
47152 * Returns a timestamp in seconds since the UNIX epoch using either the Performance or Date APIs, depending on the
47153 * availability of the Performance API.
47154 *
47155 * BUG: Note that because of how browsers implement the Performance API, the clock might stop when the computer is
47156 * asleep. This creates a skew between `dateTimestampInSeconds` and `timestampInSeconds`. The
47157 * skew can grow to arbitrary amounts like days, weeks or months.
47158 * See https://github.com/getsentry/sentry-javascript/issues/2590.
47159 */
47160const timestampInSeconds = createUnixTimestampInSecondsFunc();
47161
47162/**
47163 * Re-exported with an old name for backwards-compatibility.
47164 * TODO (v8): Remove this
47165 *
47166 * @deprecated Use `timestampInSeconds` instead.
47167 */
47168const timestampWithMs = timestampInSeconds;
47169
47170/**
47171 * Internal helper to store what is the source of browserPerformanceTimeOrigin below. For debugging only.
47172 */
47173exports._browserPerformanceTimeOriginMode = void 0;
47174
47175/**
47176 * The number of milliseconds since the UNIX epoch. This value is only usable in a browser, and only when the
47177 * performance API is available.
47178 */
47179const browserPerformanceTimeOrigin = (() => {
47180  // Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or
47181  // performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin
47182  // data as reliable if they are within a reasonable threshold of the current time.
47183
47184  const { performance } = worldwide.GLOBAL_OBJ ;
47185  if (!performance || !performance.now) {
47186    exports._browserPerformanceTimeOriginMode = 'none';
47187    return undefined;
47188  }
47189
47190  const threshold = 3600 * 1000;
47191  const performanceNow = performance.now();
47192  const dateNow = Date.now();
47193
47194  // if timeOrigin isn't available set delta to threshold so it isn't used
47195  const timeOriginDelta = performance.timeOrigin
47196    ? Math.abs(performance.timeOrigin + performanceNow - dateNow)
47197    : threshold;
47198  const timeOriginIsReliable = timeOriginDelta < threshold;
47199
47200  // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin
47201  // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.
47202  // Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always
47203  // a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the
47204  // Date API.
47205  // eslint-disable-next-line deprecation/deprecation
47206  const navigationStart = performance.timing && performance.timing.navigationStart;
47207  const hasNavigationStart = typeof navigationStart === 'number';
47208  // if navigationStart isn't available set delta to threshold so it isn't used
47209  const navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold;
47210  const navigationStartIsReliable = navigationStartDelta < threshold;
47211
47212  if (timeOriginIsReliable || navigationStartIsReliable) {
47213    // Use the more reliable time origin
47214    if (timeOriginDelta <= navigationStartDelta) {
47215      exports._browserPerformanceTimeOriginMode = 'timeOrigin';
47216      return performance.timeOrigin;
47217    } else {
47218      exports._browserPerformanceTimeOriginMode = 'navigationStart';
47219      return navigationStart;
47220    }
47221  }
47222
47223  // Either both timeOrigin and navigationStart are skewed or neither is available, fallback to Date.
47224  exports._browserPerformanceTimeOriginMode = 'dateNow';
47225  return dateNow;
47226})();
47227
47228exports.browserPerformanceTimeOrigin = browserPerformanceTimeOrigin;
47229exports.dateTimestampInSeconds = dateTimestampInSeconds;
47230exports.timestampInSeconds = timestampInSeconds;
47231exports.timestampWithMs = timestampWithMs;
47232
47233
47234},{"./worldwide.js":354}],349:[function(require,module,exports){
47235Object.defineProperty(exports, '__esModule', { value: true });
47236
47237const baggage = require('./baggage.js');
47238const misc = require('./misc.js');
47239
47240// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- RegExp is used for readability here
47241const TRACEPARENT_REGEXP = new RegExp(
47242  '^[ \\t]*' + // whitespace
47243    '([0-9a-f]{32})?' + // trace_id
47244    '-?([0-9a-f]{16})?' + // span_id
47245    '-?([01])?' + // sampled
47246    '[ \\t]*$', // whitespace
47247);
47248
47249/**
47250 * Extract transaction context data from a `sentry-trace` header.
47251 *
47252 * @param traceparent Traceparent string
47253 *
47254 * @returns Object containing data from the header, or undefined if traceparent string is malformed
47255 */
47256function extractTraceparentData(traceparent) {
47257  if (!traceparent) {
47258    return undefined;
47259  }
47260
47261  const matches = traceparent.match(TRACEPARENT_REGEXP);
47262  if (!matches) {
47263    return undefined;
47264  }
47265
47266  let parentSampled;
47267  if (matches[3] === '1') {
47268    parentSampled = true;
47269  } else if (matches[3] === '0') {
47270    parentSampled = false;
47271  }
47272
47273  return {
47274    traceId: matches[1],
47275    parentSampled,
47276    parentSpanId: matches[2],
47277  };
47278}
47279
47280/**
47281 * Create tracing context from incoming headers.
47282 *
47283 * @deprecated Use `propagationContextFromHeaders` instead.
47284 */
47285// TODO(v8): Remove this function
47286function tracingContextFromHeaders(
47287  sentryTrace,
47288  baggage$1,
47289)
47290
47291 {
47292  const traceparentData = extractTraceparentData(sentryTrace);
47293  const dynamicSamplingContext = baggage.baggageHeaderToDynamicSamplingContext(baggage$1);
47294
47295  const { traceId, parentSpanId, parentSampled } = traceparentData || {};
47296
47297  if (!traceparentData) {
47298    return {
47299      traceparentData,
47300      dynamicSamplingContext: undefined,
47301      propagationContext: {
47302        traceId: traceId || misc.uuid4(),
47303        spanId: misc.uuid4().substring(16),
47304      },
47305    };
47306  } else {
47307    return {
47308      traceparentData,
47309      dynamicSamplingContext: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it
47310      propagationContext: {
47311        traceId: traceId || misc.uuid4(),
47312        parentSpanId: parentSpanId || misc.uuid4().substring(16),
47313        spanId: misc.uuid4().substring(16),
47314        sampled: parentSampled,
47315        dsc: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it
47316      },
47317    };
47318  }
47319}
47320
47321/**
47322 * Create a propagation context from incoming headers.
47323 */
47324function propagationContextFromHeaders(
47325  sentryTrace,
47326  baggage$1,
47327) {
47328  const traceparentData = extractTraceparentData(sentryTrace);
47329  const dynamicSamplingContext = baggage.baggageHeaderToDynamicSamplingContext(baggage$1);
47330
47331  const { traceId, parentSpanId, parentSampled } = traceparentData || {};
47332
47333  if (!traceparentData) {
47334    return {
47335      traceId: traceId || misc.uuid4(),
47336      spanId: misc.uuid4().substring(16),
47337    };
47338  } else {
47339    return {
47340      traceId: traceId || misc.uuid4(),
47341      parentSpanId: parentSpanId || misc.uuid4().substring(16),
47342      spanId: misc.uuid4().substring(16),
47343      sampled: parentSampled,
47344      dsc: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it
47345    };
47346  }
47347}
47348
47349/**
47350 * Create sentry-trace header from span context values.
47351 */
47352function generateSentryTraceHeader(
47353  traceId = misc.uuid4(),
47354  spanId = misc.uuid4().substring(16),
47355  sampled,
47356) {
47357  let sampledString = '';
47358  if (sampled !== undefined) {
47359    sampledString = sampled ? '-1' : '-0';
47360  }
47361  return `${traceId}-${spanId}${sampledString}`;
47362}
47363
47364exports.TRACEPARENT_REGEXP = TRACEPARENT_REGEXP;
47365exports.extractTraceparentData = extractTraceparentData;
47366exports.generateSentryTraceHeader = generateSentryTraceHeader;
47367exports.propagationContextFromHeaders = propagationContextFromHeaders;
47368exports.tracingContextFromHeaders = tracingContextFromHeaders;
47369
47370
47371},{"./baggage.js":302,"./misc.js":334}],350:[function(require,module,exports){
47372Object.defineProperty(exports, '__esModule', { value: true });
47373
47374/**
47375 * Parses string form of URL into an object
47376 * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
47377 * // intentionally using regex and not <a/> href parsing trick because React Native and other
47378 * // environments where DOM might not be available
47379 * @returns parsed URL object
47380 */
47381function parseUrl(url) {
47382  if (!url) {
47383    return {};
47384  }
47385
47386  const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
47387
47388  if (!match) {
47389    return {};
47390  }
47391
47392  // coerce to undefined values to empty string so we don't get 'undefined'
47393  const query = match[6] || '';
47394  const fragment = match[8] || '';
47395  return {
47396    host: match[4],
47397    path: match[5],
47398    protocol: match[2],
47399    search: query,
47400    hash: fragment,
47401    relative: match[5] + query + fragment, // everything minus origin
47402  };
47403}
47404
47405/**
47406 * Strip the query string and fragment off of a given URL or path (if present)
47407 *
47408 * @param urlPath Full URL or path, including possible query string and/or fragment
47409 * @returns URL or path without query string or fragment
47410 */
47411function stripUrlQueryAndFragment(urlPath) {
47412  // eslint-disable-next-line no-useless-escape
47413  return urlPath.split(/[\?#]/, 1)[0];
47414}
47415
47416/**
47417 * Returns number of URL segments of a passed string URL.
47418 */
47419function getNumberOfUrlSegments(url) {
47420  // split at '/' or at '\/' to split regex urls correctly
47421  return url.split(/\\?\//).filter(s => s.length > 0 && s !== ',').length;
47422}
47423
47424/**
47425 * Takes a URL object and returns a sanitized string which is safe to use as span description
47426 * see: https://develop.sentry.dev/sdk/data-handling/#structuring-d
47426ata
47427 */
47428function getSanitizedUrlString(url) {
47429  const { protocol, host, path } = url;
47430
47431  const filteredHost =
47432    (host &&
47433      host
47434        // Always filter out authority
47435        .replace(/^.*@/, '[filtered]:[filtered]@')
47436        // Don't show standard :80 (http) and :443 (https) ports to reduce the noise
47437        // TODO: Use new URL global if it exists
47438        .replace(/(:80)$/, '')
47439        .replace(/(:443)$/, '')) ||
47440    '';
47441
47442  return `${protocol ? `${protocol}://` : ''}${filteredHost}${path}`;
47443}
47444
47445exports.getNumberOfUrlSegments = getNumberOfUrlSegments;
47446exports.getSanitizedUrlString = getSanitizedUrlString;
47447exports.parseUrl = parseUrl;
47448exports.stripUrlQueryAndFragment = stripUrlQueryAndFragment;
47449
47450
47451},{}],351:[function(require,module,exports){
47452Object.defineProperty(exports, '__esModule', { value: true });
47453
47454/**
47455 * Recursively traverses an object to update an existing nested key.
47456 * Note: The provided key path must include existing properties,
47457 * the function will not create objects while traversing.
47458 *
47459 * @param obj An object to update
47460 * @param value The value to update the nested key with
47461 * @param keyPath The path to the key to update ex. fizz.buzz.foo
47462 */
47463// eslint-disable-next-line @typescript-eslint/no-explicit-any
47464function setNestedKey(obj, keyPath, value) {
47465  // Ex. foo.bar.zoop will extract foo and bar.zoop
47466  const match = keyPath.match(/([a-z_]+)\.(.*)/i);
47467  // 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
47468  if (match === null) {
47469    obj[keyPath] = value;
47470  } else {
47471    // `match[1]` is the initial segment of the path, and `match[2]` is the remainder of the path
47472    const innerObj = obj[match[1]];
47473    setNestedKey(innerObj, match[2], value);
47474  }
47475}
47476
47477/**
47478 * Enforces inclusion of a given integration with specified options in an integration array originally determined by the
47479 * user, by either including the given default instance or by patching an existing user instance with the given options.
47480 *
47481 * Ideally this would happen when integrations are set up, but there isn't currently a mechanism there for merging
47482 * options from a default integration instance with those from a user-provided instance of the same integration, only
47483 * for allowing the user to override a default instance entirely. (TODO: Fix that.)
47484 *
47485 * @param defaultIntegrationInstance An instance of the integration with the correct options already set
47486 * @param userIntegrations Integrations defined by the user.
47487 * @param forcedOptions Options with which to patch an existing user-derived instance on the integration.
47488 * @returns A final integrations array.
47489 *
47490 * @deprecated This will be removed in v8.
47491 */
47492function addOrUpdateIntegration(
47493  defaultIntegrationInstance,
47494  userIntegrations,
47495  forcedOptions = {},
47496) {
47497  return (
47498    Array.isArray(userIntegrations)
47499      ? addOrUpdateIntegrationInArray(defaultIntegrationInstance, userIntegrations, forcedOptions)
47500      : addOrUpdateIntegrationInFunction(
47501          defaultIntegrationInstance,
47502          // Somehow TS can't figure out that not being an array makes this necessarily a function
47503          userIntegrations ,
47504          forcedOptions,
47505        )
47506  ) ;
47507}
47508
47509function addOrUpdateIntegrationInArray(
47510  defaultIntegrationInstance,
47511  userIntegrations,
47512  forcedOptions,
47513) {
47514  const userInstance = userIntegrations.find(integration => integration.name === defaultIntegrationInstance.name);
47515
47516  if (userInstance) {
47517    for (const [keyPath, value] of Object.entries(forcedOptions)) {
47518      setNestedKey(userInstance, keyPath, value);
47519    }
47520
47521    return userIntegrations;
47522  }
47523
47524  return [...userIntegrations, defaultIntegrationInstance];
47525}
47526
47527function addOrUpdateIntegrationInFunction(
47528  defaultIntegrationInstance,
47529  userIntegrationsFunc,
47530  forcedOptions,
47531) {
47532  const wrapper = defaultIntegrations => {
47533    const userFinalIntegrations = userIntegrationsFunc(defaultIntegrations);
47534
47535    // There are instances where we want the user to be able to prevent an integration from appearing at all, which they
47536    // would do by providing a function which filters out the integration in question. If that's happened in one of
47537    // those cases, don't add our default back in.
47538    if (defaultIntegrationInstance.allowExclusionByUser) {
47539      const userFinalInstance = userFinalIntegrations.find(
47540        integration => integration.name === defaultIntegrationInstance.name,
47541      );
47542      if (!userFinalInstance) {
47543        return userFinalIntegrations;
47544      }
47545    }
47546
47547    return addOrUpdateIntegrationInArray(defaultIntegrationInstance, userFinalIntegrations, forcedOptions);
47548  };
47549
47550  return wrapper;
47551}
47552
47553exports.addOrUpdateIntegration = addOrUpdateIntegration;
47554
47555
47556},{}],352:[function(require,module,exports){
47557Object.defineProperty(exports, '__esModule', { value: true });
47558
47559// Based on https://github.com/sindresorhus/escape-string-regexp but with modifications to:
47560//   a) reduce the size by skipping the runtime type - checking
47561//   b) ensure it gets down - compiled for old versions of Node(the published package only supports Node 12+).
47562//
47563// MIT License
47564//
47565// Copyright (c) Sindre Sorhus <[email protected]> (https://sindresorhus.com)
47566//
47567// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
47568// documentation files(the "Software"), to deal in the Software without restriction, including without limitation
47569// the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and
47570// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
47571//
47572// The above copyright notice and this permission notice shall be included in all copies or substantial portions of
47573// the Software.
47574//
47575// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
47576// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
47577// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47578// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
47579// IN THE SOFTWARE.
47580
47581/**
47582 * Given a string, escape characters which have meaning in the regex grammar, such that the result is safe to feed to
47583 * `new RegExp()`.
47584 *
47585 * @param regexString The string to escape
47586 * @returns An version of the string with all special regex characters escaped
47587 */
47588function escapeStringForRegex(regexString) {
47589  // escape the hyphen separately so we can also replace it with a unicode literal hyphen, to avoid the problems
47590  // discussed in https://github.com/sindresorhus/escape-string-regexp/issues/20.
47591  return regexString.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d');
47592}
47593
47594exports.escapeStringForRegex = escapeStringForRegex;
47595
47596
47597},{}],353:[function(require,module,exports){
47598Object.defineProperty(exports, '__esModule', { value: true });
47599
47600const worldwide = require('../worldwide.js');
47601
47602// Based on https://github.com/angular/angular.js/pull/13945/files
47603
47604// eslint-disable-next-line deprecation/deprecation
47605const WINDOW = worldwide.getGlobalObject();
47606
47607/**
47608 * Tells whether current environment supports History API
47609 * {@link supportsHistory}.
47610 *
47611 * @returns Answer to the given question.
47612 */
47613function supportsHistory() {
47614  // NOTE: in Chrome App environment, touching history.pushState, *even inside
47615  //       a try/catch block*, will cause Chrome to output an error to console.error
47616  // borrowed from: https://github.com/angular/angular.js/pull/13945/files
47617  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
47618  // eslint-disable-next-line @typescript-eslint/no-explicit-any
47619  const chromeVar = (WINDOW ).chrome;
47620  const isChromePackagedApp = chromeVar && chromeVar.app && chromeVar.app.runtime;
47621  /* eslint-enable @typescript-eslint/no-unsafe-member-access */
47622  const hasHistoryApi = 'history' in WINDOW && !!WINDOW.history.pushState && !!WINDOW.history.replaceState;
47623
47624  return !isChromePackagedApp && hasHistoryApi;
47625}
47626
47627exports.supportsHistory = supportsHistory;
47628
47629
47630},{"../worldwide.js":354}],354:[function(require,module,exports){
47631(function (global){(function (){
47632Object.defineProperty(exports, '__esModule', { value: true });
47633
47634/** Internal global with common properties and Sentry extensions  */
47635
47636// The code below for 'isGlobalObj' and 'GLOBAL_OBJ' was copied from core-js before modification
47637// https://github.com/zloirock/core-js/blob/1b944df55282cdc99c90db5f49eb0b6eda2cc0a3/packages/core-js/internals/global.js
47638// core-js has the following licence:
47639//
47640// Copyright (c) 2014-2022 Denis Pushkarev
47641//
47642// Permission is hereby granted, free of charge, to any person obtaining a copy
47643// of this software and associated documentation files (the "Software"), to deal
47644// in the Software without restriction, including without limitation the rights
47645// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
47646// copies of the Software, and to permit persons to whom the Software is
47647// furnished to do so, subject to the following conditions:
47648//
47649// The above copyright notice and this permission notice shall be included in
47650// all copies or substantial portions of the Software.
47651//
47652// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47653// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47654// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47655// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47656// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47657// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47658// THE SOFTWARE.
47659
47660/** Returns 'obj' if it's the global object, otherwise returns undefined */
47661function isGlobalObj(obj) {
47662  return obj && obj.Math == Math ? obj : undefined;
47663}
47664
47665/** Get's the global object for the current JavaScript runtime */
47666const GLOBAL_OBJ =
47667  (typeof globalThis == 'object' && isGlobalObj(globalThis)) ||
47668  // eslint-disable-next-line no-restricted-globals
47669  (typeof window == 'object' && isGlobalObj(window)) ||
47670  (typeof self == 'object' && isGlobalObj(self)) ||
47671  (typeof global == 'object' && isGlobalObj(global)) ||
47672  (function () {
47673    return this;
47674  })() ||
47675  {};
47676
47677/**
47678 * @deprecated Use GLOBAL_OBJ instead or WINDOW from @sentry/browser. This will be removed in v8
47679 */
47680function getGlobalObject() {
47681  return GLOBAL_OBJ ;
47682}
47683
47684/**
47685 * Returns a global singleton contained in the global `__SENTRY__` object.
47686 *
47687 * If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory
47688 * function and added to the `__SENTRY__` object.
47689 *
47690 * @param name name of the global singleton on __SENTRY__
47691 * @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__`
47692 * @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `GLOBAL_OBJ`'s return value
47693 * @returns the singleton
47694 */
47695function getGlobalSingleton(name, creator, obj) {
47696  const gbl = (obj || GLOBAL_OBJ) ;
47697  const __SENTRY__ = (gbl.__SENTRY__ = gbl.__SENTRY__ || {});
47698  const singleton = __SENTRY__[name] || (__SENTRY__[name] = creator());
47699  return singleton;
47700}
47701
47702exports.GLOBAL_OBJ = GLOBAL_OBJ;
47703exports.getGlobalObject = getGlobalObject;
47704exports.getGlobalSingleton = getGlobalSingleton;
47705
47706
47707}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
47708},{}],355:[function(require,module,exports){
47709(function (global){(function (){
vendor: 14,672 bytes, lines 47709-48243
47709
47710/*! https://mths.be/punycode v1.4.1 by @mathias */
47711;(function(root) {
47712
47713	/** Detect free variables */
47714	var freeExports = typeof exports == 'object' && exports &&
47715		!exports.nodeType && exports;
47716	var freeModule = typeof module == 'object' && module &&
47717		!module.nodeType && module;
47718	var freeGlobal = typeof global == 'object' && global;
47719	if (
47720		freeGlobal.global === freeGlobal ||
47721		freeGlobal.window === freeGlobal ||
47722		freeGlobal.self === freeGlobal
47723	) {
47724		root = freeGlobal;
47725	}
47726
47727	/**
47728	 * The `punycode` object.
47729	 * @name punycode
47730	 * @type Object
47731	 */
47732	var punycode,
47733
47734	/** Highest positive signed 32-bit float value */
47735	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
47736
47737	/** Bootstring parameters */
47738	base = 36,
47739	tMin = 1,
47740	tMax = 26,
47741	skew = 38,
47742	damp = 700,
47743	initialBias = 72,
47744	initialN = 128, // 0x80
47745	delimiter = '-', // '\x2D'
47746
47747	/** Regular expressions */
47748	regexPunycode = /^xn--/,
47749	regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
47750	regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
47751
47752	/** Error messages */
47753	errors = {
47754		'overflow': 'Overflow: input needs wider integers to process',
47755		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
47756		'invalid-input': 'Invalid input'
47757	},
47758
47759	/** Convenience shortcuts */
47760	baseMinusTMin = base - tMin,
47761	floor = Math.floor,
47762	stringFromCharCode = String.fromCharCode,
47763
47764	/** Temporary variable */
47765	key;
47766
47767	/*--------------------------------------------------------------------------*/
47768
47769	/**
47770	 * A generic error utility function.
47771	 * @private
47772	 * @param {String} type The error type.
47773	 * @returns {Error} Throws a `RangeError` with the applicable error message.
47774	 */
47775	function error(type) {
47776		throw new RangeError(errors[type]);
47777	}
47778
47779	/**
47780	 * A generic `Array#map` utility function.
47781	 * @private
47782	 * @param {Array} array The array to iterate over.
47783	 * @param {Function} callback The function that gets called for every array
47784	 * item.
47785	 * @returns {Array} A new array of values returned by the callback function.
47786	 */
47787	function map(array, fn) {
47788		var length = array.length;
47789		var result = [];
47790		while (length--) {
47791			result[length] = fn(array[length]);
47792		}
47793		return result;
47794	}
47795
47796	/**
47797	 * A simple `Array#map`-like wrapper to work with domain name strings or email
47798	 * addresses.
47799	 * @private
47800	 * @param {String} domain The domain name or email address.
47801	 * @param {Function} callback The function that gets called for every
47802	 * character.
47803	 * @returns {Array} A new string of characters returned by the callback
47804	 * function.
47805	 */
47806	function mapDomain(string, fn) {
47807		var parts = string.split('@');
47808		var result = '';
47809		if (parts.length > 1) {
47810			// In email addresses, only the domain name should be punycoded. Leave
47811			// the local part (i.e. everything up to `@`) intact.
47812			result = parts[0] + '@';
47813			string = parts[1];
47814		}
47815		// Avoid `split(regex)` for IE8 compatibility. See #17.
47816		string = string.replace(regexSeparators, '\x2E');
47817		var labels = string.split('.');
47818		var encoded = map(labels, fn).join('.');
47819		return result + encoded;
47820	}
47821
47822	/**
47823	 * Creates an array containing the numeric code points of each Unicode
47824	 * character in the string. While JavaScript uses UCS-2 internally,
47825	 * this function will convert a pair of surrogate halves (each of which
47826	 * UCS-2 exposes as separate characters) into a single code point,
47827	 * matching UTF-16.
47828	 * @see `punycode.ucs2.encode`
47829	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
47830	 * @memberOf punycode.ucs2
47831	 * @name decode
47832	 * @param {String} string The Unicode input string (UCS-2).
47833	 * @returns {Array} The new array of code points.
47834	 */
47835	function ucs2decode(string) {
47836		var output = [],
47837		    counter = 0,
47838		    length = string.length,
47839		    value,
47840		    extra;
47841		while (counter < length) {
47842			value = string.charCodeAt(counter++);
47843			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
47844				// high surrogate, and there is a next character
47845				extra = string.charCodeAt(counter++);
47846				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
47847					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
47848				} else {
47849					// unmatched surrogate; only append this code unit, in case the next
47850					// code unit is the high surrogate of a surrogate pair
47851					output.push(value);
47852					counter--;
47853				}
47854			} else {
47855				output.push(value);
47856			}
47857		}
47858		return output;
47859	}
47860
47861	/**
47862	 * Creates a string based on an array of numeric code points.
47863	 * @see `punycode.ucs2.decode`
47864	 * @memberOf punycode.ucs2
47865	 * @name encode
47866	 * @param {Array} codePoints The array of numeric code points.
47867	 * @returns {String} The new Unicode string (UCS-2).
47868	 */
47869	function ucs2encode(array) {
47870		return map(array, function(value) {
47871			var output = '';
47872			if (value > 0xFFFF) {
47873				value -= 0x10000;
47874				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
47875				value = 0xDC00 | value & 0x3FF;
47876			}
47877			output += stringFromCharCode(value);
47878			return output;
47879		}).join('');
47880	}
47881
47882	/**
47883	 * Converts a basic code point into a digit/integer.
47884	 * @see `digitToBasic()`
47885	 * @private
47886	 * @param {Number} codePoint The basic numeric code point value.
47887	 * @returns {Number} The numeric value of a basic code point (for use in
47888	 * representing integers) in the range `0` to `base - 1`, or `base` if
47889	 * the code point does not represent a value.
47890	 */
47891	function basicToDigit(codePoint) {
47892		if (codePoint - 48 < 10) {
47893			return codePoint - 22;
47894		}
47895		if (codePoint - 65 < 26) {
47896			return codePoint - 65;
47897		}
47898		if (codePoint - 97 < 26) {
47899			return codePoint - 97;
47900		}
47901		return base;
47902	}
47903
47904	/**
47905	 * Converts a digit/integer into a basic code point.
47906	 * @see `basicToDigit()`
47907	 * @private
47908	 * @param {Number} digit The numeric value of a basic code point.
47909	 * @returns {Number} The basic code point whose value (when used for
47910	 * representing integers) is `digit`, which needs to be in the range
47911	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
47912	 * used; else, the lowercase form is used. The behavior is undefined
47913	 * if `flag` is non-zero and `digit` has no uppercase form.
47914	 */
47915	function digitToBasic(digit, flag) {
47916		//  0..25 map to ASCII a..z or A..Z
47917		// 26..35 map to ASCII 0..9
47918		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
47919	}
47920
47921	/**
47922	 * Bias adaptation function as per section 3.4 of RFC 3492.
47923	 * https://tools.ietf.org/html/rfc3492#section-3.4
47924	 * @private
47925	 */
47926	function adapt(delta, numPoints, firstTime) {
47927		var k = 0;
47928		delta = firstTime ? floor(delta / damp) : delta >> 1;
47929		delta += floor(delta / numPoints);
47930		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
47931			delta = floor(delta / baseMinusTMin);
47932		}
47933		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
47934	}
47935
47936	/**
47937	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
47938	 * symbols.
47939	 * @memberOf punycode
47940	 * @param {String} input The Punycode string of ASCII-only symbols.
47941	 * @returns {String} The resulting string of Unicode symbols.
47942	 */
47943	function decode(input) {
47944		// Don't use UCS-2
47945		var output = [],
47946		    inputLength = input.length,
47947		    out,
47948		    i = 0,
47949		    n = initialN,
47950		    bias = initialBias,
47951		    basic,
47952		    j,
47953		    index,
47954		    oldi,
47955		    w,
47956		    k,
47957		    digit,
47958		    t,
47959		    /** Cached calculation results */
47960		    baseMinusT;
47961
47962		// Handle the basic code points: let `basic` be the number of input code
47963		// points before the last delimiter, or `0` if there is none, then copy
47964		// the first basic code points to the output.
47965
47966		basic = input.lastIndexOf(delimiter);
47967		if (basic < 0) {
47968			basic = 0;
47969		}
47970
47971		for (j = 0; j < basic; ++j) {
47972			// if it's not a basic code point
47973			if (input.charCodeAt(j) >= 0x80) {
47974				error('not-basic');
47975			}
47976			output.push(input.charCodeAt(j));
47977		}
47978
47979		// Main decoding loop: start just after the last delimiter if any basic code
47980		// points were copied; start at the beginning otherwise.
47981
47982		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
47983
47984			// `index` is the index of the next character to be consumed.
47985			// Decode a generalized variable-length integer into `delta`,
47986			// which gets added to `i`. The overflow checking is easier
47987			// if we increase `i` as we go, then subtract off its starting
47988			// value at the end to obtain `delta`.
47989			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
47990
47991				if (index >= inputLength) {
47992					error('invalid-input');
47993				}
47994
47995				digit = basicToDigit(input.charCodeAt(index++));
47996
47997				if (digit >= base || digit > floor((maxInt - i) / w)) {
47998					error('overflow');
47999				}
48000
48001				i += digit * w;
48002				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
48003
48004				if (digit < t) {
48005					break;
48006				}
48007
48008				baseMinusT = base - t;
48009				if (w > floor(maxInt / baseMinusT)) {
48010					error('overflow');
48011				}
48012
48013				w *= baseMinusT;
48014
48015			}
48016
48017			out = output.length + 1;
48018			bias = adapt(i - oldi, out, oldi == 0);
48019
48020			// `i` was supposed to wrap around from `out` to `0`,
48021			// incrementing `n` each time, so we'll fix that now:
48022			if (floor(i / out) > maxInt - n) {
48023				error('overflow');
48024			}
48025
48026			n += floor(i / out);
48027			i %= out;
48028
48029			// Insert `n` at position `i` of the output
48030			output.splice(i++, 0, n);
48031
48032		}
48033
48034		return ucs2encode(output);
48035	}
48036
48037	/**
48038	 * Converts a string of Unicode symbols (e.g. a domain name label) to a
48039	 * Punycode string of ASCII-only symbols.
48040	 * @memberOf punycode
48041	 * @param {String} input The string of Unicode symbols.
48042	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
48043	 */
48044	function encode(input) {
48045		var n,
48046		    delta,
48047		    handledCPCount,
48048		    basicLength,
48049		    bias,
48050		    j,
48051		    m,
48052		    q,
48053		    k,
48054		    t,
48055		    currentValue,
48056		    output = [],
48057		    /** `inputLength` will hold the number of code points in `input`. */
48058		    inputLength,
48059		    /** Cached calculation results */
48060		    handledCPCountPlusOne,
48061		    baseMinusT,
48062		    qMinusT;
48063
48064		// Convert the input in UCS-2 to Unicode
48065		input = ucs2decode(input);
48066
48067		// Cache the length
48068		inputLength = input.length;
48069
48070		// Initialize the state
48071		n = initialN;
48072		delta = 0;
48073		bias = initialBias;
48074
48075		// Handle the basic code points
48076		for (j = 0; j < inputLength; ++j) {
48077			currentValue = input[j];
48078			if (currentValue < 0x80) {
48079				output.push(stringFromCharCode(currentValue));
48080			}
48081		}
48082
48083		handledCPCount = basicLength = output.length;
48084
48085		// `handledCPCount` is the number of code points that have been handled;
48086		// `basicLength` is the number of basic code points.
48087
48088		// Finish the basic string - if it is not empty - with a delimiter
48089		if (basicLength) {
48090			output.push(delimiter);
48091		}
48092
48093		// Main encoding loop:
48094		while (handledCPCount < inputLength) {
48095
48096			// All non-basic code points < n have been handled already. Find the next
48097			// larger one:
48098			for (m = maxInt, j = 0; j < inputLength; ++j) {
48099				currentValue = input[j];
48100				if (currentValue >= n && currentValue < m) {
48101					m = currentValue;
48102				}
48103			}
48104
48105			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
48106			// but guard against overflow
48107			handledCPCountPlusOne = handledCPCount + 1;
48108			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
48109				error('overflow');
48110			}
48111
48112			delta += (m - n) * handledCPCountPlusOne;
48113			n = m;
48114
48115			for (j = 0; j < inputLength; ++j) {
48116				currentValue = input[j];
48117
48118				if (currentValue < n && ++delta > maxInt) {
48119					error('overflow');
48120				}
48121
48122				if (currentValue == n) {
48123					// Represent delta as a generalized variable-length integer
48124					for (q = delta, k = base; /* no condition */; k += base) {
48125						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
48126						if (q < t) {
48127							break;
48128						}
48129						qMinusT = q - t;
48130						baseMinusT = base - t;
48131						output.push(
48132							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
48133						);
48134						q = floor(qMinusT / baseMinusT);
48135					}
48136
48137					output.push(stringFromCharCode(digitToBasic(q, 0)));
48138					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
48139					delta = 0;
48140					++handledCPCount;
48141				}
48142			}
48143
48144			++delta;
48145			++n;
48146
48147		}
48148		return output.join('');
48149	}
48150
48151	/**
48152	 * Converts a Punycode string representing a domain name or an email address
48153	 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
48154	 * it doesn't matter if you call it on a string that has already been
48155	 * converted to Unicode.
48156	 * @memberOf punycode
48157	 * @param {String} input The Punycoded domain name or email address to
48158	 * convert to Unicode.
48159	 * @returns {String} The Unicode representation of the given Punycode
48160	 * string.
48161	 */
48162	function toUnicode(input) {
48163		return mapDomain(input, function(string) {
48164			return regexPunycode.test(string)
48165				? decode(string.slice(4).toLowerCase())
48166				: string;
48167		});
48168	}
48169
48170	/**
48171	 * Converts a Unicode string representing a domain name or an email address to
48172	 * Punycode. Only the non-ASCII parts of the domain name will be converted,
48173	 * i.e. it doesn't matter if you call it with a domain that's already in
48174	 * ASCII.
48175	 * @memberOf punycode
48176	 * @param {String} input The domain name or email address to convert, as a
48177	 * Unicode string.
48178	 * @returns {String} The Punycode representation of the given domain name or
48179	 * email address.
48180	 */
48181	function toASCII(input) {
48182		return mapDomain(input, function(string) {
48183			return regexNonASCII.test(string)
48184				? 'xn--' + encode(string)
48185				: string;
48186		});
48187	}
48188
48189	/*--------------------------------------------------------------------------*/
48190
48191	/** Define the public API */
48192	punycode = {
48193		/**
48194		 * A string representing the current Punycode.js version number.
48195		 * @memberOf punycode
48196		 * @type String
48197		 */
48198		'version': '1.4.1',
48199		/**
48200		 * An object of methods to convert from JavaScript's internal character
48201		 * representation (UCS-2) to Unicode code points, and back.
48202		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
48203		 * @memberOf punycode
48204		 * @type Object
48205		 */
48206		'ucs2': {
48207			'decode': ucs2decode,
48208			'encode': ucs2encode
48209		},
48210		'decode': decode,
48211		'encode': encode,
48212		'toASCII': toASCII,
48213		'toUnicode': toUnicode
48214	};
48215
48216	/** Expose `punycode` */
48217	// Some AMD build optimizers, like r.js, check for specific condition patterns
48218	// like the following:
48219	if (
48220		typeof define == 'function' &&
48221		typeof define.amd == 'object' &&
48222		define.amd
48223	) {
48224		define('punycode', function() {
48225			return punycode;
48226		});
48227	} else if (freeExports && freeModule) {
48228		if (module.exports == freeExports) {
48229			// in Node.js, io.js, or RingoJS v0.8.0+
48230			freeModule.exports = punycode;
48231		} else {
48232			// in Narwhal or RingoJS v0.7.0-
48233			for (key in punycode) {
48234				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
48235			}
48236		}
48237	} else {
48238		// in Rhino or a web browser
48239		root.punycode = punycode;
48240	}
48241
48242}(this));
48243
vendor: 4,425 bytes, lines 48244-48424
48244}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
48245},{}],356:[function(require,module,exports){
48246/*
48247 * classList.js: Cross-browser full element.classList implementation.
48248 * 1.1.20170427
48249 *
48250 * By Eli Grey, http://eligrey.com
48251 * License: Dedicated to the public domain.
48252 *   See https://github.com/eligrey/classList.js/blob/master/LICENSE.md
48253 */
48254
48255/*global self, document, DOMException */
48256
48257/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
48258
48259if ("document" in window.self) {
48260
48261// Full polyfill for browsers with no classList support
48262// Including IE < Edge missing SVGElement.classList
48263if (!("classList" in document.createElement("_")) 
48264	|| document.createElementNS && !("classList" in document.createElementNS("http://www.w3.org/2000/svg","g"))) {
48265
48266(function (view) {
48267
48268"use strict";
48269
48270if (!('Element' in view)) return;
48271
48272var
48273	  classListProp = "classList"
48274	, protoProp = "prototype"
48275	, elemCtrProto = view.Element[protoProp]
48276	, objCtr = Object
48277	, strTrim = String[protoProp].trim || function () {
48278		return this.replace(/^\s+|\s+$/g, "");
48279	}
48280	, arrIndexOf = Array[protoProp].indexOf || function (item) {
48281		var
48282			  i = 0
48283			, len = this.length
48284		;
48285		for (; i < len; i++) {
48286			if (i in this && this[i] === item) {
48287				return i;
48288			}
48289		}
48290		return -1;
48291	}
48292	// Vendors: please allow content code to instantiate DOMExceptions
48293	, DOMEx = function (type, message) {
48294		this.name = type;
48295		this.code = DOMException[type];
48296		this.message = message;
48297	}
48298	, checkTokenAndGetIndex = function (classList, token) {
48299		if (token === "") {
48300			throw new DOMEx(
48301				  "SYNTAX_ERR"
48302				, "An invalid or illegal string was specified"
48303			);
48304		}
48305		if (/\s/.test(token)) {
48306			throw new DOMEx(
48307				  "INVALID_CHARACTER_ERR"
48308				, "String contains an invalid character"
48309			);
48310		}
48311		return arrIndexOf.call(classList, token);
48312	}
48313	, ClassList = function (elem) {
48314		var
48315			  trimmedClasses = strTrim.call(elem.getAttribute("class") || "")
48316			, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
48317			, i = 0
48318			, len = classes.length
48319		;
48320		for (; i < len; i++) {
48321			this.push(classes[i]);
48322		}
48323		this._updateClassName = function () {
48324			elem.setAttribute("class", this.toString());
48325		};
48326	}
48327	, classListProto = ClassList[protoProp] = []
48328	, classListGetter = function () {
48329		return new ClassList(this);
48330	}
48331;
48332// Most DOMException implementations don't allow calling DOMException's toString()
48333// on non-DOMExceptions. Error's toString() is sufficient here.
48334DOMEx[protoProp] = Error[protoProp];
48335classListProto.item = function (i) {
48336	return this[i] || null;
48337};
48338classListProto.contains = function (token) {
48339	token += "";
48340	return checkTokenAndGetIndex(this, token) !== -1;
48341};
48342classListProto.add = function () {
48343	var
48344		  tokens = arguments
48345		, i = 0
48346		, l = tokens.length
48347		, token
48348		, updated = false
48349	;
48350	do {
48351		token = tokens[i] + "";
48352		if (checkTokenAndGetIndex(this, token) === -1) {
48353			this.push(token);
48354			updated = true;
48355		}
48356	}
48357	while (++i < l);
48358
48359	if (updated) {
48360		this._updateClassName();
48361	}
48362};
48363classListProto.remove = function () {
48364	var
48365		  tokens = arguments
48366		, i = 0
48367		, l = tokens.length
48368		, token
48369		, updated = false
48370		, index
48371	;
48372	do {
48373		token = tokens[i] + "";
48374		index = checkTokenAndGetIndex(this, token);
48375		while (index !== -1) {
48376			this.splice(index, 1);
48377			updated = true;
48378			index = checkTokenAndGetIndex(this, token);
48379		}
48380	}
48381	while (++i < l);
48382
48383	if (updated) {
48384		this._updateClassName();
48385	}
48386};
48387classListProto.toggle = function (token, force) {
48388	token += "";
48389
48390	var
48391		  result = this.contains(token)
48392		, method = result ?
48393			force !== true && "remove"
48394		:
48395			force !== false && "add"
48396	;
48397
48398	if (method) {
48399		this[method](token);
48400	}
48401
48402	if (force === true || force === false) {
48403		return force;
48404	} else {
48405		return !result;
48406	}
48407};
48408classListProto.toString = function () {
48409	return this.join(" ");
48410};
48411
48412if (objCtr.defineProperty) {
48413	var classListPropDesc = {
48414		  get: classListGetter
48415		, enumerable: true
48416		, configurable: true
48417	};
48418	try {
48419		objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
48420	} catch (ex) { // IE 8 doesn't support enumerable:true
48421		// adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36
48422		// modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected
48423		if (ex.number === undefined || ex.number === -0x7FF5EC54) {
48424			classListPropDesc.enumerable = false;
48425			objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
48426		}
48427	}
48428} else if (objCtr[protoProp].__defineGetter__) {
48429	elemCtrProto.__defineGetter__(classListProp, classListGetter);
48430}
48431
48432}(window.self));
48433
48434}
48435
48436// There is full or partial native classList support, so just check if we need
48437// to normalize the add/remove and toggle APIs.
48438
48439(function () {
48440	"use strict";
48441
48442	var testElement = document.createElement("_");
48443
48444	testElement.classList.add("c1", "c2");
48445
48446	// Polyfill for IE 10/11 and Firefox <26, where classList.add and
48447	// classList.remove exist but support only one argument at a time.
48448	if (!testElement.classList.contains("c2")) {
48449		var createMethod = function(method) {
48450			var original = DOMTokenList.prototype[method];
48451
48452			DOMTokenList.prototype[method] = function(token) {
48453				var i, len = arguments.length;
48454
48455				for (i = 0; i < len; i++) {
48456					token = arguments[i];
48457					original.call(this, token);
48458				}
48459			};
48460		};
48461		createMethod('add');
48462		createMethod('remove');
48463	}
48464
48465	testElement.classList.toggle("c3", false);
48466
48467	// Polyfill for IE 10 and Firefox <24, where classList.toggle does not
48468	// support the second argument.
48469	if (testElement.classList.contains("c3")) {
48470		var _toggle = DOMTokenList.prototype.toggle;
48471
48472		DOMTokenList.prototype.toggle = function(token, force) {
48473			if (1 in arguments && !this.contains(token) === !force) {
48474				return force;
48475			} else {
48476				return _toggle.call(this, token);
48477			}
48478		};
48479
48480	}
48481
48482	testElement = null;
48483}());
48484
48485}
48486
48487},{}],357:[function(require,module,exports){
48488module.exports = function(arr, obj){
48489  if (arr.indexOf) return arr.indexOf(obj);
48490  for (var i = 0; i < arr.length; ++i) {
48491    if (arr[i] === obj) return i;
48492  }
48493  return -1;
48494};
48495},{}],358:[function(require,module,exports){
48496'use strict';
48497
48498require('./index').polyfill();
48499
48500},{"./index":359}],359:[function(require,module,exports){
48501/**
48502 * Code refactored from Mozilla Developer Network:
48503 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
48504 */
48505
48506'use strict';
48507
48508function assign(target, firstSource) {
48509  if (target === undefined || target === null) {
48510    throw new TypeError('Cannot convert first argument to object');
48511  }
48512
48513  var to = Object(target);
48514  for (var i = 1; i < arguments.length; i++) {
48515    var nextSource = arguments[i];
48516    if (nextSource === undefined || nextSource === null) {
48517      continue;
48518    }
48519
48520    var keysArray = Object.keys(Object(nextSource));
48521    for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
48522      var nextKey = keysArray[nextIndex];
48523      var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
48524      if (desc !== undefined && desc.enumerable) {
48525        to[nextKey] = nextSource[nextKey];
48526      }
48527    }
48528  }
48529  return to;
48530}
48531
48532function polyfill() {
48533  if (!Object.assign) {
48534    Object.defineProperty(Object, 'assign', {
48535      enumerable: false,
48536      configurable: true,
48537      writable: true,
48538      value: assign
48539    });
48540  }
48541}
48542
48543module.exports = {
48544  assign: assign,
48545  polyfill: polyfill
48546};
48547
48548},{}],360:[function(require,module,exports){
48549(function (process){(function (){
48550"use strict";Object.defineProperties(exports,{t:{value:!0},[Symbol.toStringTag]:{value:"Module"}});class t{constructor(t,s,e,r=t<<16|s<<8|e){this.i=1,this.o=-1,this.h=-1,this.u=-1,this.l=-1,this.M=t,this.g=s,this.p=e,this.m=r}static distance(t,s){return(Math.abs(s.M-t.M)+Math.abs(s.g-t.g)+Math.abs(s.p-t.p))/765}clone(){const s=new t(this.M,this.g,this.p,this.m);return s.i=this.i,s}$(){const t=this.M/255,s=this.g/255,e=this.p/255,r=Math.max(t,s,e),n=Math.min(t,s,e);if(this.u=(r+n)/2,r===n)this.h=0,this.o=0,this.l=0;else{const i=r-n;switch(this.o=this.u>.5?i/(2-r-n):i/(r+n),this.l=this.o*(2*(.5-Math.abs(.5-this.u))),r){case t:this.h=((s-e)/i+(s<e?6:0))/6;break;case s:this.h=((e-t)/i+2)/6;break;case e:this.h=((t-s)/i+4)/6}}}get C(){return-1===this.h&&this.$(),this.h}get v(){return-1===this.o&&this.$(),this.o}get j(){return-1===this.u&&this.$(),this.u}get D(){return-1===this.l&&this.$(),this.l}}const s=(t,s)=>Math.abs(t-s);class e{constructor(){this.N=[],this.S=null}I(t){this.N.push(t),this.S=null}O(t,e,r,n){for(let h=0;h<this.N.length;h++){const a=this.N[h];if(!(i=a.C,o=t.C,Math.min(s(i,o),s((i+.5)%1,(o+.5)%1))<e&&s(a.v,t.v)<r&&s(a.j,t.j)<n))return!1}var i,o;return!0}get _(){if(!this.S){const{r:s,L:e,b:r}=this.N.reduce(((t,s)=>(t.r+=s.M,t.L+=s.g,t.b+=s.p,t)),{r:0,L:0,b:0}),n=this.N.reduce(((t,s)=>t+s.i),0);this.S=new t(Math.round(s/this.N.length),Math.round(e/this.N.length),Math.round(r/this.N.length)),this.S.i=n}return this.S}}
48550class r{constructor(t,s,e){this.P=[],this.C=t,this.v=s,this.j=e}I(t){const s=this.P.find((s=>s.O(t,this.C,this.v,this.j)));if(s)s.I(t);else{const s=new e;s.I(t),this.P.push(s)}}F(){return this.P.map((t=>t._))}}var n=({pixels:t=64e3,distance:s=.22,colorValidator:e=((t,s,e,r)=>(null!=r?r:255)>250),hueDistance:r=.08333333333333333,saturationDistance:n=.2,lightnessDistance:i=.2,crossOrigin:o=null}={})=>{if("production"!==process.env.NODE_ENV){const o=(t,s,e=0,r=Number.MAX_VALUE)=>{if(Number(s)!==s)throw new Error(`${t} is not a valid number (${s})`);return s<e&&console.warn(`${t} can not be less than ${e} (it's ${s})`),s>r&&console.warn(`${t} can not be more than ${r} (it's ${s})`),Math.min(Math.max(s,e),r)},h=(t,s)=>{if(!s||"[object Function]"!=={}.toString.call(s))throw new Error(`${t} is not a function (${s})`);return s};((t,s,e=0,r=Number.MAX_SAFE_INTEGER)=>{if(!Number.isInteger(s))throw new Error(`${t} is not a valid number (${s})`);return s<e&&console.warn(`${t} can not be less than ${e} (it's ${s})`),s>r&&console.warn(`${t} can not be more than ${r} (it's ${s})`),Math.min(Math.max(s,e),r)})("pixels",t||0,1),o("distance",s,0,1),h("colorValidator",e),o("hueDistance",r,0,1),o("saturationDistance",n,0,1),o("lightnessDistance",i,0,1)}return[Math.max(t,1),Math.min(Math.max(s,0),1),e,Math.min(Math.max(r,0),1),Math.min(Math.max(n,0),1),Math.min(Math.max(i,0),1),o]};class i{constructor(){this.i=0,this.k={}}I(s,e,r,n){return this.i++,this.k[s]?this.k[s].i++:this.k[s]=new t(e,r,n,s),this.k[s]}G(){return Object.keys(this.k).map((t=>this.k[t]))}H(){const t=this.G().reduce(((t,s)=>t.i>=s.i?t:s)).clone();return t.i=this.i,t}}class o{constructor(){this.i=0,this.k={}}G(){return Object.keys(this.k).map((t=>this.k[t]))}I(t,s,e){const r=t<<16|s<<8|e,n=(t>>4&15)<<8|(s>>4&15)<<4|e>>4&15;return this.i++,this.V(n).I(r,t,s,e)}V(t){return this.k[t]||(this.k[t]=new i),this.k[t]}T(s){const e=this.G().map((t=>t.H()));e.sort(((t,s)=>s.i-t.i));const r=[];for(;e.length;){const n=e.shift();e.filter((e=>t.distance(n,e)<s)).forEach((t=>{n.i+=t.i;const s=e.findIndex((s=>s===t));e.splice(s,1)})),r.push(n)}return r}}var h=({data:t,width:s,height:e},r,n,i)=>{const h=new o,a=s&&e&&Math.floor(s*e/r)||1;let c=0;for(let o=0;o<t.length;o+=4*a){const s=t[o],e=t[o+1],r=t[o+2];i(s,e,r,t[o+3])?h.I(s,e,r):c++}return{N:h.T(n),count:h.i+c}};const a=()=>"undefined"!=typeof window,c=(t,s,e,n,i)=>{const o=((t,s,e,n,i)=>{const o=new r(e,n,i);t.forEach((t=>o.I(t)));const h=o.F();return h.sort(((t,e)=>(e.D+.1)*(.9-e.i/s)-(t.D+.1)*(.9-t.i/s))),h})(t,s,e,n,i);return o.map((t=>((t,s)=>({hex:`#${"0".repeat(6-t.m.toString(16).length)}${t.m.toString(16)}`,red:t.M,green:t.g,blue:t.p,area:t.i/s,hue:t.C,saturation:t.v,lightness:t.j,intensity:t.D}))(t,s)))},u=(t,s={})=>{const[e,r,i,o,a,u]=n(s),{N:l,count:d}=h(t,e,r,i);return c(l,d,o,a,u)},l=(t,s={})=>{if(a()){const[e,r,i,o,a,u,l]=n(s);return t.crossOrigin=l,new Promise((s=>{const n=t=>{const n=((t,s)=>{const e=t.width*t.height,r=e<s?t.width:Math.round(t.width*Math.sqrt(s/e)),n=e<s?t.height:Math.round(t.height*Math.sqrt(s/e)),i=document.createElement("canvas");i.width=r,i.height=n;const o=i.getContext("2d");return o.drawImage(t,0,0,t.width,t.height,0,0,r,n),o.getImageData(0,0,r,n)})(t,e),{N:l,count:d}=h(n,e,r,i);s(c(l,d,o,a,u))};if(t.complete)n(t);else{const s=()=>{t.removeEventListener("load",s),n(t)};t.addEventListener("load",s)}}))}if("production"!==process.env.NODE_ENV)throw new Error("Can not use extractColorsFromImage for Node.js")},d=(t,s={})=>{if(a()){const e=new Image;return e.src=t,l(e,s)}if("production"!==process.env.NODE_ENV)throw new Error("Can not use extractColorsFromSrc for Node.js")};exports.extractColors=(t,s)=>{if(!a()){if("production"!==process.env.NODE_ENV){if(t instanceof String)throw new Error("Send imageData to extractColors (Image src or HTMLImageElement not supported in Nodejs)");if(!t.data)throw new Error("Send imageData to extractColors");(null==s?void 0:s.crossOrigin)&&console.warn("options.crossOrigin not supported in Node.js")}return new Promise((e=>{e(u(t,s))}))}if(t instanceof Image)return l(t,s);if(t instanceof ImageData||t instanceof Object&&t.data)return new Promise((e=>{e(u(t,s))}));if("string"==typeof t)return d(t,s);throw new Error("Can not analyse picture")},exports.extractColorsFromImage=l,exports.extractColorsFromImageData=u,exports.extractColorsFromSrc=d;
48551
48552
48553}
48553).call(this)}).call(this,require('_process'))
48554},{"_process":365}],361:[function(require,module,exports){
48555
48556var hasOwn = Object.prototype.hasOwnProperty;
48557var toString = Object.prototype.toString;
48558
48559module.exports = function forEach (obj, fn, ctx) {
48560    if (toString.call(fn) !== '[object Function]') {
48561        throw new TypeError('iterator must be a function');
48562    }
48563    var l = obj.length;
48564    if (l === +l) {
48565        for (var i = 0; i < l; i++) {
48566            fn.call(ctx, obj[i], i, obj);
48567        }
48568    } else {
48569        for (var k in obj) {
48570            if (hasOwn.call(obj, k)) {
48571                fn.call(ctx, obj[k], k, obj);
48572            }
48573        }
48574    }
48575};
48576
48577
48578},{}],362:[function(require,module,exports){
48579var each = require('each'),
48580	indexOf = require('indexof');
48581
48582var getFragment = function( url ){
48583
48584	var url = url || window.location.href;
48585	return url.replace( /^[^#]*#?(.*)$/, '$1' );
48586
48587};
48588
48589var HashChange = function(){
48590
48591	var self = this;
48592
48593	this.onChangeCallbacks = [];
48594
48595	window.addEventListener("hashchange", function(e){
48596		
48597		self.hashChanged( getFragment(e.newURL) );
48598
48599	}, false);
48600
48601	return this;
48602
48603};
48604
48605HashChange.prototype = {
48606
48607	update : function( callback ){
48608
48609		if(callback){
48610
48611			this.onChangeCallbacks.push( callback );
48612			return this;
48613
48614		} else {
48615
48616			this.hashChanged( getFragment() );
48617
48618		}
48619
48620	},
48621
48622	unbind : function( callback ){
48623
48624		var i = indexOf( this.onChangeCallbacks , callback);
48625
48626		if(i !== -1){
48627
48628			this.onChangeCallbacks.splice(i - 1, 1);
48629
48630		}
48631
48632		return this;
48633
48634	},
48635	
48636	updateHash : function( hash ){
48637 
48638			this.currentHash = hash;
48639 
48640			window.location.href = window.location.href.replace( /#.*/, '') + '#' + hash;
48641 
48642		},
48643
48644	hashChanged : function( frag ){
48645
48646		if(this.onChangeCallbacks.length){
48647
48648			each(this.onChangeCallbacks, function( callback ){
48649
48650				callback( frag );
48651
48652				return true;
48653
48654			});
48655
48656		}
48657
48658		return this;
48659
48660	},
48661
48662
48663}
48664
48665hashChange = new HashChange();
48666
48667module.exports = hashChange;
48668
48669},{"each":361,"indexof":357}],363:[function(require,module,exports){
48670/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */
48671
48672window.matchMedia || (window.matchMedia = function() {
48673    "use strict";
48674
48675    // For browsers that support matchMedium api such as IE 9 and webkit
48676    var styleMedia = (window.styleMedia || window.media);
48677
48678    // For those that don't support matchMedium
48679    if (!styleMedia) {
48680        var style       = document.createElement('style'),
48681            script      = document.getElementsByTagName('script')[0],
48682            info        = null;
48683
48684        style.type  = 'text/css';
48685        style.id    = 'matchmediajs-test';
48686
48687        script.parentNode.insertBefore(style, script);
48688
48689        // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
48690        info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
48691
48692        styleMedia = {
48693            matchMedium: function(media) {
48694                var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
48695
48696                // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
48697                if (style.styleSheet) {
48698                    style.styleSheet.cssText = text;
48699                } else {
48700                    style.textContent = text;
48701                }
48702
48703                // Test if media query is true or false
48704                return info.width === '1px';
48705            }
48706        };
48707    }
48708
48709    return function(media) {
48710        return {
48711            matches: styleMedia.matchMedium(media || 'all'),
48712            media: media || 'all'
48713        };
48714    };
48715}());
48716
48717},{}],364:[function(require,module,exports){
48718// THIS FILE IS GENERATED - DO NOT EDIT!
48719/*!mobile-detect v1.4.5 2021-03-13*/
48720/*global module:false, define:false*/
48721/*jshint latedef:false*/
48722/*!@license Copyright 2013, Heinrich Goebl, License: MIT, see https://github.com/hgoebl/mobile-detect.js*/
48723(function (define, undefined) {
48724define(function () {
48725    'use strict';
48726
48727    var impl = {};
48728
48729    impl.mobileDetectRules = {
48730    "phones": {
48731        "iPhone": "\\biPhone\\b|\\biPod\\b",
48732        "BlackBerry": "BlackBerry|\\bBB10\\b|rim[0-9]+|\\b(BBA100|BBB100|BBD100|BBE100|BBF100|STH100)\\b-[0-9]+",
48733        "Pixel": "; \\bPixel\\b",
48734        "HTC": "HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\bEVO\\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel",
48735        "Nexus": "Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 5X|Nexus 6",
48736        "Dell": "Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\\b001DL\\b|\\b101DL\\b|\\bGS01\\b",
48737        "Motorola": "Motorola|DROIDX|DROID BIONIC|\\bDroid\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\bMoto E\\b|XT1068|XT1092|XT1052",
48738        "Samsung": 
vendor: 4,913 bytes, line 48738
48738"\\bSamsung\\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-
vendor: 63,412 bytes, lines 48738-49728
48738I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F|SM-G610F|SM-G981B|SM-G892A|SM-A530F",
48739        "LG": "\\bLG\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)|LM-G710",
48740        "Sony": "SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533|SOV34|601SO|F8332",
48741        "Asus": "Asus.*Galaxy|PadFone.*Mobile",
48742        "Xiaomi": "^(?!.*\\bx11\\b).*xiaomi.*$|POCOPHONE F1|MI 8|Redmi Note 9S|Redmi Note 5A Prime|N2G47H|M2001J2G|M2001J2I|M1805E10A|M2004J11G|M1902F1G|M2002J9G|M2004J19G|M2003J6A1G",
48743        "NokiaLumia": "Lumia [0-9]{3,4}",
48744        "Micromax": "Micromax.*\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\b",
48745        "Palm": "PalmSource|Palm",
48746        "Vertu": "Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature",
48747        "Pantech": "PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790",
48748        "Fly": "IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250",
48749        "Wiko": "KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM",
48750        "iMobile": "i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)",
48751        "SimValley": "\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\b",
48752        "Wolfgang": "AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q",
48753        "Alcatel": "Alcatel",
48754        "Nintendo": "Nintendo (3DS|Switch)",
48755        "Amoi": "Amoi",
48756        "INQ": "INQ",
48757        "OnePlus": "ONEPLUS",
48758        "GenericPhone": "Tapatalk|PDA;|SAGEM|\\bmmp\\b|pocket|\\bpsp\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\bwap\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser"
48759    },
48760    "tablets": {
48761        "iPad": "iPad|iPad.*Mobile",
48762        "NexusTablet": "Android.*Nexus[\\s]+(7|9|10)",
48763        "GoogleTablet": "Android.*Pixel C",
48764        "SamsungTablet": "SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835|SM-T830|SM-T837V|SM-T720|SM-T510|SM-T387V|SM-P610|SM-T290|SM-T515|SM-T590|SM-T595|SM-T725|SM-T817P|SM-P585N0|SM-T395|SM-T295|SM-T865|SM-P610N|SM-P615|SM-T970|SM-T380|SM-T5950|SM-T905|SM-T231|SM-T500|SM-T860",
48765        "Kindle": "Kindle|Silk.*Accelerated|Android.*\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\b|Android.*Silk\/[0-9.]+ like Chrome\/[0-9.]+ (?!Mobile)",
48766        "SurfaceTablet": "Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)",
48767        "HPTablet": "HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10",
48768        "AsusTablet": "^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\bK00F\\b|\\bK00C\\b|\\bK00E\\b|\\bK00L\\b|TX201LA|ME176C|ME102A|\\bM80TA\\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\bME70C\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\bP027\\b|\\bP024\\b|\\bP00C\\b",
48769        "BlackBerryTablet": "PlayBook|RIM Tablet",
48770        "HTCtablet": "HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410",
48771        "MotorolaTablet": "xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617",
48772        "NookTablet": "Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2",
48773        "AcerTablet": "Android.*; \\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\b|W3-810|\\bA3-A10\\b|\\bA3-A11\\b|\\bA3-A20\\b|\\bA3-A30|A3-A40",
48774        "ToshibaTablet": "Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO",
48775        "LGTablet": "\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\b",
48776        "FujitsuTablet": "Android.*\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\b",
48777        "PrestigioTablet": "PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002",
48778        "LenovoTablet": "Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304X|TB-X304F|TB-X304L|TB-X505F|TB-X505L|TB-X505X|TB-X605F|TB-X605L|TB-8703F|TB-8703X|TB-8703N|TB-8704N|TB-8704F|TB-8704X|TB-8704V|TB-7304F|TB-7304I|TB-7304X|Tab2A7-10F|Tab2A7-20F|TB2-X30L|YT3-X50L|YT3-X50F|YT3-X50M|YT-X705F|YT-X703F|YT-X703L|YT-X705L|YT-X705X|TB2-X30F|TB2-X30L|TB2-X30M|A2107A-F|A2107A-H|TB3-730F|TB3-730M|TB3-730X|TB-7504F|TB-7504X|TB-X704F|TB-X104F|TB3-X70F|TB-X705F|TB-8504F|TB3-X70L|TB3-710F|TB-X704L",
48779        "DellTablet": "Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7",
48780        "YarvikTablet": "Android.*\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\b",
48781        "MedionTablet": "Android.*\\bOYO\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB",
48782        "ArnovaTablet": "97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2",
48783        "IntensoTablet": "INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004",
48784        "IRUTablet": "M702pro",
48785        "MegafonTablet": "MegaFon V9|\\bZTE V9\\b|Android.*\\bMT7A\\b",
48786        "EbodaTablet": "E-Boda (Supreme|Impresspeed|Izzycomm|Essential)",
48787        "AllViewTablet": "Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)",
48788        "ArchosTablet": "\\b(101G9|80G9|A101IT)\\b|Qilive 97R|Archos5|\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\b",
48789        "AinolTablet": "NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark",
48790        "NokiaLumiaTablet": "Lumia 2520",
48791        "SonyTablet": "Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP641|SGP612|SOT31|SGP771|SGP611|SGP612|SGP712",
48792        "PhilipsTablet": "\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\b",
48793        "CubeTablet": "Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT",
48794        "CobyTablet": "MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010",
48795        "MIDTablet": "M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10",
48796        "MSITablet": "MSI \\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\b",
48797        "SMiTTablet": "Android.*(\\bMID\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)",
48798        "RockChipTablet": "Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A",
48799        "FlyTablet": "IQ310|Fly Vision",
48800        "bqTablet": "Android.*(bq)?.*\\b(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))\\b|Maxwell.*Lite|Maxwell.*Plus",
48801        "HuaweiTablet": "MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09|AGS-L09|CMR-AL19",
48802        "NecTablet": "\\bN-06D|\\bN-08D",
48803        "PantechTablet": "Pantech.*P4100",
48804        "BronchoTablet": "Broncho.*(N701|N708|N802|a710)",
48805        "VersusTablet": "TOUCHPAD.*[78910]|\\bTOUCHTAB\\b",
48806        "ZyncTablet": "z1000|Z99 2G|z930|z990|z909|Z919|z900",
48807        "PositivoTablet": "TB07STA|TB10STA|TB07FTA|TB10FTA",
48808        "NabiTablet": "Android.*\\bNabi",
48809        "KoboTablet": "Kobo Touch|\\bK080\\b|\\bVox\\b Build|\\bArc\\b Build",
48810        "DanewTablet": "DSlide.*\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\b",
48811        "TexetTablet": "NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE",
48812        "PlaystationTablet": "Playstation.*(Portable|Vita)",
48813        "TrekstorTablet": "ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab",
48814        "PyleAudioTablet": "\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\b",
48815        "AdvanTablet": "Android.* \\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\b ",
48816        "DanyTechTablet": "Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1",
48817        "GalapadTablet": "Android [0-9.]+; [a-z-]+; \\bG1\\b",
48818        "MicromaxTablet": "Funbook|Micromax.*\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\b",
48819        "KarbonnTablet": "Android.*\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\b",
48820        "AllFineTablet": "Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide",
48821        "PROSCANTablet": "\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\b",
48822        "YONESTablet": "BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026",
48823        "ChangJiaTablet": "TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503",
48824        "GUTablet": "TX-A1301|TX-M9002|Q702|kf026",
48825        "PointOfViewTablet": "TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10",
48826        "OvermaxTablet": "OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027",
48827        "HCLTablet": "HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync",
48828        "DPSTablet": "DPS Dream 9|DPS Dual 7",
48829        "VistureTablet": "V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10",
48830        "CrestaTablet": "CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989",
48831        "MediatekTablet": "\\bMT8125|MT8389|MT8135|MT8377\\b",
48832        "ConcordeTablet": "Concorde([ ]+)?Tab|ConCorde ReadMan",
48833        "GoCleverTablet": "GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042",
48834        "ModecomTablet": "FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003",
48835        "VoninoTablet": "\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\bQ8\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\b",
48836        "ECSTablet": "V07OT2|TM105A|S10OT1|TR10CS1",
48837        "StorexTablet": "eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab",
48838        "VodafoneTablet": "SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497|VFD 1400",
48839        "EssentielBTablet": "Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2",
48840        "RossMoorTablet": "RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711",
48841        "iMobileTablet": "i-mobile i-note",
48842        "TolinoTablet": "tolino tab [0-9.]+|tolino shine",
48843        "AudioSonicTablet": "\\bC-22Q|T7-QC|T-17B|T-17P\\b",
48844        "AMPETablet": "Android.* A78 ",
48845        "SkkTablet": "Android.* (SKYPAD|PHOENIX|CYCLOPS)",
48846        "TecnoTablet": "TECNO P9|TECNO DP8D",
48847        "JXDTablet": "Android.* \\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\b",
48848        "iJoyTablet": "Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)",
48849        "FX2Tablet": "FX2 PAD7|FX2 PAD10",
48850        "XoroTablet": "KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151",
48851        "ViewsonicTablet": "ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a",
48852        "VerizonTablet": "QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1",
48853        "OdysTablet": "LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\bXELIO\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10",
48854        "CaptivaTablet": "CAPTIVA PAD",
48855        "IconbitTablet": "NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S",
48856        "TeclastTablet": "T98 4G|\\bP80\\b|\\bX90HD\\b|X98 Air|X98 Air 3G|\\bX89\\b|P80 3G|\\bX80h\\b|P98 Air|\\bX89HD\\b|P98 3G|\\bP90HD\\b|P89 3G|X98 3G|\\bP70h\\b|P79HD 3G|G18d 3G|\\bP79HD\\b|\\bP89s\\b|\\bA88\\b|\\bP10HD\\b|\\bP19HD\\b|G18 3G|\\bP78HD\\b|\\bA78\\b|\\bP75\\b|G17s 3G|G17h 3G|\\bP85t\\b|\\bP90\\b|\\bP11\\b|\\bP98t\\b|\\bP98HD\\b|\\bG18d\\b|\\bP85s\\b|\\bP11HD\\b|\\bP88s\\b|\\bA80HD\\b|\\bA80se\\b|\\bA10h\\b|\\bP89\\b|\\bP78s\\b|\\bG18\\b|\\bP85\\b|\\bA70h\\b|\\bA70\\b|\\bG17\\b|\\bP18\\b|\\bA80s\\b|\\bA11s\\b|\\bP88HD\\b|\\bA80h\\b|\\bP76s\\b|\\bP76h\\b|\\bP98\\b|\\bA10HD\\b|\\bP78\\b|\\bP88\\b|\\bA11\\b|\\bA10t\\b|\\bP76a\\b|\\bP76t\\b|\\bP76e\\b|\\bP85HD\\b|\\bP85a\\b|\\bP86\\b|\\bP75HD\\b|\\bP76v\\b|\\bA12\\b|\\bP75a\\b|\\bA15\\b|\\bP76Ti\\b|\\bP81HD\\b|\\bA10\\b|\\bT760VE\\b|\\bT720HD\\b|\\bP76\\b|\\bP73\\b|\\bP71\\b|\\bP72\\b|\\bT720SE\\b|\\bC520Ti\\b|\\bT760\\b|\\bT720VE\\b|T720-3GE|T720-WiFi",
48857        "OndaTablet": "\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\b[\\s]+|V10 \\b4G\\b",
48858        "JaytechTablet": "TPC-PA762",
48859        "BlaupunktTablet": "Endeavour 800NG|Endeavour 1010",
48860        "DigmaTablet": "\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\b",
48861        "EvolioTablet": "ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\bEvotab\\b|\\bNeura\\b",
48862        "LavaTablet": "QPAD E704|\\bIvoryS\\b|E-TAB IVORY|\\bE-TAB\\b",
48863        "AocTablet": "MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712",
48864        "MpmanTablet": "MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\bMPG7\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010",
48865        "CelkonTablet": "CT695|CT888|CT[\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\bCT-1\\b",
48866        "WolderTablet": "miTab \\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\b",
48867        "MediacomTablet": "M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA",
48868        "MiTablet": "\\bMI PAD\\b|\\bHM NOTE 1W\\b",
48869        "NibiruTablet": "Nibiru M1|Nibiru Jupiter One",
48870        "NexoTablet": "NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI",
48871        "LeaderTablet": "TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100",
48872        "UbislateTablet": "UbiSlate[\\s]?7C",
48873        "PocketBookTablet": "Pocketbook",
48874        "KocasoTablet": "\\b(TB-1207)\\b",
48875        "HisenseTablet": "\\b(F5281|E2371)\\b",
48876        "Hudl": "Hudl HT7S3|Hudl 2",
48877        "TelstraTablet": "T-Hub2",
48878        "GenericTablet": "Android.*\\b97D\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\bA7EB\\b|CatNova8|A1_07|CT704|CT1002|\\bM721\\b|rk30sdk|\\bEVOTAB\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\bM6pro\\b|CT1020W|arc 10HD|\\bTP750\\b|\\bQTAQZ3\\b|WVT101|TM1088|KT107"
48879    },
48880    "oss": {
48881        "AndroidOS": "Android",
48882        "BlackBerryOS": "blackberry|\\bBB10\\b|rim tablet os",
48883        "PalmOS": "PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino",
48884        "SymbianOS": "Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\bS60\\b",
48885        "WindowsMobileOS": "Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Windows Mobile|Windows Phone [0-9.]+|WCE;",
48886        "WindowsPhoneOS": "Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;",
48887        "iOS": "\\biPhone.*Mobile|\\biPod|\\biPad|AppleCoreMedia",
48888        "iPadOS": "CPU OS 13",
48889        "SailfishOS": "Sailfish",
48890        "MeeGoOS": "MeeGo",
48891        "MaemoOS": "Maemo",
48892        "JavaOS": "J2ME\/|\\bMIDP\\b|\\bCLDC\\b",
48893        "webOS": "webOS|hpwOS",
48894        "badaOS": "\\bBada\\b",
48895        "BREWOS": "BREW"
48896    },
48897    "uas": {
48898        "Chrome": "\\bCrMo\\b|CriOS|Android.*Chrome\/[.0-9]* (Mobile)?",
48899        "Dolfin": "\\bDolfin\\b",
48900        "Opera": "Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR\/[0-9.]+$|Coast\/[0-9.]+",
48901        "Skyfire": "Skyfire",
48902        "Edge": "\\bEdgiOS\\b|Mobile Safari\/[.0-9]* Edge",
48903        "IE": "IEMobile|MSIEMobile",
48904        "Firefox": "fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS",
48905        "Bolt": "bolt",
48906        "TeaShark": "teashark",
48907        "Blazer": "Blazer",
48908        "Safari": "Version((?!\\bEdgiOS\\b).)*Mobile.*Safari|Safari.*Mobile|MobileSafari",
48909        "WeChat": "\\bMicroMessenger\\b",
48910        "UCBrowser": "UC.*Browser|UCWEB",
48911        "baiduboxapp": "baiduboxapp",
48912        "baidubrowser": "baidubrowser",
48913        "DiigoBrowser": "DiigoBrowser",
48914        "Mercury": "\\bMercury\\b",
48915        "ObigoBrowser": "Obigo",
48916        "NetFront": "NF-Browser",
48917        "GenericBrowser": "NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger",
48918        "PaleMoon": "Android.*PaleMoon|Mobile.*PaleMoon"
48919    },
48920    "props": {
48921        "Mobile": "Mobile\/[VER]",
48922        "Build": "Build\/[VER]",
48923        "Version": "Version\/[VER]",
48924        "VendorID": "VendorID\/[VER]",
48925        "iPad": "iPad.*CPU[a-z ]+[VER]",
48926        "iPhone": "iPhone.*CPU[a-z ]+[VER]",
48927        "iPod": "iPod.*CPU[a-z ]+[VER]",
48928        "Kindle": "Kindle\/[VER]",
48929        "Chrome": [
48930            "Chrome\/[VER]",
48931            "CriOS\/[VER]",
48932            "CrMo\/[VER]"
48933        ],
48934        "Coast": [
48935            "Coast\/[VER]"
48936        ],
48937        "Dolfin": "Dolfin\/[VER]",
48938        "Firefox": [
48939            "Firefox\/[VER]",
48940            "FxiOS\/[VER]"
48941        ],
48942        "Fennec": "Fennec\/[VER]",
48943        "Edge": "Edge\/[VER]",
48944        "IE": [
48945            "IEMobile\/[VER];",
48946            "IEMobile [VER]",
48947            "MSIE [VER];",
48948            "Trident\/[0-9.]+;.*rv:[VER]"
48949        ],
48950        "NetFront": "NetFront\/[VER]",
48951        "NokiaBrowser": "NokiaBrowser\/[VER]",
48952        "Opera": [
48953            " OPR\/[VER]",
48954            "Opera Mini\/[VER]",
48955            "Version\/[VER]"
48956        ],
48957        "Opera Mini": "Opera Mini\/[VER]",
48958        "Opera Mobi": "Version\/[VER]",
48959        "UCBrowser": [
48960            "UCWEB[VER]",
48961            "UC.*Browser\/[VER]"
48962        ],
48963        "MQQBrowser": "MQQBrowser\/[VER]",
48964        "MicroMessenger": "MicroMessenger\/[VER]",
48965        "baiduboxapp": "baiduboxapp\/[VER]",
48966        "baidubrowser": "baidubrowser\/[VER]",
48967        "SamsungBrowser": "SamsungBrowser\/[VER]",
48968        "Iron": "Iron\/[VER]",
48969        "Safari": [
48970            "Version\/[VER]",
48971            "Safari\/[VER]"
48972        ],
48973        "Skyfire": "Skyfire\/[VER]",
48974        "Tizen": "Tizen\/[VER]",
48975        "Webkit": "webkit[ \/][VER]",
48976        "PaleMoon": "PaleMoon\/[VER]",
48977        "SailfishBrowser": "SailfishBrowser\/[VER]",
48978        "Gecko": "Gecko\/[VER]",
48979        "Trident": "Trident\/[VER]",
48980        "Presto": "Presto\/[VER]",
48981        "Goanna": "Goanna\/[VER]",
48982        "iOS": " \\bi?OS\\b [VER][ ;]{1}",
48983        "Android": "Android [VER]",
48984        "Sailfish": "Sailfish [VER]",
48985        "BlackBerry": [
48986            "BlackBerry[\\w]+\/[VER]",
48987            "BlackBerry.*Version\/[VER]",
48988            "Version\/[VER]"
48989        ],
48990        "BREW": "BREW [VER]",
48991        "Java": "Java\/[VER]",
48992        "Windows Phone OS": [
48993            "Windows Phone OS [VER]",
48994            "Windows Phone [VER]"
48995        ],
48996        "Windows Phone": "Windows Phone [VER]",
48997        "Windows CE": "Windows CE\/[VER]",
48998        "Windows NT": "Windows NT [VER]",
48999        "Symbian": [
49000            "SymbianOS\/[VER]",
49001            "Symbian\/[VER]"
49002        ],
49003        "webOS": [
49004            "webOS\/[VER]",
49005            "hpwOS\/[VER];"
49006        ]
49007    },
49008    "utils": {
49009        "Bot": "Googlebot|facebookexternalhit|Google-AMPHTML|s~amp-validator|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom|contentkingapp|AspiegelBot",
49010        "MobileBot": "Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker\/M1A1-R2D2",
49011        "DesktopMode": "WPDesktop",
49012        "TV": "SonyDTV|HbbTV",
49013        "WebKit": "(webkit)[ \/]([\\w.]+)",
49014        "Console": "\\b(Nintendo|Nintendo WiiU|Nintendo 3DS|Nintendo Switch|PLAYSTATION|Xbox)\\b",
49015        "Watch": "SM-V700"
49016    }
49017};
49018
49019    // following patterns come from http://detectmobilebrowsers.com/
49020    impl.detectMobileBrowsers = {
49021        fullPattern: /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i,
49022        shortPattern: /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,
49023        tabletPattern: /android|ipad|playbook|silk/i
49024    };
49025
49026    var hasOwnProp = Object.prototype.hasOwnProperty,
49027        isArray;
49028
49029    impl.FALLBACK_PHONE = 'UnknownPhone';
49030    impl.FALLBACK_TABLET = 'UnknownTablet';
49031    impl.FALLBACK_MOBILE = 'UnknownMobile';
49032
49033    isArray = ('isArray' in Array) ?
49034        Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
49035
49036    function equalIC(a, b) {
49037        return a != null && b != null && a.toLowerCase() === b.toLowerCase();
49038    }
49039
49040    function containsIC(array, value) {
49041        var valueLC, i, len = array.length;
49042        if (!len || !value) {
49043            return false;
49044        }
49045        valueLC = value.toLowerCase();
49046        for (i = 0; i < len; ++i) {
49047            if (valueLC === array[i].toLowerCase()) {
49048                return true;
49049            }
49050        }
49051        return false;
49052    }
49053
49054    function convertPropsToRegExp(object) {
49055        for (var key in object) {
49056            if (hasOwnProp.call(object, key)) {
49057                object[key] = new RegExp(object[key], 'i');
49058            }
49059        }
49060    }
49061
49062    function prepareUserAgent(userAgent) {
49063        return (userAgent || '').substr(0, 500); // mitigate vulnerable to ReDoS
49064    }
49065
49066    (function init() {
49067        var key, values, value, i, len, verPos, mobileDetectRules = impl.mobileDetectRules;
49068        for (key in mobileDetectRules.props) {
49069            if (hasOwnProp.call(mobileDetectRules.props, key)) {
49070                values = mobileDetectRules.props[key];
49071                if (!isArray(values)) {
49072                    values = [values];
49073                }
49074                len = values.length;
49075                for (i = 0; i < len; ++i) {
49076                    value = values[i];
49077                    verPos = value.indexOf('[VER]');
49078                    if (verPos >= 0) {
49079                        value = value.substring(0, verPos) + '([\\w._\\+]+)' + value.substring(verPos + 5);
49080                    }
49081                    values[i] = new RegExp(value, 'i');
49082                }
49083                mobileDetectRules.props[key] = values;
49084            }
49085        }
49086        convertPropsToRegExp(mobileDetectRules.oss);
49087        convertPropsToRegExp(mobileDetectRules.phones);
49088        convertPropsToRegExp(mobileDetectRules.tablets);
49089        convertPropsToRegExp(mobileDetectRules.uas);
49090        convertPropsToRegExp(mobileDetectRules.utils);
49091
49092        // copy some patterns to oss0 which are tested first (see issue#15)
49093        mobileDetectRules.oss0 = {
49094            WindowsPhoneOS: mobileDetectRules.oss.WindowsPhoneOS,
49095            WindowsMobileOS: mobileDetectRules.oss.WindowsMobileOS
49096        };
49097    }());
49098
49099    /**
49100     * Test userAgent string against a set of rules and find the first matched key.
49101     * @param {Object} rules (key is String, value is RegExp)
49102     * @param {String} userAgent the navigator.userAgent (or HTTP-Header 'User-Agent').
49103     * @returns {String|null} the matched key if found, otherwise <tt>null</tt>
49104     * @private
49105     */
49106    impl.findMatch = function(rules, userAgent) {
49107        for (var key in rules) {
49108            if (hasOwnProp.call(rules, key)) {
49109                if (rules[key].test(userAgent)) {
49110                    return key;
49111                }
49112            }
49113        }
49114        return null;
49115    };
49116
49117    /**
49118     * Test userAgent string against a set of rules and return an array of matched keys.
49119     * @param {Object} rules (key is String, value is RegExp)
49120     * @param {String} userAgent the navigator.userAgent (or HTTP-Header 'User-Agent').
49121     * @returns {Array} an array of matched keys, may be empty when there is no match, but not <tt>null</tt>
49122     * @private
49123     */
49124    impl.findMatches = function(rules, userAgent) {
49125        var result = [];
49126        for (var key in rules) {
49127            if (hasOwnProp.call(rules, key)) {
49128                if (rules[key].test(userAgent)) {
49129                    result.push(key);
49130                }
49131            }
49132        }
49133        return result;
49134    };
49135
49136    /**
49137     * Check the version of the given property in the User-Agent.
49138     *
49139     * @param {String} propertyName
49140     * @param {String} userAgent
49141     * @return {String} version or <tt>null</tt> if version not found
49142     * @private
49143     */
49144    impl.getVersionStr = function (propertyName, userAgent) {
49145        var props = impl.mobileDetectRules.props, patterns, i, len, match;
49146        if (hasOwnProp.call(props, propertyName)) {
49147            patterns = props[propertyName];
49148            len = patterns.length;
49149            for (i = 0; i < len; ++i) {
49150                match = patterns[i].exec(userAgent);
49151                if (match !== null) {
49152                    return match[1];
49153                }
49154            }
49155        }
49156        return null;
49157    };
49158
49159    /**
49160     * Check the version of the given property in the User-Agent.
49161     * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
49162     *
49163     * @param {String} propertyName
49164     * @param {String} userAgent
49165     * @return {Number} version or <tt>NaN</tt> if version not found
49166     * @private
49167     */
49168    impl.getVersion = function (propertyName, userAgent) {
49169        var version = impl.getVersionStr(propertyName, userAgent);
49170        return version ? impl.prepareVersionNo(version) : NaN;
49171    };
49172
49173    /**
49174     * Prepare the version number.
49175     *
49176     * @param {String} version
49177     * @return {Number} the version number as a floating number
49178     * @private
49179     */
49180    impl.prepareVersionNo = function (version) {
49181        var numbers;
49182
49183        numbers = version.split(/[a-z._ \/\-]/i);
49184        if (numbers.length === 1) {
49185            version = numbers[0];
49186        }
49187        if (numbers.length > 1) {
49188            version = numbers[0] + '.';
49189            numbers.shift();
49190            version += numbers.join('');
49191        }
49192        return Number(version);
49193    };
49194
49195    impl.isMobileFallback = function (userAgent) {
49196        return impl.detectMobileBrowsers.fullPattern.test(userAgent) ||
49197            impl.detectMobileBrowsers.shortPattern.test(userAgent.substr(0,4));
49198    };
49199
49200    impl.isTabletFallback = function (userAgent) {
49201        return impl.detectMobileBrowsers.tabletPattern.test(userAgent);
49202    };
49203
49204    impl.prepareDetectionCache = function (cache, userAgent, maxPhoneWidth) {
49205        if (cache.mobile !== undefined) {
49206            return;
49207        }
49208        var phone, tablet, phoneSized;
49209
49210        // first check for stronger tablet rules, then phone (see issue#5)
49211        tablet = impl.findMatch(impl.mobileDetectRules.tablets, userAgent);
49212        if (tablet) {
49213            cache.mobile = cache.tablet = tablet;
49214            cache.phone = null;
49215            return; // unambiguously identified as tablet
49216        }
49217
49218        phone = impl.findMatch(impl.mobileDetectRules.phones, userAgent);
49219        if (phone) {
49220            cache.mobile = cache.phone = phone;
49221            cache.tablet = null;
49222            return; // unambiguously identified as phone
49223        }
49224
49225        // our rules haven't found a match -> try more general fallback rules
49226        if (impl.isMobileFallback(userAgent)) {
49227            phoneSized = MobileDetect.isPhoneSized(maxPhoneWidth);
49228            if (phoneSized === undefined) {
49229                cache.mobile = impl.FALLBACK_MOBILE;
49230                cache.tablet = cache.phone = null;
49231            } else if (phoneSized) {
49232                cache.mobile = cache.phone = impl.FALLBACK_PHONE;
49233                cache.tablet = null;
49234            } else {
49235                cache.mobile = cache.tablet = impl.FALLBACK_TABLET;
49236                cache.phone = null;
49237            }
49238        } else if (impl.isTabletFallback(userAgent)) {
49239            cache.mobile = cache.tablet = impl.FALLBACK_TABLET;
49240            cache.phone = null;
49241        } else {
49242            // not mobile at all!
49243            cache.mobile = cache.tablet = cache.phone = null;
49244        }
49245    };
49246
49247    // t is a reference to a MobileDetect instance
49248    impl.mobileGrade = function (t) {
49249        // impl note:
49250        // To keep in sync w/ Mobile_Detect.php easily, the following code is tightly aligned to the PHP version.
49251        // When changes are made in Mobile_Detect.php, copy this method and replace:
49252        //     $this-> / t.
49253        //     self::MOBILE_GRADE_(.) / '$1'
49254        //     , self::VERSION_TYPE_FLOAT / (nothing)
49255        //     isIOS() / os('iOS')
49256        //     [reg] / (nothing)   <-- jsdelivr complaining about unescaped unicode character U+00AE
49257        var $isMobile = t.mobile() !== null;
49258
49259        if (
49260            // Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1)
49261            t.os('iOS') && t.version('iPad')>=4.3 ||
49262            t.os('iOS') && t.version('iPhone')>=3.1 ||
49263            t.os('iOS') && t.version('iPod')>=3.1 ||
49264
49265            // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)
49266            // Android 3.1 (Honeycomb)  - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
49267            // Android 4.0 (ICS)  - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
49268            // Android 4.1 (Jelly Bean)  - Tested on a Galaxy Nexus and Galaxy 7
49269            ( t.version('Android')>2.1 && t.is('Webkit') ) ||
49270
49271            // Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800
49272            t.version('Windows Phone OS')>=7.0 ||
49273
49274            // Blackberry 7 - Tested on BlackBerry Torch 9810
49275            // Blackberry 6.0 - Tested on the Torch 9800 and Style 9670
49276            t.is('BlackBerry') && t.version('BlackBerry')>=6.0 ||
49277            // Blackberry Playbook (1.0-2.0) - Tested on PlayBook
49278            t.match('Playbook.*Tablet') ||
49279
49280            // Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0)
49281            ( t.version('webOS')>=1.4 && t.match('Palm|Pre|Pixi') ) ||
49282            // Palm WebOS 3.0  - Tested on HP TouchPad
49283            t.match('hp.*TouchPad') ||
49284
49285            // Firefox Mobile (12 Beta) - Tested on Android 2.3 device
49286            ( t.is('Firefox') && t.version('Firefox')>=12 ) ||
49287
49288            // Chrome for Android - Tested on Android 4.0, 4.1 device
49289            ( t.is('Chrome') && t.is('AndroidOS') && t.version('Android')>=4.0 ) ||
49290
49291            // Skyfire 4.1 - Tested on Android 2.3 device
49292            ( t.is('Skyfire') && t.version('Skyfire')>=4.1 && t.is('AndroidOS') && t.version('Android')>=2.3 ) ||
49293
49294            // Opera Mobile 11.5-12: Tested on Android 2.3
49295            ( t.is('Opera') && t.version('Opera Mobi')>11 && t.is('AndroidOS') ) ||
49296
49297            // Meego 1.2 - Tested on Nokia 950 and N9
49298            t.is('MeeGoOS') ||
49299
49300            // Tizen (pre-release) - Tested on early hardware
49301            t.is('Tizen') ||
49302
49303            // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
49304            // @todo: more tests here!
49305            t.is('Dolfin') && t.version('Bada')>=2.0 ||
49306
49307            // UC Browser - Tested on Android 2.3 device
49308            ( (t.is('UC Browser') || t.is('Dolfin')) && t.version('Android')>=2.3 ) ||
49309
49310            // Kindle 3 and Fire  - Tested on the built-in WebKit browser for each
49311            ( t.match('Kindle Fire') ||
49312                t.is('Kindle') && t.version('Kindle')>=3.0 ) ||
49313
49314            // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
49315            t.is('AndroidOS') && t.is('NookTablet') ||
49316
49317            // Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7
49318            t.version('Chrome')>=11 && !$isMobile ||
49319
49320            // Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7
49321            t.version('Safari')>=5.0 && !$isMobile ||
49322
49323            // Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7
49324            t.version('Firefox')>=4.0 && !$isMobile ||
49325
49326            // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
49327            t.version('MSIE')>=7.0 && !$isMobile ||
49328
49329            // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
49330            // @reference: http://my.opera.com/community/openweb/idopera/
49331            t.version('Opera')>=10 && !$isMobile
49332
49333            ){
49334            return 'A';
49335        }
49336
49337        if (
49338            t.os('iOS') && t.version('iPad')<4.3 ||
49339            t.os('iOS') && t.version('iPhone')<3.1 ||
49340            t.os('iOS') && t.version('iPod')<3.1 ||
49341
49342            // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
49343            t.is('Blackberry') && t.version('BlackBerry')>=5 && t.version('BlackBerry')<6 ||
49344
49345            //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
49346            ( t.version('Opera Mini')>=5.0 && t.version('Opera Mini')<=6.5 &&
49347                (t.version('Android')>=2.3 || t.is('iOS')) ) ||
49348
49349            // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
49350            t.match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') ||
49351
49352            // @todo: report this (tested on Nokia N71)
49353            t.version('Opera Mobi')>=11 && t.is('SymbianOS')
49354            ){
49355            return 'B';
49356        }
49357
49358        if (
49359        // Blackberry 4.x - Tested on the Curve 8330
49360            t.version('BlackBerry')<5.0 ||
49361            // Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
49362            t.match('MSIEMobile|Windows CE.*Mobile') || t.version('Windows Mobile')<=5.2
49363
49364            ){
49365            return 'C';
49366        }
49367
49368        //All older smartphone platforms and featurephones - Any device that doesn't support media queries
49369        //will receive the basic, C grade experience.
49370        return 'C';
49371    };
49372
49373    impl.detectOS = function (ua) {
49374        return impl.findMatch(impl.mobileDetectRules.oss0, ua) ||
49375            impl.findMatch(impl.mobileDetectRules.oss, ua);
49376    };
49377
49378    impl.getDeviceSmallerSide = function () {
49379        return window.screen.width < window.screen.height ?
49380            window.screen.width :
49381            window.screen.height;
49382    };
49383
49384    /**
49385     * Constructor for MobileDetect object.
49386     * <br>
49387     * Such an object will keep a reference to the given user-agent string and cache most of the detect queries.<br>
49388     * <div style="background-color: #d9edf7; border: 1px solid #bce8f1; color: #3a87ad; padding: 14px; border-radius: 2px; margin-top: 20px">
49389     *     <strong>Find information how to download and install:</strong>
49390     *     <a href="https://github.com/hgoebl/mobile-detect.js/">github.com/hgoebl/mobile-detect.js/</a>
49391     * </div>
49392     *
49393     * @example <pre>
49394     *     var md = new MobileDetect(window.navigator.userAgent);
49395     *     if (md.mobile()) {
49396     *         location.href = (md.mobileGrade() === 'A') ? '/mobile/' : '/lynx/';
49397     *     }
49398     * </pre>
49399     *
49400     * @param {string} userAgent typically taken from window.navigator.userAgent or http_header['User-Agent']
49401     * @param {number} [maxPhoneWidth=600] <strong>only for browsers</strong> specify a value for the maximum
49402     *        width of smallest device side (in logical "CSS" pixels) until a device detected as mobile will be handled
49403     *        as phone.
49404     *        This is only used in cases where the device cannot be classified as phone or tablet.<br>
49405     *        See <a href="http://developer.android.com/guide/practices/screens_support.html">Declaring Tablet Layouts
49406     *        for Android</a>.<br>
49407     *        If you provide a value < 0, then this "fuzzy" check is disabled.
49408     * @constructor
49409     * @global
49410     */
49411    function MobileDetect(userAgent, maxPhoneWidth) {
49412        this.ua = prepareUserAgent(userAgent);
49413        this._cache = {};
49414        //600dp is typical 7" tablet minimum width
49415        this.maxPhoneWidth = maxPhoneWidth || 600;
49416    }
49417
49418    MobileDetect.prototype = {
49419        constructor: MobileDetect,
49420
49421        /**
49422         * Returns the detected phone or tablet type or <tt>null</tt> if it is not a mobile device.
49423         * <br>
49424         * For a list of possible return values see {@link MobileDetect#phone} and {@link MobileDetect#tablet}.<br>
49425         * <br>
49426         * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
49427         * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
49428         * is positive, a value of <code>UnknownPhone</code>, <code>UnknownTablet</code> or
49429         * <code>UnknownMobile</code> is returned.<br>
49430         * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
49431         * <br>
49432         * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
49433         * and <code>UnknownMobile</code>, so you will get <code>UnknownMobile</code> here.<br>
49434         * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
49435         * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
49436         * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
49437         * <br>
49438         * In most cases you will use the return value just as a boolean.
49439         *
49440         * @returns {String} the key for the phone family or tablet family, e.g. "Nexus".
49441         * @function MobileDetect#mobile
49442         */
49443        mobile: function () {
49444            impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
49445            return this._cache.mobile;
49446        },
49447
49448        /**
49449         * Returns the detected phone type/family string or <tt>null</tt>.
49450         * <br>
49451         * The returned tablet (family or producer) is one of following keys:<br>
49452         * <br><tt>iPhone, BlackBerry, Pixel, HTC, Nexus, Dell, Motorola, Samsung, LG, Sony, Asus,
49453         * Xiaomi, NokiaLumia, Micromax, Palm, Vertu, Pantech, Fly, Wiko, iMobile,
49454         * SimValley, Wolfgang, Alcatel, Nintendo, Amoi, INQ, OnePlus, GenericPhone</tt><br>
49455         * <br>
49456         * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
49457         * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
49458         * is positive, a value of <code>UnknownPhone</code> or <code>UnknownMobile</code> is returned.<br>
49459         * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
49460         * <br>
49461         * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
49462         * and <code>UnknownMobile</code>, so you will get <code>null</code> here, while {@link MobileDetect#mobile}
49463         * will return <code>UnknownMobile</code>.<br>
49464         * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
49465         * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
49466         * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
49467         * <br>
49468         * In most cases you will use the return value just as a boolean.
49469         *
49470         * @returns {String} the key of the phone family or producer, e.g. "iPhone"
49471         * @function MobileDetect#phone
49472         */
49473        phone: function () {
49474            impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
49475            return this._cache.phone;
49476        },
49477
49478        /**
49479         * Returns the detected tablet type/family string or <tt>null</tt>.
49480         * <br>
49481         * The returned tablet (family or producer) is one of following keys:<br>
49482         * <br><tt>iPad, NexusTablet, GoogleTablet, SamsungTablet, Kindle, SurfaceTablet,
49483         * HPTablet, AsusTablet, BlackBerryTablet, HTCtablet, MotorolaTablet, NookTablet,
49484         * AcerTablet, ToshibaTablet, LGTablet, FujitsuTablet, PrestigioTablet,
49485         * LenovoTablet, DellTablet, YarvikTablet, MedionTablet, ArnovaTablet,
49486         * IntensoTablet, IRUTablet, MegafonTablet, EbodaTablet, AllViewTablet,
49487         * ArchosTablet, AinolTablet, NokiaLumiaTablet, SonyTablet, PhilipsTablet,
49488         * CubeTablet, CobyTablet, MIDTablet, MSITablet, SMiTTablet, RockChipTablet,
49489         * FlyTablet, bqTablet, HuaweiTablet, NecTablet, PantechTablet, BronchoTablet,
49490         * VersusTablet, ZyncTablet, PositivoTablet, NabiTablet, KoboTablet, DanewTablet,
49491         * TexetTablet, PlaystationTablet, TrekstorTablet, PyleAudioTablet, AdvanTablet,
49492         * DanyTechTablet, GalapadTablet, MicromaxTablet, KarbonnTablet, AllFineTablet,
49493         * PROSCANTablet, YONESTablet, ChangJiaTablet, GUTablet, PointOfViewTablet,
49494         * OvermaxTablet, HCLTablet, DPSTablet, VistureTablet, CrestaTablet,
49495         * MediatekTablet, ConcordeTablet, GoCleverTablet, ModecomTablet, VoninoTablet,
49496         * ECSTablet, StorexTablet, VodafoneTablet, EssentielBTablet, RossMoorTablet,
49497         * iMobileTablet, TolinoTablet, AudioSonicTablet, AMPETablet, SkkTablet,
49498         * TecnoTablet, JXDTablet, iJoyTablet, FX2Tablet, XoroTablet, ViewsonicTablet,
49499         * VerizonTablet, OdysTablet, CaptivaTablet, IconbitTablet, TeclastTablet,
49500         * OndaTablet, JaytechTablet, BlaupunktTablet, DigmaTablet, EvolioTablet,
49501         * LavaTablet, AocTablet, MpmanTablet, CelkonTablet, WolderTablet, MediacomTablet,
49502         * MiTablet, NibiruTablet, NexoTablet, LeaderTablet, UbislateTablet,
49503         * PocketBookTablet, KocasoTablet, HisenseTablet, Hudl, TelstraTablet,
49504         * GenericTablet</tt><br>
49505         * <br>
49506         * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against
49507         * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test
49508         * is positive, a value of <code>UnknownTablet</code> or <code>UnknownMobile</code> is returned.<br>
49509         * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br>
49510         * <br>
49511         * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code>
49512         * and <code>UnknownMobile</code>, so you will get <code>null</code> here, while {@link MobileDetect#mobile}
49513         * will return <code>UnknownMobile</code>.<br>
49514         * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for:
49515         * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}.
49516         * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use.
49517         * <br>
49518         * In most cases you will use the return value just as a boolean.
49519         *
49520         * @returns {String} the key of the tablet family or producer, e.g. "SamsungTablet"
49521         * @function MobileDetect#tablet
49522         */
49523        tablet: function () {
49524            impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth);
49525            return this._cache.tablet;
49526        },
49527
49528        /**
49529         * Returns the (first) detected user-agent string or <tt>null</tt>.
49530         * <br>
49531         * The returned user-agent is one of following keys:<br>
49532         * <br><tt>Chrome, Dolfin, Opera, Skyfire, Edge, IE, Firefox, Bolt, TeaShark, Blazer,
49533         * Safari, WeChat, UCBrowser, baiduboxapp, baidubrowser, DiigoBrowser, Mercury,
49534         * ObigoBrowser, NetFront, GenericBrowser, PaleMoon</tt><br>
49535         * <br>
49536         * In most cases calling {@link MobileDetect#userAgent} will be sufficient. But there are rare
49537         * cases where a mobile device pretends to be more than one particular browser. You can get the
49538         * list of all matches with {@link MobileDetect#userAgents} or check for a particular value by
49539         * providing one of the defined keys as first argument to {@link MobileDetect#is}.
49540         *
49541         * @returns {String} the key for the detected user-agent or <tt>null</tt>
49542         * @function MobileDetect#userAgent
49543         */
49544        userAgent: function () {
49545            if (this._cache.userAgent === undefined) {
49546                this._cache.userAgent = impl.findMatch(impl.mobileDetectRules.uas, this.ua);
49547            }
49548            return this._cache.userAgent;
49549        },
49550
49551        /**
49552         * Returns all detected user-agent strings.
49553         * <br>
49554         * The array is empty or contains one or more of following keys:<br>
49555         * <br><tt>Chrome, Dolfin, Opera, Skyfire, Edge, IE, Firefox, Bolt, TeaShark, Blazer,
49556         * Safari, WeChat, UCBrowser, baiduboxapp, baidubrowser, DiigoBrowser, Mercury,
49557         * ObigoBrowser, NetFront, GenericBrowser, PaleMoon</tt><br>
49558         * <br>
49559         * In most cases calling {@link MobileDetect#userAgent} will be sufficient. But there are rare
49560         * cases where a mobile device pretends to be more than one particular browser. You can get the
49561         * list of all matches with {@link MobileDetect#userAgents} or check for a particular value by
49562         * providing one of the defined keys as first argument to {@link MobileDetect#is}.
49563         *
49564         * @returns {Array} the array of detected user-agent keys or <tt>[]</tt>
49565         * @function MobileDetect#userAgents
49566         */
49567        userAgents: function () {
49568            if (this._cache.userAgents === undefined) {
49569                this._cache.userAgents = impl.findMatches(impl.mobileDetectRules.uas, this.ua);
49570            }
49571            return this._cache.userAgents;
49572        },
49573
49574        /**
49575         * Returns the detected operating system string or <tt>null</tt>.
49576         * <br>
49577         * The operating system is one of following keys:<br>
49578         * <br><tt>AndroidOS, BlackBerryOS, PalmOS, SymbianOS, WindowsMobileOS, WindowsPhoneOS,
49579         * iOS, iPadOS, SailfishOS, MeeGoOS, MaemoOS, JavaOS, webOS, badaOS, BREWOS</tt><br>
49580         *
49581         * @returns {String} the key for the detected operating system.
49582         * @function MobileDetect#os
49583         */
49584        os: function () {
49585            if (this._cache.os === undefined) {
49586                this._cache.os = impl.detectOS(this.ua);
49587            }
49588            return this._cache.os;
49589        },
49590
49591        /**
49592         * Get the version (as Number) of the given property in the User-Agent.
49593         * <br>
49594         * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
49595         *
49596         * @param {String} key a key defining a thing which has a version.<br>
49597         *        You can use one of following keys:<br>
49598         * <br><tt>Mobile, Build, Version, VendorID, iPad, iPhone, iPod, Kindle, Chrome, Coast,
49599         * Dolfin, Firefox, Fennec, Edge, IE, NetFront, NokiaBrowser, Opera, Opera Mini,
49600         * Opera Mobi, UCBrowser, MQQBrowser, MicroMessenger, baiduboxapp, baidubrowser,
49601         * SamsungBrowser, Iron, Safari, Skyfire, Tizen, Webkit, PaleMoon,
49602         * SailfishBrowser, Gecko, Trident, Presto, Goanna, iOS, Android, Sailfish,
49603         * BlackBerry, BREW, Java, Windows Phone OS, Windows Phone, Windows CE, Windows
49604         * NT, Symbian, webOS</tt><br>
49605         *
49606         * @returns {Number} the version as float or <tt>NaN</tt> if User-Agent doesn't contain this version.
49607         *          Be careful when comparing this value with '==' operator!
49608         * @function MobileDetect#version
49609         */
49610        version: function (key) {
49611            return impl.getVersion(key, this.ua);
49612        },
49613
49614        /**
49615         * Get the version (as String) of the given property in the User-Agent.
49616         * <br>
49617         *
49618         * @param {String} key a key defining a thing which has a version.<br>
49619         *        You can use one of following keys:<br>
49620         * <br><tt>Mobile, Build, Version, VendorID, iPad, iPhone, iPod, Kindle, Chrome, Coast,
49621         * Dolfin, Firefox, Fennec, Edge, IE, NetFront, NokiaBrowser, Opera, Opera Mini,
49622         * Opera Mobi, UCBrowser, MQQBrowser, MicroMessenger, baiduboxapp, baidubrowser,
49623         * SamsungBrowser, Iron, Safari, Skyfire, Tizen, Webkit, PaleMoon,
49624         * SailfishBrowser, Gecko, Trident, Presto, Goanna, iOS, Android, Sailfish,
49625         * BlackBerry, BREW, Java, Windows Phone OS, Windows Phone, Windows CE, Windows
49626         * NT, Symbian, webOS</tt><br>
49627         *
49628         * @returns {String} the "raw" version as String or <tt>null</tt> if User-Agent doesn't contain this version.
49629         *
49630         * @function MobileDetect#versionStr
49631         */
49632        versionStr: function (key) {
49633            return impl.getVersionStr(key, this.ua);
49634        },
49635
49636        /**
49637         * Global test key against userAgent, os, phone, tablet and some other properties of userAgent string.
49638         *
49639         * @param {String} key the key (case-insensitive) of a userAgent, an operating system, phone or
49640         *        tablet family.<br>
49641         *        For a complete list of possible values, see {@link MobileDetect#userAgent},
49642         *        {@link MobileDetect#os}, {@link MobileDetect#phone}, {@link MobileDetect#tablet}.<br>
49643         *        Additionally you have following keys:<br>
49644         * <br><tt>Bot, MobileBot, DesktopMode, TV, WebKit, Console, Watch</tt><br>
49645         *
49646         * @returns {boolean} <tt>true</tt> when the given key is one of the defined keys of userAgent, os, phone,
49647         *                    tablet or one of the listed additional keys, otherwise <tt>false</tt>
49648         * @function MobileDetect#is
49649         */
49650        is: function (key) {
49651            return containsIC(this.userAgents(), key) ||
49652                   equalIC(key, this.os()) ||
49653                   equalIC(key, this.phone()) ||
49654                   equalIC(key, this.tablet()) ||
49655                   containsIC(impl.findMatches(impl.mobileDetectRules.utils, this.ua), key);
49656        },
49657
49658        /**
49659         * Do a quick test against navigator::userAgent.
49660         *
49661         * @param {String|RegExp} pattern the pattern, either as String or RegExp
49662         *                        (a string will be converted to a case-insensitive RegExp).
49663         * @returns {boolean} <tt>true</tt> when the pattern matches, otherwise <tt>false</tt>
49664         * @function MobileDetect#match
49665         */
49666        match: function (pattern) {
49667            if (!(pattern instanceof RegExp)) {
49668                pattern = new RegExp(pattern, 'i');
49669            }
49670            return pattern.test(this.ua);
49671        },
49672
49673        /**
49674         * Checks whether the mobile device can be considered as phone regarding <code>screen.width</code>.
49675         * <br>
49676         * Obviously this method makes sense in browser environments only (not for Node.js)!
49677         * @param {number} [maxPhoneWidth] the maximum logical pixels (aka. CSS-pixels) to be considered as phone.<br>
49678         *        The argument is optional and if not present or falsy, the value of the constructor is taken.
49679         * @returns {boolean|undefined} <code>undefined</code> if screen size wasn't detectable, else <code>true</code>
49680         *          when screen.width is less or equal to maxPhoneWidth, otherwise <code>false</code>.<br>
49681         *          Will always return <code>undefined</code> server-side.
49682         */
49683        isPhoneSized: function (maxPhoneWidth) {
49684            return MobileDetect.isPhoneSized(maxPhoneWidth || this.maxPhoneWidth);
49685        },
49686
49687        /**
49688         * Returns the mobile grade ('A', 'B', 'C').
49689         *
49690         * @returns {String} one of the mobile grades ('A', 'B', 'C').
49691         * @function MobileDetect#mobileGrade
49692         */
49693        mobileGrade: function () {
49694            if (this._cache.grade === undefined) {
49695                this._cache.grade = impl.mobileGrade(this);
49696            }
49697            return this._cache.grade;
49698        }
49699    };
49700
49701    // environment-dependent
49702    if (typeof window !== 'undefined' && window.screen) {
49703        MobileDetect.isPhoneSized = function (maxPhoneWidth) {
49704            return maxPhoneWidth < 0 ? undefined : impl.getDeviceSmallerSide() <= maxPhoneWidth;
49705        };
49706    } else {
49707        MobileDetect.isPhoneSized = function () {};
49708    }
49709
49710    // should not be replaced by a completely new object - just overwrite existing methods
49711    MobileDetect._impl = impl;
49712    
49713    MobileDetect.version = '1.4.5 2021-03-13';
49714
49715    return MobileDetect;
49716}); // end of call of define()
49717})((function (undefined) {
49718    if (typeof module !== 'undefined' && module.exports) {
49719        return function (factory) { module.exports = factory(); };
49720    } else if (typeof define === 'function' && define.amd) {
49721        return define;
49722    } else if (typeof window !== 'undefined') {
49723        return function (factory) { window.MobileDetect = factory(); };
49724    } else {
49725        // please file a bug if you get this error!
49726        throw new Error('unknown environment');
49727    }
49728})());
49728
49729},{}],365
vendor: 5,461 bytes, lines 49729-49915
49729:[function(require,module,exports){
49730// shim for using process in browser
49731var process = module.exports = {};
49732
49733// cached from whatever global is present so that test runners that stub it
49734// don't break things.  But we need to wrap it in a try catch in case it is
49735// wrapped in strict mode code which doesn't define any globals.  It's inside a
49736// function because try/catches deoptimize in certain engines.
49737
49738var cachedSetTimeout;
49739var cachedClearTimeout;
49740
49741function defaultSetTimout() {
49742    throw new Error('setTimeout has not been defined');
49743}
49744function defaultClearTimeout () {
49745    throw new Error('clearTimeout has not been defined');
49746}
49747(function () {
49748    try {
49749        if (typeof setTimeout === 'function') {
49750            cachedSetTimeout = setTimeout;
49751        } else {
49752            cachedSetTimeout = defaultSetTimout;
49753        }
49754    } catch (e) {
49755        cachedSetTimeout = defaultSetTimout;
49756    }
49757    try {
49758        if (typeof clearTimeout === 'function') {
49759            cachedClearTimeout = clearTimeout;
49760        } else {
49761            cachedClearTimeout = defaultClearTimeout;
49762        }
49763    } catch (e) {
49764        cachedClearTimeout = defaultClearTimeout;
49765    }
49766} ())
49767function runTimeout(fun) {
49768    if (cachedSetTimeout === setTimeout) {
49769        //normal enviroments in sane situations
49770        return setTimeout(fun, 0);
49771    }
49772    // if setTimeout wasn't available but was latter defined
49773    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
49774        cachedSetTimeout = setTimeout;
49775        return setTimeout(fun, 0);
49776    }
49777    try {
49778        // when when somebody has screwed with setTimeout but no I.E. maddness
49779        return cachedSetTimeout(fun, 0);
49780    } catch(e){
49781        try {
49782            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
49783            return cachedSetTimeout.call(null, fun, 0);
49784        } catch(e){
49785            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
49786            return cachedSetTimeout.call(this, fun, 0);
49787        }
49788    }
49789
49790
49791}
49792function runClearTimeout(marker) {
49793    if (cachedClearTimeout === clearTimeout) {
49794        //normal enviroments in sane situations
49795        return clearTimeout(marker);
49796    }
49797    // if clearTimeout wasn't available but was latter defined
49798    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
49799        cachedClearTimeout = clearTimeout;
49800        return clearTimeout(marker);
49801    }
49802    try {
49803        // when when somebody has screwed with setTimeout but no I.E. maddness
49804        return cachedClearTimeout(marker);
49805    } catch (e){
49806        try {
49807            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
49808            return cachedClearTimeout.call(null, marker);
49809        } catch (e){
49810            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
49811            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
49812            return cachedClearTimeout.call(this, marker);
49813        }
49814    }
49815
49816
49817
49818}
49819var queue = [];
49820var draining = false;
49821var currentQueue;
49822var queueIndex = -1;
49823
49824function cleanUpNextTick() {
49825    if (!draining || !currentQueue) {
49826        return;
49827    }
49828    draining = false;
49829    if (currentQueue.length) {
49830        queue = currentQueue.concat(queue);
49831    } else {
49832        queueIndex = -1;
49833    }
49834    if (queue.length) {
49835        drainQueue();
49836    }
49837}
49838
49839function drainQueue() {
49840    if (draining) {
49841        return;
49842    }
49843    var timeout = runTimeout(cleanUpNextTick);
49844    draining = true;
49845
49846    var len = queue.length;
49847    while(len) {
49848        currentQueue = queue;
49849        queue = [];
49850        while (++queueIndex < len) {
49851            if (currentQueue) {
49852                currentQueue[queueIndex].run();
49853            }
49854        }
49855        queueIndex = -1;
49856        len = queue.length;
49857    }
49858    currentQueue = null;
49859    draining = false;
49860    runClearTimeout(timeout);
49861}
49862
49863process.nextTick = function (fun) {
49864    var args = new Array(arguments.length - 1);
49865    if (arguments.length > 1) {
49866        for (var i = 1; i < arguments.length; i++) {
49867            args[i - 1] = arguments[i];
49868        }
49869    }
49870    queue.push(new Item(fun, args));
49871    if (queue.length === 1 && !draining) {
49872        runTimeout(drainQueue);
49873    }
49874};
49875
49876// v8 likes predictible objects
49877function Item(fun, array) {
49878    this.fun = fun;
49879    this.array = array;
49880}
49881Item.prototype.run = function () {
49882    this.fun.apply(null, this.array);
49883};
49884process.title = 'browser';
49885process.browser = true;
49886process.env = {};
49887process.argv = [];
49888process.version = ''; // empty string to avoid regexp issues
49889process.versions = {};
49890
49891function noop() {}
49892
49893process.on = noop;
49894process.addListener = noop;
49895process.once = noop;
49896process.off = noop;
49897process.removeListener = noop;
49898process.removeAllListeners = noop;
49899process.emit = noop;
49900process.prependListener = noop;
49901process.prependOnceListener = noop;
49902
49903process.listeners = function (name) { return [] }
49904
49905process.binding = function (name) {
49906    throw new Error('process.binding is not supported');
49907};
49908
49909process.cwd = function () { return '/' };
49910process.chdir = function (dir) {
49911    throw new Error('process.chdir is not supported');
49912};
49913process.umask = function() { return 0; };
49914
49915},{}],
49915366:[function(require,module,exports){
49916(function() {
49917  module.exports = function(r, g, b) {
49918    var d, h, l, max, min, s;
49919    r /= 255;
49920    g /= 255;
49921    b /= 255;
49922    max = Math.max(r, g, b);
49923    min = Math.min(r, g, b);
49924    h = 0;
49925    s = 0;
49926    l = (max + min) / 2;
49927    if (max === min) {
49928      h = s = 0;
49929    } else {
49930      d = max - min;
49931      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
49932      switch (max) {
49933        case r:
49934          h = (g - b) / d + (g < b ? 6 : 0);
49935          break;
49936        case g:
49937          h = (b - r) / d + 2;
49938          break;
49939        case b:
49940          h = (r - g) / d + 4;
49941      }
49942      h /= 6;
49943    }
49944    h = h * 360;
49945    s = (s * 100) + "%";
49946    l = (l * 100) + "%";
49947    return [h, s, l];
49948  };
49949
49950}).call(this);
49951
49952},{}],367:[function(require,module,exports){
49953!function(root, factory) {
49954    "function" == typeof define && define.amd ? // AMD. Register as an anonymous module unless amdModuleId is set
49955    define([], function() {
49956        return root.svg4everybody = factory();
49957    }) : "object" == typeof module && module.exports ? // Node. Does not work with strict CommonJS, but
49958    // only CommonJS-like environments that support module.exports,
49959    // like Node.
49960    module.exports = factory() : root.svg4everybody = factory();
49961}(this, function() {
49962    /*! svg4everybody v2.1.9 | github.com/jonathantneal/svg4everybody */
49963    function embed(parent, svg, target) {
49964        // if the target exists
49965        if (target) {
49966            // create a document fragment to hold the contents of the target
49967            var fragment = document.createDocumentFragment(), viewBox = !svg.hasAttribute("viewBox") && target.getAttribute("viewBox");
49968            // conditionally set the viewBox on the svg
vendor: 5,596 bytes, lines 49969-50077
49969            viewBox && svg.setAttribute("viewBox", viewBox);
49970            // copy the contents of the clone into the fragment
49971            for (// clone the target
49972            var clone = target.cloneNode(!0); clone.childNodes.length; ) {
49973                fragment.appendChild(clone.firstChild);
49974            }
49975            // append the fragment into the svg
49976            parent.appendChild(fragment);
49977        }
49978    }
49979    function loadreadystatechange(xhr) {
49980        // listen to changes in the request
49981        xhr.onreadystatechange = function() {
49982            // if the request is ready
49983            if (4 === xhr.readyState) {
49984                // get the cached html document
49985                var cachedDocument = xhr._cachedDocument;
49986                // ensure the cached html document based on the xhr response
49987                cachedDocument || (cachedDocument = xhr._cachedDocument = document.implementation.createHTMLDocument(""), 
49988                cachedDocument.body.innerHTML = xhr.responseText, xhr._cachedTarget = {}), // clear the xhr embeds list and embed each item
49989                xhr._embeds.splice(0).map(function(item) {
49990                    // get the cached target
49991                    var target = xhr._cachedTarget[item.id];
49992                    // ensure the cached target
49993                    target || (target = xhr._cachedTarget[item.id] = cachedDocument.getElementById(item.id)), 
49994                    // embed the target into the svg
49995                    embed(item.parent, item.svg, target);
49996                });
49997            }
49998        }, // test the ready state change immediately
49999        xhr.onreadystatechange();
50000    }
50001    function svg4everybody(rawopts) {
50002        function oninterval() {
50003            // while the index exists in the live <use> collection
50004            for (// get the cached <use> index
50005            var index = 0; index < uses.length; ) {
50006                // get the current <use>
50007                var use = uses[index], parent = use.parentNode, svg = getSVGAncestor(parent), src = use.getAttribute("xlink:href") || use.getAttribute("href");
50008                if (!src && opts.attributeName && (src = use.getAttribute(opts.attributeName)), 
50009                svg && src) {
50010                    if (polyfill) {
50011                        if (!opts.validate || opts.validate(src, svg, use)) {
50012                            // remove the <use> element
50013                            parent.removeChild(use);
50014                            // parse the src and get the url and id
50015                            var srcSplit = src.split("#"), url = srcSplit.shift(), id = srcSplit.join("#");
50016                            // if the link is external
50017                            if (url.length) {
50018                                // get the cached xhr request
50019                                var xhr = requests[url];
50020                                // ensure the xhr request exists
50021                                xhr || (xhr = requests[url] = new XMLHttpRequest(), xhr.open("GET", url), xhr.send(), 
50022                                xhr._embeds = []), // add the svg and id as an item to the xhr embeds list
50023                                xhr._embeds.push({
50024                                    parent: parent,
50025                                    svg: svg,
50026                                    id: id
50027                                }), // prepare the xhr ready state change event
50028                                loadreadystatechange(xhr);
50029                            } else {
50030                                // embed the local id into the svg
50031                                embed(parent, svg, document.getElementById(id));
50032                            }
50033                        } else {
50034                            // increase the index when the previous value was not "valid"
50035                            ++index, ++numberOfSvgUseElementsToBypass;
50036                        }
50037                    }
50038                } else {
50039                    // increase the index when the previous value was not "valid"
50040                    ++index;
50041                }
50042            }
50043            // continue the interval
50044            (!uses.length || uses.length - numberOfSvgUseElementsToBypass > 0) && requestAnimationFrame(oninterval, 67);
50045        }
50046        var polyfill, opts = Object(rawopts), newerIEUA = /\bTrident\/[567]\b|\bMSIE (?:9|10)\.0\b/, webkitUA = /\bAppleWebKit\/(\d+)\b/, olderEdgeUA = /\bEdge\/12\.(\d+)\b/, edgeUA = /\bEdge\/.(\d+)\b/, inIframe = window.top !== window.self;
50047        polyfill = "polyfill" in opts ? opts.polyfill : newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe;
50048        // create xhr requests object
50049        var requests = {}, requestAnimationFrame = window.requestAnimationFrame || setTimeout, uses = document.getElementsByTagName("use"), numberOfSvgUseElementsToBypass = 0;
50050        // conditionally start the interval if the polyfill is active
50051        polyfill && oninterval();
50052    }
50053    function getSVGAncestor(node) {
50054        for (var svg = node; "svg" !== svg.nodeName.toLowerCase() && (svg = svg.parentNode); ) {}
50055        return svg;
50056    }
50057    return svg4everybody;
50058});
50059},{}],368:[function(require,module,exports){
50060module.exports={
50061	"resourcePath": "./server/download.php",
50062	"avatarResourcePath": "/teamchatapi/files.avatar",
50063	"icewarpapiUrl": "",
50064	"i18n": {
50065		"url": "locale/%s/data.json",
50066		"map": {
50067			"zh": "cn",
50068			"da": "dk",
50069			"ja": "jp",
50070			"ko": "kr",
50071			"sv": "se"
50072		}
50073	},
50074	"sentry": false
50075}
50076
50077},{}]},{},[41]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.