PluginProbe
HubSpot All-In-One Marketing – Forms, Popups, Live Chat / 11.1.14
HubSpot All-In-One Marketing – Forms, Popups, Live Chat v11.1.14
11.3.75 11.3.73 11.3.71 11.3.70 11.3.69 11.3.64 11.3.65 11.3.62 11.3.61 11.3.56 11.3.58 11.0.31 11.0.52 11.0.54 11.0.56 11.0.58 11.0.7 11.1.10 11.1.11 11.1.13 11.1.14 11.1.15 11.1.2 11.1.20 11.1.21 All 73 releases
leadin / build / reviewBanner.js

reviewBanner.js in HubSpot All-In-One Marketing – Forms, Popups, Live Chat 11.1.14, at build/reviewBanner.js

3,731 lines 119.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ "./scripts/constants/leadinConfig.ts":
5 /*!*******************************************!*\
6 !*** ./scripts/constants/leadinConfig.ts ***!
7 \*******************************************/
8 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9
10 "use strict";
11 __webpack_require__.r(__webpack_exports__);
12 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
13 /* harmony export */ "accountName": () => (/* binding */ accountName),
14 /* harmony export */ "activationTime": () => (/* binding */ activationTime),
15 /* harmony export */ "adminUrl": () => (/* binding */ adminUrl),
16 /* harmony export */ "connectionStatus": () => (/* binding */ connectionStatus),
17 /* harmony export */ "contentEmbed": () => (/* binding */ contentEmbed),
18 /* harmony export */ "deviceId": () => (/* binding */ deviceId),
19 /* harmony export */ "didDisconnect": () => (/* binding */ didDisconnect),
20 /* harmony export */ "encryptionError": () => (/* binding */ encryptionError),
21 /* harmony export */ "env": () => (/* binding */ env),
22 /* harmony export */ "formsScript": () => (/* binding */ formsScript),
23 /* harmony export */ "formsScriptPayload": () => (/* binding */ formsScriptPayload),
24 /* harmony export */ "hublet": () => (/* binding */ hublet),
25 /* harmony export */ "hubspotBaseUrl": () => (/* binding */ hubspotBaseUrl),
26 /* harmony export */ "hubspotNonce": () => (/* binding */ hubspotNonce),
27 /* harmony export */ "iframeUrl": () => (/* binding */ iframeUrl),
28 /* harmony export */ "impactLink": () => (/* binding */ impactLink),
29 /* harmony export */ "lastAuthorizeTime": () => (/* binding */ lastAuthorizeTime),
30 /* harmony export */ "lastDeauthorizeTime": () => (/* binding */ lastDeauthorizeTime),
31 /* harmony export */ "lastDisconnectTime": () => (/* binding */ lastDisconnectTime),
32 /* harmony export */ "leadinPluginVersion": () => (/* binding */ leadinPluginVersion),
33 /* harmony export */ "leadinQueryParams": () => (/* binding */ leadinQueryParams),
34 /* harmony export */ "locale": () => (/* binding */ locale),
35 /* harmony export */ "loginUrl": () => (/* binding */ loginUrl),
36 /* harmony export */ "meetingsScript": () => (/* binding */ meetingsScript),
37 /* harmony export */ "phpVersion": () => (/* binding */ phpVersion),
38 /* harmony export */ "pluginPath": () => (/* binding */ pluginPath),
39 /* harmony export */ "plugins": () => (/* binding */ plugins),
40 /* harmony export */ "portalDomain": () => (/* binding */ portalDomain),
41 /* harmony export */ "portalEmail": () => (/* binding */ portalEmail),
42 /* harmony export */ "portalId": () => (/* binding */ portalId),
43 /* harmony export */ "redirectNonce": () => (/* binding */ redirectNonce),
44 /* harmony export */ "refreshToken": () => (/* binding */ refreshToken),
45 /* harmony export */ "refreshTokenError": () => (/* binding */ refreshTokenError),
46 /* harmony export */ "requiresContentEmbedScope": () => (/* binding */ requiresContentEmbedScope),
47 /* harmony export */ "restNonce": () => (/* binding */ restNonce),
48 /* harmony export */ "restUrl": () => (/* binding */ restUrl),
49 /* harmony export */ "reviewSkippedDate": () => (/* binding */ reviewSkippedDate),
50 /* harmony export */ "theme": () => (/* binding */ theme),
51 /* harmony export */ "trackConsent": () => (/* binding */ trackConsent),
52 /* harmony export */ "wpVersion": () => (/* binding */ wpVersion)
53 /* harmony export */ });
54 var _window$leadinConfig = window.leadinConfig,
55 accountName = _window$leadinConfig.accountName,
56 adminUrl = _window$leadinConfig.adminUrl,
57 activationTime = _window$leadinConfig.activationTime,
58 connectionStatus = _window$leadinConfig.connectionStatus,
59 deviceId = _window$leadinConfig.deviceId,
60 didDisconnect = _window$leadinConfig.didDisconnect,
61 env = _window$leadinConfig.env,
62 formsScript = _window$leadinConfig.formsScript,
63 meetingsScript = _window$leadinConfig.meetingsScript,
64 formsScriptPayload = _window$leadinConfig.formsScriptPayload,
65 hublet = _window$leadinConfig.hublet,
66 hubspotBaseUrl = _window$leadinConfig.hubspotBaseUrl,
67 hubspotNonce = _window$leadinConfig.hubspotNonce,
68 iframeUrl = _window$leadinConfig.iframeUrl,
69 impactLink = _window$leadinConfig.impactLink,
70 lastAuthorizeTime = _window$leadinConfig.lastAuthorizeTime,
71 lastDeauthorizeTime = _window$leadinConfig.lastDeauthorizeTime,
72 lastDisconnectTime = _window$leadinConfig.lastDisconnectTime,
73 leadinPluginVersion = _window$leadinConfig.leadinPluginVersion,
74 leadinQueryParams = _window$leadinConfig.leadinQueryParams,
75 locale = _window$leadinConfig.locale,
76 loginUrl = _window$leadinConfig.loginUrl,
77 phpVersion = _window$leadinConfig.phpVersion,
78 pluginPath = _window$leadinConfig.pluginPath,
79 plugins = _window$leadinConfig.plugins,
80 portalDomain = _window$leadinConfig.portalDomain,
81 portalEmail = _window$leadinConfig.portalEmail,
82 portalId = _window$leadinConfig.portalId,
83 redirectNonce = _window$leadinConfig.redirectNonce,
84 restNonce = _window$leadinConfig.restNonce,
85 restUrl = _window$leadinConfig.restUrl,
86 refreshToken = _window$leadinConfig.refreshToken,
87 reviewSkippedDate = _window$leadinConfig.reviewSkippedDate,
88 theme = _window$leadinConfig.theme,
89 trackConsent = _window$leadinConfig.trackConsent,
90 wpVersion = _window$leadinConfig.wpVersion,
91 contentEmbed = _window$leadinConfig.contentEmbed,
92 requiresContentEmbedScope = _window$leadinConfig.requiresContentEmbedScope,
93 refreshTokenError = _window$leadinConfig.refreshTokenError,
94 encryptionError = _window$leadinConfig.encryptionError;
95
96
97 /***/ }),
98
99 /***/ "./scripts/constants/selectors.ts":
100 /*!****************************************!*\
101 !*** ./scripts/constants/selectors.ts ***!
102 \****************************************/
103 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
104
105 "use strict";
106 __webpack_require__.r(__webpack_exports__);
107 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
108 /* harmony export */ "domElements": () => (/* binding */ domElements)
109 /* harmony export */ });
110 var domElements = {
111 iframe: '#leadin-iframe',
112 subMenu: '.toplevel_page_leadin > ul',
113 subMenuLinks: '.toplevel_page_leadin > ul a',
114 subMenuButtons: '.toplevel_page_leadin > ul > li',
115 deactivatePluginButton: '[data-slug="leadin"] .deactivate a',
116 deactivateFeedbackForm: 'form.leadin-deactivate-form',
117 deactivateFeedbackSubmit: 'button#leadin-feedback-submit',
118 deactivateFeedbackSkip: 'button#leadin-feedback-skip',
119 thickboxModalClose: '.leadin-modal-close',
120 thickboxModalWindow: 'div#TB_window.thickbox-loading',
121 thickboxModalContent: 'div#TB_ajaxContent.TB_modal',
122 reviewBannerContainer: '#leadin-review-banner',
123 reviewBannerLeaveReviewLink: 'a#leave-review-button',
124 reviewBannerDismissButton: 'a#dismiss-review-banner-button',
125 leadinIframeContainer: 'leadin-iframe-container',
126 leadinIframe: 'leadin-iframe',
127 leadinIframeFallbackContainer: 'leadin-iframe-fallback-container'
128 };
129
130 /***/ }),
131
132 /***/ "./scripts/iframe/integratedMessages/core/CoreMessages.ts":
133 /*!****************************************************************!*\
134 !*** ./scripts/iframe/integratedMessages/core/CoreMessages.ts ***!
135 \****************************************************************/
136 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
137
138 "use strict";
139 __webpack_require__.r(__webpack_exports__);
140 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
141 /* harmony export */ "CoreMessages": () => (/* binding */ CoreMessages)
142 /* harmony export */ });
143 var CoreMessages = {
144 HandshakeReceive: 'INTEGRATED_APP_EMBEDDER_HANDSHAKE_RECEIVED',
145 SendRefreshToken: 'INTEGRATED_APP_EMBEDDER_SEND_REFRESH_TOKEN',
146 ReloadParentFrame: 'INTEGRATED_APP_EMBEDDER_RELOAD_PARENT_FRAME',
147 RedirectParentFrame: 'INTEGRATED_APP_EMBEDDER_REDIRECT_PARENT_FRAME',
148 SendLocale: 'INTEGRATED_APP_EMBEDDER_SEND_LOCALE',
149 SendDeviceId: 'INTEGRATED_APP_EMBEDDER_SEND_DEVICE_ID'
150 };
151
152 /***/ }),
153
154 /***/ "./scripts/iframe/integratedMessages/forms/FormsMessages.ts":
155 /*!******************************************************************!*\
156 !*** ./scripts/iframe/integratedMessages/forms/FormsMessages.ts ***!
157 \******************************************************************/
158 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
159
160 "use strict";
161 __webpack_require__.r(__webpack_exports__);
162 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
163 /* harmony export */ "FormMessages": () => (/* binding */ FormMessages)
164 /* harmony export */ });
165 var FormMessages = {
166 CreateFormAppNavigation: 'CREATE_FORM_APP_NAVIGATION'
167 };
168
169 /***/ }),
170
171 /***/ "./scripts/iframe/integratedMessages/index.ts":
172 /*!****************************************************!*\
173 !*** ./scripts/iframe/integratedMessages/index.ts ***!
174 \****************************************************/
175 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
176
177 "use strict";
178 __webpack_require__.r(__webpack_exports__);
179 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
180 /* harmony export */ "CoreMessages": () => (/* reexport safe */ _core_CoreMessages__WEBPACK_IMPORTED_MODULE_0__.CoreMessages),
181 /* harmony export */ "FormMessages": () => (/* reexport safe */ _forms_FormsMessages__WEBPACK_IMPORTED_MODULE_1__.FormMessages),
182 /* harmony export */ "LiveChatMessages": () => (/* reexport safe */ _livechat_LiveChatMessages__WEBPACK_IMPORTED_MODULE_2__.LiveChatMessages),
183 /* harmony export */ "PluginMessages": () => (/* reexport safe */ _plugin_PluginMessages__WEBPACK_IMPORTED_MODULE_3__.PluginMessages),
184 /* harmony export */ "ProxyMessages": () => (/* reexport safe */ _proxy_ProxyMessages__WEBPACK_IMPORTED_MODULE_4__.ProxyMessages)
185 /* harmony export */ });
186 /* harmony import */ var _core_CoreMessages__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./core/CoreMessages */ "./scripts/iframe/integratedMessages/core/CoreMessages.ts");
187 /* harmony import */ var _forms_FormsMessages__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./forms/FormsMessages */ "./scripts/iframe/integratedMessages/forms/FormsMessages.ts");
188 /* harmony import */ var _livechat_LiveChatMessages__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./livechat/LiveChatMessages */ "./scripts/iframe/integratedMessages/livechat/LiveChatMessages.ts");
189 /* harmony import */ var _plugin_PluginMessages__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./plugin/PluginMessages */ "./scripts/iframe/integratedMessages/plugin/PluginMessages.ts");
190 /* harmony import */ var _proxy_ProxyMessages__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./proxy/ProxyMessages */ "./scripts/iframe/integratedMessages/proxy/ProxyMessages.ts");
191
192
193
194
195
196
197 /***/ }),
198
199 /***/ "./scripts/iframe/integratedMessages/livechat/LiveChatMessages.ts":
200 /*!************************************************************************!*\
201 !*** ./scripts/iframe/integratedMessages/livechat/LiveChatMessages.ts ***!
202 \************************************************************************/
203 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
204
205 "use strict";
206 __webpack_require__.r(__webpack_exports__);
207 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
208 /* harmony export */ "LiveChatMessages": () => (/* binding */ LiveChatMessages)
209 /* harmony export */ });
210 var LiveChatMessages = {
211 CreateLiveChatAppNavigation: 'CREATE_LIVE_CHAT_APP_NAVIGATION'
212 };
213
214 /***/ }),
215
216 /***/ "./scripts/iframe/integratedMessages/plugin/PluginMessages.ts":
217 /*!********************************************************************!*\
218 !*** ./scripts/iframe/integratedMessages/plugin/PluginMessages.ts ***!
219 \********************************************************************/
220 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
221
222 "use strict";
223 __webpack_require__.r(__webpack_exports__);
224 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
225 /* harmony export */ "PluginMessages": () => (/* binding */ PluginMessages)
226 /* harmony export */ });
227 var PluginMessages = {
228 PluginSettingsNavigation: 'PLUGIN_SETTINGS_NAVIGATION',
229 PluginLeadinConfig: 'PLUGIN_LEADIN_CONFIG',
230 TrackConsent: 'INTEGRATED_APP_EMBEDDER_TRACK_CONSENT',
231 InternalTrackingFetchRequest: 'INTEGRATED_TRACKING_FETCH_REQUEST',
232 InternalTrackingFetchResponse: 'INTEGRATED_TRACKING_FETCH_RESPONSE',
233 InternalTrackingFetchError: 'INTEGRATED_TRACKING_FETCH_ERROR',
234 InternalTrackingChangeRequest: 'INTEGRATED_TRACKING_CHANGE_REQUEST',
235 InternalTrackingChangeError: 'INTEGRATED_TRACKING_CHANGE_ERROR',
236 BusinessUnitFetchRequest: 'BUSINESS_UNIT_FETCH_REQUEST',
237 BusinessUnitFetchResponse: 'BUSINESS_UNIT_FETCH_FETCH_RESPONSE',
238 BusinessUnitFetchError: 'BUSINESS_UNIT_FETCH_FETCH_ERROR',
239 BusinessUnitChangeRequest: 'BUSINESS_UNIT_CHANGE_REQUEST',
240 BusinessUnitChangeError: 'BUSINESS_UNIT_CHANGE_ERROR',
241 SkipReviewRequest: 'SKIP_REVIEW_REQUEST',
242 SkipReviewResponse: 'SKIP_REVIEW_RESPONSE',
243 SkipReviewError: 'SKIP_REVIEW_ERROR',
244 RemoveParentQueryParam: 'REMOVE_PARENT_QUERY_PARAM',
245 ContentEmbedInstallRequest: 'CONTENT_EMBED_INSTALL_REQUEST',
246 ContentEmbedInstallResponse: 'CONTENT_EMBED_INSTALL_RESPONSE',
247 ContentEmbedInstallError: 'CONTENT_EMBED_INSTALL_ERROR',
248 ContentEmbedActivationRequest: 'CONTENT_EMBED_ACTIVATION_REQUEST',
249 ContentEmbedActivationResponse: 'CONTENT_EMBED_ACTIVATION_RESPONSE',
250 ContentEmbedActivationError: 'CONTENT_EMBED_ACTIVATION_ERROR'
251 };
252
253 /***/ }),
254
255 /***/ "./scripts/iframe/integratedMessages/proxy/ProxyMessages.ts":
256 /*!******************************************************************!*\
257 !*** ./scripts/iframe/integratedMessages/proxy/ProxyMessages.ts ***!
258 \******************************************************************/
259 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
260
261 "use strict";
262 __webpack_require__.r(__webpack_exports__);
263 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
264 /* harmony export */ "ProxyMessages": () => (/* binding */ ProxyMessages)
265 /* harmony export */ });
266 var ProxyMessages = {
267 FetchForms: 'FETCH_FORMS',
268 FetchForm: 'FETCH_FORM',
269 CreateFormFromTemplate: 'CREATE_FORM_FROM_TEMPLATE',
270 FetchAuth: 'FETCH_AUTH',
271 FetchMeetingsAndUsers: 'FETCH_MEETINGS_AND_USERS',
272 FetchContactsCreateSinceActivation: 'FETCH_CONTACTS_CREATED_SINCE_ACTIVATION',
273 FetchOrCreateMeetingUser: 'FETCH_OR_CREATE_MEETING_USER',
274 ConnectMeetingsCalendar: 'CONNECT_MEETINGS_CALENDAR',
275 TrackFormPreviewRender: 'TRACK_FORM_PREVIEW_RENDER',
276 TrackFormCreatedFromTemplate: 'TRACK_FORM_CREATED_FROM_TEMPLATE',
277 TrackFormCreationFailed: 'TRACK_FORM_CREATION_FAILED',
278 TrackMeetingPreviewRender: 'TRACK_MEETING_PREVIEW_RENDER',
279 TrackSidebarMetaChange: 'TRACK_SIDEBAR_META_CHANGE',
280 TrackReviewBannerRender: 'TRACK_REVIEW_BANNER_RENDER',
281 TrackReviewBannerInteraction: 'TRACK_REVIEW_BANNER_INTERACTION',
282 TrackReviewBannerDismissed: 'TRACK_REVIEW_BANNER_DISMISSED',
283 TrackPluginDeactivation: 'TRACK_PLUGIN_DEACTIVATION'
284 };
285
286 /***/ }),
287
288 /***/ "./scripts/lib/Raven.ts":
289 /*!******************************!*\
290 !*** ./scripts/lib/Raven.ts ***!
291 \******************************/
292 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
293
294 "use strict";
295 __webpack_require__.r(__webpack_exports__);
296 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
297 /* harmony export */ "configureRaven": () => (/* binding */ configureRaven),
298 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
299 /* harmony export */ });
300 /* harmony import */ var raven_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! raven-js */ "./node_modules/raven-js/src/singleton.js");
301 /* harmony import */ var raven_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(raven_js__WEBPACK_IMPORTED_MODULE_0__);
302 /* harmony import */ var _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../constants/leadinConfig */ "./scripts/constants/leadinConfig.ts");
303
304
305 function configureRaven() {
306 if (_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.hubspotBaseUrl.indexOf('app.hubspot.com') === -1) {
307 return;
308 }
309
310 raven_js__WEBPACK_IMPORTED_MODULE_0___default().config('https://e9b8f382cdd130c0d415cd977d2be56f@exceptions.hubspot.com/1', {
311 instrument: {
312 tryCatch: false
313 },
314 release: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.leadinPluginVersion
315 }).install();
316 raven_js__WEBPACK_IMPORTED_MODULE_0___default().setTagsContext({
317 v: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.leadinPluginVersion,
318 php: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.phpVersion,
319 wordpress: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.wpVersion
320 });
321 raven_js__WEBPACK_IMPORTED_MODULE_0___default().setExtraContext({
322 hub: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.portalId,
323 plugins: Object.keys(_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.plugins).map(function (name) {
324 return "".concat(name, "#").concat(_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.plugins[name]);
325 }).join(',')
326 });
327 }
328 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((raven_js__WEBPACK_IMPORTED_MODULE_0___default()));
329
330 /***/ }),
331
332 /***/ "./scripts/utils/appUtils.ts":
333 /*!***********************************!*\
334 !*** ./scripts/utils/appUtils.ts ***!
335 \***********************************/
336 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
337
338 "use strict";
339 __webpack_require__.r(__webpack_exports__);
340 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
341 /* harmony export */ "initApp": () => (/* binding */ initApp),
342 /* harmony export */ "initAppOnReady": () => (/* binding */ initAppOnReady)
343 /* harmony export */ });
344 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery");
345 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
346 /* harmony import */ var _lib_Raven__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../lib/Raven */ "./scripts/lib/Raven.ts");
347
348
349 function initApp(initFn) {
350 (0,_lib_Raven__WEBPACK_IMPORTED_MODULE_1__.configureRaven)();
351 _lib_Raven__WEBPACK_IMPORTED_MODULE_1__["default"].context(initFn);
352 }
353 function initAppOnReady(initFn) {
354 function main() {
355 jquery__WEBPACK_IMPORTED_MODULE_0___default()(initFn);
356 }
357
358 initApp(main);
359 }
360
361 /***/ }),
362
363 /***/ "./scripts/utils/backgroundAppUtils.ts":
364 /*!*********************************************!*\
365 !*** ./scripts/utils/backgroundAppUtils.ts ***!
366 \*********************************************/
367 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
368
369 "use strict";
370 __webpack_require__.r(__webpack_exports__);
371 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
372 /* harmony export */ "getOrCreateBackgroundApp": () => (/* binding */ getOrCreateBackgroundApp),
373 /* harmony export */ "initBackgroundApp": () => (/* binding */ initBackgroundApp)
374 /* harmony export */ });
375 /* harmony import */ var _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../constants/leadinConfig */ "./scripts/constants/leadinConfig.ts");
376 /* harmony import */ var _appUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./appUtils */ "./scripts/utils/appUtils.ts");
377
378
379 function initBackgroundApp(initFn) {
380 function main() {
381 if (Array.isArray(initFn)) {
382 initFn.forEach(function (callback) {
383 return callback();
384 });
385 } else {
386 initFn();
387 }
388 }
389
390 (0,_appUtils__WEBPACK_IMPORTED_MODULE_1__.initApp)(main);
391 }
392 var getOrCreateBackgroundApp = function getOrCreateBackgroundApp(refreshToken) {
393 if (window.LeadinBackgroundApp) {
394 return window.LeadinBackgroundApp;
395 }
396
397 var _window = window,
398 IntegratedAppEmbedder = _window.IntegratedAppEmbedder,
399 IntegratedAppOptions = _window.IntegratedAppOptions;
400 var options = new IntegratedAppOptions().setLocale(_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__.locale).setDeviceId(_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__.deviceId).setRefreshToken(refreshToken);
401 var embedder = new IntegratedAppEmbedder('integrated-plugin-proxy', _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__.portalId, _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__.hubspotBaseUrl, function () {}).setOptions(options);
402 embedder.attachTo(document.body, false);
403 embedder.postStartAppMessage(); // lets the app know all all data has been passed to it
404
405 window.LeadinBackgroundApp = embedder;
406 return window.LeadinBackgroundApp;
407 };
408
409 /***/ }),
410
411 /***/ "./node_modules/raven-js/src/configError.js":
412 /*!**************************************************!*\
413 !*** ./node_modules/raven-js/src/configError.js ***!
414 \**************************************************/
415 /***/ ((module) => {
416
417 function RavenConfigError(message) {
418 this.name = 'RavenConfigError';
419 this.message = message;
420 }
421 RavenConfigError.prototype = new Error();
422 RavenConfigError.prototype.constructor = RavenConfigError;
423
424 module.exports = RavenConfigError;
425
426
427 /***/ }),
428
429 /***/ "./node_modules/raven-js/src/console.js":
430 /*!**********************************************!*\
431 !*** ./node_modules/raven-js/src/console.js ***!
432 \**********************************************/
433 /***/ ((module) => {
434
435 var wrapMethod = function(console, level, callback) {
436 var originalConsoleLevel = console[level];
437 var originalConsole = console;
438
439 if (!(level in console)) {
440 return;
441 }
442
443 var sentryLevel = level === 'warn' ? 'warning' : level;
444
445 console[level] = function() {
446 var args = [].slice.call(arguments);
447
448 var msg = '' + args.join(' ');
449 var data = {level: sentryLevel, logger: 'console', extra: {arguments: args}};
450
451 if (level === 'assert') {
452 if (args[0] === false) {
453 // Default browsers message
454 msg = 'Assertion failed: ' + (args.slice(1).join(' ') || 'console.assert');
455 data.extra.arguments = args.slice(1);
456 callback && callback(msg, data);
457 }
458 } else {
459 callback && callback(msg, data);
460 }
461
462 // this fails for some browsers. :(
463 if (originalConsoleLevel) {
464 // IE9 doesn't allow calling apply on console functions directly
465 // See: https://stackoverflow.com/questions/5472938/does-ie9-support-console-log-and-is-it-a-real-function#answer-5473193
466 Function.prototype.apply.call(originalConsoleLevel, originalConsole, args);
467 }
468 };
469 };
470
471 module.exports = {
472 wrapMethod: wrapMethod
473 };
474
475
476 /***/ }),
477
478 /***/ "./node_modules/raven-js/src/raven.js":
479 /*!********************************************!*\
480 !*** ./node_modules/raven-js/src/raven.js ***!
481 \********************************************/
482 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
483
484 /*global XDomainRequest:false */
485
486 var TraceKit = __webpack_require__(/*! ../vendor/TraceKit/tracekit */ "./node_modules/raven-js/vendor/TraceKit/tracekit.js");
487 var stringify = __webpack_require__(/*! ../vendor/json-stringify-safe/stringify */ "./node_modules/raven-js/vendor/json-stringify-safe/stringify.js");
488 var RavenConfigError = __webpack_require__(/*! ./configError */ "./node_modules/raven-js/src/configError.js");
489
490 var utils = __webpack_require__(/*! ./utils */ "./node_modules/raven-js/src/utils.js");
491 var isError = utils.isError;
492 var isObject = utils.isObject;
493 var isObject = utils.isObject;
494 var isErrorEvent = utils.isErrorEvent;
495 var isUndefined = utils.isUndefined;
496 var isFunction = utils.isFunction;
497 var isString = utils.isString;
498 var isEmptyObject = utils.isEmptyObject;
499 var each = utils.each;
500 var objectMerge = utils.objectMerge;
501 var truncate = utils.truncate;
502 var objectFrozen = utils.objectFrozen;
503 var hasKey = utils.hasKey;
504 var joinRegExp = utils.joinRegExp;
505 var urlencode = utils.urlencode;
506 var uuid4 = utils.uuid4;
507 var htmlTreeAsString = utils.htmlTreeAsString;
508 var isSameException = utils.isSameException;
509 var isSameStacktrace = utils.isSameStacktrace;
510 var parseUrl = utils.parseUrl;
511 var fill = utils.fill;
512
513 var wrapConsoleMethod = (__webpack_require__(/*! ./console */ "./node_modules/raven-js/src/console.js").wrapMethod);
514
515 var dsnKeys = 'source protocol user pass host port path'.split(' '),
516 dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;
517
518 function now() {
519 return +new Date();
520 }
521
522 // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785)
523 var _window =
524 typeof window !== 'undefined'
525 ? window
526 : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof self !== 'undefined' ? self : {};
527 var _document = _window.document;
528 var _navigator = _window.navigator;
529
530 function keepOriginalCallback(original, callback) {
531 return isFunction(callback)
532 ? function(data) {
533 return callback(data, original);
534 }
535 : callback;
536 }
537
538 // First, check for JSON support
539 // If there is no JSON, we no-op the core features of Raven
540 // since JSON is required to encode the payload
541 function Raven() {
542 this._hasJSON = !!(typeof JSON === 'object' && JSON.stringify);
543 // Raven can run in contexts where there's no document (react-native)
544 this._hasDocument = !isUndefined(_document);
545 this._hasNavigator = !isUndefined(_navigator);
546 this._lastCapturedException = null;
547 this._lastData = null;
548 this._lastEventId = null;
549 this._globalServer = null;
550 this._globalKey = null;
551 this._globalProject = null;
552 this._globalContext = {};
553 this._globalOptions = {
554 logger: 'javascript',
555 ignoreErrors: [],
556 ignoreUrls: [],
557 whitelistUrls: [],
558 includePaths: [],
559 collectWindowErrors: true,
560 maxMessageLength: 0,
561
562 // By default, truncates URL values to 250 chars
563 maxUrlLength: 250,
564 stackTraceLimit: 50,
565 autoBreadcrumbs: true,
566 instrument: true,
567 sampleRate: 1
568 };
569 this._ignoreOnError = 0;
570 this._isRavenInstalled = false;
571 this._originalErrorStackTraceLimit = Error.stackTraceLimit;
572 // capture references to window.console *and* all its methods first
573 // before the console plugin has a chance to monkey patch
574 this._originalConsole = _window.console || {};
575 this._originalConsoleMethods = {};
576 this._plugins = [];
577 this._startTime = now();
578 this._wrappedBuiltIns = [];
579 this._breadcrumbs = [];
580 this._lastCapturedEvent = null;
581 this._keypressTimeout;
582 this._location = _window.location;
583 this._lastHref = this._location && this._location.href;
584 this._resetBackoff();
585
586 // eslint-disable-next-line guard-for-in
587 for (var method in this._originalConsole) {
588 this._originalConsoleMethods[method] = this._originalConsole[method];
589 }
590 }
591
592 /*
593 * The core Raven singleton
594 *
595 * @this {Raven}
596 */
597
598 Raven.prototype = {
599 // Hardcode version string so that raven source can be loaded directly via
600 // webpack (using a build step causes webpack #1617). Grunt verifies that
601 // this value matches package.json during build.
602 // See: https://github.com/getsentry/raven-js/issues/465
603 VERSION: '3.19.1',
604
605 debug: false,
606
607 TraceKit: TraceKit, // alias to TraceKit
608
609 /*
610 * Configure Raven with a DSN and extra options
611 *
612 * @param {string} dsn The public Sentry DSN
613 * @param {object} options Set of global options [optional]
614 * @return {Raven}
615 */
616 config: function(dsn, options) {
617 var self = this;
618
619 if (self._globalServer) {
620 this._logDebug('error', 'Error: Raven has already been configured');
621 return self;
622 }
623 if (!dsn) return self;
624
625 var globalOptions = self._globalOptions;
626
627 // merge in options
628 if (options) {
629 each(options, function(key, value) {
630 // tags and extra are special and need to be put into context
631 if (key === 'tags' || key === 'extra' || key === 'user') {
632 self._globalContext[key] = value;
633 } else {
634 globalOptions[key] = value;
635 }
636 });
637 }
638
639 self.setDSN(dsn);
640
641 // "Script error." is hard coded into browsers for errors that it can't read.
642 // this is the result of a script being pulled in from an external domain and CORS.
643 globalOptions.ignoreErrors.push(/^Script error\.?$/);
644 globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/);
645
646 // join regexp rules into one big rule
647 globalOptions.ignoreErrors = joinRegExp(globalOptions.ignoreErrors);
648 globalOptions.ignoreUrls = globalOptions.ignoreUrls.length
649 ? joinRegExp(globalOptions.ignoreUrls)
650 : false;
651 globalOptions.whitelistUrls = globalOptions.whitelistUrls.length
652 ? joinRegExp(globalOptions.whitelistUrls)
653 : false;
654 globalOptions.includePaths = joinRegExp(globalOptions.includePaths);
655 globalOptions.maxBreadcrumbs = Math.max(
656 0,
657 Math.min(globalOptions.maxBreadcrumbs || 100, 100)
658 ); // default and hard limit is 100
659
660 var autoBreadcrumbDefaults = {
661 xhr: true,
662 console: true,
663 dom: true,
664 location: true
665 };
666
667 var autoBreadcrumbs = globalOptions.autoBreadcrumbs;
668 if ({}.toString.call(autoBreadcrumbs) === '[object Object]') {
669 autoBreadcrumbs = objectMerge(autoBreadcrumbDefaults, autoBreadcrumbs);
670 } else if (autoBreadcrumbs !== false) {
671 autoBreadcrumbs = autoBreadcrumbDefaults;
672 }
673 globalOptions.autoBreadcrumbs = autoBreadcrumbs;
674
675 var instrumentDefaults = {
676 tryCatch: true
677 };
678
679 var instrument = globalOptions.instrument;
680 if ({}.toString.call(instrument) === '[object Object]') {
681 instrument = objectMerge(instrumentDefaults, instrument);
682 } else if (instrument !== false) {
683 instrument = instrumentDefaults;
684 }
685 globalOptions.instrument = instrument;
686
687 TraceKit.collectWindowErrors = !!globalOptions.collectWindowErrors;
688
689 // return for chaining
690 return self;
691 },
692
693 /*
694 * Installs a global window.onerror error handler
695 * to capture and report uncaught exceptions.
696 * At this point, install() is required to be called due
697 * to the way TraceKit is set up.
698 *
699 * @return {Raven}
700 */
701 install: function() {
702 var self = this;
703 if (self.isSetup() && !self._isRavenInstalled) {
704 TraceKit.report.subscribe(function() {
705 self._handleOnErrorStackInfo.apply(self, arguments);
706 });
707 if (self._globalOptions.instrument && self._globalOptions.instrument.tryCatch) {
708 self._instrumentTryCatch();
709 }
710
711 if (self._globalOptions.autoBreadcrumbs) self._instrumentBreadcrumbs();
712
713 // Install all of the plugins
714 self._drainPlugins();
715
716 self._isRavenInstalled = true;
717 }
718
719 Error.stackTraceLimit = self._globalOptions.stackTraceLimit;
720 return this;
721 },
722
723 /*
724 * Set the DSN (can be called multiple time unlike config)
725 *
726 * @param {string} dsn The public Sentry DSN
727 */
728 setDSN: function(dsn) {
729 var self = this,
730 uri = self._parseDSN(dsn),
731 lastSlash = uri.path.lastIndexOf('/'),
732 path = uri.path.substr(1, lastSlash);
733
734 self._dsn = dsn;
735 self._globalKey = uri.user;
736 self._globalSecret = uri.pass && uri.pass.substr(1);
737 self._globalProject = uri.path.substr(lastSlash + 1);
738
739 self._globalServer = self._getGlobalServer(uri);
740
741 self._globalEndpoint =
742 self._globalServer + '/' + path + 'api/' + self._globalProject + '/store/';
743
744 // Reset backoff state since we may be pointing at a
745 // new project/server
746 this._resetBackoff();
747 },
748
749 /*
750 * Wrap code within a context so Raven can capture errors
751 * reliably across domains that is executed immediately.
752 *
753 * @param {object} options A specific set of options for this context [optional]
754 * @param {function} func The callback to be immediately executed within the context
755 * @param {array} args An array of arguments to be called with the callback [optional]
756 */
757 context: function(options, func, args) {
758 if (isFunction(options)) {
759 args = func || [];
760 func = options;
761 options = undefined;
762 }
763
764 return this.wrap(options, func).apply(this, args);
765 },
766
767 /*
768 * Wrap code within a context and returns back a new function to be executed
769 *
770 * @param {object} options A specific set of options for this context [optional]
771 * @param {function} func The function to be wrapped in a new context
772 * @param {function} func A function to call before the try/catch wrapper [optional, private]
773 * @return {function} The newly wrapped functions with a context
774 */
775 wrap: function(options, func, _before) {
776 var self = this;
777 // 1 argument has been passed, and it's not a function
778 // so just return it
779 if (isUndefined(func) && !isFunction(options)) {
780 return options;
781 }
782
783 // options is optional
784 if (isFunction(options)) {
785 func = options;
786 options = undefined;
787 }
788
789 // At this point, we've passed along 2 arguments, and the second one
790 // is not a function either, so we'll just return the second argument.
791 if (!isFunction(func)) {
792 return func;
793 }
794
795 // We don't wanna wrap it twice!
796 try {
797 if (func.__raven__) {
798 return func;
799 }
800
801 // If this has already been wrapped in the past, return that
802 if (func.__raven_wrapper__) {
803 return func.__raven_wrapper__;
804 }
805 } catch (e) {
806 // Just accessing custom props in some Selenium environments
807 // can cause a "Permission denied" exception (see raven-js#495).
808 // Bail on wrapping and return the function as-is (defers to window.onerror).
809 return func;
810 }
811
812 function wrapped() {
813 var args = [],
814 i = arguments.length,
815 deep = !options || (options && options.deep !== false);
816
817 if (_before && isFunction(_before)) {
818 _before.apply(this, arguments);
819 }
820
821 // Recursively wrap all of a function's arguments that are
822 // functions themselves.
823 while (i--) args[i] = deep ? self.wrap(options, arguments[i]) : arguments[i];
824
825 try {
826 // Attempt to invoke user-land function
827 // NOTE: If you are a Sentry user, and you are seeing this stack frame, it
828 // means Raven caught an error invoking your application code. This is
829 // expected behavior and NOT indicative of a bug with Raven.js.
830 return func.apply(this, args);
831 } catch (e) {
832 self._ignoreNextOnError();
833 self.captureException(e, options);
834 throw e;
835 }
836 }
837
838 // copy over properties of the old function
839 for (var property in func) {
840 if (hasKey(func, property)) {
841 wrapped[property] = func[property];
842 }
843 }
844 wrapped.prototype = func.prototype;
845
846 func.__raven_wrapper__ = wrapped;
847 // Signal that this function has been wrapped already
848 // for both debugging and to prevent it to being wrapped twice
849 wrapped.__raven__ = true;
850 wrapped.__inner__ = func;
851
852 return wrapped;
853 },
854
855 /*
856 * Uninstalls the global error handler.
857 *
858 * @return {Raven}
859 */
860 uninstall: function() {
861 TraceKit.report.uninstall();
862
863 this._restoreBuiltIns();
864
865 Error.stackTraceLimit = this._originalErrorStackTraceLimit;
866 this._isRavenInstalled = false;
867
868 return this;
869 },
870
871 /*
872 * Manually capture an exception and send it over to Sentry
873 *
874 * @param {error} ex An exception to be logged
875 * @param {object} options A specific set of options for this error [optional]
876 * @return {Raven}
877 */
878 captureException: function(ex, options) {
879 // Cases for sending ex as a message, rather than an exception
880 var isNotError = !isError(ex);
881 var isNotErrorEvent = !isErrorEvent(ex);
882 var isErrorEventWithoutError = isErrorEvent(ex) && !ex.error;
883
884 if ((isNotError && isNotErrorEvent) || isErrorEventWithoutError) {
885 return this.captureMessage(
886 ex,
887 objectMerge(
888 {
889 trimHeadFrames: 1,
890 stacktrace: true // if we fall back to captureMessage, default to attempting a new trace
891 },
892 options
893 )
894 );
895 }
896
897 // Get actual Error from ErrorEvent
898 if (isErrorEvent(ex)) ex = ex.error;
899
900 // Store the raw exception object for potential debugging and introspection
901 this._lastCapturedException = ex;
902
903 // TraceKit.report will re-raise any exception passed to it,
904 // which means you have to wrap it in try/catch. Instead, we
905 // can wrap it here and only re-raise if TraceKit.report
906 // raises an exception different from the one we asked to
907 // report on.
908 try {
909 var stack = TraceKit.computeStackTrace(ex);
910 this._handleStackInfo(stack, options);
911 } catch (ex1) {
912 if (ex !== ex1) {
913 throw ex1;
914 }
915 }
916
917 return this;
918 },
919
920 /*
921 * Manually send a message to Sentry
922 *
923 * @param {string} msg A plain message to be captured in Sentry
924 * @param {object} options A specific set of options for this message [optional]
925 * @return {Raven}
926 */
927 captureMessage: function(msg, options) {
928 // config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an
929 // early call; we'll error on the side of logging anything called before configuration since it's
930 // probably something you should see:
931 if (
932 !!this._globalOptions.ignoreErrors.test &&
933 this._globalOptions.ignoreErrors.test(msg)
934 ) {
935 return;
936 }
937
938 options = options || {};
939
940 var data = objectMerge(
941 {
942 message: msg + '' // Make sure it's actually a string
943 },
944 options
945 );
946
947 var ex;
948 // Generate a "synthetic" stack trace from this point.
949 // NOTE: If you are a Sentry user, and you are seeing this stack frame, it is NOT indicative
950 // of a bug with Raven.js. Sentry generates synthetic traces either by configuration,
951 // or if it catches a thrown object without a "stack" property.
952 try {
953 throw new Error(msg);
954 } catch (ex1) {
955 ex = ex1;
956 }
957
958 // null exception name so `Error` isn't prefixed to msg
959 ex.name = null;
960 var stack = TraceKit.computeStackTrace(ex);
961
962 // stack[0] is `throw new Error(msg)` call itself, we are interested in the frame that was just before that, stack[1]
963 var initialCall = stack.stack[1];
964
965 var fileurl = (initialCall && initialCall.url) || '';
966
967 if (
968 !!this._globalOptions.ignoreUrls.test &&
969 this._globalOptions.ignoreUrls.test(fileurl)
970 ) {
971 return;
972 }
973
974 if (
975 !!this._globalOptions.whitelistUrls.test &&
976 !this._globalOptions.whitelistUrls.test(fileurl)
977 ) {
978 return;
979 }
980
981 if (this._globalOptions.stacktrace || (options && options.stacktrace)) {
982 options = objectMerge(
983 {
984 // fingerprint on msg, not stack trace (legacy behavior, could be
985 // revisited)
986 fingerprint: msg,
987 // since we know this is a synthetic trace, the top N-most frames
988 // MUST be from Raven.js, so mark them as in_app later by setting
989 // trimHeadFrames
990 trimHeadFrames: (options.trimHeadFrames || 0) + 1
991 },
992 options
993 );
994
995 var frames = this._prepareFrames(stack, options);
996 data.stacktrace = {
997 // Sentry expects frames oldest to newest
998 frames: frames.reverse()
999 };
1000 }
1001
1002 // Fire away!
1003 this._send(data);
1004
1005 return this;
1006 },
1007
1008 captureBreadcrumb: function(obj) {
1009 var crumb = objectMerge(
1010 {
1011 timestamp: now() / 1000
1012 },
1013 obj
1014 );
1015
1016 if (isFunction(this._globalOptions.breadcrumbCallback)) {
1017 var result = this._globalOptions.breadcrumbCallback(crumb);
1018
1019 if (isObject(result) && !isEmptyObject(result)) {
1020 crumb = result;
1021 } else if (result === false) {
1022 return this;
1023 }
1024 }
1025
1026 this._breadcrumbs.push(crumb);
1027 if (this._breadcrumbs.length > this._globalOptions.maxBreadcrumbs) {
1028 this._breadcrumbs.shift();
1029 }
1030 return this;
1031 },
1032
1033 addPlugin: function(plugin /*arg1, arg2, ... argN*/) {
1034 var pluginArgs = [].slice.call(arguments, 1);
1035
1036 this._plugins.push([plugin, pluginArgs]);
1037 if (this._isRavenInstalled) {
1038 this._drainPlugins();
1039 }
1040
1041 return this;
1042 },
1043
1044 /*
1045 * Set/clear a user to be sent along with the payload.
1046 *
1047 * @param {object} user An object representing user data [optional]
1048 * @return {Raven}
1049 */
1050 setUserContext: function(user) {
1051 // Intentionally do not merge here since that's an unexpected behavior.
1052 this._globalContext.user = user;
1053
1054 return this;
1055 },
1056
1057 /*
1058 * Merge extra attributes to be sent along with the payload.
1059 *
1060 * @param {object} extra An object representing extra data [optional]
1061 * @return {Raven}
1062 */
1063 setExtraContext: function(extra) {
1064 this._mergeContext('extra', extra);
1065
1066 return this;
1067 },
1068
1069 /*
1070 * Merge tags to be sent along with the payload.
1071 *
1072 * @param {object} tags An object representing tags [optional]
1073 * @return {Raven}
1074 */
1075 setTagsContext: function(tags) {
1076 this._mergeContext('tags', tags);
1077
1078 return this;
1079 },
1080
1081 /*
1082 * Clear all of the context.
1083 *
1084 * @return {Raven}
1085 */
1086 clearContext: function() {
1087 this._globalContext = {};
1088
1089 return this;
1090 },
1091
1092 /*
1093 * Get a copy of the current context. This cannot be mutated.
1094 *
1095 * @return {object} copy of context
1096 */
1097 getContext: function() {
1098 // lol javascript
1099 return JSON.parse(stringify(this._globalContext));
1100 },
1101
1102 /*
1103 * Set environment of application
1104 *
1105 * @param {string} environment Typically something like 'production'.
1106 * @return {Raven}
1107 */
1108 setEnvironment: function(environment) {
1109 this._globalOptions.environment = environment;
1110
1111 return this;
1112 },
1113
1114 /*
1115 * Set release version of application
1116 *
1117 * @param {string} release Typically something like a git SHA to identify version
1118 * @return {Raven}
1119 */
1120 setRelease: function(release) {
1121 this._globalOptions.release = release;
1122
1123 return this;
1124 },
1125
1126 /*
1127 * Set the dataCallback option
1128 *
1129 * @param {function} callback The callback to run which allows the
1130 * data blob to be mutated before sending
1131 * @return {Raven}
1132 */
1133 setDataCallback: function(callback) {
1134 var original = this._globalOptions.dataCallback;
1135 this._globalOptions.dataCallback = keepOriginalCallback(original, callback);
1136 return this;
1137 },
1138
1139 /*
1140 * Set the breadcrumbCallback option
1141 *
1142 * @param {function} callback The callback to run which allows filtering
1143 * or mutating breadcrumbs
1144 * @return {Raven}
1145 */
1146 setBreadcrumbCallback: function(callback) {
1147 var original = this._globalOptions.breadcrumbCallback;
1148 this._globalOptions.breadcrumbCallback = keepOriginalCallback(original, callback);
1149 return this;
1150 },
1151
1152 /*
1153 * Set the shouldSendCallback option
1154 *
1155 * @param {function} callback The callback to run which allows
1156 * introspecting the blob before sending
1157 * @return {Raven}
1158 */
1159 setShouldSendCallback: function(callback) {
1160 var original = this._globalOptions.shouldSendCallback;
1161 this._globalOptions.shouldSendCallback = keepOriginalCallback(original, callback);
1162 return this;
1163 },
1164
1165 /**
1166 * Override the default HTTP transport mechanism that transmits data
1167 * to the Sentry server.
1168 *
1169 * @param {function} transport Function invoked instead of the default
1170 * `makeRequest` handler.
1171 *
1172 * @return {Raven}
1173 */
1174 setTransport: function(transport) {
1175 this._globalOptions.transport = transport;
1176
1177 return this;
1178 },
1179
1180 /*
1181 * Get the latest raw exception that was captured by Raven.
1182 *
1183 * @return {error}
1184 */
1185 lastException: function() {
1186 return this._lastCapturedException;
1187 },
1188
1189 /*
1190 * Get the last event id
1191 *
1192 * @return {string}
1193 */
1194 lastEventId: function() {
1195 return this._lastEventId;
1196 },
1197
1198 /*
1199 * Determine if Raven is setup and ready to go.
1200 *
1201 * @return {boolean}
1202 */
1203 isSetup: function() {
1204 if (!this._hasJSON) return false; // needs JSON support
1205 if (!this._globalServer) {
1206 if (!this.ravenNotConfiguredError) {
1207 this.ravenNotConfiguredError = true;
1208 this._logDebug('error', 'Error: Raven has not been configured.');
1209 }
1210 return false;
1211 }
1212 return true;
1213 },
1214
1215 afterLoad: function() {
1216 // TODO: remove window dependence?
1217
1218 // Attempt to initialize Raven on load
1219 var RavenConfig = _window.RavenConfig;
1220 if (RavenConfig) {
1221 this.config(RavenConfig.dsn, RavenConfig.config).install();
1222 }
1223 },
1224
1225 showReportDialog: function(options) {
1226 if (
1227 !_document // doesn't work without a document (React native)
1228 )
1229 return;
1230
1231 options = options || {};
1232
1233 var lastEventId = options.eventId || this.lastEventId();
1234 if (!lastEventId) {
1235 throw new RavenConfigError('Missing eventId');
1236 }
1237
1238 var dsn = options.dsn || this._dsn;
1239 if (!dsn) {
1240 throw new RavenConfigError('Missing DSN');
1241 }
1242
1243 var encode = encodeURIComponent;
1244 var qs = '';
1245 qs += '?eventId=' + encode(lastEventId);
1246 qs += '&dsn=' + encode(dsn);
1247
1248 var user = options.user || this._globalContext.user;
1249 if (user) {
1250 if (user.name) qs += '&name=' + encode(user.name);
1251 if (user.email) qs += '&email=' + encode(user.email);
1252 }
1253
1254 var globalServer = this._getGlobalServer(this._parseDSN(dsn));
1255
1256 var script = _document.createElement('script');
1257 script.async = true;
1258 script.src = globalServer + '/api/embed/error-page/' + qs;
1259 (_document.head || _document.body).appendChild(script);
1260 },
1261
1262 /**** Private functions ****/
1263 _ignoreNextOnError: function() {
1264 var self = this;
1265 this._ignoreOnError += 1;
1266 setTimeout(function() {
1267 // onerror should trigger before setTimeout
1268 self._ignoreOnError -= 1;
1269 });
1270 },
1271
1272 _triggerEvent: function(eventType, options) {
1273 // NOTE: `event` is a native browser thing, so let's avoid conflicting wiht it
1274 var evt, key;
1275
1276 if (!this._hasDocument) return;
1277
1278 options = options || {};
1279
1280 eventType = 'raven' + eventType.substr(0, 1).toUpperCase() + eventType.substr(1);
1281
1282 if (_document.createEvent) {
1283 evt = _document.createEvent('HTMLEvents');
1284 evt.initEvent(eventType, true, true);
1285 } else {
1286 evt = _document.createEventObject();
1287 evt.eventType = eventType;
1288 }
1289
1290 for (key in options)
1291 if (hasKey(options, key)) {
1292 evt[key] = options[key];
1293 }
1294
1295 if (_document.createEvent) {
1296 // IE9 if standards
1297 _document.dispatchEvent(evt);
1298 } else {
1299 // IE8 regardless of Quirks or Standards
1300 // IE9 if quirks
1301 try {
1302 _document.fireEvent('on' + evt.eventType.toLowerCase(), evt);
1303 } catch (e) {
1304 // Do nothing
1305 }
1306 }
1307 },
1308
1309 /**
1310 * Wraps addEventListener to capture UI breadcrumbs
1311 * @param evtName the event name (e.g. "click")
1312 * @returns {Function}
1313 * @private
1314 */
1315 _breadcrumbEventHandler: function(evtName) {
1316 var self = this;
1317 return function(evt) {
1318 // reset keypress timeout; e.g. triggering a 'click' after
1319 // a 'keypress' will reset the keypress debounce so that a new
1320 // set of keypresses can be recorded
1321 self._keypressTimeout = null;
1322
1323 // It's possible this handler might trigger multiple times for the same
1324 // event (e.g. event propagation through node ancestors). Ignore if we've
1325 // already captured the event.
1326 if (self._lastCapturedEvent === evt) return;
1327
1328 self._lastCapturedEvent = evt;
1329
1330 // try/catch both:
1331 // - accessing evt.target (see getsentry/raven-js#838, #768)
1332 // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly
1333 // can throw an exception in some circumstances.
1334 var target;
1335 try {
1336 target = htmlTreeAsString(evt.target);
1337 } catch (e) {
1338 target = '<unknown>';
1339 }
1340
1341 self.captureBreadcrumb({
1342 category: 'ui.' + evtName, // e.g. ui.click, ui.input
1343 message: target
1344 });
1345 };
1346 },
1347
1348 /**
1349 * Wraps addEventListener to capture keypress UI events
1350 * @returns {Function}
1351 * @private
1352 */
1353 _keypressEventHandler: function() {
1354 var self = this,
1355 debounceDuration = 1000; // milliseconds
1356
1357 // TODO: if somehow user switches keypress target before
1358 // debounce timeout is triggered, we will only capture
1359 // a single breadcrumb from the FIRST target (acceptable?)
1360 return function(evt) {
1361 var target;
1362 try {
1363 target = evt.target;
1364 } catch (e) {
1365 // just accessing event properties can throw an exception in some rare circumstances
1366 // see: https://github.com/getsentry/raven-js/issues/838
1367 return;
1368 }
1369 var tagName = target && target.tagName;
1370
1371 // only consider keypress events on actual input elements
1372 // this will disregard keypresses targeting body (e.g. tabbing
1373 // through elements, hotkeys, etc)
1374 if (
1375 !tagName ||
1376 (tagName !== 'INPUT' && tagName !== 'TEXTAREA' && !target.isContentEditable)
1377 )
1378 return;
1379
1380 // record first keypress in a series, but ignore subsequent
1381 // keypresses until debounce clears
1382 var timeout = self._keypressTimeout;
1383 if (!timeout) {
1384 self._breadcrumbEventHandler('input')(evt);
1385 }
1386 clearTimeout(timeout);
1387 self._keypressTimeout = setTimeout(function() {
1388 self._keypressTimeout = null;
1389 }, debounceDuration);
1390 };
1391 },
1392
1393 /**
1394 * Captures a breadcrumb of type "navigation", normalizing input URLs
1395 * @param to the originating URL
1396 * @param from the target URL
1397 * @private
1398 */
1399 _captureUrlChange: function(from, to) {
1400 var parsedLoc = parseUrl(this._location.href);
1401 var parsedTo = parseUrl(to);
1402 var parsedFrom = parseUrl(from);
1403
1404 // because onpopstate only tells you the "new" (to) value of location.href, and
1405 // not the previous (from) value, we need to track the value of the current URL
1406 // state ourselves
1407 this._lastHref = to;
1408
1409 // Use only the path component of the URL if the URL matches the current
1410 // document (almost all the time when using pushState)
1411 if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host)
1412 to = parsedTo.relative;
1413 if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host)
1414 from = parsedFrom.relative;
1415
1416 this.captureBreadcrumb({
1417 category: 'navigation',
1418 data: {
1419 to: to,
1420 from: from
1421 }
1422 });
1423 },
1424
1425 /**
1426 * Wrap timer functions and event targets to catch errors and provide
1427 * better metadata.
1428 */
1429 _instrumentTryCatch: function() {
1430 var self = this;
1431
1432 var wrappedBuiltIns = self._wrappedBuiltIns;
1433
1434 function wrapTimeFn(orig) {
1435 return function(fn, t) {
1436 // preserve arity
1437 // Make a copy of the arguments to prevent deoptimization
1438 // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
1439 var args = new Array(arguments.length);
1440 for (var i = 0; i < args.length; ++i) {
1441 args[i] = arguments[i];
1442 }
1443 var originalCallback = args[0];
1444 if (isFunction(originalCallback)) {
1445 args[0] = self.wrap(originalCallback);
1446 }
1447
1448 // IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it
1449 // also supports only two arguments and doesn't care what this is, so we
1450 // can just call the original function directly.
1451 if (orig.apply) {
1452 return orig.apply(this, args);
1453 } else {
1454 return orig(args[0], args[1]);
1455 }
1456 };
1457 }
1458
1459 var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs;
1460
1461 function wrapEventTarget(global) {
1462 var proto = _window[global] && _window[global].prototype;
1463 if (proto && proto.hasOwnProperty && proto.hasOwnProperty('addEventListener')) {
1464 fill(
1465 proto,
1466 'addEventListener',
1467 function(orig) {
1468 return function(evtName, fn, capture, secure) {
1469 // preserve arity
1470 try {
1471 if (fn && fn.handleEvent) {
1472 fn.handleEvent = self.wrap(fn.handleEvent);
1473 }
1474 } catch (err) {
1475 // can sometimes get 'Permission denied to access property "handle Event'
1476 }
1477
1478 // More breadcrumb DOM capture ... done here and not in `_instrumentBreadcrumbs`
1479 // so that we don't have more than one wrapper function
1480 var before, clickHandler, keypressHandler;
1481
1482 if (
1483 autoBreadcrumbs &&
1484 autoBreadcrumbs.dom &&
1485 (global === 'EventTarget' || global === 'Node')
1486 ) {
1487 // NOTE: generating multiple handlers per addEventListener invocation, should
1488 // revisit and verify we can just use one (almost certainly)
1489 clickHandler = self._breadcrumbEventHandler('click');
1490 keypressHandler = self._keypressEventHandler();
1491 before = function(evt) {
1492 // need to intercept every DOM event in `before` argument, in case that
1493 // same wrapped method is re-used for different events (e.g. mousemove THEN click)
1494 // see #724
1495 if (!evt) return;
1496
1497 var eventType;
1498 try {
1499 eventType = evt.type;
1500 } catch (e) {
1501 // just accessing event properties can throw an exception in some rare circumstances
1502 // see: https://github.com/getsentry/raven-js/issues/838
1503 return;
1504 }
1505 if (eventType === 'click') return clickHandler(evt);
1506 else if (eventType === 'keypress') return keypressHandler(evt);
1507 };
1508 }
1509 return orig.call(
1510 this,
1511 evtName,
1512 self.wrap(fn, undefined, before),
1513 capture,
1514 secure
1515 );
1516 };
1517 },
1518 wrappedBuiltIns
1519 );
1520 fill(
1521 proto,
1522 'removeEventListener',
1523 function(orig) {
1524 return function(evt, fn, capture, secure) {
1525 try {
1526 fn = fn && (fn.__raven_wrapper__ ? fn.__raven_wrapper__ : fn);
1527 } catch (e) {
1528 // ignore, accessing __raven_wrapper__ will throw in some Selenium environments
1529 }
1530 return orig.call(this, evt, fn, capture, secure);
1531 };
1532 },
1533 wrappedBuiltIns
1534 );
1535 }
1536 }
1537
1538 fill(_window, 'setTimeout', wrapTimeFn, wrappedBuiltIns);
1539 fill(_window, 'setInterval', wrapTimeFn, wrappedBuiltIns);
1540 if (_window.requestAnimationFrame) {
1541 fill(
1542 _window,
1543 'requestAnimationFrame',
1544 function(orig) {
1545 return function(cb) {
1546 return orig(self.wrap(cb));
1547 };
1548 },
1549 wrappedBuiltIns
1550 );
1551 }
1552
1553 // event targets borrowed from bugsnag-js:
1554 // https://github.com/bugsnag/bugsnag-js/blob/master/src/bugsnag.js#L666
1555 var eventTargets = [
1556 'EventTarget',
1557 'Window',
1558 'Node',
1559 'ApplicationCache',
1560 'AudioTrackList',
1561 'ChannelMergerNode',
1562 'CryptoOperation',
1563 'EventSource',
1564 'FileReader',
1565 'HTMLUnknownElement',
1566 'IDBDatabase',
1567 'IDBRequest',
1568 'IDBTransaction',
1569 'KeyOperation',
1570 'MediaController',
1571 'MessagePort',
1572 'ModalWindow',
1573 'Notification',
1574 'SVGElementInstance',
1575 'Screen',
1576 'TextTrack',
1577 'TextTrackCue',
1578 'TextTrackList',
1579 'WebSocket',
1580 'WebSocketWorker',
1581 'Worker',
1582 'XMLHttpRequest',
1583 'XMLHttpRequestEventTarget',
1584 'XMLHttpRequestUpload'
1585 ];
1586 for (var i = 0; i < eventTargets.length; i++) {
1587 wrapEventTarget(eventTargets[i]);
1588 }
1589 },
1590
1591 /**
1592 * Instrument browser built-ins w/ breadcrumb capturing
1593 * - XMLHttpRequests
1594 * - DOM interactions (click/typing)
1595 * - window.location changes
1596 * - console
1597 *
1598 * Can be disabled or individually configured via the `autoBreadcrumbs` config option
1599 */
1600 _instrumentBreadcrumbs: function() {
1601 var self = this;
1602 var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs;
1603
1604 var wrappedBuiltIns = self._wrappedBuiltIns;
1605
1606 function wrapProp(prop, xhr) {
1607 if (prop in xhr && isFunction(xhr[prop])) {
1608 fill(xhr, prop, function(orig) {
1609 return self.wrap(orig);
1610 }); // intentionally don't track filled methods on XHR instances
1611 }
1612 }
1613
1614 if (autoBreadcrumbs.xhr && 'XMLHttpRequest' in _window) {
1615 var xhrproto = XMLHttpRequest.prototype;
1616 fill(
1617 xhrproto,
1618 'open',
1619 function(origOpen) {
1620 return function(method, url) {
1621 // preserve arity
1622
1623 // if Sentry key appears in URL, don't capture
1624 if (isString(url) && url.indexOf(self._globalKey) === -1) {
1625 this.__raven_xhr = {
1626 method: method,
1627 url: url,
1628 status_code: null
1629 };
1630 }
1631
1632 return origOpen.apply(this, arguments);
1633 };
1634 },
1635 wrappedBuiltIns
1636 );
1637
1638 fill(
1639 xhrproto,
1640 'send',
1641 function(origSend) {
1642 return function(data) {
1643 // preserve arity
1644 var xhr = this;
1645
1646 function onreadystatechangeHandler() {
1647 if (xhr.__raven_xhr && xhr.readyState === 4) {
1648 try {
1649 // touching statusCode in some platforms throws
1650 // an exception
1651 xhr.__raven_xhr.status_code = xhr.status;
1652 } catch (e) {
1653 /* do nothing */
1654 }
1655
1656 self.captureBreadcrumb({
1657 type: 'http',
1658 category: 'xhr',
1659 data: xhr.__raven_xhr
1660 });
1661 }
1662 }
1663
1664 var props = ['onload', 'onerror', 'onprogress'];
1665 for (var j = 0; j < props.length; j++) {
1666 wrapProp(props[j], xhr);
1667 }
1668
1669 if ('onreadystatechange' in xhr && isFunction(xhr.onreadystatechange)) {
1670 fill(
1671 xhr,
1672 'onreadystatechange',
1673 function(orig) {
1674 return self.wrap(orig, undefined, onreadystatechangeHandler);
1675 } /* intentionally don't track this instrumentation */
1676 );
1677 } else {
1678 // if onreadystatechange wasn't actually set by the page on this xhr, we
1679 // are free to set our own and capture the breadcrumb
1680 xhr.onreadystatechange = onreadystatechangeHandler;
1681 }
1682
1683 return origSend.apply(this, arguments);
1684 };
1685 },
1686 wrappedBuiltIns
1687 );
1688 }
1689
1690 if (autoBreadcrumbs.xhr && 'fetch' in _window) {
1691 fill(
1692 _window,
1693 'fetch',
1694 function(origFetch) {
1695 return function(fn, t) {
1696 // preserve arity
1697 // Make a copy of the arguments to prevent deoptimization
1698 // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
1699 var args = new Array(arguments.length);
1700 for (var i = 0; i < args.length; ++i) {
1701 args[i] = arguments[i];
1702 }
1703
1704 var fetchInput = args[0];
1705 var method = 'GET';
1706 var url;
1707
1708 if (typeof fetchInput === 'string') {
1709 url = fetchInput;
1710 } else if ('Request' in _window && fetchInput instanceof _window.Request) {
1711 url = fetchInput.url;
1712 if (fetchInput.method) {
1713 method = fetchInput.method;
1714 }
1715 } else {
1716 url = '' + fetchInput;
1717 }
1718
1719 if (args[1] && args[1].method) {
1720 method = args[1].method;
1721 }
1722
1723 var fetchData = {
1724 method: method,
1725 url: url,
1726 status_code: null
1727 };
1728
1729 self.captureBreadcrumb({
1730 type: 'http',
1731 category: 'fetch',
1732 data: fetchData
1733 });
1734
1735 return origFetch.apply(this, args).then(function(response) {
1736 fetchData.status_code = response.status;
1737
1738 return response;
1739 });
1740 };
1741 },
1742 wrappedBuiltIns
1743 );
1744 }
1745
1746 // Capture breadcrumbs from any click that is unhandled / bubbled up all the way
1747 // to the document. Do this before we instrument addEventListener.
1748 if (autoBreadcrumbs.dom && this._hasDocument) {
1749 if (_document.addEventListener) {
1750 _document.addEventListener('click', self._breadcrumbEventHandler('click'), false);
1751 _document.addEventListener('keypress', self._keypressEventHandler(), false);
1752 } else {
1753 // IE8 Compatibility
1754 _document.attachEvent('onclick', self._breadcrumbEventHandler('click'));
1755 _document.attachEvent('onkeypress', self._keypressEventHandler());
1756 }
1757 }
1758
1759 // record navigation (URL) changes
1760 // NOTE: in Chrome App environment, touching history.pushState, *even inside
1761 // a try/catch block*, will cause Chrome to output an error to console.error
1762 // borrowed from: https://github.com/angular/angular.js/pull/13945/files
1763 var chrome = _window.chrome;
1764 var isChromePackagedApp = chrome && chrome.app && chrome.app.runtime;
1765 var hasPushAndReplaceState =
1766 !isChromePackagedApp &&
1767 _window.history &&
1768 history.pushState &&
1769 history.replaceState;
1770 if (autoBreadcrumbs.location && hasPushAndReplaceState) {
1771 // TODO: remove onpopstate handler on uninstall()
1772 var oldOnPopState = _window.onpopstate;
1773 _window.onpopstate = function() {
1774 var currentHref = self._location.href;
1775 self._captureUrlChange(self._lastHref, currentHref);
1776
1777 if (oldOnPopState) {
1778 return oldOnPopState.apply(this, arguments);
1779 }
1780 };
1781
1782 var historyReplacementFunction = function(origHistFunction) {
1783 // note history.pushState.length is 0; intentionally not declaring
1784 // params to preserve 0 arity
1785 return function(/* state, title, url */) {
1786 var url = arguments.length > 2 ? arguments[2] : undefined;
1787
1788 // url argument is optional
1789 if (url) {
1790 // coerce to string (this is what pushState does)
1791 self._captureUrlChange(self._lastHref, url + '');
1792 }
1793
1794 return origHistFunction.apply(this, arguments);
1795 };
1796 };
1797
1798 fill(history, 'pushState', historyReplacementFunction, wrappedBuiltIns);
1799 fill(history, 'replaceState', historyReplacementFunction, wrappedBuiltIns);
1800 }
1801
1802 if (autoBreadcrumbs.console && 'console' in _window && console.log) {
1803 // console
1804 var consoleMethodCallback = function(msg, data) {
1805 self.captureBreadcrumb({
1806 message: msg,
1807 level: data.level,
1808 category: 'console'
1809 });
1810 };
1811
1812 each(['debug', 'info', 'warn', 'error', 'log'], function(_, level) {
1813 wrapConsoleMethod(console, level, consoleMethodCallback);
1814 });
1815 }
1816 },
1817
1818 _restoreBuiltIns: function() {
1819 // restore any wrapped builtins
1820 var builtin;
1821 while (this._wrappedBuiltIns.length) {
1822 builtin = this._wrappedBuiltIns.shift();
1823
1824 var obj = builtin[0],
1825 name = builtin[1],
1826 orig = builtin[2];
1827
1828 obj[name] = orig;
1829 }
1830 },
1831
1832 _drainPlugins: function() {
1833 var self = this;
1834
1835 // FIX ME TODO
1836 each(this._plugins, function(_, plugin) {
1837 var installer = plugin[0];
1838 var args = plugin[1];
1839 installer.apply(self, [self].concat(args));
1840 });
1841 },
1842
1843 _parseDSN: function(str) {
1844 var m = dsnPattern.exec(str),
1845 dsn = {},
1846 i = 7;
1847
1848 try {
1849 while (i--) dsn[dsnKeys[i]] = m[i] || '';
1850 } catch (e) {
1851 throw new RavenConfigError('Invalid DSN: ' + str);
1852 }
1853
1854 if (dsn.pass && !this._globalOptions.allowSecretKey) {
1855 throw new RavenConfigError(
1856 'Do not specify your secret key in the DSN. See: http://bit.ly/raven-secret-key'
1857 );
1858 }
1859
1860 return dsn;
1861 },
1862
1863 _getGlobalServer: function(uri) {
1864 // assemble the endpoint from the uri pieces
1865 var globalServer = '//' + uri.host + (uri.port ? ':' + uri.port : '');
1866
1867 if (uri.protocol) {
1868 globalServer = uri.protocol + ':' + globalServer;
1869 }
1870 return globalServer;
1871 },
1872
1873 _handleOnErrorStackInfo: function() {
1874 // if we are intentionally ignoring errors via onerror, bail out
1875 if (!this._ignoreOnError) {
1876 this._handleStackInfo.apply(this, arguments);
1877 }
1878 },
1879
1880 _handleStackInfo: function(stackInfo, options) {
1881 var frames = this._prepareFrames(stackInfo, options);
1882
1883 this._triggerEvent('handle', {
1884 stackInfo: stackInfo,
1885 options: options
1886 });
1887
1888 this._processException(
1889 stackInfo.name,
1890 stackInfo.message,
1891 stackInfo.url,
1892 stackInfo.lineno,
1893 frames,
1894 options
1895 );
1896 },
1897
1898 _prepareFrames: function(stackInfo, options) {
1899 var self = this;
1900 var frames = [];
1901 if (stackInfo.stack && stackInfo.stack.length) {
1902 each(stackInfo.stack, function(i, stack) {
1903 var frame = self._normalizeFrame(stack, stackInfo.url);
1904 if (frame) {
1905 frames.push(frame);
1906 }
1907 });
1908
1909 // e.g. frames captured via captureMessage throw
1910 if (options && options.trimHeadFrames) {
1911 for (var j = 0; j < options.trimHeadFrames && j < frames.length; j++) {
1912 frames[j].in_app = false;
1913 }
1914 }
1915 }
1916 frames = frames.slice(0, this._globalOptions.stackTraceLimit);
1917 return frames;
1918 },
1919
1920 _normalizeFrame: function(frame, stackInfoUrl) {
1921 // normalize the frames data
1922 var normalized = {
1923 filename: frame.url,
1924 lineno: frame.line,
1925 colno: frame.column,
1926 function: frame.func || '?'
1927 };
1928
1929 // Case when we don't have any information about the error
1930 // E.g. throwing a string or raw object, instead of an `Error` in Firefox
1931 // Generating synthetic error doesn't add any value here
1932 //
1933 // We should probably somehow let a user know that they should fix their code
1934 if (!frame.url) {
1935 normalized.filename = stackInfoUrl; // fallback to whole stacks url from onerror handler
1936 }
1937
1938 normalized.in_app = !// determine if an exception came from outside of our app
1939 // first we check the global includePaths list.
1940 (
1941 (!!this._globalOptions.includePaths.test &&
1942 !this._globalOptions.includePaths.test(normalized.filename)) ||
1943 // Now we check for fun, if the function name is Raven or TraceKit
1944 /(Raven|TraceKit)\./.test(normalized['function']) ||
1945 // finally, we do a last ditch effort and check for raven.min.js
1946 /raven\.(min\.)?js$/.test(normalized.filename)
1947 );
1948
1949 return normalized;
1950 },
1951
1952 _processException: function(type, message, fileurl, lineno, frames, options) {
1953 var prefixedMessage = (type ? type + ': ' : '') + (message || '');
1954 if (
1955 !!this._globalOptions.ignoreErrors.test &&
1956 (this._globalOptions.ignoreErrors.test(message) ||
1957 this._globalOptions.ignoreErrors.test(prefixedMessage))
1958 ) {
1959 return;
1960 }
1961
1962 var stacktrace;
1963
1964 if (frames && frames.length) {
1965 fileurl = frames[0].filename || fileurl;
1966 // Sentry expects frames oldest to newest
1967 // and JS sends them as newest to oldest
1968 frames.reverse();
1969 stacktrace = {frames: frames};
1970 } else if (fileurl) {
1971 stacktrace = {
1972 frames: [
1973 {
1974 filename: fileurl,
1975 lineno: lineno,
1976 in_app: true
1977 }
1978 ]
1979 };
1980 }
1981
1982 if (
1983 !!this._globalOptions.ignoreUrls.test &&
1984 this._globalOptions.ignoreUrls.test(fileurl)
1985 ) {
1986 return;
1987 }
1988
1989 if (
1990 !!this._globalOptions.whitelistUrls.test &&
1991 !this._globalOptions.whitelistUrls.test(fileurl)
1992 ) {
1993 return;
1994 }
1995
1996 var data = objectMerge(
1997 {
1998 // sentry.interfaces.Exception
1999 exception: {
2000 values: [
2001 {
2002 type: type,
2003 value: message,
2004 stacktrace: stacktrace
2005 }
2006 ]
2007 },
2008 culprit: fileurl
2009 },
2010 options
2011 );
2012
2013 // Fire away!
2014 this._send(data);
2015 },
2016
2017 _trimPacket: function(data) {
2018 // For now, we only want to truncate the two different messages
2019 // but this could/should be expanded to just trim everything
2020 var max = this._globalOptions.maxMessageLength;
2021 if (data.message) {
2022 data.message = truncate(data.message, max);
2023 }
2024 if (data.exception) {
2025 var exception = data.exception.values[0];
2026 exception.value = truncate(exception.value, max);
2027 }
2028
2029 var request = data.request;
2030 if (request) {
2031 if (request.url) {
2032 request.url = truncate(request.url, this._globalOptions.maxUrlLength);
2033 }
2034 if (request.Referer) {
2035 request.Referer = truncate(request.Referer, this._globalOptions.maxUrlLength);
2036 }
2037 }
2038
2039 if (data.breadcrumbs && data.breadcrumbs.values)
2040 this._trimBreadcrumbs(data.breadcrumbs);
2041
2042 return data;
2043 },
2044
2045 /**
2046 * Truncate breadcrumb values (right now just URLs)
2047 */
2048 _trimBreadcrumbs: function(breadcrumbs) {
2049 // known breadcrumb properties with urls
2050 // TODO: also consider arbitrary prop values that start with (https?)?://
2051 var urlProps = ['to', 'from', 'url'],
2052 urlProp,
2053 crumb,
2054 data;
2055
2056 for (var i = 0; i < breadcrumbs.values.length; ++i) {
2057 crumb = breadcrumbs.values[i];
2058 if (
2059 !crumb.hasOwnProperty('data') ||
2060 !isObject(crumb.data) ||
2061 objectFrozen(crumb.data)
2062 )
2063 continue;
2064
2065 data = objectMerge({}, crumb.data);
2066 for (var j = 0; j < urlProps.length; ++j) {
2067 urlProp = urlProps[j];
2068 if (data.hasOwnProperty(urlProp) && data[urlProp]) {
2069 data[urlProp] = truncate(data[urlProp], this._globalOptions.maxUrlLength);
2070 }
2071 }
2072 breadcrumbs.values[i].data = data;
2073 }
2074 },
2075
2076 _getHttpData: function() {
2077 if (!this._hasNavigator && !this._hasDocument) return;
2078 var httpData = {};
2079
2080 if (this._hasNavigator && _navigator.userAgent) {
2081 httpData.headers = {
2082 'User-Agent': navigator.userAgent
2083 };
2084 }
2085
2086 if (this._hasDocument) {
2087 if (_document.location && _document.location.href) {
2088 httpData.url = _document.location.href;
2089 }
2090 if (_document.referrer) {
2091 if (!httpData.headers) httpData.headers = {};
2092 httpData.headers.Referer = _document.referrer;
2093 }
2094 }
2095
2096 return httpData;
2097 },
2098
2099 _resetBackoff: function() {
2100 this._backoffDuration = 0;
2101 this._backoffStart = null;
2102 },
2103
2104 _shouldBackoff: function() {
2105 return this._backoffDuration && now() - this._backoffStart < this._backoffDuration;
2106 },
2107
2108 /**
2109 * Returns true if the in-process data payload matches the signature
2110 * of the previously-sent data
2111 *
2112 * NOTE: This has to be done at this level because TraceKit can generate
2113 * data from window.onerror WITHOUT an exception object (IE8, IE9,
2114 * other old browsers). This can take the form of an "exception"
2115 * data object with a single frame (derived from the onerror args).
2116 */
2117 _isRepeatData: function(current) {
2118 var last = this._lastData;
2119
2120 if (
2121 !last ||
2122 current.message !== last.message || // defined for captureMessage
2123 current.culprit !== last.culprit // defined for captureException/onerror
2124 )
2125 return false;
2126
2127 // Stacktrace interface (i.e. from captureMessage)
2128 if (current.stacktrace || last.stacktrace) {
2129 return isSameStacktrace(current.stacktrace, last.stacktrace);
2130 } else if (current.exception || last.exception) {
2131 // Exception interface (i.e. from captureException/onerror)
2132 return isSameException(current.exception, last.exception);
2133 }
2134
2135 return true;
2136 },
2137
2138 _setBackoffState: function(request) {
2139 // If we are already in a backoff state, don't change anything
2140 if (this._shouldBackoff()) {
2141 return;
2142 }
2143
2144 var status = request.status;
2145
2146 // 400 - project_id doesn't exist or some other fatal
2147 // 401 - invalid/revoked dsn
2148 // 429 - too many requests
2149 if (!(status === 400 || status === 401 || status === 429)) return;
2150
2151 var retry;
2152 try {
2153 // If Retry-After is not in Access-Control-Expose-Headers, most
2154 // browsers will throw an exception trying to access it
2155 retry = request.getResponseHeader('Retry-After');
2156 retry = parseInt(retry, 10) * 1000; // Retry-After is returned in seconds
2157 } catch (e) {
2158 /* eslint no-empty:0 */
2159 }
2160
2161 this._backoffDuration = retry
2162 ? // If Sentry server returned a Retry-After value, use it
2163 retry
2164 : // Otherwise, double the last backoff duration (starts at 1 sec)
2165 this._backoffDuration * 2 || 1000;
2166
2167 this._backoffStart = now();
2168 },
2169
2170 _send: function(data) {
2171 var globalOptions = this._globalOptions;
2172
2173 var baseData = {
2174 project: this._globalProject,
2175 logger: globalOptions.logger,
2176 platform: 'javascript'
2177 },
2178 httpData = this._getHttpData();
2179
2180 if (httpData) {
2181 baseData.request = httpData;
2182 }
2183
2184 // HACK: delete `trimHeadFrames` to prevent from appearing in outbound payload
2185 if (data.trimHeadFrames) delete data.trimHeadFrames;
2186
2187 data = objectMerge(baseData, data);
2188
2189 // Merge in the tags and extra separately since objectMerge doesn't handle a deep merge
2190 data.tags = objectMerge(objectMerge({}, this._globalContext.tags), data.tags);
2191 data.extra = objectMerge(objectMerge({}, this._globalContext.extra), data.extra);
2192
2193 // Send along our own collected metadata with extra
2194 data.extra['session:duration'] = now() - this._startTime;
2195
2196 if (this._breadcrumbs && this._breadcrumbs.length > 0) {
2197 // intentionally make shallow copy so that additions
2198 // to breadcrumbs aren't accidentally sent in this request
2199 data.breadcrumbs = {
2200 values: [].slice.call(this._breadcrumbs, 0)
2201 };
2202 }
2203
2204 // If there are no tags/extra, strip the key from the payload alltogther.
2205 if (isEmptyObject(data.tags)) delete data.tags;
2206
2207 if (this._globalContext.user) {
2208 // sentry.interfaces.User
2209 data.user = this._globalContext.user;
2210 }
2211
2212 // Include the environment if it's defined in globalOptions
2213 if (globalOptions.environment) data.environment = globalOptions.environment;
2214
2215 // Include the release if it's defined in globalOptions
2216 if (globalOptions.release) data.release = globalOptions.release;
2217
2218 // Include server_name if it's defined in globalOptions
2219 if (globalOptions.serverName) data.server_name = globalOptions.serverName;
2220
2221 if (isFunction(globalOptions.dataCallback)) {
2222 data = globalOptions.dataCallback(data) || data;
2223 }
2224
2225 // Why??????????
2226 if (!data || isEmptyObject(data)) {
2227 return;
2228 }
2229
2230 // Check if the request should be filtered or not
2231 if (
2232 isFunction(globalOptions.shouldSendCallback) &&
2233 !globalOptions.shouldSendCallback(data)
2234 ) {
2235 return;
2236 }
2237
2238 // Backoff state: Sentry server previously responded w/ an error (e.g. 429 - too many requests),
2239 // so drop requests until "cool-off" period has elapsed.
2240 if (this._shouldBackoff()) {
2241 this._logDebug('warn', 'Raven dropped error due to backoff: ', data);
2242 return;
2243 }
2244
2245 if (typeof globalOptions.sampleRate === 'number') {
2246 if (Math.random() < globalOptions.sampleRate) {
2247 this._sendProcessedPayload(data);
2248 }
2249 } else {
2250 this._sendProcessedPayload(data);
2251 }
2252 },
2253
2254 _getUuid: function() {
2255 return uuid4();
2256 },
2257
2258 _sendProcessedPayload: function(data, callback) {
2259 var self = this;
2260 var globalOptions = this._globalOptions;
2261
2262 if (!this.isSetup()) return;
2263
2264 // Try and clean up the packet before sending by truncating long values
2265 data = this._trimPacket(data);
2266
2267 // ideally duplicate error testing should occur *before* dataCallback/shouldSendCallback,
2268 // but this would require copying an un-truncated copy of the data packet, which can be
2269 // arbitrarily deep (extra_data) -- could be worthwhile? will revisit
2270 if (!this._globalOptions.allowDuplicates && this._isRepeatData(data)) {
2271 this._logDebug('warn', 'Raven dropped repeat event: ', data);
2272 return;
2273 }
2274
2275 // Send along an event_id if not explicitly passed.
2276 // This event_id can be used to reference the error within Sentry itself.
2277 // Set lastEventId after we know the error should actually be sent
2278 this._lastEventId = data.event_id || (data.event_id = this._getUuid());
2279
2280 // Store outbound payload after trim
2281 this._lastData = data;
2282
2283 this._logDebug('debug', 'Raven about to send:', data);
2284
2285 var auth = {
2286 sentry_version: '7',
2287 sentry_client: 'raven-js/' + this.VERSION,
2288 sentry_key: this._globalKey
2289 };
2290
2291 if (this._globalSecret) {
2292 auth.sentry_secret = this._globalSecret;
2293 }
2294
2295 var exception = data.exception && data.exception.values[0];
2296 this.captureBreadcrumb({
2297 category: 'sentry',
2298 message: exception
2299 ? (exception.type ? exception.type + ': ' : '') + exception.value
2300 : data.message,
2301 event_id: data.event_id,
2302 level: data.level || 'error' // presume error unless specified
2303 });
2304
2305 var url = this._globalEndpoint;
2306 (globalOptions.transport || this._makeRequest).call(this, {
2307 url: url,
2308 auth: auth,
2309 data: data,
2310 options: globalOptions,
2311 onSuccess: function success() {
2312 self._resetBackoff();
2313
2314 self._triggerEvent('success', {
2315 data: data,
2316 src: url
2317 });
2318 callback && callback();
2319 },
2320 onError: function failure(error) {
2321 self._logDebug('error', 'Raven transport failed to send: ', error);
2322
2323 if (error.request) {
2324 self._setBackoffState(error.request);
2325 }
2326
2327 self._triggerEvent('failure', {
2328 data: data,
2329 src: url
2330 });
2331 error = error || new Error('Raven send failed (no additional details provided)');
2332 callback && callback(error);
2333 }
2334 });
2335 },
2336
2337 _makeRequest: function(opts) {
2338 var request = _window.XMLHttpRequest && new _window.XMLHttpRequest();
2339 if (!request) return;
2340
2341 // if browser doesn't support CORS (e.g. IE7), we are out of luck
2342 var hasCORS = 'withCredentials' in request || typeof XDomainRequest !== 'undefined';
2343
2344 if (!hasCORS) return;
2345
2346 var url = opts.url;
2347
2348 if ('withCredentials' in request) {
2349 request.onreadystatechange = function() {
2350 if (request.readyState !== 4) {
2351 return;
2352 } else if (request.status === 200) {
2353 opts.onSuccess && opts.onSuccess();
2354 } else if (opts.onError) {
2355 var err = new Error('Sentry error code: ' + request.status);
2356 err.request = request;
2357 opts.onError(err);
2358 }
2359 };
2360 } else {
2361 request = new XDomainRequest();
2362 // xdomainrequest cannot go http -> https (or vice versa),
2363 // so always use protocol relative
2364 url = url.replace(/^https?:/, '');
2365
2366 // onreadystatechange not supported by XDomainRequest
2367 if (opts.onSuccess) {
2368 request.onload = opts.onSuccess;
2369 }
2370 if (opts.onError) {
2371 request.onerror = function() {
2372 var err = new Error('Sentry error code: XDomainRequest');
2373 err.request = request;
2374 opts.onError(err);
2375 };
2376 }
2377 }
2378
2379 // NOTE: auth is intentionally sent as part of query string (NOT as custom
2380 // HTTP header) so as to avoid preflight CORS requests
2381 request.open('POST', url + '?' + urlencode(opts.auth));
2382 request.send(stringify(opts.data));
2383 },
2384
2385 _logDebug: function(level) {
2386 if (this._originalConsoleMethods[level] && this.debug) {
2387 // In IE<10 console methods do not have their own 'apply' method
2388 Function.prototype.apply.call(
2389 this._originalConsoleMethods[level],
2390 this._originalConsole,
2391 [].slice.call(arguments, 1)
2392 );
2393 }
2394 },
2395
2396 _mergeContext: function(key, context) {
2397 if (isUndefined(context)) {
2398 delete this._globalContext[key];
2399 } else {
2400 this._globalContext[key] = objectMerge(this._globalContext[key] || {}, context);
2401 }
2402 }
2403 };
2404
2405 // Deprecations
2406 Raven.prototype.setUser = Raven.prototype.setUserContext;
2407 Raven.prototype.setReleaseContext = Raven.prototype.setRelease;
2408
2409 module.exports = Raven;
2410
2411
2412 /***/ }),
2413
2414 /***/ "./node_modules/raven-js/src/singleton.js":
2415 /*!************************************************!*\
2416 !*** ./node_modules/raven-js/src/singleton.js ***!
2417 \************************************************/
2418 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
2419
2420 /**
2421 * Enforces a single instance of the Raven client, and the
2422 * main entry point for Raven. If you are a consumer of the
2423 * Raven library, you SHOULD load this file (vs raven.js).
2424 **/
2425
2426 var RavenConstructor = __webpack_require__(/*! ./raven */ "./node_modules/raven-js/src/raven.js");
2427
2428 // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785)
2429 var _window =
2430 typeof window !== 'undefined'
2431 ? window
2432 : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof self !== 'undefined' ? self : {};
2433 var _Raven = _window.Raven;
2434
2435 var Raven = new RavenConstructor();
2436
2437 /*
2438 * Allow multiple versions of Raven to be installed.
2439 * Strip Raven from the global context and returns the instance.
2440 *
2441 * @return {Raven}
2442 */
2443 Raven.noConflict = function() {
2444 _window.Raven = _Raven;
2445 return Raven;
2446 };
2447
2448 Raven.afterLoad();
2449
2450 module.exports = Raven;
2451
2452
2453 /***/ }),
2454
2455 /***/ "./node_modules/raven-js/src/utils.js":
2456 /*!********************************************!*\
2457 !*** ./node_modules/raven-js/src/utils.js ***!
2458 \********************************************/
2459 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
2460
2461 var _window =
2462 typeof window !== 'undefined'
2463 ? window
2464 : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof self !== 'undefined' ? self : {};
2465
2466 function isObject(what) {
2467 return typeof what === 'object' && what !== null;
2468 }
2469
2470 // Yanked from https://git.io/vS8DV re-used under CC0
2471 // with some tiny modifications
2472 function isError(value) {
2473 switch ({}.toString.call(value)) {
2474 case '[object Error]':
2475 return true;
2476 case '[object Exception]':
2477 return true;
2478 case '[object DOMException]':
2479 return true;
2480 default:
2481 return value instanceof Error;
2482 }
2483 }
2484
2485 function isErrorEvent(value) {
2486 return supportsErrorEvent() && {}.toString.call(value) === '[object ErrorEvent]';
2487 }
2488
2489 function isUndefined(what) {
2490 return what === void 0;
2491 }
2492
2493 function isFunction(what) {
2494 return typeof what === 'function';
2495 }
2496
2497 function isString(what) {
2498 return Object.prototype.toString.call(what) === '[object String]';
2499 }
2500
2501 function isEmptyObject(what) {
2502 for (var _ in what) return false; // eslint-disable-line guard-for-in, no-unused-vars
2503 return true;
2504 }
2505
2506 function supportsErrorEvent() {
2507 try {
2508 new ErrorEvent(''); // eslint-disable-line no-new
2509 return true;
2510 } catch (e) {
2511 return false;
2512 }
2513 }
2514
2515 function wrappedCallback(callback) {
2516 function dataCallback(data, original) {
2517 var normalizedData = callback(data) || data;
2518 if (original) {
2519 return original(normalizedData) || normalizedData;
2520 }
2521 return normalizedData;
2522 }
2523
2524 return dataCallback;
2525 }
2526
2527 function each(obj, callback) {
2528 var i, j;
2529
2530 if (isUndefined(obj.length)) {
2531 for (i in obj) {
2532 if (hasKey(obj, i)) {
2533 callback.call(null, i, obj[i]);
2534 }
2535 }
2536 } else {
2537 j = obj.length;
2538 if (j) {
2539 for (i = 0; i < j; i++) {
2540 callback.call(null, i, obj[i]);
2541 }
2542 }
2543 }
2544 }
2545
2546 function objectMerge(obj1, obj2) {
2547 if (!obj2) {
2548 return obj1;
2549 }
2550 each(obj2, function(key, value) {
2551 obj1[key] = value;
2552 });
2553 return obj1;
2554 }
2555
2556 /**
2557 * This function is only used for react-native.
2558 * react-native freezes object that have already been sent over the
2559 * js bridge. We need this function in order to check if the object is frozen.
2560 * So it's ok that objectFrozen returns false if Object.isFrozen is not
2561 * supported because it's not relevant for other "platforms". See related issue:
2562 * https://github.com/getsentry/react-native-sentry/issues/57
2563 */
2564 function objectFrozen(obj) {
2565 if (!Object.isFrozen) {
2566 return false;
2567 }
2568 return Object.isFrozen(obj);
2569 }
2570
2571 function truncate(str, max) {
2572 return !max || str.length <= max ? str : str.substr(0, max) + '\u2026';
2573 }
2574
2575 /**
2576 * hasKey, a better form of hasOwnProperty
2577 * Example: hasKey(MainHostObject, property) === true/false
2578 *
2579 * @param {Object} host object to check property
2580 * @param {string} key to check
2581 */
2582 function hasKey(object, key) {
2583 return Object.prototype.hasOwnProperty.call(object, key);
2584 }
2585
2586 function joinRegExp(patterns) {
2587 // Combine an array of regular expressions and strings into one large regexp
2588 // Be mad.
2589 var sources = [],
2590 i = 0,
2591 len = patterns.length,
2592 pattern;
2593
2594 for (; i < len; i++) {
2595 pattern = patterns[i];
2596 if (isString(pattern)) {
2597 // If it's a string, we need to escape it
2598 // Taken from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
2599 sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'));
2600 } else if (pattern && pattern.source) {
2601 // If it's a regexp already, we want to extract the source
2602 sources.push(pattern.source);
2603 }
2604 // Intentionally skip other cases
2605 }
2606 return new RegExp(sources.join('|'), 'i');
2607 }
2608
2609 function urlencode(o) {
2610 var pairs = [];
2611 each(o, function(key, value) {
2612 pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
2613 });
2614 return pairs.join('&');
2615 }
2616
2617 // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
2618 // intentionally using regex and not <a/> href parsing trick because React Native and other
2619 // environments where DOM might not be available
2620 function parseUrl(url) {
2621 var match = url.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
2622 if (!match) return {};
2623
2624 // coerce to undefined values to empty string so we don't get 'undefined'
2625 var query = match[6] || '';
2626 var fragment = match[8] || '';
2627 return {
2628 protocol: match[2],
2629 host: match[4],
2630 path: match[5],
2631 relative: match[5] + query + fragment // everything minus origin
2632 };
2633 }
2634 function uuid4() {
2635 var crypto = _window.crypto || _window.msCrypto;
2636
2637 if (!isUndefined(crypto) && crypto.getRandomValues) {
2638 // Use window.crypto API if available
2639 // eslint-disable-next-line no-undef
2640 var arr = new Uint16Array(8);
2641 crypto.getRandomValues(arr);
2642
2643 // set 4 in byte 7
2644 arr[3] = (arr[3] & 0xfff) | 0x4000;
2645 // set 2 most significant bits of byte 9 to '10'
2646 arr[4] = (arr[4] & 0x3fff) | 0x8000;
2647
2648 var pad = function(num) {
2649 var v = num.toString(16);
2650 while (v.length < 4) {
2651 v = '0' + v;
2652 }
2653 return v;
2654 };
2655
2656 return (
2657 pad(arr[0]) +
2658 pad(arr[1]) +
2659 pad(arr[2]) +
2660 pad(arr[3]) +
2661 pad(arr[4]) +
2662 pad(arr[5]) +
2663 pad(arr[6]) +
2664 pad(arr[7])
2665 );
2666 } else {
2667 // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
2668 return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
2669 var r = (Math.random() * 16) | 0,
2670 v = c === 'x' ? r : (r & 0x3) | 0x8;
2671 return v.toString(16);
2672 });
2673 }
2674 }
2675
2676 /**
2677 * Given a child DOM element, returns a query-selector statement describing that
2678 * and its ancestors
2679 * e.g. [HTMLElement] => body > div > input#foo.btn[name=baz]
2680 * @param elem
2681 * @returns {string}
2682 */
2683 function htmlTreeAsString(elem) {
2684 /* eslint no-extra-parens:0*/
2685 var MAX_TRAVERSE_HEIGHT = 5,
2686 MAX_OUTPUT_LEN = 80,
2687 out = [],
2688 height = 0,
2689 len = 0,
2690 separator = ' > ',
2691 sepLength = separator.length,
2692 nextStr;
2693
2694 while (elem && height++ < MAX_TRAVERSE_HEIGHT) {
2695 nextStr = htmlElementAsString(elem);
2696 // bail out if
2697 // - nextStr is the 'html' element
2698 // - the length of the string that would be created exceeds MAX_OUTPUT_LEN
2699 // (ignore this limit if we are on the first iteration)
2700 if (
2701 nextStr === 'html' ||
2702 (height > 1 && len + out.length * sepLength + nextStr.length >= MAX_OUTPUT_LEN)
2703 ) {
2704 break;
2705 }
2706
2707 out.push(nextStr);
2708
2709 len += nextStr.length;
2710 elem = elem.parentNode;
2711 }
2712
2713 return out.reverse().join(separator);
2714 }
2715
2716 /**
2717 * Returns a simple, query-selector representation of a DOM element
2718 * e.g. [HTMLElement] => input#foo.btn[name=baz]
2719 * @param HTMLElement
2720 * @returns {string}
2721 */
2722 function htmlElementAsString(elem) {
2723 var out = [],
2724 className,
2725 classes,
2726 key,
2727 attr,
2728 i;
2729
2730 if (!elem || !elem.tagName) {
2731 return '';
2732 }
2733
2734 out.push(elem.tagName.toLowerCase());
2735 if (elem.id) {
2736 out.push('#' + elem.id);
2737 }
2738
2739 className = elem.className;
2740 if (className && isString(className)) {
2741 classes = className.split(/\s+/);
2742 for (i = 0; i < classes.length; i++) {
2743 out.push('.' + classes[i]);
2744 }
2745 }
2746 var attrWhitelist = ['type', 'name', 'title', 'alt'];
2747 for (i = 0; i < attrWhitelist.length; i++) {
2748 key = attrWhitelist[i];
2749 attr = elem.getAttribute(key);
2750 if (attr) {
2751 out.push('[' + key + '="' + attr + '"]');
2752 }
2753 }
2754 return out.join('');
2755 }
2756
2757 /**
2758 * Returns true if either a OR b is truthy, but not both
2759 */
2760 function isOnlyOneTruthy(a, b) {
2761 return !!(!!a ^ !!b);
2762 }
2763
2764 /**
2765 * Returns true if the two input exception interfaces have the same content
2766 */
2767 function isSameException(ex1, ex2) {
2768 if (isOnlyOneTruthy(ex1, ex2)) return false;
2769
2770 ex1 = ex1.values[0];
2771 ex2 = ex2.values[0];
2772
2773 if (ex1.type !== ex2.type || ex1.value !== ex2.value) return false;
2774
2775 return isSameStacktrace(ex1.stacktrace, ex2.stacktrace);
2776 }
2777
2778 /**
2779 * Returns true if the two input stack trace interfaces have the same content
2780 */
2781 function isSameStacktrace(stack1, stack2) {
2782 if (isOnlyOneTruthy(stack1, stack2)) return false;
2783
2784 var frames1 = stack1.frames;
2785 var frames2 = stack2.frames;
2786
2787 // Exit early if frame count differs
2788 if (frames1.length !== frames2.length) return false;
2789
2790 // Iterate through every frame; bail out if anything differs
2791 var a, b;
2792 for (var i = 0; i < frames1.length; i++) {
2793 a = frames1[i];
2794 b = frames2[i];
2795 if (
2796 a.filename !== b.filename ||
2797 a.lineno !== b.lineno ||
2798 a.colno !== b.colno ||
2799 a['function'] !== b['function']
2800 )
2801 return false;
2802 }
2803 return true;
2804 }
2805
2806 /**
2807 * Polyfill a method
2808 * @param obj object e.g. `document`
2809 * @param name method name present on object e.g. `addEventListener`
2810 * @param replacement replacement function
2811 * @param track {optional} record instrumentation to an array
2812 */
2813 function fill(obj, name, replacement, track) {
2814 var orig = obj[name];
2815 obj[name] = replacement(orig);
2816 if (track) {
2817 track.push([obj, name, orig]);
2818 }
2819 }
2820
2821 module.exports = {
2822 isObject: isObject,
2823 isError: isError,
2824 isErrorEvent: isErrorEvent,
2825 isUndefined: isUndefined,
2826 isFunction: isFunction,
2827 isString: isString,
2828 isEmptyObject: isEmptyObject,
2829 supportsErrorEvent: supportsErrorEvent,
2830 wrappedCallback: wrappedCallback,
2831 each: each,
2832 objectMerge: objectMerge,
2833 truncate: truncate,
2834 objectFrozen: objectFrozen,
2835 hasKey: hasKey,
2836 joinRegExp: joinRegExp,
2837 urlencode: urlencode,
2838 uuid4: uuid4,
2839 htmlTreeAsString: htmlTreeAsString,
2840 htmlElementAsString: htmlElementAsString,
2841 isSameException: isSameException,
2842 isSameStacktrace: isSameStacktrace,
2843 parseUrl: parseUrl,
2844 fill: fill
2845 };
2846
2847
2848 /***/ }),
2849
2850 /***/ "./node_modules/raven-js/vendor/TraceKit/tracekit.js":
2851 /*!***********************************************************!*\
2852 !*** ./node_modules/raven-js/vendor/TraceKit/tracekit.js ***!
2853 \***********************************************************/
2854 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
2855
2856 var utils = __webpack_require__(/*! ../../src/utils */ "./node_modules/raven-js/src/utils.js");
2857
2858 /*
2859 TraceKit - Cross brower stack traces
2860
2861 This was originally forked from github.com/occ/TraceKit, but has since been
2862 largely re-written and is now maintained as part of raven-js. Tests for
2863 this are in test/vendor.
2864
2865 MIT license
2866 */
2867
2868 var TraceKit = {
2869 collectWindowErrors: true,
2870 debug: false
2871 };
2872
2873 // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785)
2874 var _window =
2875 typeof window !== 'undefined'
2876 ? window
2877 : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof self !== 'undefined' ? self : {};
2878
2879 // global reference to slice
2880 var _slice = [].slice;
2881 var UNKNOWN_FUNCTION = '?';
2882
2883 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_types
2884 var ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/;
2885
2886 function getLocationHref() {
2887 if (typeof document === 'undefined' || document.location == null) return '';
2888
2889 return document.location.href;
2890 }
2891
2892 /**
2893 * TraceKit.report: cross-browser processing of unhandled exceptions
2894 *
2895 * Syntax:
2896 * TraceKit.report.subscribe(function(stackInfo) { ... })
2897 * TraceKit.report.unsubscribe(function(stackInfo) { ... })
2898 * TraceKit.report(exception)
2899 * try { ...code... } catch(ex) { TraceKit.report(ex); }
2900 *
2901 * Supports:
2902 * - Firefox: full stack trace with line numbers, plus column number
2903 * on top frame; column number is not guaranteed
2904 * - Opera: full stack trace with line and column numbers
2905 * - Chrome: full stack trace with line and column numbers
2906 * - Safari: line and column number for the top frame only; some frames
2907 * may be missing, and column number is not guaranteed
2908 * - IE: line and column number for the top frame only; some frames
2909 * may be missing, and column number is not guaranteed
2910 *
2911 * In theory, TraceKit should work on all of the following versions:
2912 * - IE5.5+ (only 8.0 tested)
2913 * - Firefox 0.9+ (only 3.5+ tested)
2914 * - Opera 7+ (only 10.50 tested; versions 9 and earlier may require
2915 * Exceptions Have Stacktrace to be enabled in opera:config)
2916 * - Safari 3+ (only 4+ tested)
2917 * - Chrome 1+ (only 5+ tested)
2918 * - Konqueror 3.5+ (untested)
2919 *
2920 * Requires TraceKit.computeStackTrace.
2921 *
2922 * Tries to catch all unhandled exceptions and report them to the
2923 * subscribed handlers. Please note that TraceKit.report will rethrow the
2924 * exception. This is REQUIRED in order to get a useful stack trace in IE.
2925 * If the exception does not reach the top of the browser, you will only
2926 * get a stack trace from the point where TraceKit.report was called.
2927 *
2928 * Handlers receive a stackInfo object as described in the
2929 * TraceKit.computeStackTrace docs.
2930 */
2931 TraceKit.report = (function reportModuleWrapper() {
2932 var handlers = [],
2933 lastArgs = null,
2934 lastException = null,
2935 lastExceptionStack = null;
2936
2937 /**
2938 * Add a crash handler.
2939 * @param {Function} handler
2940 */
2941 function subscribe(handler) {
2942 installGlobalHandler();
2943 handlers.push(handler);
2944 }
2945
2946 /**
2947 * Remove a crash handler.
2948 * @param {Function} handler
2949 */
2950 function unsubscribe(handler) {
2951 for (var i = handlers.length - 1; i >= 0; --i) {
2952 if (handlers[i] === handler) {
2953 handlers.splice(i, 1);
2954 }
2955 }
2956 }
2957
2958 /**
2959 * Remove all crash handlers.
2960 */
2961 function unsubscribeAll() {
2962 uninstallGlobalHandler();
2963 handlers = [];
2964 }
2965
2966 /**
2967 * Dispatch stack information to all handlers.
2968 * @param {Object.<string, *>} stack
2969 */
2970 function notifyHandlers(stack, isWindowError) {
2971 var exception = null;
2972 if (isWindowError && !TraceKit.collectWindowErrors) {
2973 return;
2974 }
2975 for (var i in handlers) {
2976 if (handlers.hasOwnProperty(i)) {
2977 try {
2978 handlers[i].apply(null, [stack].concat(_slice.call(arguments, 2)));
2979 } catch (inner) {
2980 exception = inner;
2981 }
2982 }
2983 }
2984
2985 if (exception) {
2986 throw exception;
2987 }
2988 }
2989
2990 var _oldOnerrorHandler, _onErrorHandlerInstalled;
2991
2992 /**
2993 * Ensures all global unhandled exceptions are recorded.
2994 * Supported by Gecko and IE.
2995 * @param {string} message Error message.
2996 * @param {string} url URL of script that generated the exception.
2997 * @param {(number|string)} lineNo The line number at which the error
2998 * occurred.
2999 * @param {?(number|string)} colNo The column number at which the error
3000 * occurred.
3001 * @param {?Error} ex The actual Error object.
3002 */
3003 function traceKitWindowOnError(message, url, lineNo, colNo, ex) {
3004 var stack = null;
3005
3006 if (lastExceptionStack) {
3007 TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(
3008 lastExceptionStack,
3009 url,
3010 lineNo,
3011 message
3012 );
3013 processLastException();
3014 } else if (ex && utils.isError(ex)) {
3015 // non-string `ex` arg; attempt to extract stack trace
3016
3017 // New chrome and blink send along a real error object
3018 // Let's just report that like a normal error.
3019 // See: https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror
3020 stack = TraceKit.computeStackTrace(ex);
3021 notifyHandlers(stack, true);
3022 } else {
3023 var location = {
3024 url: url,
3025 line: lineNo,
3026 column: colNo
3027 };
3028
3029 var name = undefined;
3030 var msg = message; // must be new var or will modify original `arguments`
3031 var groups;
3032 if ({}.toString.call(message) === '[object String]') {
3033 var groups = message.match(ERROR_TYPES_RE);
3034 if (groups) {
3035 name = groups[1];
3036 msg = groups[2];
3037 }
3038 }
3039
3040 location.func = UNKNOWN_FUNCTION;
3041
3042 stack = {
3043 name: name,
3044 message: msg,
3045 url: getLocationHref(),
3046 stack: [location]
3047 };
3048 notifyHandlers(stack, true);
3049 }
3050
3051 if (_oldOnerrorHandler) {
3052 return _oldOnerrorHandler.apply(this, arguments);
3053 }
3054
3055 return false;
3056 }
3057
3058 function installGlobalHandler() {
3059 if (_onErrorHandlerInstalled) {
3060 return;
3061 }
3062 _oldOnerrorHandler = _window.onerror;
3063 _window.onerror = traceKitWindowOnError;
3064 _onErrorHandlerInstalled = true;
3065 }
3066
3067 function uninstallGlobalHandler() {
3068 if (!_onErrorHandlerInstalled) {
3069 return;
3070 }
3071 _window.onerror = _oldOnerrorHandler;
3072 _onErrorHandlerInstalled = false;
3073 _oldOnerrorHandler = undefined;
3074 }
3075
3076 function processLastException() {
3077 var _lastExceptionStack = lastExceptionStack,
3078 _lastArgs = lastArgs;
3079 lastArgs = null;
3080 lastExceptionStack = null;
3081 lastException = null;
3082 notifyHandlers.apply(null, [_lastExceptionStack, false].concat(_lastArgs));
3083 }
3084
3085 /**
3086 * Reports an unhandled Error to TraceKit.
3087 * @param {Error} ex
3088 * @param {?boolean} rethrow If false, do not re-throw the exception.
3089 * Only used for window.onerror to not cause an infinite loop of
3090 * rethrowing.
3091 */
3092 function report(ex, rethrow) {
3093 var args = _slice.call(arguments, 1);
3094 if (lastExceptionStack) {
3095 if (lastException === ex) {
3096 return; // already caught by an inner catch block, ignore
3097 } else {
3098 processLastException();
3099 }
3100 }
3101
3102 var stack = TraceKit.computeStackTrace(ex);
3103 lastExceptionStack = stack;
3104 lastException = ex;
3105 lastArgs = args;
3106
3107 // If the stack trace is incomplete, wait for 2 seconds for
3108 // slow slow IE to see if onerror occurs or not before reporting
3109 // this exception; otherwise, we will end up with an incomplete
3110 // stack trace
3111 setTimeout(function() {
3112 if (lastException === ex) {
3113 processLastException();
3114 }
3115 }, stack.incomplete ? 2000 : 0);
3116
3117 if (rethrow !== false) {
3118 throw ex; // re-throw to propagate to the top level (and cause window.onerror)
3119 }
3120 }
3121
3122 report.subscribe = subscribe;
3123 report.unsubscribe = unsubscribe;
3124 report.uninstall = unsubscribeAll;
3125 return report;
3126 })();
3127
3128 /**
3129 * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript
3130 *
3131 * Syntax:
3132 * s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below)
3133 * Returns:
3134 * s.name - exception name
3135 * s.message - exception message
3136 * s.stack[i].url - JavaScript or HTML file URL
3137 * s.stack[i].func - function name, or empty for anonymous functions (if guessing did not work)
3138 * s.stack[i].args - arguments passed to the function, if known
3139 * s.stack[i].line - line number, if known
3140 * s.stack[i].column - column number, if known
3141 *
3142 * Supports:
3143 * - Firefox: full stack trace with line numbers and unreliable column
3144 * number on top frame
3145 * - Opera 10: full stack trace with line and column numbers
3146 * - Opera 9-: full stack trace with line numbers
3147 * - Chrome: full stack trace with line and column numbers
3148 * - Safari: line and column number for the topmost stacktrace element
3149 * only
3150 * - IE: no line numbers whatsoever
3151 *
3152 * Tries to guess names of anonymous functions by looking for assignments
3153 * in the source code. In IE and Safari, we have to guess source file names
3154 * by searching for function bodies inside all page scripts. This will not
3155 * work for scripts that are loaded cross-domain.
3156 * Here be dragons: some function names may be guessed incorrectly, and
3157 * duplicate functions may be mismatched.
3158 *
3159 * TraceKit.computeStackTrace should only be used for tracing purposes.
3160 * Logging of unhandled exceptions should be done with TraceKit.report,
3161 * which builds on top of TraceKit.computeStackTrace and provides better
3162 * IE support by utilizing the window.onerror event to retrieve information
3163 * about the top of the stack.
3164 *
3165 * Note: In IE and Safari, no stack trace is recorded on the Error object,
3166 * so computeStackTrace instead walks its *own* chain of callers.
3167 * This means that:
3168 * * in Safari, some methods may be missing from the stack trace;
3169 * * in IE, the topmost function in the stack trace will always be the
3170 * caller of computeStackTrace.
3171 *
3172 * This is okay for tracing (because you are likely to be calling
3173 * computeStackTrace from the function you want to be the topmost element
3174 * of the stack trace anyway), but not okay for logging unhandled
3175 * exceptions (because your catch block will likely be far away from the
3176 * inner function that actually caused the exception).
3177 *
3178 */
3179 TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
3180 // Contents of Exception in various browsers.
3181 //
3182 // SAFARI:
3183 // ex.message = Can't find variable: qq
3184 // ex.line = 59
3185 // ex.sourceId = 580238192
3186 // ex.sourceURL = http://...
3187 // ex.expressionBeginOffset = 96
3188 // ex.expressionCaretOffset = 98
3189 // ex.expressionEndOffset = 98
3190 // ex.name = ReferenceError
3191 //
3192 // FIREFOX:
3193 // ex.message = qq is not defined
3194 // ex.fileName = http://...
3195 // ex.lineNumber = 59
3196 // ex.columnNumber = 69
3197 // ex.stack = ...stack trace... (see the example below)
3198 // ex.name = ReferenceError
3199 //
3200 // CHROME:
3201 // ex.message = qq is not defined
3202 // ex.name = ReferenceError
3203 // ex.type = not_defined
3204 // ex.arguments = ['aa']
3205 // ex.stack = ...stack trace...
3206 //
3207 // INTERNET EXPLORER:
3208 // ex.message = ...
3209 // ex.name = ReferenceError
3210 //
3211 // OPERA:
3212 // ex.message = ...message... (see the example below)
3213 // ex.name = ReferenceError
3214 // ex.opera#sourceloc = 11 (pretty much useless, duplicates the info in ex.message)
3215 // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace'
3216
3217 /**
3218 * Computes stack trace information from the stack property.
3219 * Chrome and Gecko use this property.
3220 * @param {Error} ex
3221 * @return {?Object.<string, *>} Stack trace information.
3222 */
3223 function computeStackTraceFromStackProp(ex) {
3224 if (typeof ex.stack === 'undefined' || !ex.stack) return;
3225
3226 var chrome = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|[a-z]:|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,
3227 gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i,
3228 winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,
3229 // Used to additionally parse URL/line/column from eval frames
3230 geckoEval = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i,
3231 chromeEval = /\((\S*)(?::(\d+))(?::(\d+))\)/,
3232 lines = ex.stack.split('\n'),
3233 stack = [],
3234 submatch,
3235 parts,
3236 element,
3237 reference = /^(.*) is undefined$/.exec(ex.message);
3238
3239 for (var i = 0, j = lines.length; i < j; ++i) {
3240 if ((parts = chrome.exec(lines[i]))) {
3241 var isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line
3242 var isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line
3243 if (isEval && (submatch = chromeEval.exec(parts[2]))) {
3244 // throw out eval line/column and use top-most line/column number
3245 parts[2] = submatch[1]; // url
3246 parts[3] = submatch[2]; // line
3247 parts[4] = submatch[3]; // column
3248 }
3249 element = {
3250 url: !isNative ? parts[2] : null,
3251 func: parts[1] || UNKNOWN_FUNCTION,
3252 args: isNative ? [parts[2]] : [],
3253 line: parts[3] ? +parts[3] : null,
3254 column: parts[4] ? +parts[4] : null
3255 };
3256 } else if ((parts = winjs.exec(lines[i]))) {
3257 element = {
3258 url: parts[2],
3259 func: parts[1] || UNKNOWN_FUNCTION,
3260 args: [],
3261 line: +parts[3],
3262 column: parts[4] ? +parts[4] : null
3263 };
3264 } else if ((parts = gecko.exec(lines[i]))) {
3265 var isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
3266 if (isEval && (submatch = geckoEval.exec(parts[3]))) {
3267 // throw out eval line/column and use top-most line number
3268 parts[3] = submatch[1];
3269 parts[4] = submatch[2];
3270 parts[5] = null; // no column when eval
3271 } else if (i === 0 && !parts[5] && typeof ex.columnNumber !== 'undefined') {
3272 // FireFox uses this awesome columnNumber property for its top frame
3273 // Also note, Firefox's column number is 0-based and everything else expects 1-based,
3274 // so adding 1
3275 // NOTE: this hack doesn't work if top-most frame is eval
3276 stack[0].column = ex.columnNumber + 1;
3277 }
3278 element = {
3279 url: parts[3],
3280 func: parts[1] || UNKNOWN_FUNCTION,
3281 args: parts[2] ? parts[2].split(',') : [],
3282 line: parts[4] ? +parts[4] : null,
3283 column: parts[5] ? +parts[5] : null
3284 };
3285 } else {
3286 continue;
3287 }
3288
3289 if (!element.func && element.line) {
3290 element.func = UNKNOWN_FUNCTION;
3291 }
3292
3293 stack.push(element);
3294 }
3295
3296 if (!stack.length) {
3297 return null;
3298 }
3299
3300 return {
3301 name: ex.name,
3302 message: ex.message,
3303 url: getLocationHref(),
3304 stack: stack
3305 };
3306 }
3307
3308 /**
3309 * Adds information about the first frame to incomplete stack traces.
3310 * Safari and IE require this to get complete data on the first frame.
3311 * @param {Object.<string, *>} stackInfo Stack trace information from
3312 * one of the compute* methods.
3313 * @param {string} url The URL of the script that caused an error.
3314 * @param {(number|string)} lineNo The line number of the script that
3315 * caused an error.
3316 * @param {string=} message The error generated by the browser, which
3317 * hopefully contains the name of the object that caused the error.
3318 * @return {boolean} Whether or not the stack information was
3319 * augmented.
3320 */
3321 function augmentStackTraceWithInitialElement(stackInfo, url, lineNo, message) {
3322 var initial = {
3323 url: url,
3324 line: lineNo
3325 };
3326
3327 if (initial.url && initial.line) {
3328 stackInfo.incomplete = false;
3329
3330 if (!initial.func) {
3331 initial.func = UNKNOWN_FUNCTION;
3332 }
3333
3334 if (stackInfo.stack.length > 0) {
3335 if (stackInfo.stack[0].url === initial.url) {
3336 if (stackInfo.stack[0].line === initial.line) {
3337 return false; // already in stack trace
3338 } else if (
3339 !stackInfo.stack[0].line &&
3340 stackInfo.stack[0].func === initial.func
3341 ) {
3342 stackInfo.stack[0].line = initial.line;
3343 return false;
3344 }
3345 }
3346 }
3347
3348 stackInfo.stack.unshift(initial);
3349 stackInfo.partial = true;
3350 return true;
3351 } else {
3352 stackInfo.incomplete = true;
3353 }
3354
3355 return false;
3356 }
3357
3358 /**
3359 * Computes stack trace information by walking the arguments.caller
3360 * chain at the time the exception occurred. This will cause earlier
3361 * frames to be missed but is the only way to get any stack trace in
3362 * Safari and IE. The top frame is restored by
3363 * {@link augmentStackTraceWithInitialElement}.
3364 * @param {Error} ex
3365 * @return {?Object.<string, *>} Stack trace information.
3366 */
3367 function computeStackTraceByWalkingCallerChain(ex, depth) {
3368 var functionName = /function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,
3369 stack = [],
3370 funcs = {},
3371 recursion = false,
3372 parts,
3373 item,
3374 source;
3375
3376 for (
3377 var curr = computeStackTraceByWalkingCallerChain.caller;
3378 curr && !recursion;
3379 curr = curr.caller
3380 ) {
3381 if (curr === computeStackTrace || curr === TraceKit.report) {
3382 // console.log('skipping internal function');
3383 continue;
3384 }
3385
3386 item = {
3387 url: null,
3388 func: UNKNOWN_FUNCTION,
3389 line: null,
3390 column: null
3391 };
3392
3393 if (curr.name) {
3394 item.func = curr.name;
3395 } else if ((parts = functionName.exec(curr.toString()))) {
3396 item.func = parts[1];
3397 }
3398
3399 if (typeof item.func === 'undefined') {
3400 try {
3401 item.func = parts.input.substring(0, parts.input.indexOf('{'));
3402 } catch (e) {}
3403 }
3404
3405 if (funcs['' + curr]) {
3406 recursion = true;
3407 } else {
3408 funcs['' + curr] = true;
3409 }
3410
3411 stack.push(item);
3412 }
3413
3414 if (depth) {
3415 // console.log('depth is ' + depth);
3416 // console.log('stack is ' + stack.length);
3417 stack.splice(0, depth);
3418 }
3419
3420 var result = {
3421 name: ex.name,
3422 message: ex.message,
3423 url: getLocationHref(),
3424 stack: stack
3425 };
3426 augmentStackTraceWithInitialElement(
3427 result,
3428 ex.sourceURL || ex.fileName,
3429 ex.line || ex.lineNumber,
3430 ex.message || ex.description
3431 );
3432 return result;
3433 }
3434
3435 /**
3436 * Computes a stack trace for an exception.
3437 * @param {Error} ex
3438 * @param {(string|number)=} depth
3439 */
3440 function computeStackTrace(ex, depth) {
3441 var stack = null;
3442 depth = depth == null ? 0 : +depth;
3443
3444 try {
3445 stack = computeStackTraceFromStackProp(ex);
3446 if (stack) {
3447 return stack;
3448 }
3449 } catch (e) {
3450 if (TraceKit.debug) {
3451 throw e;
3452 }
3453 }
3454
3455 try {
3456 stack = computeStackTraceByWalkingCallerChain(ex, depth + 1);
3457 if (stack) {
3458 return stack;
3459 }
3460 } catch (e) {
3461 if (TraceKit.debug) {
3462 throw e;
3463 }
3464 }
3465 return {
3466 name: ex.name,
3467 message: ex.message,
3468 url: getLocationHref()
3469 };
3470 }
3471
3472 computeStackTrace.augmentStackTraceWithInitialElement = augmentStackTraceWithInitialElement;
3473 computeStackTrace.computeStackTraceFromStackProp = computeStackTraceFromStackProp;
3474
3475 return computeStackTrace;
3476 })();
3477
3478 module.exports = TraceKit;
3479
3480
3481 /***/ }),
3482
3483 /***/ "./node_modules/raven-js/vendor/json-stringify-safe/stringify.js":
3484 /*!***********************************************************************!*\
3485 !*** ./node_modules/raven-js/vendor/json-stringify-safe/stringify.js ***!
3486 \***********************************************************************/
3487 /***/ ((module, exports) => {
3488
3489 /*
3490 json-stringify-safe
3491 Like JSON.stringify, but doesn't throw on circular references.
3492
3493 Originally forked from https://github.com/isaacs/json-stringify-safe
3494 version 5.0.1 on 3/8/2017 and modified to handle Errors serialization
3495 and IE8 compatibility. Tests for this are in test/vendor.
3496
3497 ISC license: https://github.com/isaacs/json-stringify-safe/blob/master/LICENSE
3498 */
3499
3500 exports = module.exports = stringify;
3501 exports.getSerialize = serializer;
3502
3503 function indexOf(haystack, needle) {
3504 for (var i = 0; i < haystack.length; ++i) {
3505 if (haystack[i] === needle) return i;
3506 }
3507 return -1;
3508 }
3509
3510 function stringify(obj, replacer, spaces, cycleReplacer) {
3511 return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
3512 }
3513
3514 // https://github.com/ftlabs/js-abbreviate/blob/fa709e5f139e7770a71827b1893f22418097fbda/index.js#L95-L106
3515 function stringifyError(value) {
3516 var err = {
3517 // These properties are implemented as magical getters and don't show up in for in
3518 stack: value.stack,
3519 message: value.message,
3520 name: value.name
3521 };
3522
3523 for (var i in value) {
3524 if (Object.prototype.hasOwnProperty.call(value, i)) {
3525 err[i] = value[i];
3526 }
3527 }
3528
3529 return err;
3530 }
3531
3532 function serializer(replacer, cycleReplacer) {
3533 var stack = [];
3534 var keys = [];
3535
3536 if (cycleReplacer == null) {
3537 cycleReplacer = function(key, value) {
3538 if (stack[0] === value) {
3539 return '[Circular ~]';
3540 }
3541 return '[Circular ~.' + keys.slice(0, indexOf(stack, value)).join('.') + ']';
3542 };
3543 }
3544
3545 return function(key, value) {
3546 if (stack.length > 0) {
3547 var thisPos = indexOf(stack, this);
3548 ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
3549 ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
3550
3551 if (~indexOf(stack, value)) {
3552 value = cycleReplacer.call(this, key, value);
3553 }
3554 } else {
3555 stack.push(value);
3556 }
3557
3558 return replacer == null
3559 ? value instanceof Error ? stringifyError(value) : value
3560 : replacer.call(this, key, value);
3561 };
3562 }
3563
3564
3565 /***/ }),
3566
3567 /***/ "jquery":
3568 /*!*************************!*\
3569 !*** external "jQuery" ***!
3570 \*************************/
3571 /***/ ((module) => {
3572
3573 "use strict";
3574 module.exports = window["jQuery"];
3575
3576 /***/ })
3577
3578 /******/ });
3579 /************************************************************************/
3580 /******/ // The module cache
3581 /******/ var __webpack_module_cache__ = {};
3582 /******/
3583 /******/ // The require function
3584 /******/ function __webpack_require__(moduleId) {
3585 /******/ // Check if module is in cache
3586 /******/ var cachedModule = __webpack_module_cache__[moduleId];
3587 /******/ if (cachedModule !== undefined) {
3588 /******/ return cachedModule.exports;
3589 /******/ }
3590 /******/ // Create a new module (and put it into the cache)
3591 /******/ var module = __webpack_module_cache__[moduleId] = {
3592 /******/ // no module.id needed
3593 /******/ // no module.loaded needed
3594 /******/ exports: {}
3595 /******/ };
3596 /******/
3597 /******/ // Execute the module function
3598 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
3599 /******/
3600 /******/ // Return the exports of the module
3601 /******/ return module.exports;
3602 /******/ }
3603 /******/
3604 /************************************************************************/
3605 /******/ /* webpack/runtime/compat get default export */
3606 /******/ (() => {
3607 /******/ // getDefaultExport function for compatibility with non-harmony modules
3608 /******/ __webpack_require__.n = (module) => {
3609 /******/ var getter = module && module.__esModule ?
3610 /******/ () => (module['default']) :
3611 /******/ () => (module);
3612 /******/ __webpack_require__.d(getter, { a: getter });
3613 /******/ return getter;
3614 /******/ };
3615 /******/ })();
3616 /******/
3617 /******/ /* webpack/runtime/define property getters */
3618 /******/ (() => {
3619 /******/ // define getter functions for harmony exports
3620 /******/ __webpack_require__.d = (exports, definition) => {
3621 /******/ for(var key in definition) {
3622 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
3623 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
3624 /******/ }
3625 /******/ }
3626 /******/ };
3627 /******/ })();
3628 /******/
3629 /******/ /* webpack/runtime/global */
3630 /******/ (() => {
3631 /******/ __webpack_require__.g = (function() {
3632 /******/ if (typeof globalThis === 'object') return globalThis;
3633 /******/ try {
3634 /******/ return this || new Function('return this')();
3635 /******/ } catch (e) {
3636 /******/ if (typeof window === 'object') return window;
3637 /******/ }
3638 /******/ })();
3639 /******/ })();
3640 /******/
3641 /******/ /* webpack/runtime/hasOwnProperty shorthand */
3642 /******/ (() => {
3643 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
3644 /******/ })();
3645 /******/
3646 /******/ /* webpack/runtime/make namespace object */
3647 /******/ (() => {
3648 /******/ // define __esModule on exports
3649 /******/ __webpack_require__.r = (exports) => {
3650 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
3651 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3652 /******/ }
3653 /******/ Object.defineProperty(exports, '__esModule', { value: true });
3654 /******/ };
3655 /******/ })();
3656 /******/
3657 /************************************************************************/
3658 var __webpack_exports__ = {};
3659 // This entry need to be wrapped in an IIFE because it need to be in strict mode.
3660 (() => {
3661 "use strict";
3662 /*!*****************************************!*\
3663 !*** ./scripts/entries/reviewBanner.ts ***!
3664 \*****************************************/
3665 __webpack_require__.r(__webpack_exports__);
3666 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3667 /* harmony export */ "initMonitorReviewBanner": () => (/* binding */ initMonitorReviewBanner)
3668 /* harmony export */ });
3669 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery");
3670 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
3671 /* harmony import */ var _utils_backgroundAppUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/backgroundAppUtils */ "./scripts/utils/backgroundAppUtils.ts");
3672 /* harmony import */ var _constants_selectors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../constants/selectors */ "./scripts/constants/selectors.ts");
3673 /* harmony import */ var _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../constants/leadinConfig */ "./scripts/constants/leadinConfig.ts");
3674 /* harmony import */ var _iframe_integratedMessages__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../iframe/integratedMessages */ "./scripts/iframe/integratedMessages/index.ts");
3675
3676
3677
3678
3679
3680 var REVIEW_BANNER_INTRO_PERIOD_DAYS = 15;
3681
3682 var userIsAfterIntroductoryPeriod = function userIsAfterIntroductoryPeriod() {
3683 var activationDate = new Date(+_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_3__.activationTime * 1000);
3684 var currentDate = new Date();
3685 var timeElapsed = new Date(currentDate.getTime() - activationDate.getTime());
3686 return timeElapsed.getUTCDate() - 1 >= REVIEW_BANNER_INTRO_PERIOD_DAYS;
3687 };
3688 /**
3689 * Adds some methods to window when review banner is
3690 * displayed to monitor events
3691 */
3692
3693
3694 function initMonitorReviewBanner() {
3695 if (_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_3__.refreshToken) {
3696 var embedder = (0,_utils_backgroundAppUtils__WEBPACK_IMPORTED_MODULE_1__.getOrCreateBackgroundApp)(_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_3__.refreshToken);
3697 var container = jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_2__.domElements.reviewBannerContainer);
3698
3699 if (container && userIsAfterIntroductoryPeriod()) {
3700 jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_2__.domElements.reviewBannerLeaveReviewLink).off('click').on('click', function () {
3701 embedder.postMessage({
3702 key: _iframe_integratedMessages__WEBPACK_IMPORTED_MODULE_4__.ProxyMessages.TrackReviewBannerInteraction
3703 });
3704 });
3705 jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_2__.domElements.reviewBannerDismissButton).off('click').on('click', function () {
3706 embedder.postMessage({
3707 key: _iframe_integratedMessages__WEBPACK_IMPORTED_MODULE_4__.ProxyMessages.TrackReviewBannerDismissed
3708 });
3709 });
3710 embedder.postAsyncMessage({
3711 key: _iframe_integratedMessages__WEBPACK_IMPORTED_MODULE_4__.ProxyMessages.FetchContactsCreateSinceActivation,
3712 payload: +_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_3__.activationTime * 1000
3713 }).then(function (_ref) {
3714 var total = _ref.total;
3715
3716 if (total >= 5) {
3717 container.removeClass('leadin-review-banner--hide');
3718 embedder.postMessage({
3719 key: _iframe_integratedMessages__WEBPACK_IMPORTED_MODULE_4__.ProxyMessages.TrackReviewBannerRender
3720 });
3721 }
3722 });
3723 }
3724 }
3725 }
3726 (0,_utils_backgroundAppUtils__WEBPACK_IMPORTED_MODULE_1__.initBackgroundApp)(initMonitorReviewBanner);
3727 })();
3728
3729 /******/ })()
3730 ;
3731 //# sourceMappingURL=reviewBanner.js.map