@pendo/agent 2.320.2 → 2.321.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3967,8 +3967,8 @@ let SERVER = '';
3967
3967
  let ASSET_HOST = '';
3968
3968
  let ASSET_PATH = '';
3969
3969
  let DESIGNER_SERVER = '';
3970
- let VERSION = '2.320.2_';
3971
- let PACKAGE_VERSION = '2.320.2';
3970
+ let VERSION = '2.321.0_';
3971
+ let PACKAGE_VERSION = '2.321.0';
3972
3972
  let LOADER = 'xhr';
3973
3973
  /* eslint-enable web-sdk-eslint-rules/no-gulp-env-references */
3974
3974
  /**
@@ -6157,22 +6157,6 @@ function wasSessionCleared(evt) {
6157
6157
  return _.get(props, 'wasCleared');
6158
6158
  }
6159
6159
 
6160
- // Wraps any function with a try/catch that reports errors back to the server
6161
- // Optionally will log the exception. Defaults to logging enabled.
6162
- var makeSafe = function (method, noLogging) {
6163
- noLogging = !!noLogging;
6164
- return function () {
6165
- try {
6166
- return method.apply(this, arguments);
6167
- }
6168
- catch (e) {
6169
- if (!noLogging) {
6170
- log.critical(e);
6171
- }
6172
- }
6173
- };
6174
- };
6175
-
6176
6160
  // NOT A TRUE POLYFILL
6177
6161
  // This really only replaces the location portion of the URL API.
6178
6162
  //
@@ -9975,7 +9959,7 @@ var writeMessage = function (msg) {
9975
9959
  msg,
9976
9960
  version: VERSION
9977
9961
  });
9978
- return writeImgTag(url);
9962
+ return q.resolve(writeImgTag(url)).catch(_.noop);
9979
9963
  };
9980
9964
  /**
9981
9965
  * @access private
@@ -13348,6 +13332,22 @@ function initializeEventBuffer(options) {
13348
13332
  };
13349
13333
  }
13350
13334
 
13335
+ // Wraps any function with a try/catch that reports errors back to the server
13336
+ // Optionally will log the exception. Defaults to logging enabled.
13337
+ var makeSafe = function (method, noLogging) {
13338
+ noLogging = !!noLogging;
13339
+ return function () {
13340
+ try {
13341
+ return method.apply(this, arguments);
13342
+ }
13343
+ catch (e) {
13344
+ if (!noLogging) {
13345
+ log.critical(e);
13346
+ }
13347
+ }
13348
+ };
13349
+ };
13350
+
13351
13351
  /**
13352
13352
  * Registers a new load event. Collects only if the URL has changed.
13353
13353
  *
@@ -19837,6 +19837,51 @@ function writeLastStepSeenCache(lastSeen) {
19837
19837
  store.dispatch('guideState/write');
19838
19838
  store.dispatch('frames/changeLastGuideStepSeen', lastSeen);
19839
19839
  }
19840
+ function getGuideEvent(evt) {
19841
+ return _.get(evt, 'data.0');
19842
+ }
19843
+ function shouldResumeGuide(evt) {
19844
+ const guideEvent = getGuideEvent(evt);
19845
+ if (!guideEvent)
19846
+ return false;
19847
+ const props = guideEvent.props || {};
19848
+ const guide = findGuideById(props.guide_id);
19849
+ if (!guide)
19850
+ return false;
19851
+ if (guide.attributes && guide.attributes.doNotResume) {
19852
+ return false;
19853
+ }
19854
+ return true;
19855
+ }
19856
+ function onGuideEventWriteLastStepSeen(evt, stepSeenState) {
19857
+ const guideEvent = getGuideEvent(evt);
19858
+ if (!guideEvent)
19859
+ return;
19860
+ const props = guideEvent.props || {};
19861
+ const lastSeen = {
19862
+ guideId: props.guide_id,
19863
+ guideStepId: props.guide_step_id,
19864
+ time: guideEvent.browser_time,
19865
+ state: stepSeenState,
19866
+ visitorId: guideEvent.visitor_id
19867
+ };
19868
+ if (props.reason != null) {
19869
+ lastSeen.seenReason = props.reason;
19870
+ }
19871
+ else if (props.seen_reason != null) {
19872
+ lastSeen.seenReason = props.seen_reason;
19873
+ }
19874
+ if (props.destination_step_id != null) {
19875
+ lastSeen.destinationStepId = props.destination_step_id;
19876
+ }
19877
+ if (props.dismiss_count != null) {
19878
+ lastSeen.dismissCount = props.dismiss_count;
19879
+ }
19880
+ if (props.snooze_duration != null) {
19881
+ lastSeen.snoozeEndTime = guideEvent.browser_time + props.snooze_duration;
19882
+ }
19883
+ writeLastStepSeenCache(lastSeen);
19884
+ }
19840
19885
  function listenForGuideStateChange() {
19841
19886
  const unlisten = [];
19842
19887
  store.dispatch('guideState/init');
@@ -19903,6 +19948,22 @@ var GuideStateModule = (function () {
19903
19948
  removeIdentificationCookies([LAST_STEP_ADVANCED_COOKIE]);
19904
19949
  }
19905
19950
  });
19951
+ Events.guideSeen.on(function (evt) {
19952
+ onGuideEventWriteLastStepSeen(evt, 'active');
19953
+ });
19954
+ Events.guideAdvanced.on(function (evt) {
19955
+ if (shouldResumeGuide(evt)) {
19956
+ onGuideEventWriteLastStepSeen(evt, 'advanced');
19957
+ }
19958
+ });
19959
+ Events.guideDismissed.on(function (evt) {
19960
+ if (shouldResumeGuide(evt)) {
19961
+ onGuideEventWriteLastStepSeen(evt, 'dismissed');
19962
+ }
19963
+ });
19964
+ Events.guideSnoozed.on(function (evt) {
19965
+ onGuideEventWriteLastStepSeen(evt, 'snoozed');
19966
+ });
19906
19967
  },
19907
19968
  load(context) {
19908
19969
  const storage = context.getters.storage();
@@ -20886,7 +20947,6 @@ function resourceCenterBadgeProc(resourceCenter, eligibleModules, controlGuidesI
20886
20947
  if (!eligibleModules || !eligibleModules.length) {
20887
20948
  var isBadgeActivated = resourceCenter.launchMethod.indexOf('badge') !== -1;
20888
20949
  var isElementActivated = resourceCenter.launchMethod.indexOf('dom') !== -1;
20889
- var isExtensionActivated = resourceCenter.launchMethod.indexOf('extensionIcon') !== -1;
20890
20950
  resourceCenter.hasResourceCenterContent = false;
20891
20951
  // If the RC is badge activated, hide it from the dom completely. Otherwise, leave it alone
20892
20952
  // This is important for element-activated RC, which should still display with an empty state
@@ -20907,7 +20967,7 @@ function resourceCenterBadgeProc(resourceCenter, eligibleModules, controlGuidesI
20907
20967
  resourceCenter.badgeHidden = true;
20908
20968
  delete resourceCenter.activeModule;
20909
20969
  }
20910
- else if (isElementActivated || isExtensionActivated) {
20970
+ else if (isElementActivated) {
20911
20971
  resourceCenter.showEmptyState = true;
20912
20972
  resourceCenter.controlGuidesInAllModules = controlGuidesInAllModules;
20913
20973
  }
@@ -23176,16 +23236,6 @@ function getPreviewModeAssetUrl() {
23176
23236
  }
23177
23237
  var GUIDE_CSS_NAME = '_pendo-guide_';
23178
23238
  var GUIDE_ID_PREFIX = '_pendo_g_';
23179
- // This is used to determine the duration of a guide event.
23180
- // It gets set at the time a guide is shown and then used in
23181
- // comparison with the time the guide is closed.
23182
- var seenTime = 0;
23183
- function setSeenTime(time) {
23184
- seenTime = time;
23185
- }
23186
- function getSeenTime() {
23187
- return seenTime;
23188
- }
23189
23239
  var addCloseButton = function (elem, cb) {
23190
23240
  var closeButton = dom('._pendo-close-guide_', elem);
23191
23241
  if (closeButton.length) {
@@ -23391,22 +23441,9 @@ var onGuideDismissed = function (evt, step) {
23391
23441
  var seenReason = firstStep && firstStep.seenReason;
23392
23442
  var language = currentGuide && currentGuide.language;
23393
23443
  var dismissCount = _.get(step, 'dismissCount', 0) + 1;
23394
- dismissedGuide(guideId, stepId, get_visitor_id(), seenReason, language);
23444
+ dismissedGuide(guideId, stepId, get_visitor_id(), seenReason, language, dismissCount);
23395
23445
  var now = getNow();
23396
23446
  _updateGuideStepStatus(guideId, stepId, 'dismissed', now, dismissCount);
23397
- var guide = _.isFunction(step.getGuide) && step.getGuide();
23398
- var doNotResume = guide && guide.attributes && guide.attributes.doNotResume;
23399
- if (!doNotResume) {
23400
- writeLastStepSeenCache({
23401
- guideId,
23402
- guideStepId: stepId,
23403
- time: now,
23404
- state: 'dismissed',
23405
- seenReason,
23406
- visitorId: get_visitor_id(),
23407
- dismissCount
23408
- });
23409
- }
23410
23447
  // maintain latestDismissedAutoAt client-side
23411
23448
  if (shouldAffectThrottling(currentGuide, seenReason)) {
23412
23449
  writeThrottlingStateCache(now, THROTTLING_STATE.DISMISSED);
@@ -23468,18 +23505,6 @@ var onGuideSnoozed = function (evt, step, snoozeDuration) {
23468
23505
  step.snoozeEndTime = snoozeEndTime;
23469
23506
  snoozedGuide(guideId, stepId, visitorId, seenReason, language, snoozeDuration);
23470
23507
  _updateGuideStepStatus(guideId, stepId, 'snoozed', now);
23471
- var doNotResume = guide && guide.attributes && guide.attributes.doNotResume;
23472
- if (!doNotResume) {
23473
- writeLastStepSeenCache({
23474
- guideId,
23475
- guideStepId: stepId,
23476
- time: now,
23477
- state: 'snoozed',
23478
- seenReason,
23479
- visitorId: get_visitor_id(),
23480
- snoozeEndTime
23481
- });
23482
- }
23483
23508
  // maintain latestSnoozedAutoAt client-side
23484
23509
  if (shouldAffectThrottling(guide, seenReason)) {
23485
23510
  writeThrottlingStateCache(now, THROTTLING_STATE.SNOOZED);
@@ -23610,14 +23635,6 @@ var onGuideAdvanced = function (evt, step, isIntermediateStep) {
23610
23635
  step = currentGuide.steps[i];
23611
23636
  advancedGuide(currentGuide.id, step.id, get_visitor_id(), step.seenReason, language, i !== currentIndex);
23612
23637
  var stepNow = getNow();
23613
- writeLastStepSeenCache({
23614
- guideId: step.guideId,
23615
- guideStepId: step.id,
23616
- time: stepNow,
23617
- state: 'advanced',
23618
- seenReason: step.seenReason,
23619
- visitorId: get_visitor_id()
23620
- });
23621
23638
  _updateGuideStepStatus(currentGuide.id, step.id, 'advanced', stepNow, undefined, destinationStepId);
23622
23639
  }
23623
23640
  return onGuideAdvanced(currentGuide.steps[destinationIndex], step, true);
@@ -23635,30 +23652,16 @@ var onGuideAdvanced = function (evt, step, isIntermediateStep) {
23635
23652
  if (!destinationStepId) {
23636
23653
  log.info('missing destination step id');
23637
23654
  }
23638
- log.info('advancing guide');
23639
- advancedGuide(guideId, stepId, get_visitor_id(), seenReason, language, isIntermediateStep, destinationStepId);
23640
- log.info('update guide status');
23641
23655
  var dismissCount;
23642
23656
  // increment dismissCount for advancing the last step of a guide
23643
23657
  if (currentGuide && _.last(currentGuide.steps).id === stepId) {
23644
23658
  dismissCount = _.get(step, 'dismissCount', 0) + 1;
23645
23659
  }
23660
+ log.info('advancing guide');
23661
+ advancedGuide(guideId, stepId, get_visitor_id(), seenReason, language, isIntermediateStep, destinationStepId, dismissCount);
23662
+ log.info('update guide status');
23646
23663
  var now = new Date().getTime();
23647
23664
  _updateGuideStepStatus(guideId, stepId, 'advanced', now, dismissCount, destinationStepId);
23648
- var guide = _.isFunction(step.getGuide) && step.getGuide();
23649
- var doNotResume = guide && guide.attributes && guide.attributes.doNotResume;
23650
- if (!doNotResume) {
23651
- writeLastStepSeenCache({
23652
- guideId,
23653
- guideStepId: stepId,
23654
- time: now,
23655
- state: 'advanced',
23656
- seenReason,
23657
- visitorId: get_visitor_id(),
23658
- destinationStepId,
23659
- dismissCount
23660
- });
23661
- }
23662
23665
  // maintain finalAdvancedAutoAt client-side
23663
23666
  if (shouldAffectThrottling(currentGuide, seenReason)) {
23664
23667
  writeThrottlingStateCache(now, THROTTLING_STATE.ADVANCED);
@@ -23723,19 +23726,6 @@ var onGuidePrevious = function (evt, step) {
23723
23726
  log.info('update guide status');
23724
23727
  var now = new Date().getTime();
23725
23728
  _updateGuideStepStatus(step.guideId, step.id, 'advanced', now, undefined, destinationStepId);
23726
- var guide = _.isFunction(step.getGuide) && step.getGuide();
23727
- var doNotResume = guide && guide.attributes && guide.attributes.doNotResume;
23728
- if (!doNotResume) {
23729
- writeLastStepSeenCache({
23730
- guideId: step.guideId,
23731
- guideStepId: step.id,
23732
- time: now,
23733
- state: 'advanced',
23734
- seenReason,
23735
- visitorId: get_visitor_id(),
23736
- destinationStepId
23737
- });
23738
- }
23739
23729
  stopGuides();
23740
23730
  startGuides();
23741
23731
  };
@@ -23986,25 +23976,16 @@ var seenGuide = function (guideId, stepId, visitorId, reason, language, props) {
23986
23976
  stepId,
23987
23977
  visitorId,
23988
23978
  reason,
23989
- language
23979
+ language,
23980
+ duration: 0
23990
23981
  });
23991
23982
  _.extend(evt.props, props);
23992
23983
  stageGuideEvent(evt);
23993
23984
  var now = getNow();
23994
- // XXX consider publishing an event guideShown
23995
- // and then hook writing this up to that.
23996
- writeLastStepSeenCache({
23997
- guideId,
23998
- guideStepId: stepId,
23999
- time: now,
24000
- state: 'active',
24001
- seenReason: reason,
24002
- visitorId: get_visitor_id()
24003
- });
24004
23985
  _updateGuideStepStatus(guideId, stepId, 'active', now);
24005
23986
  Events.guideSeen.trigger(evt);
24006
23987
  };
24007
- function dismissedGuide(guideId, stepId, visitorId, seenReason, language) {
23988
+ function dismissedGuide(guideId, stepId, visitorId, seenReason, language, dismissCount) {
24008
23989
  var evt = createGuideEvent({
24009
23990
  type: 'guideDismissed',
24010
23991
  guideId,
@@ -24013,6 +23994,9 @@ function dismissedGuide(guideId, stepId, visitorId, seenReason, language) {
24013
23994
  seen_reason: seenReason,
24014
23995
  language
24015
23996
  });
23997
+ if (dismissCount != null) {
23998
+ evt.props.dismiss_count = dismissCount;
23999
+ }
24016
24000
  stageGuideEvent(evt);
24017
24001
  Events.guideDismissed.trigger(evt);
24018
24002
  }
@@ -24029,7 +24013,7 @@ function snoozedGuide(guideId, stepId, visitorId, seenReason, language, snoozeDu
24029
24013
  stageGuideEvent(evt);
24030
24014
  Events.guideSnoozed.trigger(evt);
24031
24015
  }
24032
- function advancedGuide(guideId, stepId, visitorId, seenReason, language, isIntermediateStep, destinationStepId) {
24016
+ function advancedGuide(guideId, stepId, visitorId, seenReason, language, isIntermediateStep, destinationStepId, dismissCount) {
24033
24017
  var guideEventParams = {
24034
24018
  type: 'guideAdvanced',
24035
24019
  guideId,
@@ -24041,6 +24025,9 @@ function advancedGuide(guideId, stepId, visitorId, seenReason, language, isInter
24041
24025
  if (destinationStepId) {
24042
24026
  guideEventParams.destination_step_id = destinationStepId;
24043
24027
  }
24028
+ if (dismissCount != null) {
24029
+ guideEventParams.dismiss_count = dismissCount;
24030
+ }
24044
24031
  var evt = createGuideEvent(guideEventParams);
24045
24032
  stageGuideEvent(evt, null, isIntermediateStep);
24046
24033
  Events.guideAdvanced.trigger(evt);
@@ -24122,9 +24109,17 @@ var startStagedTimer = function (timeLimit) {
24122
24109
  window.clearTimeout(stagedEventsTimer);
24123
24110
  stagedEventsTimer = setTimeout$1(processGuideEventCache, timeLimit);
24124
24111
  };
24112
+ function getStepLastSeenAt(guideId, guideStepId) {
24113
+ const step = findStepInGuide(findGuideById(guideId), guideStepId);
24114
+ return step && step.lastSeenAt;
24115
+ }
24125
24116
  var stageGuideEvent = function (evt, delay, isIntermediateStep) {
24126
24117
  delay = delay || 500;
24127
- evt.props.duration = isIntermediateStep ? 0 : (new Date().getTime() - getSeenTime());
24118
+ if (evt.props.duration == null) {
24119
+ const { guide_id, guide_step_id } = evt.props;
24120
+ const lastSeenAt = getStepLastSeenAt(guide_id, guide_step_id);
24121
+ evt.props.duration = isIntermediateStep || lastSeenAt == null ? 0 : (getNow() - lastSeenAt);
24122
+ }
24128
24123
  initGuideAnalytics();
24129
24124
  guideEventQueue.push(evt);
24130
24125
  startStagedTimer(delay);
@@ -26388,6 +26383,15 @@ const Keys = (function () {
26388
26383
  },
26389
26384
  tamperedWith() {
26390
26385
  return pendo$1.apiKey !== _apiKey || pendo$1.additionalApiKeys !== _additionalApiKeys;
26386
+ },
26387
+ /** Clears installed app keys on `pendo` and internal bookkeeping (e.g. failed `initialize`). */
26388
+ clearInstalledKeys() {
26389
+ _apiKey = null;
26390
+ _additionalApiKeys = [];
26391
+ delete pendo$1.apiKey;
26392
+ delete pendo$1.publicAppId;
26393
+ delete pendo$1.additionalApiKeys;
26394
+ delete pendo$1.additionalPublicAppIds;
26391
26395
  }
26392
26396
  };
26393
26397
  })();
@@ -27988,9 +27992,6 @@ EventRouter.deregisterAction = function deregisterAction(action) {
27988
27992
  */
27989
27993
  var GuideActivity = (function () {
27990
27994
  var GA_TYPE = 'guideActivity';
27991
- // it *should* be reliable for us to use b/c the guide *should* be active at
27992
- // time of the click.
27993
- var getDuration = function () { return new Date().getTime() - getSeenTime(); };
27994
27995
  var isObject = _.isObject;
27995
27996
  var findWhere = _.findWhere;
27996
27997
  var conditionalSplitEventQueue = [];
@@ -28272,7 +28273,6 @@ var GuideActivity = (function () {
28272
28273
  ui_element_actions: elementActions,
28273
28274
  guideId: activeGuideObj.guide.id,
28274
28275
  stepId: activeGuideObj.step.id,
28275
- duration: getDuration(),
28276
28276
  language: activeGuideObj.guide.language
28277
28277
  });
28278
28278
  }
@@ -28331,8 +28331,7 @@ const PluginAPI = {
28331
28331
  GuideActivity,
28332
28332
  GuideEvents: {
28333
28333
  stageGuideEvent,
28334
- createGuideEvent,
28335
- getSeenTime
28334
+ createGuideEvent
28336
28335
  },
28337
28336
  GuideLoop: {
28338
28337
  addUpdatePhase,
@@ -28499,9 +28498,6 @@ function initIdentityEvents() {
28499
28498
  var ResourceCenterActivity = (function () {
28500
28499
  // resource center activity is still considered guide activity
28501
28500
  var GA_TYPE = 'guideActivity';
28502
- // it *should* be reliable for us to use b/c the guide *should* be active at
28503
- // time of the click.
28504
- var getDuration = function () { return new Date().getTime() - getSeenTime(); };
28505
28501
  var isObject = _.isObject;
28506
28502
  return {
28507
28503
  type: GA_TYPE,
@@ -28636,7 +28632,6 @@ var ResourceCenterActivity = (function () {
28636
28632
  ui_element_actions: eventProps.actions,
28637
28633
  guideId: eventProps.guideId,
28638
28634
  stepId: eventProps.stepId,
28639
- duration: getDuration(),
28640
28635
  language: eventProps.language
28641
28636
  });
28642
28637
  }
@@ -28876,161 +28871,176 @@ const initializeImmediately = 'initializeImmediately';
28876
28871
  });
28877
28872
  */
28878
28873
  const teardownFns = [];
28879
- const initialize = makeSafe(function (options) {
28874
+ function initialize(options) {
28880
28875
  if (document.readyState !== 'complete' && !(_.get(options, initializeImmediately) || ConfigReader.get(initializeImmediately))) {
28881
- enqueueCall(pendo$1, 'initialize', arguments);
28882
- return;
28883
- }
28884
- log.info('pendo.initialize called with ' + JSON.stringify(options));
28885
- if (pendo$1.apiKey) {
28886
- if (initializeCounter++ === 1) {
28887
- log.info([
28888
- 'pendo.initialize only needs to be called once',
28889
- isSfdcLightning() ? ' per namespace' : '',
28890
- '. Use pendo.updateOptions to update metadata after the web SDK has initialized.'
28891
- ].join(''));
28876
+ try {
28877
+ enqueueCall(pendo$1, 'initialize', arguments);
28892
28878
  }
28893
- return;
28894
- }
28895
- if (!options) {
28896
- options = {};
28897
- }
28898
- if (_.isEmpty(JWT.get())) {
28899
- const jwtOptions = JWT.getJwtOptions(options, 'initialize');
28900
- if (jwtOptions) {
28901
- JWT.set(_.pick(options, 'jwt', 'signingKeyName'));
28902
- _.extend(options, jwtOptions, { forceAnonymous: true });
28879
+ catch (e) {
28880
+ log.critical('pendo.initialize failed while enqueueing deferred call.', e);
28903
28881
  }
28904
- }
28905
- if (_.isString(options)) { // treat as URL
28906
- return ajax.get(options)
28907
- .then((response) => {
28908
- // eslint-disable-next-line no-global-assign, no-native-reassign
28909
- setPendoConfig(PendoConfig = response.data);
28910
- return initialize();
28911
- });
28882
+ return;
28912
28883
  }
28913
28884
  try {
28885
+ log.info('pendo.initialize called with ' + JSON.stringify(options));
28886
+ if (pendo$1.apiKey) {
28887
+ if (initializeCounter++ === 1) {
28888
+ log.info([
28889
+ 'pendo.initialize only needs to be called once',
28890
+ isSfdcLightning() ? ' per namespace' : '',
28891
+ '. Use pendo.updateOptions to update metadata after the web SDK has initialized.'
28892
+ ].join(''));
28893
+ }
28894
+ return;
28895
+ }
28896
+ if (!options) {
28897
+ options = {};
28898
+ }
28899
+ if (_.isEmpty(JWT.get())) {
28900
+ const jwtOptions = JWT.getJwtOptions(options, 'initialize');
28901
+ if (jwtOptions) {
28902
+ JWT.set(_.pick(options, 'jwt', 'signingKeyName'));
28903
+ _.extend(options, jwtOptions, { forceAnonymous: true });
28904
+ }
28905
+ }
28906
+ if (_.isString(options)) { // treat as URL
28907
+ return ajax.get(options)
28908
+ .then((response) => {
28909
+ // eslint-disable-next-line no-global-assign, no-native-reassign
28910
+ setPendoConfig(PendoConfig = response.data);
28911
+ return initialize();
28912
+ });
28913
+ }
28914
28914
  store.dispatch('location/init', options.location || {});
28915
+ // Save the options somewhere
28916
+ ConfigReader.setLocalConfig(options);
28917
+ initDataHost();
28918
+ exportDataHost(pendo$1);
28919
+ const cookieDomain = ConfigReader.get('cookieDomain');
28920
+ if (cookieDomain) {
28921
+ setCookieDomain(cookieDomain, location.host);
28922
+ }
28923
+ Keys.discoverKeys(options);
28924
+ if (!Keys.getApiKey()) {
28925
+ log.debug('API key is not set, Pendo will not initialize.');
28926
+ return;
28927
+ }
28928
+ store.commit('metadata/setMetadata', { selfHosted: isSelfHosted() });
28929
+ if (options.logStackTraces) {
28930
+ pendo$1.logStackTraces = options.logStackTraces;
28931
+ }
28932
+ // If using the new frame communication support, make sure all
28933
+ // postMessage handlers are origin checked
28934
+ if (ConfigReader.get('preferBroadcastChannel')) {
28935
+ SingletonMessageHandler.secure(true);
28936
+ }
28937
+ const localStorageUnloadEnabled = ConfigReader.get('analytics.localStorageUnload');
28938
+ localStorageEventBuffer.read(agentStorage);
28939
+ teardownFns.push(initializeEventBuffer({
28940
+ localStorageUnload: localStorageUnloadEnabled
28941
+ }));
28942
+ // needs to happen before initGuides
28943
+ observer.initialize(pendo$1, PluginAPI);
28944
+ teardownFns.push(() => observer.teardown());
28945
+ if (pendoCore) {
28946
+ /**
28947
+ * Current visitor id for pendo installation, either anonymous or identified. Used to determine
28948
+ * a visitor's guide experience, settings, and associated data.
28949
+ *
28950
+ * @name _pendo_visitorId
28951
+ * @category Cookies/localStorage
28952
+ * @access public
28953
+ * @label VISITOR_ID_KEY
28954
+ */
28955
+ agentStorage.registry.addLocal(VISITOR_ID_KEY);
28956
+ /**
28957
+ * Often an anonymous visitor id that is replaced by a logged in user.
28958
+ *
28959
+ * @name _pendo_oldVisitorId
28960
+ * @category Cookies/localStorage
28961
+ * @access public
28962
+ * @label OLD_VISITOR_ID_KEY
28963
+ */
28964
+ agentStorage.registry.addLocal(OLD_VISITOR_ID_KEY);
28965
+ /**
28966
+ * The current account id for pendo installation provided in the `pendo.initialize()` call.
28967
+ *
28968
+ * @name _pendo_accountId
28969
+ * @category Cookies/localStorage
28970
+ * @access public
28971
+ * @label ACCOUNT_ID_KEY
28972
+ */
28973
+ agentStorage.registry.addLocal(ACCOUNT_ID_KEY);
28974
+ /**
28975
+ * Unique hash of the options object passed to `pendo.initialize()` or `pendo.updateOptions()`. This
28976
+ * is used to determine if the options have changed and if the metadata event should be fired.
28977
+ *
28978
+ * @name _pendo_meta
28979
+ * @category Cookies/localStorage
28980
+ * @access public
28981
+ * @label OPTIONS_HASH_KEY_NAME
28982
+ */
28983
+ agentStorage.registry.addLocal(OPTIONS_HASH_KEY_NAME);
28984
+ // Disable content pre-fetch for guide center
28985
+ pendo$1.disableGuideCenterContentSearch = options.disableGuideCenterContentSearch;
28986
+ // Register handlers passed through pendo_options
28987
+ teardownFns.push(forwardInternalEvents(Events));
28988
+ registerEventHandlers(options);
28989
+ teardownFns.push(initializeCrossFrameChannel(store));
28990
+ teardownFns.push(initGuides(observer)); // this is safe. loadGuides actually does the loading.
28991
+ teardownFns.push(P2AutoLaunch.loadPluginJs());
28992
+ teardownFns.push(initIdentityEvents()); // setup identify and meta event listeners
28993
+ teardownFns.push(wirePage());
28994
+ teardownFns.push(initializePlugins());
28995
+ teardownFns.push(launchDesignerOrPreview(options));
28996
+ Events.appUsage.on(GuideActivity.handler);
28997
+ Events.appUsage.on(ResourceCenterActivity.handler);
28998
+ teardownFns.push(flushEvery(SEND_INTERVAL));
28999
+ teardownFns.push(performanceMonitor.initialize());
29000
+ }
29001
+ const flushOnAppHidden = () => {
29002
+ flushNow(true, { hidden: true });
29003
+ };
29004
+ Events.appHidden.on(flushOnAppHidden);
29005
+ teardownFns.push(() => Events.appHidden.off(flushOnAppHidden));
29006
+ const flushOnAppUnloaded = () => {
29007
+ flushNow(true, { unload: true });
29008
+ if (localStorageUnloadEnabled) {
29009
+ localStorageEventBuffer.write(agentStorage);
29010
+ }
29011
+ };
29012
+ Events.appUnloaded.on(flushOnAppUnloaded);
29013
+ teardownFns.push(() => Events.appUnloaded.off(flushOnAppUnloaded));
29014
+ // Remove existing visitor and account identification cookies if
29015
+ // disablePersistence is set to true via administration UI or snippet
29016
+ if (!shouldPersist()) {
29017
+ removeIdentificationCookies();
29018
+ }
29019
+ pendo$1.updateOptions(options);
29020
+ if (options.visitorId && options.visitorId != DEFAULT_VISITOR_ID) {
29021
+ pendo$1.identify(options.visitorId);
29022
+ }
29023
+ teardownFns.push(pendoDotUrl.watch(function () {
29024
+ pendo$1.pageLoad();
29025
+ }));
29026
+ if (pendoCore) {
29027
+ Events.ready.trigger();
29028
+ }
29029
+ pageLoad(pendoDotUrl.get());
29030
+ initializeCounter++;
29031
+ announceFrameToDesignerPlugin();
29032
+ flushCallQueue();
28915
29033
  }
28916
29034
  catch (e) {
28917
- log.critical('Location API Exception', e);
28918
- }
28919
- // Save the options somewhere
28920
- ConfigReader.setLocalConfig(options);
28921
- initDataHost();
28922
- exportDataHost(pendo$1);
28923
- const cookieDomain = ConfigReader.get('cookieDomain');
28924
- if (cookieDomain) {
28925
- setCookieDomain(cookieDomain, location.host);
28926
- }
28927
- Keys.discoverKeys(options);
28928
- if (!Keys.getApiKey()) {
28929
- log.debug('API key is not set, Pendo will not initialize.');
28930
- return;
28931
- }
28932
- store.commit('metadata/setMetadata', { selfHosted: isSelfHosted() });
28933
- if (options.logStackTraces) {
28934
- pendo$1.logStackTraces = options.logStackTraces;
28935
- }
28936
- // If using the new frame communication support, make sure all
28937
- // postMessage handlers are origin checked
28938
- if (ConfigReader.get('preferBroadcastChannel')) {
28939
- SingletonMessageHandler.secure(true);
28940
- }
28941
- const localStorageUnloadEnabled = ConfigReader.get('analytics.localStorageUnload');
28942
- localStorageEventBuffer.read(agentStorage);
28943
- teardownFns.push(initializeEventBuffer({
28944
- localStorageUnload: localStorageUnloadEnabled
28945
- }));
28946
- // needs to happen before initGuides
28947
- observer.initialize(pendo$1, PluginAPI);
28948
- teardownFns.push(() => observer.teardown());
28949
- if (pendoCore) {
28950
- /**
28951
- * Current visitor id for pendo installation, either anonymous or identified. Used to determine
28952
- * a visitor's guide experience, settings, and associated data.
28953
- *
28954
- * @name _pendo_visitorId
28955
- * @category Cookies/localStorage
28956
- * @access public
28957
- * @label VISITOR_ID_KEY
28958
- */
28959
- agentStorage.registry.addLocal(VISITOR_ID_KEY);
28960
- /**
28961
- * Often an anonymous visitor id that is replaced by a logged in user.
28962
- *
28963
- * @name _pendo_oldVisitorId
28964
- * @category Cookies/localStorage
28965
- * @access public
28966
- * @label OLD_VISITOR_ID_KEY
28967
- */
28968
- agentStorage.registry.addLocal(OLD_VISITOR_ID_KEY);
28969
- /**
28970
- * The current account id for pendo installation provided in the `pendo.initialize()` call.
28971
- *
28972
- * @name _pendo_accountId
28973
- * @category Cookies/localStorage
28974
- * @access public
28975
- * @label ACCOUNT_ID_KEY
28976
- */
28977
- agentStorage.registry.addLocal(ACCOUNT_ID_KEY);
28978
- /**
28979
- * Unique hash of the options object passed to `pendo.initialize()` or `pendo.updateOptions()`. This
28980
- * is used to determine if the options have changed and if the metadata event should be fired.
28981
- *
28982
- * @name _pendo_meta
28983
- * @category Cookies/localStorage
28984
- * @access public
28985
- * @label OPTIONS_HASH_KEY_NAME
28986
- */
28987
- agentStorage.registry.addLocal(OPTIONS_HASH_KEY_NAME);
28988
- // Disable content pre-fetch for guide center
28989
- pendo$1.disableGuideCenterContentSearch = options.disableGuideCenterContentSearch;
28990
- // Register handlers passed through pendo_options
28991
- teardownFns.push(forwardInternalEvents(Events));
28992
- registerEventHandlers(options);
28993
- teardownFns.push(initializeCrossFrameChannel(store));
28994
- teardownFns.push(initGuides(observer)); // this is safe. loadGuides actually does the loading.
28995
- teardownFns.push(P2AutoLaunch.loadPluginJs());
28996
- teardownFns.push(initIdentityEvents()); // setup identify and meta event listeners
28997
- teardownFns.push(wirePage());
28998
- teardownFns.push(initializePlugins());
28999
- teardownFns.push(launchDesignerOrPreview(options));
29000
- Events.appUsage.on(GuideActivity.handler);
29001
- Events.appUsage.on(ResourceCenterActivity.handler);
29002
- teardownFns.push(flushEvery(SEND_INTERVAL));
29003
- teardownFns.push(performanceMonitor.initialize());
29004
- }
29005
- Events.appHidden.on(() => {
29006
- flushNow(true, { hidden: true });
29007
- });
29008
- Events.appUnloaded.on(() => {
29009
- flushNow(true, { unload: true });
29010
- if (localStorageUnloadEnabled) {
29011
- localStorageEventBuffer.write(agentStorage);
29035
+ log.critical('An exception occurred during pendo.initialize.', e);
29036
+ try {
29037
+ teardown();
29038
+ }
29039
+ catch (teardownErr) {
29040
+ log.critical('Error during pendo.initialize rollback teardown', teardownErr);
29012
29041
  }
29013
- });
29014
- // Remove existing visitor and account identification cookies if
29015
- // disablePersistence is set to true via administration UI or snippet
29016
- if (!shouldPersist()) {
29017
- removeIdentificationCookies();
29018
- }
29019
- pendo$1.updateOptions(options);
29020
- if (options.visitorId && options.visitorId != DEFAULT_VISITOR_ID) {
29021
- pendo$1.identify(options.visitorId);
29022
- }
29023
- teardownFns.push(pendoDotUrl.watch(function () {
29024
- pendo$1.pageLoad();
29025
- }));
29026
- if (pendoCore) {
29027
- Events.ready.trigger();
29028
29042
  }
29029
- pageLoad(pendoDotUrl.get());
29030
- initializeCounter++;
29031
- announceFrameToDesignerPlugin();
29032
- flushCallQueue();
29033
- });
29043
+ }
29034
29044
  function announceFrameToDesignerPlugin() {
29035
29045
  if (!window.parent || !window.parent.postMessage || typeof window.parent.postMessage != 'function')
29036
29046
  return;
@@ -29126,18 +29136,22 @@ function startup(callQueue, autoInitialize) {
29126
29136
  * delete window.pendo;
29127
29137
  */
29128
29138
  function teardown() {
29129
- Events.appHidden.trigger();
29130
- Events.appUnloaded.trigger();
29131
- _.each(teardownFns, function (teardownFn) {
29132
- teardownFn();
29133
- });
29134
- pageLoad.reset();
29135
- teardownFns.length = 0;
29136
- SingletonMessageHandler.close();
29137
- Eventable.clear(Events);
29138
- Eventable.clear(PublicEvents);
29139
- delete pendo$1.apiKey;
29140
- initializeCounter = 0;
29139
+ try {
29140
+ Events.appHidden.trigger();
29141
+ Events.appUnloaded.trigger();
29142
+ _.each(teardownFns, function (teardownFn) {
29143
+ teardownFn();
29144
+ });
29145
+ pageLoad.reset();
29146
+ teardownFns.length = 0;
29147
+ SingletonMessageHandler.close();
29148
+ Eventable.clear(Events);
29149
+ Eventable.clear(PublicEvents);
29150
+ }
29151
+ finally {
29152
+ Keys.clearInstalledKeys();
29153
+ initializeCounter = 0;
29154
+ }
29141
29155
  }
29142
29156
 
29143
29157
  function getActiveDefaultGuide(options = { channel: Channel.DEFAULT }) {
@@ -29993,7 +30007,7 @@ logPublic.getLoggedContexts = getLoggedContexts;
29993
30007
  /**
29994
30008
  * Shared helper for event collection
29995
30009
  */
29996
- function collectEventHelper({ type, name, props }) {
30010
+ function collectEventHelper({ type, name, props, eventProperties }) {
29997
30011
  if (!name || !_.isString(name)) {
29998
30012
  log.error('Must provide valid name string for event tracking');
29999
30013
  return;
@@ -30006,8 +30020,12 @@ function collectEventHelper({ type, name, props }) {
30006
30020
  if (!_.isObject(props)) {
30007
30021
  correctedProps = { __err__: props };
30008
30022
  }
30023
+ let correctedEventProperties = eventProperties;
30024
+ if (eventProperties !== undefined && !_.isObject(eventProperties)) {
30025
+ correctedEventProperties = { __err__: eventProperties };
30026
+ }
30009
30027
  var url = pendoDotUrl.get();
30010
- collectEvent(type, correctedProps, url, name);
30028
+ collectEvent(type, correctedProps, url, name, correctedEventProperties);
30011
30029
  }
30012
30030
  /**
30013
30031
  * Method to manually track events. Requires a non-empty name string to collect event.
@@ -30016,11 +30034,13 @@ function collectEventHelper({ type, name, props }) {
30016
30034
  * @category Events
30017
30035
  * @param {string} name name of the collected event
30018
30036
  * @param {Object} [props] optional properties object to collect with to the event
30037
+ * @param {Object} [eventProperties] optional key-value map stored on the event as top-level event properties
30019
30038
  * @example
30020
30039
  * pendo.track('scroll')
30040
+ * pendo.track('Registered', { plan: 'Pro' }, { experiment: 'variant_a' })
30021
30041
  */
30022
- function track(name, props) {
30023
- collectEventHelper({ type: 'track', name, props });
30042
+ function track(name, props, eventProperties) {
30043
+ collectEventHelper({ type: 'track', name, props, eventProperties });
30024
30044
  }
30025
30045
 
30026
30046
  const privacyFilterCache = new Map();
@@ -30032,6 +30052,7 @@ const privacyFilterCache = new Map();
30032
30052
  * @category Events
30033
30053
  * @param {string} type type of the collected agentic event ['prompt', 'agent_response', 'user_reaction']
30034
30054
  * @param {Object} props event-specific properties object
30055
+ * @param {Object} [eventProperties] optional key-value map stored on the event as top-level event properties (same as pendo.track)
30035
30056
  * @example
30036
30057
  * pendo.trackAgent('type_of_event', {
30037
30058
  * agentId: 'weather_assistant',
@@ -30042,14 +30063,14 @@ const privacyFilterCache = new Map();
30042
30063
  * suggestedPrompt: false,
30043
30064
  * toolsUsed: [],
30044
30065
  * fileUploaded: false
30045
- * })
30066
+ * }, { experiment: 'variant_a' })
30046
30067
  */
30047
- function trackAgent(type, props) {
30068
+ function trackAgent(type, props, eventProperties) {
30048
30069
  const filteredTypes = ['prompt', 'agent_response'];
30049
30070
  if (_.contains(filteredTypes, type)) {
30050
30071
  props = applyPrivacyFilters(props);
30051
30072
  }
30052
- collectEventHelper({ type, name: 'agentic', props });
30073
+ collectEventHelper({ type, name: 'agentic', props, eventProperties });
30053
30074
  }
30054
30075
  /**
30055
30076
  * Apply privacy filters to event properties based on agent configuration
@@ -32115,12 +32136,6 @@ function Poll(guide) {
32115
32136
  var now = getNow();
32116
32137
  advancedGuide(guideId, stepId, get_visitor_id(), step.seenReason, guide.language);
32117
32138
  _updateGuideStepStatus(guideId, stepId, 'advanced', now);
32118
- writeLastStepSeenCache({
32119
- guideId,
32120
- guideStepId: stepId,
32121
- time: now,
32122
- state: 'advanced'
32123
- });
32124
32139
  };
32125
32140
  var afterResponse = function () {
32126
32141
  var pollElement = dom('._pendo-poll_');
@@ -32731,7 +32746,7 @@ function GuideStep(guide) {
32731
32746
  var step = this;
32732
32747
  if (!isPreviewing()) {
32733
32748
  step.seenReason = reason;
32734
- setSeenTime(getNow());
32749
+ step.lastSeenAt = getNow();
32735
32750
  var pollTypes = this.getStepPollTypes(guide, step);
32736
32751
  if (!step.hasBeenControlled()) {
32737
32752
  controlledGuide(step.guideId, step.id, get_visitor_id(), reason, guide.language, pollTypes);
@@ -32742,7 +32757,7 @@ function GuideStep(guide) {
32742
32757
  }
32743
32758
  }
32744
32759
  };
32745
- this.onShown = function (reason, processGuideSeen = true) {
32760
+ this.onShown = function (reason) {
32746
32761
  var step = this;
32747
32762
  if (step.overrideElement) {
32748
32763
  dom.addClass(step.overrideElement, 'triggered');
@@ -32753,7 +32768,6 @@ function GuideStep(guide) {
32753
32768
  if (!isPreviewing()) {
32754
32769
  step.seenReason = reason;
32755
32770
  step.seenState = 'active';
32756
- setSeenTime(getNow());
32757
32771
  var seenProps = {
32758
32772
  color_mode: step.isDarkMode ? 'dark' : 'default',
32759
32773
  last_updated_at: step.lastUpdatedAt
@@ -32762,17 +32776,7 @@ function GuideStep(guide) {
32762
32776
  if (pollTypes) {
32763
32777
  seenProps.step_poll_types = pollTypes;
32764
32778
  }
32765
- if (processGuideSeen) {
32766
- seenGuide(step.guideId, step.id, get_visitor_id(), reason, guide.language, seenProps);
32767
- }
32768
- store.dispatch('guideState/updateLastGuideStepSeen', {
32769
- guideId: guide.id,
32770
- guideStepId: step.id,
32771
- time: getSeenTime(),
32772
- state: step.seenState,
32773
- seenReason: reason,
32774
- visitorId: get_visitor_id()
32775
- });
32779
+ seenGuide(step.guideId, step.id, get_visitor_id(), reason, guide.language, seenProps);
32776
32780
  // Cancel snoozes on the guide when any step of a guide is seen
32777
32781
  _.each(guide.steps, function (step) {
32778
32782
  if (step.seenState === 'snoozed') {
@@ -34053,7 +34057,7 @@ var FramesModule = (function () {
34053
34057
  };
34054
34058
  function cloneGuide(guide) {
34055
34059
  var clonedGuide = _.pick(guide, 'id', 'name', 'launchMethod', 'isMultiStep', 'steps', 'control', 'lastUpdatedAt', 'language', 'state', 'polls', 'redisplay', 'channel');
34056
- clonedGuide.attributes = _.pick(guide.attributes, 'overrideAutoThrottling', 'priority', 'isAnnouncement', 'resourceCenter', 'device', 'sharedServiceVersion', 'embedConfig');
34060
+ clonedGuide.attributes = _.pick(guide.attributes, 'overrideAutoThrottling', 'priority', 'isAnnouncement', 'resourceCenter', 'device', 'sharedServiceVersion', 'embedConfig', 'activation');
34057
34061
  clonedGuide._shouldBeAddedToLauncher = _.isFunction(guide.shouldBeAddedToLauncher) ? guide.shouldBeAddedToLauncher() : (guide._shouldBeAddedToLauncher || false);
34058
34062
  clonedGuide._shouldBeAddedToResourceCenter = _.isFunction(guide.shouldBeAddedToResourceCenter) ? guide.shouldBeAddedToResourceCenter() : (guide._shouldBeAddedToResourceCenter || false);
34059
34063
  clonedGuide.steps = _.map(guide.steps, function (step) {
@@ -36867,18 +36871,29 @@ const FrustrationEvent = (function () {
36867
36871
  */
36868
36872
  pluginApi.agentStorage.registry.addSession(previousPageLoadsCookie);
36869
36873
  if (pendoGlobal.sniffer.MutationObserver) {
36870
- const MutationObserver = getZoneSafeMethod('MutationObserver');
36871
- mutationObserver = new MutationObserver(observeDOMMutation);
36872
- try {
36873
- mutationObserver.observe(pendoGlobal.dom.getBody(), {
36874
- childList: true,
36875
- attributes: true,
36876
- subtree: true
36877
- });
36878
- }
36879
- catch (e) {
36880
- mutationObserver = null;
36881
- }
36874
+ initializeMutationObserver();
36875
+ }
36876
+ }
36877
+ function initializeMutationObserver() {
36878
+ if (observer.observing) {
36879
+ observer.addEventListener('mutation', onSharedMutation);
36880
+ }
36881
+ else {
36882
+ createMutationObserver();
36883
+ }
36884
+ }
36885
+ function createMutationObserver() {
36886
+ const MutationObserver = getZoneSafeMethod('MutationObserver');
36887
+ mutationObserver = new MutationObserver(observeDOMMutation);
36888
+ try {
36889
+ mutationObserver.observe(pendoGlobal.dom.getBody(), {
36890
+ childList: true,
36891
+ attributes: true,
36892
+ subtree: true
36893
+ });
36894
+ }
36895
+ catch (e) {
36896
+ mutationObserver = null;
36882
36897
  }
36883
36898
  }
36884
36899
  function teardown() {
@@ -36896,6 +36911,9 @@ const FrustrationEvent = (function () {
36896
36911
  if (mutationObserver) {
36897
36912
  mutationObserver.disconnect();
36898
36913
  }
36914
+ if (observer.observing) {
36915
+ observer.removeEventListener('mutation', onSharedMutation);
36916
+ }
36899
36917
  }
36900
36918
  function performanceNow() {
36901
36919
  if (typeof performance === 'undefined' || typeof performance.now !== 'function') {
@@ -36926,6 +36944,9 @@ const FrustrationEvent = (function () {
36926
36944
  suspendDeadClickQueue();
36927
36945
  hasHighlightedText = !!activelyHighlightedText.length;
36928
36946
  }
36947
+ function onSharedMutation({ mutation = [] } = {}) {
36948
+ observeDOMMutation(mutation);
36949
+ }
36929
36950
  function observeDOMMutation(mutations) {
36930
36951
  if (mutations.length) {
36931
36952
  suspendDeadClickQueue();
@@ -39936,7 +39957,11 @@ class PromptPlugin {
39936
39957
  });
39937
39958
  }
39938
39959
  handleRequest({ method, url, body }) {
39960
+ const currentUrl = getNormalizedUrl();
39939
39961
  this._.each(this.networkAgents, aiAgent => {
39962
+ if (!this.testPageRule(aiAgent.pageRule, currentUrl, aiAgent.id)) {
39963
+ return;
39964
+ }
39940
39965
  const originalBody = body || '';
39941
39966
  const filteredPrompt = this.applyPrivacyFilter(originalBody, aiAgent.privacyFilters);
39942
39967
  this.api.analytics.collectEvent('prompt', {
@@ -46467,7 +46492,10 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
46467
46492
  adds: [{ rule, index: index2 }]
46468
46493
  });
46469
46494
  }
46470
- return target.apply(thisArg, argumentsList);
46495
+ try {
46496
+ return target.apply(thisArg, argumentsList);
46497
+ } catch (e2) {
46498
+ }
46471
46499
  }
46472
46500
  )
46473
46501
  });
@@ -46596,7 +46624,10 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
46596
46624
  ]
46597
46625
  });
46598
46626
  }
46599
- return target.apply(thisArg, argumentsList);
46627
+ try {
46628
+ return target.apply(thisArg, argumentsList);
46629
+ } catch (e2) {
46630
+ }
46600
46631
  }
46601
46632
  )
46602
46633
  }
@@ -51525,59 +51556,59 @@ function ConsoleCapture() {
51525
51556
  }
51526
51557
 
51527
51558
  function NetworkCapture() {
51528
- var pluginAPI;
51529
- var globalPendo;
51530
- var requestMap = {};
51531
- var buffer;
51532
- var sendQueue;
51533
- var sendInterval;
51534
- var transport;
51535
- var isPtmPaused;
51536
- var requestBodyCb;
51537
- var responseBodyCb;
51538
- var pendoDevlogBaseUrl;
51539
- var isCapturingNetworkLogs = false;
51540
- var excludeRequestUrls = [];
51541
- var CAPTURE_NETWORK_CONFIG = 'captureNetworkRequests';
51542
- var NETWORK_SUB_TYPE = 'network';
51543
- var NETWORK_LOGS_CONFIG = 'networkLogs';
51544
- var NETWORK_LOGS_CONFIG_ALLOWED_REQUEST_HEADERS = 'networkLogs.allowedRequestHeaders';
51545
- var NETWORK_LOGS_CONFIG_ALLOWED_RESPONSE_HEADERS = 'networkLogs.allowedResponseHeaders';
51546
- var NETWORK_LOGS_CONFIG_CAPTURE_REQUEST_BODY = 'networkLogs.captureRequestBody';
51547
- var NETWORK_LOGS_CONFIG_CAPTURE_RESPONSE_BODY = 'networkLogs.captureResponseBody';
51548
- var NETWORK_LOGS_CONFIG_EXCLUDE_REQUEST_URLS = 'networkLogs.excludeRequestUrls';
51549
- var allowedRequestHeaders = {
51559
+ let pluginAPI;
51560
+ let globalPendo;
51561
+ let requestMap = {};
51562
+ let buffer;
51563
+ let sendQueue;
51564
+ let sendInterval;
51565
+ let transport;
51566
+ let isPtmPaused;
51567
+ let requestBodyCb;
51568
+ let responseBodyCb;
51569
+ let pendoDevlogBaseUrl;
51570
+ let isCapturingNetworkLogs = false;
51571
+ let excludeRequestUrls = [];
51572
+ const CAPTURE_NETWORK_CONFIG = 'captureNetworkRequests';
51573
+ const NETWORK_SUB_TYPE = 'network';
51574
+ const NETWORK_LOGS_CONFIG = 'networkLogs';
51575
+ const NETWORK_LOGS_CONFIG_ALLOWED_REQUEST_HEADERS = 'networkLogs.allowedRequestHeaders';
51576
+ const NETWORK_LOGS_CONFIG_ALLOWED_RESPONSE_HEADERS = 'networkLogs.allowedResponseHeaders';
51577
+ const NETWORK_LOGS_CONFIG_CAPTURE_REQUEST_BODY = 'networkLogs.captureRequestBody';
51578
+ const NETWORK_LOGS_CONFIG_CAPTURE_RESPONSE_BODY = 'networkLogs.captureResponseBody';
51579
+ const NETWORK_LOGS_CONFIG_EXCLUDE_REQUEST_URLS = 'networkLogs.excludeRequestUrls';
51580
+ const allowedRequestHeaders = {
51550
51581
  'content-type': true, 'content-length': true, 'accept': true, 'accept-language': true
51551
51582
  };
51552
- var allowedResponseHeaders = {
51583
+ const allowedResponseHeaders = {
51553
51584
  'cache-control': true, 'content-length': true, 'content-type': true, 'content-language': true
51554
51585
  };
51555
51586
  return {
51556
51587
  name: 'NetworkCapture',
51557
- initialize: initialize,
51558
- teardown: teardown,
51559
- handleRequest: handleRequest,
51560
- handleResponse: handleResponse,
51561
- handleError: handleError,
51562
- startCapture: startCapture,
51563
- createNetworkEvent: createNetworkEvent,
51564
- send: send,
51565
- onPtmPaused: onPtmPaused,
51566
- onPtmUnpaused: onPtmUnpaused,
51567
- onAppHidden: onAppHidden,
51568
- onAppUnloaded: onAppUnloaded,
51569
- setCaptureState: setCaptureState,
51570
- recordingStarted: recordingStarted,
51571
- recordingStopped: recordingStopped,
51572
- addConfigOptions: addConfigOptions,
51573
- processHeaderConfig: processHeaderConfig,
51574
- extractHeaders: extractHeaders,
51575
- setupBodyCallbacks: setupBodyCallbacks,
51576
- processBody: processBody,
51577
- processRequestBody: processRequestBody,
51578
- processResponseBody: processResponseBody,
51579
- buildExcludeRequestUrls: buildExcludeRequestUrls,
51580
- isUrlExcluded: isUrlExcluded,
51588
+ initialize,
51589
+ teardown,
51590
+ handleRequest,
51591
+ handleResponse,
51592
+ handleError,
51593
+ startCapture,
51594
+ createNetworkEvent,
51595
+ send,
51596
+ onPtmPaused,
51597
+ onPtmUnpaused,
51598
+ onAppHidden,
51599
+ onAppUnloaded,
51600
+ setCaptureState,
51601
+ recordingStarted,
51602
+ recordingStopped,
51603
+ addConfigOptions,
51604
+ processHeaderConfig,
51605
+ extractHeaders,
51606
+ setupBodyCallbacks,
51607
+ processBody,
51608
+ processRequestBody,
51609
+ processResponseBody,
51610
+ buildExcludeRequestUrls,
51611
+ isUrlExcluded,
51581
51612
  get isCapturingNetworkLogs() {
51582
51613
  return isCapturingNetworkLogs;
51583
51614
  },
@@ -51612,9 +51643,9 @@ function NetworkCapture() {
51612
51643
  function initialize(pendo, PluginAPI) {
51613
51644
  pluginAPI = PluginAPI;
51614
51645
  globalPendo = pendo;
51615
- var ConfigReader = pluginAPI.ConfigReader;
51646
+ const { ConfigReader } = pluginAPI;
51616
51647
  ConfigReader.addOption(CAPTURE_NETWORK_CONFIG, [ConfigReader.sources.PENDO_CONFIG_SRC], false);
51617
- var captureNetworkEnabled = ConfigReader.get(CAPTURE_NETWORK_CONFIG);
51648
+ const captureNetworkEnabled = ConfigReader.get(CAPTURE_NETWORK_CONFIG);
51618
51649
  if (!captureNetworkEnabled)
51619
51650
  return;
51620
51651
  buffer = new DevlogBuffer(pendo, pluginAPI);
@@ -51625,7 +51656,7 @@ function NetworkCapture() {
51625
51656
  processHeaderConfig(NETWORK_LOGS_CONFIG_ALLOWED_RESPONSE_HEADERS, allowedResponseHeaders);
51626
51657
  setupBodyCallbacks();
51627
51658
  buildExcludeRequestUrls();
51628
- sendInterval = setInterval(function () {
51659
+ sendInterval = setInterval(() => {
51629
51660
  if (!sendQueue.failed()) {
51630
51661
  send();
51631
51662
  }
@@ -51641,7 +51672,7 @@ function NetworkCapture() {
51641
51672
  pendoDevlogBaseUrl = pluginAPI.transmit.buildBaseDataUrl(DEV_LOG_TYPE, globalPendo.apiKey);
51642
51673
  }
51643
51674
  function addConfigOptions() {
51644
- var ConfigReader = pluginAPI.ConfigReader;
51675
+ const { ConfigReader } = pluginAPI;
51645
51676
  ConfigReader.addOption(NETWORK_LOGS_CONFIG, [ConfigReader.sources.SNIPPET_SRC], {});
51646
51677
  /**
51647
51678
  * Additional request headers to capture in network logs.
@@ -51700,17 +51731,17 @@ function NetworkCapture() {
51700
51731
  ConfigReader.addOption(NETWORK_LOGS_CONFIG_EXCLUDE_REQUEST_URLS, [ConfigReader.sources.SNIPPET_SRC], []);
51701
51732
  }
51702
51733
  function processHeaderConfig(configHeaderName, targetHeaders) {
51703
- var configHeaders = pluginAPI.ConfigReader.get(configHeaderName);
51734
+ const configHeaders = pluginAPI.ConfigReader.get(configHeaderName);
51704
51735
  if (!configHeaders || configHeaders.length === 0)
51705
51736
  return;
51706
- globalPendo._.each(configHeaders, function (header) {
51737
+ globalPendo._.each(configHeaders, (header) => {
51707
51738
  if (!header || !globalPendo._.isString(header))
51708
51739
  return;
51709
51740
  targetHeaders[header.toLowerCase()] = true;
51710
51741
  });
51711
51742
  }
51712
51743
  function setupBodyCallbacks() {
51713
- var config = pluginAPI.ConfigReader.get(NETWORK_LOGS_CONFIG);
51744
+ const config = pluginAPI.ConfigReader.get(NETWORK_LOGS_CONFIG);
51714
51745
  if (!config)
51715
51746
  return;
51716
51747
  if (globalPendo._.isFunction(config.captureRequestBody)) {
@@ -51721,11 +51752,11 @@ function NetworkCapture() {
51721
51752
  }
51722
51753
  }
51723
51754
  function buildExcludeRequestUrls() {
51724
- var requestUrls = pluginAPI.ConfigReader.get(NETWORK_LOGS_CONFIG_EXCLUDE_REQUEST_URLS);
51755
+ const requestUrls = pluginAPI.ConfigReader.get(NETWORK_LOGS_CONFIG_EXCLUDE_REQUEST_URLS);
51725
51756
  if (!requestUrls || requestUrls.length === 0)
51726
51757
  return;
51727
- globalPendo._.each(requestUrls, function (requestUrl) {
51728
- var processedRequestUrl = processUrlPattern(requestUrl);
51758
+ globalPendo._.each(requestUrls, (requestUrl) => {
51759
+ const processedRequestUrl = processUrlPattern(requestUrl);
51729
51760
  if (!processedRequestUrl)
51730
51761
  return;
51731
51762
  excludeRequestUrls.push(processedRequestUrl);
@@ -51734,13 +51765,13 @@ function NetworkCapture() {
51734
51765
  function processUrlPattern(url) {
51735
51766
  if (!url)
51736
51767
  return;
51737
- var isRegex = globalPendo._.isRegExp(url);
51768
+ const isRegex = globalPendo._.isRegExp(url);
51738
51769
  if (!globalPendo._.isString(url) && !isRegex)
51739
51770
  return;
51740
51771
  if (isRegex)
51741
51772
  return url;
51742
- var escapedUrl = pluginAPI.util.escapeRegExp(url);
51743
- return new RegExp("^".concat(escapedUrl, "$"));
51773
+ const escapedUrl = pluginAPI.util.escapeRegExp(url);
51774
+ return new RegExp(`^${escapedUrl}$`);
51744
51775
  }
51745
51776
  function onPtmPaused() {
51746
51777
  isPtmPaused = true;
@@ -51748,9 +51779,8 @@ function NetworkCapture() {
51748
51779
  function onPtmUnpaused() {
51749
51780
  isPtmPaused = false;
51750
51781
  if (!buffer.isEmpty()) {
51751
- for (var _i = 0, _a = buffer.events; _i < _a.length; _i++) {
51752
- var event_1 = _a[_i];
51753
- pluginAPI.Events.eventCaptured.trigger(event_1);
51782
+ for (const event of buffer.events) {
51783
+ pluginAPI.Events.eventCaptured.trigger(event);
51754
51784
  }
51755
51785
  send();
51756
51786
  }
@@ -51761,12 +51791,11 @@ function NetworkCapture() {
51761
51791
  function onAppUnloaded() {
51762
51792
  send({ unload: true });
51763
51793
  }
51764
- function setCaptureState(_a) {
51765
- var _b = _a === void 0 ? {} : _a, _c = _b.shouldCapture, shouldCapture = _c === void 0 ? false : _c, _d = _b.reason, reason = _d === void 0 ? '' : _d;
51794
+ function setCaptureState({ shouldCapture = false, reason = '' } = {}) {
51766
51795
  if (shouldCapture === isCapturingNetworkLogs)
51767
51796
  return;
51768
51797
  isCapturingNetworkLogs = shouldCapture;
51769
- pluginAPI.log.info("[NetworkCapture] Network request capture ".concat(shouldCapture ? 'started' : 'stopped').concat(reason ? ": ".concat(reason) : ''));
51798
+ pluginAPI.log.info(`[NetworkCapture] Network request capture ${shouldCapture ? 'started' : 'stopped'}${reason ? `: ${reason}` : ''}`);
51770
51799
  }
51771
51800
  function recordingStarted() {
51772
51801
  return setCaptureState({ shouldCapture: true, reason: 'recording started' });
@@ -51801,7 +51830,7 @@ function NetworkCapture() {
51801
51830
  return false;
51802
51831
  if (excludeRequestUrls.length === 0)
51803
51832
  return false;
51804
- return globalPendo._.some(excludeRequestUrls, function (excludeRequestUrl) {
51833
+ return globalPendo._.some(excludeRequestUrls, (excludeRequestUrl) => {
51805
51834
  return excludeRequestUrl.test(url);
51806
51835
  });
51807
51836
  }
@@ -51815,7 +51844,7 @@ function NetworkCapture() {
51815
51844
  return;
51816
51845
  if (!response)
51817
51846
  return;
51818
- var request = requestMap[response.requestId];
51847
+ const request = requestMap[response.requestId];
51819
51848
  if (!request)
51820
51849
  return;
51821
51850
  // Skip capturing successful devlog events to avoid infinite loops
@@ -51827,9 +51856,9 @@ function NetworkCapture() {
51827
51856
  delete requestMap[response.requestId];
51828
51857
  return;
51829
51858
  }
51830
- var networkEvent = createNetworkEvent({
51831
- request: request,
51832
- response: response
51859
+ const networkEvent = createNetworkEvent({
51860
+ request,
51861
+ response
51833
51862
  });
51834
51863
  if (!isPtmPaused) {
51835
51864
  pluginAPI.Events.eventCaptured.trigger(networkEvent);
@@ -51837,8 +51866,7 @@ function NetworkCapture() {
51837
51866
  buffer.push(networkEvent);
51838
51867
  delete requestMap[response.requestId];
51839
51868
  }
51840
- function handleError(_a) {
51841
- var error = _a.error, context = _a.context;
51869
+ function handleError({ error, context }) {
51842
51870
  if (!isCapturingNetworkLogs)
51843
51871
  return;
51844
51872
  if (error.requestId && requestMap[error.requestId]) {
@@ -51852,13 +51880,13 @@ function NetworkCapture() {
51852
51880
  }
51853
51881
  }
51854
51882
  function extractHeaders(headers, allowedHeaders) {
51855
- var _a = globalPendo._, keys = _a.keys, reduce = _a.reduce;
51883
+ const { keys, reduce } = globalPendo._;
51856
51884
  if (!headers || !allowedHeaders)
51857
51885
  return [];
51858
- return reduce(keys(headers), function (acc, key) {
51859
- var normalizedKey = key.toLowerCase();
51886
+ return reduce(keys(headers), (acc, key) => {
51887
+ const normalizedKey = key.toLowerCase();
51860
51888
  if (allowedHeaders[normalizedKey]) {
51861
- acc.push("".concat(key, ": ").concat(headers[key]));
51889
+ acc.push(`${key}: ${headers[key]}`);
51862
51890
  }
51863
51891
  return acc;
51864
51892
  }, []);
@@ -51866,16 +51894,15 @@ function NetworkCapture() {
51866
51894
  function processBody(body, contentType) {
51867
51895
  if (!body || !globalPendo._.isString(body))
51868
51896
  return '';
51869
- var processedBody = maskSensitiveFields({ string: body, contentType: contentType, _: globalPendo._ });
51897
+ const processedBody = maskSensitiveFields({ string: body, contentType, _: globalPendo._ });
51870
51898
  return truncate(processedBody, true);
51871
51899
  }
51872
- function processRequestBody(_a) {
51873
- var request = _a.request;
51900
+ function processRequestBody({ request }) {
51874
51901
  if (!request || !request.body || !requestBodyCb)
51875
51902
  return '';
51876
51903
  try {
51877
- var body = requestBodyCb(request.body, { request: request });
51878
- var contentType = globalPendo._.get(request, 'headers.content-type', '');
51904
+ const body = requestBodyCb(request.body, { request });
51905
+ const contentType = globalPendo._.get(request, 'headers.content-type', '');
51879
51906
  return processBody(body, contentType);
51880
51907
  }
51881
51908
  catch (error) {
@@ -51883,13 +51910,12 @@ function NetworkCapture() {
51883
51910
  return '[Failed to process request body]';
51884
51911
  }
51885
51912
  }
51886
- function processResponseBody(_a) {
51887
- var response = _a.response;
51913
+ function processResponseBody({ response }) {
51888
51914
  if (!response || !response.body || !responseBodyCb)
51889
51915
  return '';
51890
51916
  try {
51891
- var body = responseBodyCb(response.body, { response: response });
51892
- var contentType = globalPendo._.get(response, 'headers.content-type', '');
51917
+ const body = responseBodyCb(response.body, { response });
51918
+ const contentType = globalPendo._.get(response, 'headers.content-type', '');
51893
51919
  return processBody(body, contentType);
51894
51920
  }
51895
51921
  catch (error) {
@@ -51897,34 +51923,32 @@ function NetworkCapture() {
51897
51923
  return '[Failed to process response body]';
51898
51924
  }
51899
51925
  }
51900
- function createNetworkEvent(_a) {
51901
- var request = _a.request, response = _a.response;
51902
- var devLogEnvelope = createDevLogEnvelope(pluginAPI, globalPendo);
51903
- var requestHeaders = extractHeaders(request.headers, allowedRequestHeaders);
51904
- var responseHeaders = extractHeaders(response.headers, allowedResponseHeaders);
51905
- var networkEvent = __assign(__assign({}, devLogEnvelope), { subType: NETWORK_SUB_TYPE, devLogMethod: request.method, devLogStatusCode: response.status, devLogRequestUrl: request.url, devLogRequestHeaders: requestHeaders, devLogResponseHeaders: responseHeaders, devLogCount: 1 });
51926
+ function createNetworkEvent({ request, response }) {
51927
+ const devLogEnvelope = createDevLogEnvelope(pluginAPI, globalPendo);
51928
+ const requestHeaders = extractHeaders(request.headers, allowedRequestHeaders);
51929
+ const responseHeaders = extractHeaders(response.headers, allowedResponseHeaders);
51930
+ const networkEvent = Object.assign(Object.assign({}, devLogEnvelope), { subType: NETWORK_SUB_TYPE, devLogMethod: request.method, devLogStatusCode: response.status, devLogRequestUrl: request.url, devLogRequestHeaders: requestHeaders, devLogResponseHeaders: responseHeaders, devLogCount: 1 });
51906
51931
  if (requestBodyCb) {
51907
- networkEvent.devLogRequestBody = processRequestBody({ request: request });
51932
+ networkEvent.devLogRequestBody = processRequestBody({ request });
51908
51933
  }
51909
51934
  if (responseBodyCb) {
51910
- networkEvent.devLogResponseBody = processResponseBody({ response: response });
51935
+ networkEvent.devLogResponseBody = processResponseBody({ response });
51911
51936
  }
51912
51937
  return networkEvent;
51913
51938
  }
51914
- function send(_a) {
51915
- var _b = _a === void 0 ? {} : _a, _c = _b.unload, unload = _c === void 0 ? false : _c, _d = _b.hidden, hidden = _d === void 0 ? false : _d;
51939
+ function send({ unload = false, hidden = false } = {}) {
51916
51940
  if (!buffer || buffer.isEmpty())
51917
51941
  return;
51918
51942
  if (!globalPendo.isSendingEvents()) {
51919
51943
  buffer.clear();
51920
51944
  return;
51921
51945
  }
51922
- var payloads = buffer.pack();
51946
+ const payloads = buffer.pack();
51923
51947
  if (unload || hidden) {
51924
51948
  sendQueue.drain(payloads, unload);
51925
51949
  }
51926
51950
  else {
51927
- sendQueue.push.apply(sendQueue, payloads);
51951
+ sendQueue.push(...payloads);
51928
51952
  }
51929
51953
  }
51930
51954
  }
@@ -52258,13 +52282,13 @@ var predictGuidesScript = function (_a) {
52258
52282
  cleanupArray.push(createFloatingModal({ recordId: recordId, configuration: configuration }));
52259
52283
  };
52260
52284
 
52261
- var PredictGuides = function () {
52262
- var pluginApiRef = null;
52263
- var cleanupArray = [];
52264
- var cleanup = function () {
52285
+ const PredictGuides = () => {
52286
+ let pluginApiRef = null;
52287
+ let cleanupArray = [];
52288
+ const cleanup = () => {
52265
52289
  var _a;
52266
52290
  (_a = pluginApiRef === null || pluginApiRef === void 0 ? void 0 : pluginApiRef.log) === null || _a === void 0 ? void 0 : _a.debug('[predict] cleaning up');
52267
- for (var i = 0; i < cleanupArray.length; i++) {
52291
+ for (let i = 0; i < cleanupArray.length; i++) {
52268
52292
  try {
52269
52293
  cleanupArray[i]();
52270
52294
  }
@@ -52272,44 +52296,44 @@ var PredictGuides = function () {
52272
52296
  }
52273
52297
  cleanupArray = [];
52274
52298
  };
52275
- var initialize = function (_pendo, PluginAPI) {
52299
+ const initialize = (_pendo, PluginAPI) => {
52276
52300
  pluginApiRef = PluginAPI;
52277
- var configReader = PluginAPI.ConfigReader;
52278
- var PREDICT_GUIDES_CONFIG = 'predictGuides';
52301
+ const configReader = PluginAPI.ConfigReader;
52302
+ const PREDICT_GUIDES_CONFIG = 'predictGuides';
52279
52303
  configReader.addOption(PREDICT_GUIDES_CONFIG, [
52280
52304
  configReader.sources.SNIPPET_SRC,
52281
52305
  configReader.sources.PENDO_CONFIG_SRC
52282
52306
  ], false);
52283
- var predictGuidesEnabled = configReader.get(PREDICT_GUIDES_CONFIG);
52307
+ const predictGuidesEnabled = configReader.get(PREDICT_GUIDES_CONFIG);
52284
52308
  if (!predictGuidesEnabled)
52285
52309
  return;
52286
- var log = PluginAPI.log.debug.bind(PluginAPI.log);
52310
+ const log = PluginAPI.log.debug.bind(PluginAPI.log);
52287
52311
  pluginApiRef.Events.urlChanged.on(cleanup);
52288
- var script = {
52312
+ const script = {
52289
52313
  name: 'PredictFrameScript',
52290
- script: function (step, _guide, pendo) {
52291
- predictGuidesScript({ step: step, pendo: pendo, cleanupArray: cleanupArray, cleanup: cleanup, log: log });
52292
- this.on('unmounted', function (evt) {
52314
+ script(step, _guide, pendo) {
52315
+ predictGuidesScript({ step, pendo, cleanupArray, cleanup, log });
52316
+ this.on('unmounted', (evt) => {
52293
52317
  if (evt.reason !== 'hidden')
52294
52318
  cleanup();
52295
52319
  });
52296
52320
  },
52297
- test: function (step, _guide) {
52298
- var stepName = step.name || '';
52321
+ test(step, _guide) {
52322
+ const stepName = step.name || '';
52299
52323
  return PREDICT_STEP_REGEX.test(stepName);
52300
52324
  }
52301
52325
  };
52302
52326
  pluginApiRef.GlobalRuntime.addGlobalScript(script);
52303
52327
  };
52304
- var teardown = function () {
52328
+ const teardown = () => {
52305
52329
  var _a, _b;
52306
52330
  cleanup();
52307
52331
  (_b = (_a = pluginApiRef === null || pluginApiRef === void 0 ? void 0 : pluginApiRef.Events) === null || _a === void 0 ? void 0 : _a.urlChanged) === null || _b === void 0 ? void 0 : _b.off(cleanup);
52308
52332
  };
52309
52333
  return {
52310
52334
  name: 'PredictGuides',
52311
- initialize: initialize,
52312
- teardown: teardown
52335
+ initialize,
52336
+ teardown
52313
52337
  };
52314
52338
  };
52315
52339