@webex/internal-plugin-device 3.11.0 → 3.12.0-next.1

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.
package/dist/config.js CHANGED
@@ -59,15 +59,21 @@ var _default = exports.default = {
59
59
  * energyForcast
60
60
  * @type {boolean}
61
61
  */
62
- energyForecast: false
63
- },
64
- /**
65
- * installationId is used exclusively as web client for fraud prevention,
66
- * and is aliased to as machineId by CA.
67
- *
68
- * @alias device.machineId
69
- * @type {string}
70
- */
71
- installationId: undefined
62
+ energyForecast: false,
63
+ /**
64
+ * debugFeatureTogglesKey
65
+ * The session storage key for debug feature toggles
66
+ * @type {string}
67
+ */
68
+ debugFeatureTogglesKey: undefined,
69
+ /**
70
+ * installationId is used exclusively as web client for fraud prevention,
71
+ * and is aliased to as machineId by CA.
72
+ *
73
+ * @alias device.machineId
74
+ * @type {string}
75
+ */
76
+ installationId: undefined
77
+ }
72
78
  };
73
79
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_common","require","_default","exports","default","device","canRegisterWaitDuration","defaults","body","name","process","title","trim","undefined","inBrowser","deviceType","WEB","model","localizedModel","systemName","systemVersion","enableInactivityEnforcement","ephemeral","ephemeralDeviceTTL","energyForecast","installationId"],"sources":["config.js"],"sourcesContent":["import {inBrowser, deviceType} from '@webex/common';\n\nexport default {\n device: {\n /**\n * The duration to wait for the catalog to populate in seconds.\n *\n * @type {number}\n */\n canRegisterWaitDuration: 10,\n\n /**\n * The default configuration group when sending registration requests.\n *\n * @type {Object}\n */\n defaults: {\n /**\n * The default body configuration of registration requests.\n *\n * @type {Object}\n */\n body: {\n name:\n (typeof process.title === 'string' ? process.title.trim() : undefined) ||\n (inBrowser && 'browser') ||\n 'javascript',\n deviceType: deviceType.WEB,\n model: 'web-js-sdk',\n localizedModel: 'webex-js-sdk',\n systemName: 'WEBEX_JS_SDK',\n systemVersion: '1.0.0',\n },\n },\n\n /**\n * When true, the **wdm** service will enforce an inactivity duration.\n *\n * @type {boolean}\n */\n enableInactivityEnforcement: false,\n\n /**\n * When true, the device registration will include a ttl value of\n * {@link config.device.ephemeralDeviceTTL} and refresh on an interval of\n * {@link config.device.ephemeralDeviceTTL} / 2 + 60 seconds.\n *\n * @type {boolean}\n */\n ephemeral: false,\n\n /**\n * The ttl value to include in device registration if\n * {@link config.device.ephemeral} is true. Measured in seconds.\n *\n * @type {boolean}\n */\n ephemeralDeviceTTL: 30 * 60,\n\n /**\n * energyForcast\n * @type {boolean}\n */\n energyForecast: false,\n },\n\n /**\n * installationId is used exclusively as web client for fraud prevention,\n * and is aliased to as machineId by CA.\n *\n * @alias device.machineId\n * @type {string}\n */\n installationId: undefined,\n};\n"],"mappings":";;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAAoD,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAErC;EACbC,MAAM,EAAE;IACN;AACJ;AACA;AACA;AACA;IACIC,uBAAuB,EAAE,EAAE;IAE3B;AACJ;AACA;AACA;AACA;IACIC,QAAQ,EAAE;MACR;AACN;AACA;AACA;AACA;MACMC,IAAI,EAAE;QACJC,IAAI,EACF,CAAC,OAAOC,OAAO,CAACC,KAAK,KAAK,QAAQ,GAAGD,OAAO,CAACC,KAAK,CAACC,IAAI,CAAC,CAAC,GAAGC,SAAS,KACpEC,iBAAS,IAAI,SAAU,IACxB,YAAY;QACdC,UAAU,EAAEA,kBAAU,CAACC,GAAG;QAC1BC,KAAK,EAAE,YAAY;QACnBC,cAAc,EAAE,cAAc;QAC9BC,UAAU,EAAE,cAAc;QAC1BC,aAAa,EAAE;MACjB;IACF,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIC,2BAA2B,EAAE,KAAK;IAElC;AACJ;AACA;AACA;AACA;AACA;AACA;IACIC,SAAS,EAAE,KAAK;IAEhB;AACJ;AACA;AACA;AACA;AACA;IACIC,kBAAkB,EAAE,EAAE,GAAG,EAAE;IAE3B;AACJ;AACA;AACA;IACIC,cAAc,EAAE;EAClB,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;EACEC,cAAc,EAAEZ;AAClB,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_common","require","_default","exports","default","device","canRegisterWaitDuration","defaults","body","name","process","title","trim","undefined","inBrowser","deviceType","WEB","model","localizedModel","systemName","systemVersion","enableInactivityEnforcement","ephemeral","ephemeralDeviceTTL","energyForecast","debugFeatureTogglesKey","installationId"],"sources":["config.js"],"sourcesContent":["import {inBrowser, deviceType} from '@webex/common';\n\nexport default {\n device: {\n /**\n * The duration to wait for the catalog to populate in seconds.\n *\n * @type {number}\n */\n canRegisterWaitDuration: 10,\n\n /**\n * The default configuration group when sending registration requests.\n *\n * @type {Object}\n */\n defaults: {\n /**\n * The default body configuration of registration requests.\n *\n * @type {Object}\n */\n body: {\n name:\n (typeof process.title === 'string' ? process.title.trim() : undefined) ||\n (inBrowser && 'browser') ||\n 'javascript',\n deviceType: deviceType.WEB,\n model: 'web-js-sdk',\n localizedModel: 'webex-js-sdk',\n systemName: 'WEBEX_JS_SDK',\n systemVersion: '1.0.0',\n },\n },\n\n /**\n * When true, the **wdm** service will enforce an inactivity duration.\n *\n * @type {boolean}\n */\n enableInactivityEnforcement: false,\n\n /**\n * When true, the device registration will include a ttl value of\n * {@link config.device.ephemeralDeviceTTL} and refresh on an interval of\n * {@link config.device.ephemeralDeviceTTL} / 2 + 60 seconds.\n *\n * @type {boolean}\n */\n ephemeral: false,\n\n /**\n * The ttl value to include in device registration if\n * {@link config.device.ephemeral} is true. Measured in seconds.\n *\n * @type {boolean}\n */\n ephemeralDeviceTTL: 30 * 60,\n\n /**\n * energyForcast\n * @type {boolean}\n */\n energyForecast: false,\n\n /**\n * debugFeatureTogglesKey\n * The session storage key for debug feature toggles\n * @type {string}\n */\n debugFeatureTogglesKey: undefined,\n\n /**\n * installationId is used exclusively as web client for fraud prevention,\n * and is aliased to as machineId by CA.\n *\n * @alias device.machineId\n * @type {string}\n */\n installationId: undefined,\n },\n};\n"],"mappings":";;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAAoD,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAErC;EACbC,MAAM,EAAE;IACN;AACJ;AACA;AACA;AACA;IACIC,uBAAuB,EAAE,EAAE;IAE3B;AACJ;AACA;AACA;AACA;IACIC,QAAQ,EAAE;MACR;AACN;AACA;AACA;AACA;MACMC,IAAI,EAAE;QACJC,IAAI,EACF,CAAC,OAAOC,OAAO,CAACC,KAAK,KAAK,QAAQ,GAAGD,OAAO,CAACC,KAAK,CAACC,IAAI,CAAC,CAAC,GAAGC,SAAS,KACpEC,iBAAS,IAAI,SAAU,IACxB,YAAY;QACdC,UAAU,EAAEA,kBAAU,CAACC,GAAG;QAC1BC,KAAK,EAAE,YAAY;QACnBC,cAAc,EAAE,cAAc;QAC9BC,UAAU,EAAE,cAAc;QAC1BC,aAAa,EAAE;MACjB;IACF,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIC,2BAA2B,EAAE,KAAK;IAElC;AACJ;AACA;AACA;AACA;AACA;AACA;IACIC,SAAS,EAAE,KAAK;IAEhB;AACJ;AACA;AACA;AACA;AACA;IACIC,kBAAkB,EAAE,EAAE,GAAG,EAAE;IAE3B;AACJ;AACA;AACA;IACIC,cAAc,EAAE,KAAK;IAErB;AACJ;AACA;AACA;AACA;IACIC,sBAAsB,EAAEZ,SAAS;IAEjC;AACJ;AACA;AACA;AACA;AACA;AACA;IACIa,cAAc,EAAEb;EAClB;AACF,CAAC","ignoreList":[]}
package/dist/device.js CHANGED
@@ -13,8 +13,11 @@ _Object$defineProperty(exports, "__esModule", {
13
13
  exports.default = void 0;
14
14
  var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
15
15
  var _apply = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/apply"));
16
+ var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
16
17
  var _now = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/date/now"));
17
18
  var _getOwnPropertyDescriptor = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor"));
19
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
20
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
18
21
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
19
22
  var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/applyDecoratedDescriptor"));
20
23
  var _common = require("@webex/common");
@@ -675,6 +678,33 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
675
678
  }
676
679
  return _promise.default.reject(new Error('device: failed to get the current websocket url'));
677
680
  },
681
+ /**
682
+ * Get sanitized processed debug features from session storage
683
+ * these should be JSON encoded and in the form {feature1: true, feature2: false}
684
+ *
685
+ * @returns {Array<Object>} - Array of sanitized debug feature toggles
686
+ */
687
+ getDebugFeatures: function getDebugFeatures() {
688
+ var sanitizedDebugFeatures = [];
689
+ if (this.config.debugFeatureTogglesKey) {
690
+ var debugFeaturesString = this.webex.getWindow().sessionStorage.getItem(this.config.debugFeatureTogglesKey);
691
+ if (debugFeaturesString) {
692
+ var debugFeatures = JSON.parse(debugFeaturesString);
693
+ (0, _entries.default)(debugFeatures).forEach(function (_ref) {
694
+ var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
695
+ key = _ref2[0],
696
+ value = _ref2[1];
697
+ sanitizedDebugFeatures.push({
698
+ key: key,
699
+ val: value ? 'true' : 'false',
700
+ mutable: true,
701
+ lastModified: new Date().toISOString()
702
+ });
703
+ });
704
+ }
705
+ }
706
+ return sanitizedDebugFeatures;
707
+ },
678
708
  /**
679
709
  * Process a successful device registration.
680
710
  *
@@ -682,7 +712,8 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
682
712
  * @returns {void}
683
713
  */
684
714
  processRegistrationSuccess: function processRegistrationSuccess(response) {
685
- var _this8 = this;
715
+ var _body$features,
716
+ _this8 = this;
686
717
  this.logger.info('device: received registration payload');
687
718
 
688
719
  // Clone the response body for service cleaning.
@@ -691,8 +722,8 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
691
722
  // Clean service data.
692
723
  delete body.services;
693
724
  delete body.serviceHostMap;
694
- var _ref = response.headers || {},
695
- etag = _ref.etag;
725
+ var _ref3 = response.headers || {},
726
+ etag = _ref3.etag;
696
727
  if (this.etag && etag && this.etag === etag) {
697
728
  // If current etag matches the previous one and we have sent
698
729
  // If-None-Match header the developer and entitlement feature
@@ -702,6 +733,15 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
702
733
  // When using the etag feature cache, user and entitlement features are still returned
703
734
  this.features.user.reset(features.user);
704
735
  this.features.entitlement.reset(features.entitlement);
736
+ } else if (this.config.debugFeatureTogglesKey && body !== null && body !== void 0 && (_body$features = body.features) !== null && _body$features !== void 0 && _body$features.developer) {
737
+ // Add the debug feature toggles from session storage if available
738
+ try {
739
+ var _body$features$develo;
740
+ var debugFeatures = this.getDebugFeatures();
741
+ (_body$features$develo = body.features.developer).push.apply(_body$features$develo, (0, _toConsumableArray2.default)(debugFeatures));
742
+ } catch (error) {
743
+ this.logger.error('Failed to parse debug feature toggles from session storage:', error);
744
+ }
705
745
  }
706
746
 
707
747
  // Assign the recieved DTO from **WDM** to this device.
@@ -808,6 +848,12 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
808
848
  }
809
849
  // Prototype the extended class in order to preserve the parent member.
810
850
  (0, _apply.default)(_webexCore.WebexPlugin.prototype.initialize, this, args);
851
+ this.listenToOnce(this.webex, 'change:config', function () {
852
+ // If debug feature toggles exist, clear the etag to ensure developer feature toggles are fetched
853
+ if (_this1.getDebugFeatures(_this1.config.debugFeatureTogglesKey).length > 0) {
854
+ _this1.set('etag', undefined);
855
+ }
856
+ });
811
857
 
812
858
  // Initialize feature events and listeners.
813
859
  _constants.FEATURE_COLLECTION_NAMES.forEach(function (collectionName) {
@@ -849,7 +895,7 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
849
895
  _this1.resetLogoutTimer();
850
896
  });
851
897
  } /* eslint-enable require-jsdoc */,
852
- version: "0.0.0"
898
+ version: "3.12.0-next.1"
853
899
  }, (0, _applyDecoratedDescriptor2.default)(_obj, "refresh", [_common.oneFlight, _dec], (0, _getOwnPropertyDescriptor.default)(_obj, "refresh"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "register", [_dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "register"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "_registerInternal", [_common.oneFlight, _dec3], (0, _getOwnPropertyDescriptor.default)(_obj, "_registerInternal"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "unregister", [_common.oneFlight, _dec4], (0, _getOwnPropertyDescriptor.default)(_obj, "unregister"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "markUrlFailedAndGetNew", [_dec5], (0, _getOwnPropertyDescriptor.default)(_obj, "markUrlFailedAndGetNew"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "initialize", [_dec6], (0, _getOwnPropertyDescriptor.default)(_obj, "initialize"), _obj), _obj));
854
900
  var _default = exports.default = Device;
855
901
  //# sourceMappingURL=device.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_common","require","_webexCore","_commonTimers","_lodash","_uuid","_interopRequireDefault","_metrics","_constants","_featuresModel","_ipNetworkDetector","_types","_dec","_dec2","_dec3","_dec4","_dec5","_dec6","_obj","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor2","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","decider","config","ephemeral","Device","WebexPlugin","extend","waitForValue","deprecated","persist","namespace","extraProperties","idAttribute","children","features","FeaturesModel","ipNetworkDetector","IpNetworkDetector","props","clientMessagingGiphy","customerCompanyName","customerLogoUrl","deviceType","helpUrl","intranetInactivityDuration","intranetInactivityCheckUrl","inNetworkInactivityDuration","ecmEnabledForAllUsers","ecmSupportedStorageProviders","modificationTime","navigationBarColor","partnerCompanyName","partnerLogoUrl","peopleInsightsEnabled","reportingSiteDesc","reportingSiteUrl","searchEncryptionKeyUrl","showSupportText","supportProviderCompanyName","supportProviderLogoUrl","url","userId","webFileShareControl","webSocketUrl","whiteboardFileShareControl","derived","registered","deps","fn","session","logoutTimer","lastUserActivityDate","isReachabilityChecked","energyForecastConfig","isInMeeting","isInNetwork","meetingStarted","webex","trigger","meetingEnded","setEnergyForecastConfig","undefined","refresh","_this","deviceRegistrationOptions","logger","info","canRegister","then","register","body","serialize","mediaCluster","etag","ttl","ephemeralDeviceTTL","headers","defaults","_deviceRegistrationOp","includeDetails","CatalogDetails","all","requestId","uuid","v4","set","request","method","uri","qs","includeUpstreamServices","concat","energyForecast","response","get","_promise","resolve","processRegistrationSuccess","catch","reason","statusCode","clear","reject","deleteDevices","_this2","service","resource","devices","_this2$_getBody","_getBody","webDevices","item","sortedDevices","orderBy","Date","totalItems","countToDelete","Math","ceil","urlsToDelete","slice","map","race","error","_this3","internal","newMetrics","callDiagnosticMetrics","setDeviceInfo","_registerInternal","_error$body","message","_this4","submitInternalEvent","name","_deviceRegistrationOp2","metrics","submitClientMetrics","METRICS","JS_SDK_WDM_REGISTRATION_SUCCESSFUL","JS_SDK_WDM_REGISTRATION_FAILED","fields","unregister","_this5","warn","services","waitForCatalog","canRegisterWaitDuration","Error","join","checkNetworkReachability","_this6","resetLogoutTimer","trackingid","_len","args","Array","_key","_apply","prototype","getWebSocketUrl","_this7","wait","waitForRegistration","convertUrlToPriorityHostUrl","wsUrl","_this8","serviceHostMap","_ref","user","reset","entitlement","delay","refreshTimer","safeSetTimeout","DEVICE_EVENT_REGISTRATION_SUCCESS","clearTimeout","off","unset","enableInactivityEnforcement","setLogoutTimer","duration","_this9","on","logout","_this0","timeout","timeoutTimer","once","markUrlFailedAndGetNew","markFailedUrl","initialize","_this1","_len2","_key2","FEATURE_COLLECTION_NAMES","collectionName","model","value","options","listenTo","_now","version","_applyDecoratedDescriptor2","oneFlight","_getOwnPropertyDescriptor","_default","exports"],"sources":["device.js"],"sourcesContent":["// Internal Dependencies\nimport {deprecated, oneFlight} from '@webex/common';\nimport {persist, waitForValue, WebexPlugin} from '@webex/webex-core';\nimport {safeSetTimeout} from '@webex/common-timers';\nimport {orderBy} from 'lodash';\nimport uuid from 'uuid';\n\nimport METRICS from './metrics';\nimport {FEATURE_COLLECTION_NAMES, DEVICE_EVENT_REGISTRATION_SUCCESS} from './constants';\nimport FeaturesModel from './features/features-model';\nimport IpNetworkDetector from './ipNetworkDetector';\nimport {CatalogDetails} from './types';\n\n/**\n * Determine if the plugin should be initialized based on cached storage.\n *\n * @returns {boolean} - If the device is ephemeral.\n */\nfunction decider() {\n return !this.config.ephemeral;\n}\n\nconst Device = WebexPlugin.extend({\n // Ampersand property members.\n\n namespace: 'Device',\n\n // Allow for extra properties to prevent the plugin from failing due to\n // **WDM** service DTO changes.\n extraProperties: 'allow',\n\n idAttribute: 'url',\n\n children: {\n /**\n * The class object that contains all of the feature collections.\n *\n * @type {FeaturesModel}\n */\n features: FeaturesModel,\n /**\n * Helper class for detecting what IP network version (ipv4, ipv6) we're on.\n *\n * @type {IpNetworkDetector}\n */\n ipNetworkDetector: IpNetworkDetector,\n },\n\n /**\n * A collection of device properties mostly assigned by the retrieved DTO from\n * the **WDM** service that are mapped against the ampersand properties.\n *\n * @type {Object}\n */\n props: {\n /**\n * This property determines whether or not giphy support is enabled.\n *\n * @type {'ALLOW' | 'BLOCK'}\n */\n clientMessagingGiphy: 'string',\n\n /**\n * This property should store the company name.\n *\n * @type {string}\n */\n customerCompanyName: 'string',\n\n /**\n * This property should store the logo url.\n *\n * @type {string}\n */\n customerLogoUrl: 'string',\n\n /**\n * This property doesn't have any real values, but is sent during device\n * refresh to prevent the **wdm** service from falling back to an iOS device\n * type.\n *\n * @type {string}\n */\n deviceType: 'string',\n\n /**\n * This property should store the help url.\n *\n * @type {string}\n */\n helpUrl: 'string',\n\n /**\n * This property should store the intranet inactivity timer duration.\n *\n * @type {number}\n */\n intranetInactivityDuration: 'number',\n\n /**\n * This property stores the url required to validate if the device is able\n * to actively reach the intranet network.\n *\n * @type {string}\n */\n intranetInactivityCheckUrl: 'string',\n\n /**\n * This property stores the inactivity timer duration, and could possibly\n * deprecate the `intranetInactivityDuration` property.\n *\n * @type {number}\n */\n inNetworkInactivityDuration: 'number',\n\n /**\n * This property stores the ECM (external content management) enabled value\n * for the whole organization.\n *\n * @type {boolean}\n */\n ecmEnabledForAllUsers: ['boolean', false, false],\n\n /**\n * This property stores an array of ECM (external content management)\n * providers that are currently available.\n *\n * @returns {Array<string>}\n */\n ecmSupportedStorageProviders: ['array', false, () => []],\n\n /**\n * This property stores the modification time value retrieved from the\n * **WDM** endpoint formatted as ISO 8601.\n *\n * @type {string}\n */\n modificationTime: 'string',\n\n /**\n * This property stores the navigation bar color.\n *\n * @type {string}\n */\n navigationBarColor: 'string',\n\n /**\n * This property stores the partner company's name when available.\n *\n * @type {string}\n */\n partnerCompanyName: 'string',\n\n /**\n * This property stores the partner company's logo when available.\n *\n * @type {string}\n */\n partnerLogoUrl: 'string',\n\n /**\n * This property stores the availability of people data from the **WDM**\n * service.\n *\n * @type {boolean}\n */\n peopleInsightsEnabled: 'boolean',\n\n /**\n * This property stores the reporting site's description when available.\n *\n * @type {string}\n */\n reportingSiteDesc: 'string',\n\n /**\n * This property stores the reporting site's access url when available.\n *\n * @type {string}\n */\n reportingSiteUrl: 'string',\n\n /**\n * This property stores the encryption key url when available.\n *\n * @type {string}\n */\n searchEncryptionKeyUrl: 'string',\n\n /**\n * This property stores the availability of support-provided text from the\n * **WDM** service.\n *\n * @type {boolean}\n */\n showSupportText: 'boolean',\n\n /**\n * This property stores the support provider's company name when available.\n *\n * @type {string}\n */\n supportProviderCompanyName: 'string',\n\n /**\n * This property stores the support provider's logo url when available.\n *\n * @type {string}\n */\n supportProviderLogoUrl: 'string',\n\n /**\n * This property stores the device's url retrieved from a registration\n * request. This property gets set via the initial registration process by a\n * `this.set()` method.\n *\n * @type {string}\n */\n url: 'string',\n\n /**\n * This property stores the device's userId uuid value, which can also be\n * derived from the device's registerd user's userId retrieved from\n * the **Hydra** service.\n *\n * @type {string}\n */\n userId: 'string',\n\n /**\n * This property stores whether or not file sharing is enabled\n *\n * @type {'BLOCK_BOTH' | 'BLOCK_UPLOAD'}\n */\n webFileShareControl: 'string',\n\n /**\n * This property stores the current web socket url used by the registered\n * device.\n *\n * @type {string}\n */\n webSocketUrl: 'string',\n\n /**\n * This property stores the value indicating whether or not white board file\n * sharing is enabled for the current device.\n *\n * @type {'ALLOW' | 'BLOCK'}\n */\n whiteboardFileShareControl: 'string',\n },\n\n /**\n * A list of derived properties that populate based when their parent data\n * available via the device's properties.\n *\n * @type {Object}\n */\n derived: {\n /**\n * This property determines if the current device is registered.\n *\n * @type {boolean}\n */\n registered: {\n deps: ['url'],\n\n /**\n * Checks if the device is registered by validating that the url exists.\n * Amperstand does not allow this to method to be written as an arrow\n * function.\n *\n * @returns {boolean}\n */\n fn() {\n return !!this.url;\n },\n },\n },\n\n /**\n * Stores timer data as well as other state details.\n *\n * @type {Object}\n */\n session: {\n /**\n * This property stores the logout timer object\n *\n * @type {any}\n */\n logoutTimer: 'any',\n\n /**\n * This property stores the date for the last activity the user made\n * with the current device.\n *\n * @type {number}\n */\n lastUserActivityDate: 'number',\n\n /**\n * This property stores whether or not the reachability check has been\n * performed to prevent the reachability check from performing its\n * operation more than once after a successful check.\n *\n * @returns {boolean}\n */\n isReachabilityChecked: ['boolean', false, false],\n\n /**\n * This property stores whether or not the next refresh or register request should request energy forecast data\n * in order to prevent over fetching energy forecasts\n *\n * @type {boolean}\n */\n energyForecastConfig: 'boolean',\n\n /**\n * This property stores whether or not the current device is in a meeting\n * to prevent an unneeded timeout of a meeting due to inactivity.\n *\n * @type {boolean}\n */\n isInMeeting: 'boolean',\n\n /**\n * This property identifies if the device is currently in network to prevent\n * the `resetLogoutTimer()` method from being called repeatedly once its\n * known client is connected to the organization's internal network.\n *\n * @type {boolean}\n */\n isInNetwork: 'boolean',\n },\n\n // Event method members.\n\n /**\n * Trigger meeting started event for webex instance. Used by web-client team.\n *\n * @returns {void}\n */\n meetingStarted() {\n this.webex.trigger('meeting started');\n },\n\n /**\n * Trigger meeting ended event for webex instance. Used by web-client team.\n *\n * @returns {void}\n */\n meetingEnded() {\n this.webex.trigger('meeting ended');\n },\n\n /**\n * Set the value of energy forecast config for the current registered device.\n * @param {boolean} [energyForecastConfig=false] - fetch an energy forecast on the next refresh/register\n * @returns {void}\n */\n setEnergyForecastConfig(energyForecastConfig = false) {\n this.energyForecastConfig = energyForecastConfig;\n },\n\n // Registration method members\n\n /**\n * Refresh the current registered device if able.\n *\n * @param {DeviceRegistrationOptions} options - The options for refresh.\n * @param {CatalogDetails} options.includeDetails - The details to include in the refresh/register request.\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n refresh(deviceRegistrationOptions = {}) {\n this.logger.info('device: refreshing');\n\n // Validate that the device can be registered.\n return this.canRegister().then(() => {\n // Validate if the device is not registered and register instead.\n if (!this.registered) {\n this.logger.info('device: device not registered, registering');\n\n return this.register(deviceRegistrationOptions);\n }\n\n // Merge body configurations, overriding defaults.\n const body = {\n ...this.serialize(),\n ...(this.config.body ? this.config.body : {}),\n };\n\n // Remove unneeded properties from the body object.\n delete body.features;\n delete body.mediaCluster;\n delete body.etag;\n\n // Append a ttl value if the device is marked as ephemeral.\n if (this.config.ephemeral) {\n body.ttl = this.config.ephemeralDeviceTTL;\n }\n\n // Merge header configurations, overriding defaults.\n const headers = {\n ...(this.config.defaults.headers ? this.config.defaults.headers : {}),\n ...(this.config.headers ? this.config.headers : {}),\n // If etag is sent, WDM will not send developer feature toggles unless they have changed\n ...(this.etag ? {'If-None-Match': this.etag} : {}),\n };\n\n const {includeDetails = CatalogDetails.all} = deviceRegistrationOptions;\n\n const requestId = uuid.v4();\n this.set('refresh-request-id', requestId);\n\n return this.request({\n method: 'PUT',\n uri: this.url,\n body,\n headers,\n qs: {\n includeUpstreamServices: `${includeDetails}${\n this.config.energyForecast && this.energyForecastConfig ? ',energyforecast' : ''\n }`,\n },\n })\n .then((response) => {\n // If we've signed out in the mean time, the request ID will have changed\n if (this.get('refresh-request-id') !== requestId) {\n this.logger.info('device: refresh request ID mismatch, ignoring response');\n\n return Promise.resolve();\n }\n\n return this.processRegistrationSuccess(response);\n })\n .catch((reason) => {\n // Handle a 404 error, which indicates that the device is no longer\n // valid and needs to be registered as a new device.\n if (reason.statusCode === 404) {\n this.logger.info('device: refresh failed, device is not valid');\n this.logger.info('device: attempting to register a new device');\n\n this.clear();\n\n return this.register(deviceRegistrationOptions);\n }\n\n return Promise.reject(reason);\n });\n });\n },\n /**\n * Fetches the web devices and deletes the third of them which are not recent devices in use\n * @returns {Promise<void, Error>}\n */\n deleteDevices() {\n // Fetch devices with a GET request\n return this.request({\n method: 'GET',\n service: 'wdm',\n resource: 'devices',\n })\n .then((response) => {\n const {devices} = response.body;\n\n const {deviceType} = this._getBody();\n\n // Filter devices of type deviceType\n const webDevices = devices.filter((item) => item.deviceType === deviceType);\n\n const sortedDevices = orderBy(webDevices, [(item) => new Date(item.modificationTime)]);\n\n // If there are more than two devices, delete the last third\n if (sortedDevices.length > 2) {\n const totalItems = sortedDevices.length;\n const countToDelete = Math.ceil(totalItems / 3);\n const urlsToDelete = sortedDevices.slice(0, countToDelete).map((item) => item.url);\n\n return Promise.race(\n urlsToDelete.map((url) => {\n return this.request({\n uri: url,\n method: 'DELETE',\n });\n })\n );\n }\n\n return Promise.resolve();\n })\n .catch((error) => {\n this.logger.error('Failed to retrieve devices:', error);\n\n return Promise.reject(error);\n });\n },\n\n /**\n * Registers and when fails deletes devices\n */\n @waitForValue('@')\n register(deviceRegistrationOptions = {}) {\n this.logger.info('device: registering');\n\n this.webex.internal.newMetrics.callDiagnosticMetrics.setDeviceInfo(this);\n\n // Validate that the device can be registered.\n return this.canRegister().then(() => {\n // Validate if the device is already registered and refresh instead.\n if (this.registered) {\n this.logger.info('device: device already registered, refreshing');\n\n return this.refresh(deviceRegistrationOptions);\n }\n\n return this._registerInternal(deviceRegistrationOptions).catch((error) => {\n if (error?.body?.message === 'User has excessive device registrations') {\n return this.deleteDevices().then(() => {\n return this._registerInternal(deviceRegistrationOptions);\n });\n }\n throw error;\n });\n });\n },\n\n _getBody() {\n return {\n ...(this.config.defaults.body ? this.config.defaults.body : {}),\n ...(this.config.body ? this.config.body : {}),\n };\n },\n\n /**\n * Register or refresh a device depending on the current device state. Device\n * registration utilizes the services plugin to send the request to the\n * **WDM** service.\n *\n * @param {Object} options - The options for registration.\n * @param {CatalogDetails} options.includeDetails - The details to include in the refresh/register request.\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n _registerInternal(deviceRegistrationOptions = {}) {\n this.logger.info('device: making registration request');\n\n // Merge body configurations, overriding defaults.\n const body = this._getBody();\n\n // Merge header configurations, overriding defaults.\n const headers = {\n ...(this.config.defaults.headers ? this.config.defaults.headers : {}),\n ...(this.config.headers ? this.config.headers : {}),\n };\n\n // Append a ttl value if the device is marked as ephemeral\n if (this.config.ephemeral) {\n body.ttl = this.config.ephemeralDeviceTTL;\n }\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.request',\n });\n\n const {includeDetails = CatalogDetails.all} = deviceRegistrationOptions;\n\n const requestId = uuid.v4();\n this.set('register-request-id', requestId);\n\n // This will be replaced by a `create()` method.\n return this.request({\n method: 'POST',\n service: 'wdm',\n resource: 'devices',\n body,\n headers,\n qs: {\n includeUpstreamServices: `${includeDetails}${\n this.config.energyForecast && this.energyForecastConfig ? ',energyforecast' : ''\n }`,\n },\n })\n .catch((error) => {\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.response',\n });\n\n throw error;\n })\n .then((response) => {\n // If we've signed out in the mean time, the request ID will have changed\n if (this.get('register-request-id') !== requestId) {\n this.logger.info('device: register request ID mismatch, ignoring response');\n\n return Promise.resolve();\n }\n\n // Do not add any processing of response above this as that will affect timestamp\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.response',\n });\n\n this.webex.internal.metrics.submitClientMetrics(METRICS.JS_SDK_WDM_REGISTRATION_SUCCESSFUL);\n\n return this.processRegistrationSuccess(response);\n })\n .catch((error) => {\n this.webex.internal.metrics.submitClientMetrics(METRICS.JS_SDK_WDM_REGISTRATION_FAILED, {\n fields: {error},\n });\n throw error;\n });\n },\n /**\n * Unregister the current registered device if available. Unregistering a\n * device utilizes the services plugin to send the request to the **WDM**\n * service.\n *\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n unregister() {\n this.logger.info('device: unregistering');\n\n if (!this.registered) {\n this.logger.warn('device: not registered');\n\n return Promise.resolve();\n }\n\n return this.request({\n uri: this.url,\n method: 'DELETE',\n })\n .then(() => this.clear())\n .catch((reason) => {\n if (reason.statusCode === 404) {\n this.logger.info(\n 'device: 404 when deleting device, device is already deleted, clearing device'\n );\n\n this.clear();\n }\n throw reason;\n });\n },\n /* eslint-enable require-jsdoc */\n\n // Helper method members\n\n /**\n * Determine if registration methods can be performed. This method utilizes\n * the `services` plugin to confirm if the appropriate service urls are\n * available for device registration.\n *\n * @returns {Promise<void, Error>}\n */\n canRegister() {\n this.logger.info('device: validating if registration can occur');\n\n // Destructure the services plugin for ease of reference.\n const {services} = this.webex.internal;\n\n // Wait for the postauth catalog to populate.\n return services.waitForCatalog('postauth', this.config.canRegisterWaitDuration).then(() =>\n // Validate that the service exists after waiting for the catalog.\n services.get('wdm')\n ? Promise.resolve()\n : Promise.reject(\n new Error(\n [\n 'device: cannot register,',\n \"'wdm' service is not available from the postauth catalog\",\n ].join(' ')\n )\n )\n );\n },\n\n /**\n * Check if the device can currently reach the inactivity check url.\n *\n * @returns {Promise<void, Error>}\n */\n checkNetworkReachability() {\n this.logger.info('device: checking network reachability');\n\n // Validate if the device has been checked and reset the logout timer.\n if (this.isReachabilityChecked) {\n return Promise.resolve(this.resetLogoutTimer());\n }\n\n this.isReachabilityChecked = true;\n\n // Validate if the device has a intranet checking url.\n if (!this.intranetInactivityCheckUrl) {\n this.isInNetwork = false;\n\n return Promise.resolve(this.resetLogoutTimer());\n }\n\n // Clear unnecessary headers for reachability request.\n const headers = {\n 'cisco-no-http-redirect': null,\n 'spark-user-agent': null,\n trackingid: null,\n };\n\n // Send the network reachability request.\n return this.request({\n headers,\n method: 'GET',\n uri: this.intranetInactivityCheckUrl,\n })\n .then(() => {\n this.isInNetwork = true;\n\n return Promise.resolve(this.resetLogoutTimer());\n })\n .catch(() => {\n this.logger.info('device: did not reach ping endpoint');\n this.logger.info('device: triggering off-network timer');\n\n this.isInNetwork = false;\n\n return Promise.resolve(this.resetLogoutTimer());\n });\n },\n\n /**\n * Clears the registration ttl value if available.\n *\n * @param {Object} options - Values to be cleared.\n * @returns {void}\n */\n clear(...args) {\n this.logger.info('device: clearing registered device');\n\n // Prototype the extended class in order to preserve the parent member.\n Reflect.apply(WebexPlugin.prototype.clear, this, args);\n },\n\n /**\n * Get the current websocket url with the appropriate priority host.\n *\n * @param {boolean} [wait=false] - Willing to wait on a valid url.\n * @returns {Promise<string, Error>} - The priority-mapped web socket url.\n */\n getWebSocketUrl(wait = false) {\n this.logger.info('device: getting the current websocket url');\n\n // Destructure the services plugin for ease of reference.\n const {services} = this.webex.internal;\n\n // Validate if the method should wait for registration.\n if (wait) {\n return this.waitForRegistration()\n .then(() => services.convertUrlToPriorityHostUrl(this.webSocketUrl))\n .catch((error) => {\n this.logger.warn(error.message);\n\n return Promise.reject(new Error('device: failed to get the current websocket url'));\n });\n }\n\n // Validate if the device is registered.\n if (!this.registered) {\n return Promise.reject(\n new Error('device: cannot get websocket url, device is not registered')\n );\n }\n\n // Attempt to collect the priority-host-mapped web socket URL.\n const wsUrl = services.convertUrlToPriorityHostUrl(this.webSocketUrl);\n\n // Validate that the url was collected.\n if (wsUrl) {\n return Promise.resolve(wsUrl);\n }\n\n return Promise.reject(new Error('device: failed to get the current websocket url'));\n },\n\n /**\n * Process a successful device registration.\n *\n * @param {Object} response - response object from registration success.\n * @returns {void}\n */\n processRegistrationSuccess(response) {\n this.logger.info('device: received registration payload');\n\n // Clone the response body for service cleaning.\n const body = {...response.body};\n\n // Clean service data.\n delete body.services;\n delete body.serviceHostMap;\n\n const {etag} = response.headers || {};\n\n if (this.etag && etag && this.etag === etag) {\n // If current etag matches the previous one and we have sent\n // If-None-Match header the developer and entitlement feature\n // toggles will not be returned\n const {features} = body;\n\n delete body.features;\n // When using the etag feature cache, user and entitlement features are still returned\n this.features.user.reset(features.user);\n this.features.entitlement.reset(features.entitlement);\n }\n\n // Assign the recieved DTO from **WDM** to this device.\n this.set(body);\n\n // Assign the new etag to this device.\n this.set({etag});\n\n // Validate if device is ephemeral and setup refresh timer.\n if (this.config.ephemeral) {\n this.logger.info('device: enqueuing device refresh');\n\n const delay = (this.config.ephemeralDeviceTTL / 2 + 60) * 1000;\n\n this.refreshTimer = safeSetTimeout(() => this.refresh(), delay);\n }\n\n // Emit the registration:success event.\n this.trigger(DEVICE_EVENT_REGISTRATION_SUCCESS, this);\n },\n\n /**\n * Reset the current local logout timer for the registered device if\n * registered.\n *\n * @returns {void}\n */\n resetLogoutTimer() {\n this.logger.info('device: resetting logout timer');\n\n // Clear current logout timer.\n clearTimeout(this.logoutTimer);\n\n // Remove last activity date event listener.\n this.off('change:lastUserActivityDate');\n\n // Remove the logout timer.\n this.unset('logoutTimer');\n\n // Validate if the device is currently in a meeting and is configured to\n // required inactivity enforcement.\n if (\n !this.isInMeeting &&\n this.config.enableInactivityEnforcement &&\n this.isReachabilityChecked\n ) {\n if (this.isInNetwork) {\n this.setLogoutTimer(this.inNetworkInactivityDuration);\n } else {\n this.setLogoutTimer(this.intranetInactivityDuration);\n }\n }\n },\n\n /**\n * Set the value of the logout timer for the current registered device.\n *\n * @param {number} duration - Value in seconds of the new logout timer.\n * @returns {void}\n */\n setLogoutTimer(duration) {\n this.logger.info('device: setting logout timer');\n\n if (!duration || duration <= 0) {\n return;\n }\n\n // Setup user activity date event listener.\n this.on('change:lastUserActivityDate', () => {\n this.resetLogoutTimer();\n });\n\n // Initialize a new timer.\n this.logoutTimer = safeSetTimeout(() => {\n this.webex.logout();\n }, duration * 1000);\n },\n\n /**\n * Wait for the device to be registered.\n *\n * @param {number} [timeout=10] - The maximum duration to wait, in seconds.\n * @returns {Promise<void, Error>}\n */\n waitForRegistration(timeout = 10) {\n this.logger.info('device: waiting for registration');\n\n return new Promise((resolve, reject) => {\n if (this.registered) {\n resolve();\n }\n\n const timeoutTimer = safeSetTimeout(\n () => reject(new Error('device: timeout occured while waiting for registration')),\n timeout * 1000\n );\n\n this.once(DEVICE_EVENT_REGISTRATION_SUCCESS, () => {\n clearTimeout(timeoutTimer);\n resolve();\n });\n });\n },\n\n // Deprecated methods.\n\n /**\n * Mark a url as failed and get the next priority host url.\n *\n * @param {string} url - The url to mark as failed.\n * @returns {Promise<string>} - The next priority url.\n */\n @deprecated('device#markUrlFailedAndGetNew(): Use services#markFailedUrl()')\n markUrlFailedAndGetNew(url) {\n return Promise.resolve(this.webex.internal.services.markFailedUrl(url));\n },\n\n // Ampersand method members\n\n /* eslint-disable require-jsdoc */\n /**\n * Initializer method for the device plugin.\n *\n * @override\n * @param {Array<any>} args - An array of items to be mapped as properties.\n * @returns {void}\n */\n @persist('@', decider)\n initialize(...args) {\n // Prototype the extended class in order to preserve the parent member.\n Reflect.apply(WebexPlugin.prototype.initialize, this, args);\n\n // Initialize feature events and listeners.\n FEATURE_COLLECTION_NAMES.forEach((collectionName) => {\n this.features.on(`change:${collectionName}`, (model, value, options) => {\n this.trigger('change', this, options);\n this.trigger('change:features', this, this.features, options);\n });\n });\n\n // Initialize network reachability checking event for url change.\n this.on('change:intranetInactivityCheckUrl', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize network reachability checking event for duration change.\n this.on('change:intranetInactivityDuration', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize network reachability checking event for duration change.\n this.on('change:inNetworkInactivityDuration', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize listener for activity checking.\n this.listenTo(this.webex, 'user-activity', () => {\n this.lastUserActivityDate = Date.now();\n });\n\n // Initialize listener for meeting started event.\n this.listenTo(this.webex, 'meeting started', () => {\n this.isInMeeting = true;\n this.resetLogoutTimer();\n });\n\n // Initialize listener for meeting ended event.\n this.listenTo(this.webex, 'meeting ended', () => {\n this.isInMeeting = false;\n this.resetLogoutTimer();\n });\n },\n /* eslint-enable require-jsdoc */\n});\n\nexport default Device;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_common","require","_webexCore","_commonTimers","_lodash","_uuid","_interopRequireDefault","_metrics","_constants","_featuresModel","_ipNetworkDetector","_types","_dec","_dec2","_dec3","_dec4","_dec5","_dec6","_obj","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor2","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","decider","config","ephemeral","Device","WebexPlugin","extend","waitForValue","deprecated","persist","namespace","extraProperties","idAttribute","children","features","FeaturesModel","ipNetworkDetector","IpNetworkDetector","props","clientMessagingGiphy","customerCompanyName","customerLogoUrl","deviceType","helpUrl","intranetInactivityDuration","intranetInactivityCheckUrl","inNetworkInactivityDuration","ecmEnabledForAllUsers","ecmSupportedStorageProviders","modificationTime","navigationBarColor","partnerCompanyName","partnerLogoUrl","peopleInsightsEnabled","reportingSiteDesc","reportingSiteUrl","searchEncryptionKeyUrl","showSupportText","supportProviderCompanyName","supportProviderLogoUrl","url","userId","webFileShareControl","webSocketUrl","whiteboardFileShareControl","derived","registered","deps","fn","session","logoutTimer","lastUserActivityDate","isReachabilityChecked","energyForecastConfig","isInMeeting","isInNetwork","meetingStarted","webex","trigger","meetingEnded","setEnergyForecastConfig","undefined","refresh","_this","deviceRegistrationOptions","logger","info","canRegister","then","register","body","serialize","mediaCluster","etag","ttl","ephemeralDeviceTTL","headers","defaults","_deviceRegistrationOp","includeDetails","CatalogDetails","all","requestId","uuid","v4","set","request","method","uri","qs","includeUpstreamServices","concat","energyForecast","response","get","_promise","resolve","processRegistrationSuccess","catch","reason","statusCode","clear","reject","deleteDevices","_this2","service","resource","devices","_this2$_getBody","_getBody","webDevices","item","sortedDevices","orderBy","Date","totalItems","countToDelete","Math","ceil","urlsToDelete","slice","map","race","error","_this3","internal","newMetrics","callDiagnosticMetrics","setDeviceInfo","_registerInternal","_error$body","message","_this4","submitInternalEvent","name","_deviceRegistrationOp2","metrics","submitClientMetrics","METRICS","JS_SDK_WDM_REGISTRATION_SUCCESSFUL","JS_SDK_WDM_REGISTRATION_FAILED","fields","unregister","_this5","warn","services","waitForCatalog","canRegisterWaitDuration","Error","join","checkNetworkReachability","_this6","resetLogoutTimer","trackingid","_len","args","Array","_key","_apply","prototype","getWebSocketUrl","_this7","wait","waitForRegistration","convertUrlToPriorityHostUrl","wsUrl","getDebugFeatures","sanitizedDebugFeatures","debugFeatureTogglesKey","debugFeaturesString","getWindow","sessionStorage","getItem","debugFeatures","JSON","parse","_entries","_ref","_ref2","_slicedToArray2","key","value","val","mutable","lastModified","toISOString","_body$features","_this8","serviceHostMap","_ref3","user","reset","entitlement","developer","_body$features$develo","_toConsumableArray2","delay","refreshTimer","safeSetTimeout","DEVICE_EVENT_REGISTRATION_SUCCESS","clearTimeout","off","unset","enableInactivityEnforcement","setLogoutTimer","duration","_this9","on","logout","_this0","timeout","timeoutTimer","once","markUrlFailedAndGetNew","markFailedUrl","initialize","_this1","_len2","_key2","listenToOnce","FEATURE_COLLECTION_NAMES","collectionName","model","options","listenTo","_now","version","_applyDecoratedDescriptor2","oneFlight","_getOwnPropertyDescriptor","_default","exports"],"sources":["device.js"],"sourcesContent":["// Internal Dependencies\nimport {deprecated, oneFlight} from '@webex/common';\nimport {persist, waitForValue, WebexPlugin} from '@webex/webex-core';\nimport {safeSetTimeout} from '@webex/common-timers';\nimport {orderBy} from 'lodash';\nimport uuid from 'uuid';\n\nimport METRICS from './metrics';\nimport {FEATURE_COLLECTION_NAMES, DEVICE_EVENT_REGISTRATION_SUCCESS} from './constants';\nimport FeaturesModel from './features/features-model';\nimport IpNetworkDetector from './ipNetworkDetector';\nimport {CatalogDetails} from './types';\n\n/**\n * Determine if the plugin should be initialized based on cached storage.\n *\n * @returns {boolean} - If the device is ephemeral.\n */\nfunction decider() {\n return !this.config.ephemeral;\n}\n\nconst Device = WebexPlugin.extend({\n // Ampersand property members.\n\n namespace: 'Device',\n\n // Allow for extra properties to prevent the plugin from failing due to\n // **WDM** service DTO changes.\n extraProperties: 'allow',\n\n idAttribute: 'url',\n\n children: {\n /**\n * The class object that contains all of the feature collections.\n *\n * @type {FeaturesModel}\n */\n features: FeaturesModel,\n /**\n * Helper class for detecting what IP network version (ipv4, ipv6) we're on.\n *\n * @type {IpNetworkDetector}\n */\n ipNetworkDetector: IpNetworkDetector,\n },\n\n /**\n * A collection of device properties mostly assigned by the retrieved DTO from\n * the **WDM** service that are mapped against the ampersand properties.\n *\n * @type {Object}\n */\n props: {\n /**\n * This property determines whether or not giphy support is enabled.\n *\n * @type {'ALLOW' | 'BLOCK'}\n */\n clientMessagingGiphy: 'string',\n\n /**\n * This property should store the company name.\n *\n * @type {string}\n */\n customerCompanyName: 'string',\n\n /**\n * This property should store the logo url.\n *\n * @type {string}\n */\n customerLogoUrl: 'string',\n\n /**\n * This property doesn't have any real values, but is sent during device\n * refresh to prevent the **wdm** service from falling back to an iOS device\n * type.\n *\n * @type {string}\n */\n deviceType: 'string',\n\n /**\n * This property should store the help url.\n *\n * @type {string}\n */\n helpUrl: 'string',\n\n /**\n * This property should store the intranet inactivity timer duration.\n *\n * @type {number}\n */\n intranetInactivityDuration: 'number',\n\n /**\n * This property stores the url required to validate if the device is able\n * to actively reach the intranet network.\n *\n * @type {string}\n */\n intranetInactivityCheckUrl: 'string',\n\n /**\n * This property stores the inactivity timer duration, and could possibly\n * deprecate the `intranetInactivityDuration` property.\n *\n * @type {number}\n */\n inNetworkInactivityDuration: 'number',\n\n /**\n * This property stores the ECM (external content management) enabled value\n * for the whole organization.\n *\n * @type {boolean}\n */\n ecmEnabledForAllUsers: ['boolean', false, false],\n\n /**\n * This property stores an array of ECM (external content management)\n * providers that are currently available.\n *\n * @returns {Array<string>}\n */\n ecmSupportedStorageProviders: ['array', false, () => []],\n\n /**\n * This property stores the modification time value retrieved from the\n * **WDM** endpoint formatted as ISO 8601.\n *\n * @type {string}\n */\n modificationTime: 'string',\n\n /**\n * This property stores the navigation bar color.\n *\n * @type {string}\n */\n navigationBarColor: 'string',\n\n /**\n * This property stores the partner company's name when available.\n *\n * @type {string}\n */\n partnerCompanyName: 'string',\n\n /**\n * This property stores the partner company's logo when available.\n *\n * @type {string}\n */\n partnerLogoUrl: 'string',\n\n /**\n * This property stores the availability of people data from the **WDM**\n * service.\n *\n * @type {boolean}\n */\n peopleInsightsEnabled: 'boolean',\n\n /**\n * This property stores the reporting site's description when available.\n *\n * @type {string}\n */\n reportingSiteDesc: 'string',\n\n /**\n * This property stores the reporting site's access url when available.\n *\n * @type {string}\n */\n reportingSiteUrl: 'string',\n\n /**\n * This property stores the encryption key url when available.\n *\n * @type {string}\n */\n searchEncryptionKeyUrl: 'string',\n\n /**\n * This property stores the availability of support-provided text from the\n * **WDM** service.\n *\n * @type {boolean}\n */\n showSupportText: 'boolean',\n\n /**\n * This property stores the support provider's company name when available.\n *\n * @type {string}\n */\n supportProviderCompanyName: 'string',\n\n /**\n * This property stores the support provider's logo url when available.\n *\n * @type {string}\n */\n supportProviderLogoUrl: 'string',\n\n /**\n * This property stores the device's url retrieved from a registration\n * request. This property gets set via the initial registration process by a\n * `this.set()` method.\n *\n * @type {string}\n */\n url: 'string',\n\n /**\n * This property stores the device's userId uuid value, which can also be\n * derived from the device's registerd user's userId retrieved from\n * the **Hydra** service.\n *\n * @type {string}\n */\n userId: 'string',\n\n /**\n * This property stores whether or not file sharing is enabled\n *\n * @type {'BLOCK_BOTH' | 'BLOCK_UPLOAD'}\n */\n webFileShareControl: 'string',\n\n /**\n * This property stores the current web socket url used by the registered\n * device.\n *\n * @type {string}\n */\n webSocketUrl: 'string',\n\n /**\n * This property stores the value indicating whether or not white board file\n * sharing is enabled for the current device.\n *\n * @type {'ALLOW' | 'BLOCK'}\n */\n whiteboardFileShareControl: 'string',\n },\n\n /**\n * A list of derived properties that populate based when their parent data\n * available via the device's properties.\n *\n * @type {Object}\n */\n derived: {\n /**\n * This property determines if the current device is registered.\n *\n * @type {boolean}\n */\n registered: {\n deps: ['url'],\n\n /**\n * Checks if the device is registered by validating that the url exists.\n * Amperstand does not allow this to method to be written as an arrow\n * function.\n *\n * @returns {boolean}\n */\n fn() {\n return !!this.url;\n },\n },\n },\n\n /**\n * Stores timer data as well as other state details.\n *\n * @type {Object}\n */\n session: {\n /**\n * This property stores the logout timer object\n *\n * @type {any}\n */\n logoutTimer: 'any',\n\n /**\n * This property stores the date for the last activity the user made\n * with the current device.\n *\n * @type {number}\n */\n lastUserActivityDate: 'number',\n\n /**\n * This property stores whether or not the reachability check has been\n * performed to prevent the reachability check from performing its\n * operation more than once after a successful check.\n *\n * @returns {boolean}\n */\n isReachabilityChecked: ['boolean', false, false],\n\n /**\n * This property stores whether or not the next refresh or register request should request energy forecast data\n * in order to prevent over fetching energy forecasts\n *\n * @type {boolean}\n */\n energyForecastConfig: 'boolean',\n\n /**\n * This property stores whether or not the current device is in a meeting\n * to prevent an unneeded timeout of a meeting due to inactivity.\n *\n * @type {boolean}\n */\n isInMeeting: 'boolean',\n\n /**\n * This property identifies if the device is currently in network to prevent\n * the `resetLogoutTimer()` method from being called repeatedly once its\n * known client is connected to the organization's internal network.\n *\n * @type {boolean}\n */\n isInNetwork: 'boolean',\n },\n\n // Event method members.\n\n /**\n * Trigger meeting started event for webex instance. Used by web-client team.\n *\n * @returns {void}\n */\n meetingStarted() {\n this.webex.trigger('meeting started');\n },\n\n /**\n * Trigger meeting ended event for webex instance. Used by web-client team.\n *\n * @returns {void}\n */\n meetingEnded() {\n this.webex.trigger('meeting ended');\n },\n\n /**\n * Set the value of energy forecast config for the current registered device.\n * @param {boolean} [energyForecastConfig=false] - fetch an energy forecast on the next refresh/register\n * @returns {void}\n */\n setEnergyForecastConfig(energyForecastConfig = false) {\n this.energyForecastConfig = energyForecastConfig;\n },\n\n // Registration method members\n\n /**\n * Refresh the current registered device if able.\n *\n * @param {DeviceRegistrationOptions} options - The options for refresh.\n * @param {CatalogDetails} options.includeDetails - The details to include in the refresh/register request.\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n refresh(deviceRegistrationOptions = {}) {\n this.logger.info('device: refreshing');\n\n // Validate that the device can be registered.\n return this.canRegister().then(() => {\n // Validate if the device is not registered and register instead.\n if (!this.registered) {\n this.logger.info('device: device not registered, registering');\n\n return this.register(deviceRegistrationOptions);\n }\n\n // Merge body configurations, overriding defaults.\n const body = {\n ...this.serialize(),\n ...(this.config.body ? this.config.body : {}),\n };\n\n // Remove unneeded properties from the body object.\n delete body.features;\n delete body.mediaCluster;\n delete body.etag;\n\n // Append a ttl value if the device is marked as ephemeral.\n if (this.config.ephemeral) {\n body.ttl = this.config.ephemeralDeviceTTL;\n }\n\n // Merge header configurations, overriding defaults.\n const headers = {\n ...(this.config.defaults.headers ? this.config.defaults.headers : {}),\n ...(this.config.headers ? this.config.headers : {}),\n // If etag is sent, WDM will not send developer feature toggles unless they have changed\n ...(this.etag ? {'If-None-Match': this.etag} : {}),\n };\n\n const {includeDetails = CatalogDetails.all} = deviceRegistrationOptions;\n\n const requestId = uuid.v4();\n this.set('refresh-request-id', requestId);\n\n return this.request({\n method: 'PUT',\n uri: this.url,\n body,\n headers,\n qs: {\n includeUpstreamServices: `${includeDetails}${\n this.config.energyForecast && this.energyForecastConfig ? ',energyforecast' : ''\n }`,\n },\n })\n .then((response) => {\n // If we've signed out in the mean time, the request ID will have changed\n if (this.get('refresh-request-id') !== requestId) {\n this.logger.info('device: refresh request ID mismatch, ignoring response');\n\n return Promise.resolve();\n }\n\n return this.processRegistrationSuccess(response);\n })\n .catch((reason) => {\n // Handle a 404 error, which indicates that the device is no longer\n // valid and needs to be registered as a new device.\n if (reason.statusCode === 404) {\n this.logger.info('device: refresh failed, device is not valid');\n this.logger.info('device: attempting to register a new device');\n\n this.clear();\n\n return this.register(deviceRegistrationOptions);\n }\n\n return Promise.reject(reason);\n });\n });\n },\n /**\n * Fetches the web devices and deletes the third of them which are not recent devices in use\n * @returns {Promise<void, Error>}\n */\n deleteDevices() {\n // Fetch devices with a GET request\n return this.request({\n method: 'GET',\n service: 'wdm',\n resource: 'devices',\n })\n .then((response) => {\n const {devices} = response.body;\n\n const {deviceType} = this._getBody();\n\n // Filter devices of type deviceType\n const webDevices = devices.filter((item) => item.deviceType === deviceType);\n\n const sortedDevices = orderBy(webDevices, [(item) => new Date(item.modificationTime)]);\n\n // If there are more than two devices, delete the last third\n if (sortedDevices.length > 2) {\n const totalItems = sortedDevices.length;\n const countToDelete = Math.ceil(totalItems / 3);\n const urlsToDelete = sortedDevices.slice(0, countToDelete).map((item) => item.url);\n\n return Promise.race(\n urlsToDelete.map((url) => {\n return this.request({\n uri: url,\n method: 'DELETE',\n });\n })\n );\n }\n\n return Promise.resolve();\n })\n .catch((error) => {\n this.logger.error('Failed to retrieve devices:', error);\n\n return Promise.reject(error);\n });\n },\n\n /**\n * Registers and when fails deletes devices\n */\n @waitForValue('@')\n register(deviceRegistrationOptions = {}) {\n this.logger.info('device: registering');\n\n this.webex.internal.newMetrics.callDiagnosticMetrics.setDeviceInfo(this);\n\n // Validate that the device can be registered.\n return this.canRegister().then(() => {\n // Validate if the device is already registered and refresh instead.\n if (this.registered) {\n this.logger.info('device: device already registered, refreshing');\n\n return this.refresh(deviceRegistrationOptions);\n }\n\n return this._registerInternal(deviceRegistrationOptions).catch((error) => {\n if (error?.body?.message === 'User has excessive device registrations') {\n return this.deleteDevices().then(() => {\n return this._registerInternal(deviceRegistrationOptions);\n });\n }\n throw error;\n });\n });\n },\n\n _getBody() {\n return {\n ...(this.config.defaults.body ? this.config.defaults.body : {}),\n ...(this.config.body ? this.config.body : {}),\n };\n },\n\n /**\n * Register or refresh a device depending on the current device state. Device\n * registration utilizes the services plugin to send the request to the\n * **WDM** service.\n *\n * @param {Object} options - The options for registration.\n * @param {CatalogDetails} options.includeDetails - The details to include in the refresh/register request.\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n _registerInternal(deviceRegistrationOptions = {}) {\n this.logger.info('device: making registration request');\n\n // Merge body configurations, overriding defaults.\n const body = this._getBody();\n\n // Merge header configurations, overriding defaults.\n const headers = {\n ...(this.config.defaults.headers ? this.config.defaults.headers : {}),\n ...(this.config.headers ? this.config.headers : {}),\n };\n\n // Append a ttl value if the device is marked as ephemeral\n if (this.config.ephemeral) {\n body.ttl = this.config.ephemeralDeviceTTL;\n }\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.request',\n });\n\n const {includeDetails = CatalogDetails.all} = deviceRegistrationOptions;\n\n const requestId = uuid.v4();\n this.set('register-request-id', requestId);\n\n // This will be replaced by a `create()` method.\n return this.request({\n method: 'POST',\n service: 'wdm',\n resource: 'devices',\n body,\n headers,\n qs: {\n includeUpstreamServices: `${includeDetails}${\n this.config.energyForecast && this.energyForecastConfig ? ',energyforecast' : ''\n }`,\n },\n })\n .catch((error) => {\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.response',\n });\n\n throw error;\n })\n .then((response) => {\n // If we've signed out in the mean time, the request ID will have changed\n if (this.get('register-request-id') !== requestId) {\n this.logger.info('device: register request ID mismatch, ignoring response');\n\n return Promise.resolve();\n }\n\n // Do not add any processing of response above this as that will affect timestamp\n this.webex.internal.newMetrics.submitInternalEvent({\n name: 'internal.register.device.response',\n });\n\n this.webex.internal.metrics.submitClientMetrics(METRICS.JS_SDK_WDM_REGISTRATION_SUCCESSFUL);\n\n return this.processRegistrationSuccess(response);\n })\n .catch((error) => {\n this.webex.internal.metrics.submitClientMetrics(METRICS.JS_SDK_WDM_REGISTRATION_FAILED, {\n fields: {error},\n });\n throw error;\n });\n },\n /**\n * Unregister the current registered device if available. Unregistering a\n * device utilizes the services plugin to send the request to the **WDM**\n * service.\n *\n * @returns {Promise<void, Error>}\n */\n @oneFlight\n @waitForValue('@')\n unregister() {\n this.logger.info('device: unregistering');\n\n if (!this.registered) {\n this.logger.warn('device: not registered');\n\n return Promise.resolve();\n }\n\n return this.request({\n uri: this.url,\n method: 'DELETE',\n })\n .then(() => this.clear())\n .catch((reason) => {\n if (reason.statusCode === 404) {\n this.logger.info(\n 'device: 404 when deleting device, device is already deleted, clearing device'\n );\n\n this.clear();\n }\n throw reason;\n });\n },\n /* eslint-enable require-jsdoc */\n\n // Helper method members\n\n /**\n * Determine if registration methods can be performed. This method utilizes\n * the `services` plugin to confirm if the appropriate service urls are\n * available for device registration.\n *\n * @returns {Promise<void, Error>}\n */\n canRegister() {\n this.logger.info('device: validating if registration can occur');\n\n // Destructure the services plugin for ease of reference.\n const {services} = this.webex.internal;\n\n // Wait for the postauth catalog to populate.\n return services.waitForCatalog('postauth', this.config.canRegisterWaitDuration).then(() =>\n // Validate that the service exists after waiting for the catalog.\n services.get('wdm')\n ? Promise.resolve()\n : Promise.reject(\n new Error(\n [\n 'device: cannot register,',\n \"'wdm' service is not available from the postauth catalog\",\n ].join(' ')\n )\n )\n );\n },\n\n /**\n * Check if the device can currently reach the inactivity check url.\n *\n * @returns {Promise<void, Error>}\n */\n checkNetworkReachability() {\n this.logger.info('device: checking network reachability');\n\n // Validate if the device has been checked and reset the logout timer.\n if (this.isReachabilityChecked) {\n return Promise.resolve(this.resetLogoutTimer());\n }\n\n this.isReachabilityChecked = true;\n\n // Validate if the device has a intranet checking url.\n if (!this.intranetInactivityCheckUrl) {\n this.isInNetwork = false;\n\n return Promise.resolve(this.resetLogoutTimer());\n }\n\n // Clear unnecessary headers for reachability request.\n const headers = {\n 'cisco-no-http-redirect': null,\n 'spark-user-agent': null,\n trackingid: null,\n };\n\n // Send the network reachability request.\n return this.request({\n headers,\n method: 'GET',\n uri: this.intranetInactivityCheckUrl,\n })\n .then(() => {\n this.isInNetwork = true;\n\n return Promise.resolve(this.resetLogoutTimer());\n })\n .catch(() => {\n this.logger.info('device: did not reach ping endpoint');\n this.logger.info('device: triggering off-network timer');\n\n this.isInNetwork = false;\n\n return Promise.resolve(this.resetLogoutTimer());\n });\n },\n\n /**\n * Clears the registration ttl value if available.\n *\n * @param {Object} options - Values to be cleared.\n * @returns {void}\n */\n clear(...args) {\n this.logger.info('device: clearing registered device');\n\n // Prototype the extended class in order to preserve the parent member.\n Reflect.apply(WebexPlugin.prototype.clear, this, args);\n },\n\n /**\n * Get the current websocket url with the appropriate priority host.\n *\n * @param {boolean} [wait=false] - Willing to wait on a valid url.\n * @returns {Promise<string, Error>} - The priority-mapped web socket url.\n */\n getWebSocketUrl(wait = false) {\n this.logger.info('device: getting the current websocket url');\n\n // Destructure the services plugin for ease of reference.\n const {services} = this.webex.internal;\n\n // Validate if the method should wait for registration.\n if (wait) {\n return this.waitForRegistration()\n .then(() => services.convertUrlToPriorityHostUrl(this.webSocketUrl))\n .catch((error) => {\n this.logger.warn(error.message);\n\n return Promise.reject(new Error('device: failed to get the current websocket url'));\n });\n }\n\n // Validate if the device is registered.\n if (!this.registered) {\n return Promise.reject(\n new Error('device: cannot get websocket url, device is not registered')\n );\n }\n\n // Attempt to collect the priority-host-mapped web socket URL.\n const wsUrl = services.convertUrlToPriorityHostUrl(this.webSocketUrl);\n\n // Validate that the url was collected.\n if (wsUrl) {\n return Promise.resolve(wsUrl);\n }\n\n return Promise.reject(new Error('device: failed to get the current websocket url'));\n },\n\n /**\n * Get sanitized processed debug features from session storage\n * these should be JSON encoded and in the form {feature1: true, feature2: false}\n *\n * @returns {Array<Object>} - Array of sanitized debug feature toggles\n */\n getDebugFeatures() {\n const sanitizedDebugFeatures = [];\n if (this.config.debugFeatureTogglesKey) {\n const debugFeaturesString = this.webex\n .getWindow()\n .sessionStorage.getItem(this.config.debugFeatureTogglesKey);\n if (debugFeaturesString) {\n const debugFeatures = JSON.parse(debugFeaturesString);\n Object.entries(debugFeatures).forEach(([key, value]) => {\n sanitizedDebugFeatures.push({\n key,\n val: value ? 'true' : 'false',\n mutable: true,\n lastModified: new Date().toISOString(),\n });\n });\n }\n }\n\n return sanitizedDebugFeatures;\n },\n\n /**\n * Process a successful device registration.\n *\n * @param {Object} response - response object from registration success.\n * @returns {void}\n */\n processRegistrationSuccess(response) {\n this.logger.info('device: received registration payload');\n\n // Clone the response body for service cleaning.\n const body = {...response.body};\n\n // Clean service data.\n delete body.services;\n delete body.serviceHostMap;\n\n const {etag} = response.headers || {};\n\n if (this.etag && etag && this.etag === etag) {\n // If current etag matches the previous one and we have sent\n // If-None-Match header the developer and entitlement feature\n // toggles will not be returned\n const {features} = body;\n\n delete body.features;\n // When using the etag feature cache, user and entitlement features are still returned\n this.features.user.reset(features.user);\n this.features.entitlement.reset(features.entitlement);\n } else if (this.config.debugFeatureTogglesKey && body?.features?.developer) {\n // Add the debug feature toggles from session storage if available\n try {\n const debugFeatures = this.getDebugFeatures();\n body.features.developer.push(...debugFeatures);\n } catch (error) {\n this.logger.error('Failed to parse debug feature toggles from session storage:', error);\n }\n }\n\n // Assign the recieved DTO from **WDM** to this device.\n this.set(body);\n\n // Assign the new etag to this device.\n this.set({etag});\n\n // Validate if device is ephemeral and setup refresh timer.\n if (this.config.ephemeral) {\n this.logger.info('device: enqueuing device refresh');\n\n const delay = (this.config.ephemeralDeviceTTL / 2 + 60) * 1000;\n\n this.refreshTimer = safeSetTimeout(() => this.refresh(), delay);\n }\n\n // Emit the registration:success event.\n this.trigger(DEVICE_EVENT_REGISTRATION_SUCCESS, this);\n },\n\n /**\n * Reset the current local logout timer for the registered device if\n * registered.\n *\n * @returns {void}\n */\n resetLogoutTimer() {\n this.logger.info('device: resetting logout timer');\n\n // Clear current logout timer.\n clearTimeout(this.logoutTimer);\n\n // Remove last activity date event listener.\n this.off('change:lastUserActivityDate');\n\n // Remove the logout timer.\n this.unset('logoutTimer');\n\n // Validate if the device is currently in a meeting and is configured to\n // required inactivity enforcement.\n if (\n !this.isInMeeting &&\n this.config.enableInactivityEnforcement &&\n this.isReachabilityChecked\n ) {\n if (this.isInNetwork) {\n this.setLogoutTimer(this.inNetworkInactivityDuration);\n } else {\n this.setLogoutTimer(this.intranetInactivityDuration);\n }\n }\n },\n\n /**\n * Set the value of the logout timer for the current registered device.\n *\n * @param {number} duration - Value in seconds of the new logout timer.\n * @returns {void}\n */\n setLogoutTimer(duration) {\n this.logger.info('device: setting logout timer');\n\n if (!duration || duration <= 0) {\n return;\n }\n\n // Setup user activity date event listener.\n this.on('change:lastUserActivityDate', () => {\n this.resetLogoutTimer();\n });\n\n // Initialize a new timer.\n this.logoutTimer = safeSetTimeout(() => {\n this.webex.logout();\n }, duration * 1000);\n },\n\n /**\n * Wait for the device to be registered.\n *\n * @param {number} [timeout=10] - The maximum duration to wait, in seconds.\n * @returns {Promise<void, Error>}\n */\n waitForRegistration(timeout = 10) {\n this.logger.info('device: waiting for registration');\n\n return new Promise((resolve, reject) => {\n if (this.registered) {\n resolve();\n }\n\n const timeoutTimer = safeSetTimeout(\n () => reject(new Error('device: timeout occured while waiting for registration')),\n timeout * 1000\n );\n\n this.once(DEVICE_EVENT_REGISTRATION_SUCCESS, () => {\n clearTimeout(timeoutTimer);\n resolve();\n });\n });\n },\n\n // Deprecated methods.\n\n /**\n * Mark a url as failed and get the next priority host url.\n *\n * @param {string} url - The url to mark as failed.\n * @returns {Promise<string>} - The next priority url.\n */\n @deprecated('device#markUrlFailedAndGetNew(): Use services#markFailedUrl()')\n markUrlFailedAndGetNew(url) {\n return Promise.resolve(this.webex.internal.services.markFailedUrl(url));\n },\n\n // Ampersand method members\n\n /* eslint-disable require-jsdoc */\n /**\n * Initializer method for the device plugin.\n *\n * @override\n * @param {Array<any>} args - An array of items to be mapped as properties.\n * @returns {void}\n */\n @persist('@', decider)\n initialize(...args) {\n // Prototype the extended class in order to preserve the parent member.\n Reflect.apply(WebexPlugin.prototype.initialize, this, args);\n\n this.listenToOnce(this.webex, 'change:config', () => {\n // If debug feature toggles exist, clear the etag to ensure developer feature toggles are fetched\n if (this.getDebugFeatures(this.config.debugFeatureTogglesKey).length > 0) {\n this.set('etag', undefined);\n }\n });\n\n // Initialize feature events and listeners.\n FEATURE_COLLECTION_NAMES.forEach((collectionName) => {\n this.features.on(`change:${collectionName}`, (model, value, options) => {\n this.trigger('change', this, options);\n this.trigger('change:features', this, this.features, options);\n });\n });\n\n // Initialize network reachability checking event for url change.\n this.on('change:intranetInactivityCheckUrl', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize network reachability checking event for duration change.\n this.on('change:intranetInactivityDuration', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize network reachability checking event for duration change.\n this.on('change:inNetworkInactivityDuration', () => {\n this.checkNetworkReachability();\n });\n\n // Initialize listener for activity checking.\n this.listenTo(this.webex, 'user-activity', () => {\n this.lastUserActivityDate = Date.now();\n });\n\n // Initialize listener for meeting started event.\n this.listenTo(this.webex, 'meeting started', () => {\n this.isInMeeting = true;\n this.resetLogoutTimer();\n });\n\n // Initialize listener for meeting ended event.\n this.listenTo(this.webex, 'meeting ended', () => {\n this.isInMeeting = false;\n this.resetLogoutTimer();\n });\n },\n /* eslint-enable require-jsdoc */\n});\n\nexport default Device;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AACA,IAAAE,aAAA,GAAAF,OAAA;AACA,IAAAG,OAAA,GAAAH,OAAA;AACA,IAAAI,KAAA,GAAAC,sBAAA,CAAAL,OAAA;AAEA,IAAAM,QAAA,GAAAD,sBAAA,CAAAL,OAAA;AACA,IAAAO,UAAA,GAAAP,OAAA;AACA,IAAAQ,cAAA,GAAAH,sBAAA,CAAAL,OAAA;AACA,IAAAS,kBAAA,GAAAJ,sBAAA,CAAAL,OAAA;AACA,IAAAU,MAAA,GAAAV,OAAA;AAAuC,IAAAW,IAAA,EAAAC,KAAA,EAAAC,KAAA,EAAAC,KAAA,EAAAC,KAAA,EAAAC,KAAA,EAAAC,IAAA,EAXvC;AAAA,SAAAC,QAAAC,CAAA,EAAAC,CAAA,QAAAC,CAAA,GAAAC,YAAA,CAAAH,CAAA,OAAAI,6BAAA,QAAAC,CAAA,GAAAD,6BAAA,CAAAJ,CAAA,GAAAC,CAAA,KAAAI,CAAA,GAAAA,CAAA,CAAAC,MAAA,WAAAL,CAAA,WAAAM,iCAAA,CAAAP,CAAA,EAAAC,CAAA,EAAAO,UAAA,OAAAN,CAAA,CAAAO,IAAA,CAAAC,KAAA,CAAAR,CAAA,EAAAG,CAAA,YAAAH,CAAA;AAAA,SAAAS,cAAAX,CAAA,aAAAC,CAAA,MAAAA,CAAA,GAAAW,SAAA,CAAAC,MAAA,EAAAZ,CAAA,UAAAC,CAAA,WAAAU,SAAA,CAAAX,CAAA,IAAAW,SAAA,CAAAX,CAAA,QAAAA,CAAA,OAAAF,OAAA,CAAAe,MAAA,CAAAZ,CAAA,OAAAa,OAAA,WAAAd,CAAA,QAAAe,gBAAA,CAAAC,OAAA,EAAAjB,CAAA,EAAAC,CAAA,EAAAC,CAAA,CAAAD,CAAA,SAAAiB,iCAAA,GAAAC,wBAAA,CAAAnB,CAAA,EAAAkB,iCAAA,CAAAhB,CAAA,KAAAH,OAAA,CAAAe,MAAA,CAAAZ,CAAA,GAAAa,OAAA,WAAAd,CAAA,IAAAmB,sBAAA,CAAApB,CAAA,EAAAC,CAAA,EAAAM,iCAAA,CAAAL,CAAA,EAAAD,CAAA,iBAAAD,CAAA;AAaA;AACA;AACA;AACA;AACA;AACA,SAASqB,OAAOA,CAAA,EAAG;EACjB,OAAO,CAAC,IAAI,CAACC,MAAM,CAACC,SAAS;AAC/B;AAEA,IAAMC,MAAM,GAAGC,sBAAW,CAACC,MAAM,EAAAlC,IAAA,GAkW9B,IAAAmC,uBAAY,EAAC,GAAG,CAAC,EAAAlC,KAAA,GAgIjB,IAAAkC,uBAAY,EAAC,GAAG,CAAC,EAAAjC,KAAA,GA2CjB,IAAAiC,uBAAY,EAAC,GAAG,CAAC,EAAAhC,KAAA,GA8EjB,IAAAgC,uBAAY,EAAC,GAAG,CAAC,EAAA/B,KAAA,GAmVjB,IAAAgC,kBAAU,EAAC,+DAA+D,CAAC,EAAA/B,KAAA,GAe3E,IAAAgC,kBAAO,EAAC,GAAG,EAAER,OAAO,CAAC,EAAAvB,IAAA,GA77BU;EAChC;;EAEAgC,SAAS,EAAE,QAAQ;EAEnB;EACA;EACAC,eAAe,EAAE,OAAO;EAExBC,WAAW,EAAE,KAAK;EAElBC,QAAQ,EAAE;IACR;AACJ;AACA;AACA;AACA;IACIC,QAAQ,EAAEC,sBAAa;IACvB;AACJ;AACA;AACA;AACA;IACIC,iBAAiB,EAAEC;EACrB,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACEC,KAAK,EAAE;IACL;AACJ;AACA;AACA;AACA;IACIC,oBAAoB,EAAE,QAAQ;IAE9B;AACJ;AACA;AACA;AACA;IACIC,mBAAmB,EAAE,QAAQ;IAE7B;AACJ;AACA;AACA;AACA;IACIC,eAAe,EAAE,QAAQ;IAEzB;AACJ;AACA;AACA;AACA;AACA;AACA;IACIC,UAAU,EAAE,QAAQ;IAEpB;AACJ;AACA;AACA;AACA;IACIC,OAAO,EAAE,QAAQ;IAEjB;AACJ;AACA;AACA;AACA;IACIC,0BAA0B,EAAE,QAAQ;IAEpC;AACJ;AACA;AACA;AACA;AACA;IACIC,0BAA0B,EAAE,QAAQ;IAEpC;AACJ;AACA;AACA;AACA;AACA;IACIC,2BAA2B,EAAE,QAAQ;IAErC;AACJ;AACA;AACA;AACA;AACA;IACIC,qBAAqB,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC;IAEhD;AACJ;AACA;AACA;AACA;AACA;IACIC,4BAA4B,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE;MAAA,OAAM,EAAE;IAAA,EAAC;IAExD;AACJ;AACA;AACA;AACA;AACA;IACIC,gBAAgB,EAAE,QAAQ;IAE1B;AACJ;AACA;AACA;AACA;IACIC,kBAAkB,EAAE,QAAQ;IAE5B;AACJ;AACA;AACA;AACA;IACIC,kBAAkB,EAAE,QAAQ;IAE5B;AACJ;AACA;AACA;AACA;IACIC,cAAc,EAAE,QAAQ;IAExB;AACJ;AACA;AACA;AACA;AACA;IACIC,qBAAqB,EAAE,SAAS;IAEhC;AACJ;AACA;AACA;AACA;IACIC,iBAAiB,EAAE,QAAQ;IAE3B;AACJ;AACA;AACA;AACA;IACIC,gBAAgB,EAAE,QAAQ;IAE1B;AACJ;AACA;AACA;AACA;IACIC,sBAAsB,EAAE,QAAQ;IAEhC;AACJ;AACA;AACA;AACA;AACA;IACIC,eAAe,EAAE,SAAS;IAE1B;AACJ;AACA;AACA;AACA;IACIC,0BAA0B,EAAE,QAAQ;IAEpC;AACJ;AACA;AACA;AACA;IACIC,sBAAsB,EAAE,QAAQ;IAEhC;AACJ;AACA;AACA;AACA;AACA;AACA;IACIC,GAAG,EAAE,QAAQ;IAEb;AACJ;AACA;AACA;AACA;AACA;AACA;IACIC,MAAM,EAAE,QAAQ;IAEhB;AACJ;AACA;AACA;AACA;IACIC,mBAAmB,EAAE,QAAQ;IAE7B;AACJ;AACA;AACA;AACA;AACA;IACIC,YAAY,EAAE,QAAQ;IAEtB;AACJ;AACA;AACA;AACA;AACA;IACIC,0BAA0B,EAAE;EAC9B,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACEC,OAAO,EAAE;IACP;AACJ;AACA;AACA;AACA;IACIC,UAAU,EAAE;MACVC,IAAI,EAAE,CAAC,KAAK,CAAC;MAEb;AACN;AACA;AACA;AACA;AACA;AACA;MACMC,EAAE,WAAFA,EAAEA,CAAA,EAAG;QACH,OAAO,CAAC,CAAC,IAAI,CAACR,GAAG;MACnB;IACF;EACF,CAAC;EAED;AACF;AACA;AACA;AACA;EACES,OAAO,EAAE;IACP;AACJ;AACA;AACA;AACA;IACIC,WAAW,EAAE,KAAK;IAElB;AACJ;AACA;AACA;AACA;AACA;IACIC,oBAAoB,EAAE,QAAQ;IAE9B;AACJ;AACA;AACA;AACA;AACA;AACA;IACIC,qBAAqB,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC;IAEhD;AACJ;AACA;AACA;AACA;AACA;IACIC,oBAAoB,EAAE,SAAS;IAE/B;AACJ;AACA;AACA;AACA;AACA;IACIC,WAAW,EAAE,SAAS;IAEtB;AACJ;AACA;AACA;AACA;AACA;AACA;IACIC,WAAW,EAAE;EACf,CAAC;EAED;EAEA;AACF;AACA;AACA;AACA;EACEC,cAAc,WAAdA,cAAcA,CAAA,EAAG;IACf,IAAI,CAACC,KAAK,CAACC,OAAO,CAAC,iBAAiB,CAAC;EACvC,CAAC;EAED;AACF;AACA;AACA;AACA;EACEC,YAAY,WAAZA,YAAYA,CAAA,EAAG;IACb,IAAI,CAACF,KAAK,CAACC,OAAO,CAAC,eAAe,CAAC;EACrC,CAAC;EAED;AACF;AACA;AACA;AACA;EACEE,uBAAuB,WAAvBA,uBAAuBA,CAAA,EAA+B;IAAA,IAA9BP,oBAAoB,GAAA7D,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAqE,SAAA,GAAArE,SAAA,MAAG,KAAK;IAClD,IAAI,CAAC6D,oBAAoB,GAAGA,oBAAoB;EAClD,CAAC;EAaDS,OAAO,WAAPA,OAAOA,CAAA,EAAiC;IAAA,IAAAC,KAAA;IAAA,IAAhCC,yBAAyB,GAAAxE,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAqE,SAAA,GAAArE,SAAA,MAAG,CAAC,CAAC;IACpC,IAAI,CAACyE,MAAM,CAACC,IAAI,CAAC,oBAAoB,CAAC;;IAEtC;IACA,OAAO,IAAI,CAACC,WAAW,CAAC,CAAC,CAACC,IAAI,CAAC,YAAM;MACnC;MACA,IAAI,CAACL,KAAI,CAACjB,UAAU,EAAE;QACpBiB,KAAI,CAACE,MAAM,CAACC,IAAI,CAAC,4CAA4C,CAAC;QAE9D,OAAOH,KAAI,CAACM,QAAQ,CAACL,yBAAyB,CAAC;MACjD;;MAEA;MACA,IAAMM,IAAI,GAAA/E,aAAA,CAAAA,aAAA,KACLwE,KAAI,CAACQ,SAAS,CAAC,CAAC,GACfR,KAAI,CAAC7D,MAAM,CAACoE,IAAI,GAAGP,KAAI,CAAC7D,MAAM,CAACoE,IAAI,GAAG,CAAC,CAAC,CAC7C;;MAED;MACA,OAAOA,IAAI,CAACxD,QAAQ;MACpB,OAAOwD,IAAI,CAACE,YAAY;MACxB,OAAOF,IAAI,CAACG,IAAI;;MAEhB;MACA,IAAIV,KAAI,CAAC7D,MAAM,CAACC,SAAS,EAAE;QACzBmE,IAAI,CAACI,GAAG,GAAGX,KAAI,CAAC7D,MAAM,CAACyE,kBAAkB;MAC3C;;MAEA;MACA,IAAMC,OAAO,GAAArF,aAAA,CAAAA,aAAA,CAAAA,aAAA,KACPwE,KAAI,CAAC7D,MAAM,CAAC2E,QAAQ,CAACD,OAAO,GAAGb,KAAI,CAAC7D,MAAM,CAAC2E,QAAQ,CAACD,OAAO,GAAG,CAAC,CAAC,GAChEb,KAAI,CAAC7D,MAAM,CAAC0E,OAAO,GAAGb,KAAI,CAAC7D,MAAM,CAAC0E,OAAO,GAAG,CAAC,CAAC,GAE9Cb,KAAI,CAACU,IAAI,GAAG;QAAC,eAAe,EAAEV,KAAI,CAACU;MAAI,CAAC,GAAG,CAAC,CAAC,CAClD;MAED,IAAAK,qBAAA,GAA8Cd,yBAAyB,CAAhEe,cAAc;QAAdA,cAAc,GAAAD,qBAAA,cAAGE,qBAAc,CAACC,GAAG,GAAAH,qBAAA;MAE1C,IAAMI,SAAS,GAAGC,aAAI,CAACC,EAAE,CAAC,CAAC;MAC3BrB,KAAI,CAACsB,GAAG,CAAC,oBAAoB,EAAEH,SAAS,CAAC;MAEzC,OAAOnB,KAAI,CAACuB,OAAO,CAAC;QAClBC,MAAM,EAAE,KAAK;QACbC,GAAG,EAAEzB,KAAI,CAACvB,GAAG;QACb8B,IAAI,EAAJA,IAAI;QACJM,OAAO,EAAPA,OAAO;QACPa,EAAE,EAAE;UACFC,uBAAuB,KAAAC,MAAA,CAAKZ,cAAc,EAAAY,MAAA,CACxC5B,KAAI,CAAC7D,MAAM,CAAC0F,cAAc,IAAI7B,KAAI,CAACV,oBAAoB,GAAG,iBAAiB,GAAG,EAAE;QAEpF;MACF,CAAC,CAAC,CACCe,IAAI,CAAC,UAACyB,QAAQ,EAAK;QAClB;QACA,IAAI9B,KAAI,CAAC+B,GAAG,CAAC,oBAAoB,CAAC,KAAKZ,SAAS,EAAE;UAChDnB,KAAI,CAACE,MAAM,CAACC,IAAI,CAAC,wDAAwD,CAAC;UAE1E,OAAO6B,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAAC,CAAC;QAC1B;QAEA,OAAOjC,KAAI,CAACkC,0BAA0B,CAACJ,QAAQ,CAAC;MAClD,CAAC,CAAC,CACDK,KAAK,CAAC,UAACC,MAAM,EAAK;QACjB;QACA;QACA,IAAIA,MAAM,CAACC,UAAU,KAAK,GAAG,EAAE;UAC7BrC,KAAI,CAACE,MAAM,CAACC,IAAI,CAAC,6CAA6C,CAAC;UAC/DH,KAAI,CAACE,MAAM,CAACC,IAAI,CAAC,6CAA6C,CAAC;UAE/DH,KAAI,CAACsC,KAAK,CAAC,CAAC;UAEZ,OAAOtC,KAAI,CAACM,QAAQ,CAACL,yBAAyB,CAAC;QACjD;QAEA,OAAO+B,QAAA,CAAAlG,OAAA,CAAQyG,MAAM,CAACH,MAAM,CAAC;MAC/B,CAAC,CAAC;IACN,CAAC,CAAC;EACJ,CAAC;EACD;AACF;AACA;AACA;EACEI,aAAa,WAAbA,aAAaA,CAAA,EAAG;IAAA,IAAAC,MAAA;IACd;IACA,OAAO,IAAI,CAAClB,OAAO,CAAC;MAClBC,MAAM,EAAE,KAAK;MACbkB,OAAO,EAAE,KAAK;MACdC,QAAQ,EAAE;IACZ,CAAC,CAAC,CACCtC,IAAI,CAAC,UAACyB,QAAQ,EAAK;MAClB,IAAOc,OAAO,GAAId,QAAQ,CAACvB,IAAI,CAAxBqC,OAAO;MAEd,IAAAC,eAAA,GAAqBJ,MAAI,CAACK,QAAQ,CAAC,CAAC;QAA7BvF,UAAU,GAAAsF,eAAA,CAAVtF,UAAU;;MAEjB;MACA,IAAMwF,UAAU,GAAGH,OAAO,CAACzH,MAAM,CAAC,UAAC6H,IAAI;QAAA,OAAKA,IAAI,CAACzF,UAAU,KAAKA,UAAU;MAAA,EAAC;MAE3E,IAAM0F,aAAa,GAAG,IAAAC,eAAO,EAACH,UAAU,EAAE,CAAC,UAACC,IAAI;QAAA,OAAK,IAAIG,IAAI,CAACH,IAAI,CAAClF,gBAAgB,CAAC;MAAA,EAAC,CAAC;;MAEtF;MACA,IAAImF,aAAa,CAACvH,MAAM,GAAG,CAAC,EAAE;QAC5B,IAAM0H,UAAU,GAAGH,aAAa,CAACvH,MAAM;QACvC,IAAM2H,aAAa,GAAGC,IAAI,CAACC,IAAI,CAACH,UAAU,GAAG,CAAC,CAAC;QAC/C,IAAMI,YAAY,GAAGP,aAAa,CAACQ,KAAK,CAAC,CAAC,EAAEJ,aAAa,CAAC,CAACK,GAAG,CAAC,UAACV,IAAI;UAAA,OAAKA,IAAI,CAACvE,GAAG;QAAA,EAAC;QAElF,OAAOuD,QAAA,CAAAlG,OAAA,CAAQ6H,IAAI,CACjBH,YAAY,CAACE,GAAG,CAAC,UAACjF,GAAG,EAAK;UACxB,OAAOgE,MAAI,CAAClB,OAAO,CAAC;YAClBE,GAAG,EAAEhD,GAAG;YACR+C,MAAM,EAAE;UACV,CAAC,CAAC;QACJ,CAAC,CACH,CAAC;MACH;MAEA,OAAOQ,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAAC,CAAC;IAC1B,CAAC,CAAC,CACDE,KAAK,CAAC,UAACyB,KAAK,EAAK;MAChBnB,MAAI,CAACvC,MAAM,CAAC0D,KAAK,CAAC,6BAA6B,EAAEA,KAAK,CAAC;MAEvD,OAAO5B,QAAA,CAAAlG,OAAA,CAAQyG,MAAM,CAACqB,KAAK,CAAC;IAC9B,CAAC,CAAC;EACN,CAAC;EAMDtD,QAAQ,WAARA,QAAQA,CAAA,EAAiC;IAAA,IAAAuD,MAAA;IAAA,IAAhC5D,yBAAyB,GAAAxE,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAqE,SAAA,GAAArE,SAAA,MAAG,CAAC,CAAC;IACrC,IAAI,CAACyE,MAAM,CAACC,IAAI,CAAC,qBAAqB,CAAC;IAEvC,IAAI,CAACT,KAAK,CAACoE,QAAQ,CAACC,UAAU,CAACC,qBAAqB,CAACC,aAAa,CAAC,IAAI,CAAC;;IAExE;IACA,OAAO,IAAI,CAAC7D,WAAW,CAAC,CAAC,CAACC,IAAI,CAAC,YAAM;MACnC;MACA,IAAIwD,MAAI,CAAC9E,UAAU,EAAE;QACnB8E,MAAI,CAAC3D,MAAM,CAACC,IAAI,CAAC,+CAA+C,CAAC;QAEjE,OAAO0D,MAAI,CAAC9D,OAAO,CAACE,yBAAyB,CAAC;MAChD;MAEA,OAAO4D,MAAI,CAACK,iBAAiB,CAACjE,yBAAyB,CAAC,CAACkC,KAAK,CAAC,UAACyB,KAAK,EAAK;QAAA,IAAAO,WAAA;QACxE,IAAI,CAAAP,KAAK,aAALA,KAAK,wBAAAO,WAAA,GAALP,KAAK,CAAErD,IAAI,cAAA4D,WAAA,uBAAXA,WAAA,CAAaC,OAAO,MAAK,yCAAyC,EAAE;UACtE,OAAOP,MAAI,CAACrB,aAAa,CAAC,CAAC,CAACnC,IAAI,CAAC,YAAM;YACrC,OAAOwD,MAAI,CAACK,iBAAiB,CAACjE,yBAAyB,CAAC;UAC1D,CAAC,CAAC;QACJ;QACA,MAAM2D,KAAK;MACb,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ,CAAC;EAEDd,QAAQ,WAARA,QAAQA,CAAA,EAAG;IACT,OAAAtH,aAAA,CAAAA,aAAA,KACM,IAAI,CAACW,MAAM,CAAC2E,QAAQ,CAACP,IAAI,GAAG,IAAI,CAACpE,MAAM,CAAC2E,QAAQ,CAACP,IAAI,GAAG,CAAC,CAAC,GAC1D,IAAI,CAACpE,MAAM,CAACoE,IAAI,GAAG,IAAI,CAACpE,MAAM,CAACoE,IAAI,GAAG,CAAC,CAAC;EAEhD,CAAC;EAaD2D,iBAAiB,WAAjBA,iBAAiBA,CAAA,EAAiC;IAAA,IAAAG,MAAA;IAAA,IAAhCpE,yBAAyB,GAAAxE,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAqE,SAAA,GAAArE,SAAA,MAAG,CAAC,CAAC;IAC9C,IAAI,CAACyE,MAAM,CAACC,IAAI,CAAC,qCAAqC,CAAC;;IAEvD;IACA,IAAMI,IAAI,GAAG,IAAI,CAACuC,QAAQ,CAAC,CAAC;;IAE5B;IACA,IAAMjC,OAAO,GAAArF,aAAA,CAAAA,aAAA,KACP,IAAI,CAACW,MAAM,CAAC2E,QAAQ,CAACD,OAAO,GAAG,IAAI,CAAC1E,MAAM,CAAC2E,QAAQ,CAACD,OAAO,GAAG,CAAC,CAAC,GAChE,IAAI,CAAC1E,MAAM,CAAC0E,OAAO,GAAG,IAAI,CAAC1E,MAAM,CAAC0E,OAAO,GAAG,CAAC,CAAC,CACnD;;IAED;IACA,IAAI,IAAI,CAAC1E,MAAM,CAACC,SAAS,EAAE;MACzBmE,IAAI,CAACI,GAAG,GAAG,IAAI,CAACxE,MAAM,CAACyE,kBAAkB;IAC3C;IACA,IAAI,CAAClB,KAAK,CAACoE,QAAQ,CAACC,UAAU,CAACO,mBAAmB,CAAC;MACjDC,IAAI,EAAE;IACR,CAAC,CAAC;IAEF,IAAAC,sBAAA,GAA8CvE,yBAAyB,CAAhEe,cAAc;MAAdA,cAAc,GAAAwD,sBAAA,cAAGvD,qBAAc,CAACC,GAAG,GAAAsD,sBAAA;IAE1C,IAAMrD,SAAS,GAAGC,aAAI,CAACC,EAAE,CAAC,CAAC;IAC3B,IAAI,CAACC,GAAG,CAAC,qBAAqB,EAAEH,SAAS,CAAC;;IAE1C;IACA,OAAO,IAAI,CAACI,OAAO,CAAC;MAClBC,MAAM,EAAE,MAAM;MACdkB,OAAO,EAAE,KAAK;MACdC,QAAQ,EAAE,SAAS;MACnBpC,IAAI,EAAJA,IAAI;MACJM,OAAO,EAAPA,OAAO;MACPa,EAAE,EAAE;QACFC,uBAAuB,KAAAC,MAAA,CAAKZ,cAAc,EAAAY,MAAA,CACxC,IAAI,CAACzF,MAAM,CAAC0F,cAAc,IAAI,IAAI,CAACvC,oBAAoB,GAAG,iBAAiB,GAAG,EAAE;MAEpF;IACF,CAAC,CAAC,CACC6C,KAAK,CAAC,UAACyB,KAAK,EAAK;MAChBS,MAAI,CAAC3E,KAAK,CAACoE,QAAQ,CAACC,UAAU,CAACO,mBAAmB,CAAC;QACjDC,IAAI,EAAE;MACR,CAAC,CAAC;MAEF,MAAMX,KAAK;IACb,CAAC,CAAC,CACDvD,IAAI,CAAC,UAACyB,QAAQ,EAAK;MAClB;MACA,IAAIuC,MAAI,CAACtC,GAAG,CAAC,qBAAqB,CAAC,KAAKZ,SAAS,EAAE;QACjDkD,MAAI,CAACnE,MAAM,CAACC,IAAI,CAAC,yDAAyD,CAAC;QAE3E,OAAO6B,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAAC,CAAC;MAC1B;;MAEA;MACAoC,MAAI,CAAC3E,KAAK,CAACoE,QAAQ,CAACC,UAAU,CAACO,mBAAmB,CAAC;QACjDC,IAAI,EAAE;MACR,CAAC,CAAC;MAEFF,MAAI,CAAC3E,KAAK,CAACoE,QAAQ,CAACW,OAAO,CAACC,mBAAmB,CAACC,gBAAO,CAACC,kCAAkC,CAAC;MAE3F,OAAOP,MAAI,CAACnC,0BAA0B,CAACJ,QAAQ,CAAC;IAClD,CAAC,CAAC,CACDK,KAAK,CAAC,UAACyB,KAAK,EAAK;MAChBS,MAAI,CAAC3E,KAAK,CAACoE,QAAQ,CAACW,OAAO,CAACC,mBAAmB,CAACC,gBAAO,CAACE,8BAA8B,EAAE;QACtFC,MAAM,EAAE;UAAClB,KAAK,EAALA;QAAK;MAChB,CAAC,CAAC;MACF,MAAMA,KAAK;IACb,CAAC,CAAC;EACN,CAAC;EAUDmB,UAAU,WAAVA,UAAUA,CAAA,EAAG;IAAA,IAAAC,MAAA;IACX,IAAI,CAAC9E,MAAM,CAACC,IAAI,CAAC,uBAAuB,CAAC;IAEzC,IAAI,CAAC,IAAI,CAACpB,UAAU,EAAE;MACpB,IAAI,CAACmB,MAAM,CAAC+E,IAAI,CAAC,wBAAwB,CAAC;MAE1C,OAAOjD,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAAC,CAAC;IAC1B;IAEA,OAAO,IAAI,CAACV,OAAO,CAAC;MAClBE,GAAG,EAAE,IAAI,CAAChD,GAAG;MACb+C,MAAM,EAAE;IACV,CAAC,CAAC,CACCnB,IAAI,CAAC;MAAA,OAAM2E,MAAI,CAAC1C,KAAK,CAAC,CAAC;IAAA,EAAC,CACxBH,KAAK,CAAC,UAACC,MAAM,EAAK;MACjB,IAAIA,MAAM,CAACC,UAAU,KAAK,GAAG,EAAE;QAC7B2C,MAAI,CAAC9E,MAAM,CAACC,IAAI,CACd,8EACF,CAAC;QAED6E,MAAI,CAAC1C,KAAK,CAAC,CAAC;MACd;MACA,MAAMF,MAAM;IACd,CAAC,CAAC;EACN,CAAC;EACD;EAEA;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEhC,WAAW,WAAXA,WAAWA,CAAA,EAAG;IACZ,IAAI,CAACF,MAAM,CAACC,IAAI,CAAC,8CAA8C,CAAC;;IAEhE;IACA,IAAO+E,QAAQ,GAAI,IAAI,CAACxF,KAAK,CAACoE,QAAQ,CAA/BoB,QAAQ;;IAEf;IACA,OAAOA,QAAQ,CAACC,cAAc,CAAC,UAAU,EAAE,IAAI,CAAChJ,MAAM,CAACiJ,uBAAuB,CAAC,CAAC/E,IAAI,CAAC;MAAA;QACnF;QACA6E,QAAQ,CAACnD,GAAG,CAAC,KAAK,CAAC,GACfC,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAAC,CAAC,GACjBD,QAAA,CAAAlG,OAAA,CAAQyG,MAAM,CACZ,IAAI8C,KAAK,CACP,CACE,0BAA0B,EAC1B,0DAA0D,CAC3D,CAACC,IAAI,CAAC,GAAG,CACZ,CACF;MAAC;IAAA,CACP,CAAC;EACH,CAAC;EAED;AACF;AACA;AACA;AACA;EACEC,wBAAwB,WAAxBA,wBAAwBA,CAAA,EAAG;IAAA,IAAAC,MAAA;IACzB,IAAI,CAACtF,MAAM,CAACC,IAAI,CAAC,uCAAuC,CAAC;;IAEzD;IACA,IAAI,IAAI,CAACd,qBAAqB,EAAE;MAC9B,OAAO2C,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAAC,IAAI,CAACwD,gBAAgB,CAAC,CAAC,CAAC;IACjD;IAEA,IAAI,CAACpG,qBAAqB,GAAG,IAAI;;IAEjC;IACA,IAAI,CAAC,IAAI,CAAC3B,0BAA0B,EAAE;MACpC,IAAI,CAAC8B,WAAW,GAAG,KAAK;MAExB,OAAOwC,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAAC,IAAI,CAACwD,gBAAgB,CAAC,CAAC,CAAC;IACjD;;IAEA;IACA,IAAM5E,OAAO,GAAG;MACd,wBAAwB,EAAE,IAAI;MAC9B,kBAAkB,EAAE,IAAI;MACxB6E,UAAU,EAAE;IACd,CAAC;;IAED;IACA,OAAO,IAAI,CAACnE,OAAO,CAAC;MAClBV,OAAO,EAAPA,OAAO;MACPW,MAAM,EAAE,KAAK;MACbC,GAAG,EAAE,IAAI,CAAC/D;IACZ,CAAC,CAAC,CACC2C,IAAI,CAAC,YAAM;MACVmF,MAAI,CAAChG,WAAW,GAAG,IAAI;MAEvB,OAAOwC,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAACuD,MAAI,CAACC,gBAAgB,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CACDtD,KAAK,CAAC,YAAM;MACXqD,MAAI,CAACtF,MAAM,CAACC,IAAI,CAAC,qCAAqC,CAAC;MACvDqF,MAAI,CAACtF,MAAM,CAACC,IAAI,CAAC,sCAAsC,CAAC;MAExDqF,MAAI,CAAChG,WAAW,GAAG,KAAK;MAExB,OAAOwC,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAACuD,MAAI,CAACC,gBAAgB,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC;EACN,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACEnD,KAAK,WAALA,KAAKA,CAAA,EAAU;IACb,IAAI,CAACpC,MAAM,CAACC,IAAI,CAAC,oCAAoC,CAAC;;IAEtD;IAAA,SAAAwF,IAAA,GAAAlK,SAAA,CAAAC,MAAA,EAHOkK,IAAI,OAAAC,KAAA,CAAAF,IAAA,GAAAG,IAAA,MAAAA,IAAA,GAAAH,IAAA,EAAAG,IAAA;MAAJF,IAAI,CAAAE,IAAA,IAAArK,SAAA,CAAAqK,IAAA;IAAA;IAIX,IAAAC,MAAA,CAAAjK,OAAA,EAAcQ,sBAAW,CAAC0J,SAAS,CAAC1D,KAAK,EAAE,IAAI,EAAEsD,IAAI,CAAC;EACxD,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACEK,eAAe,WAAfA,eAAeA,CAAA,EAAe;IAAA,IAAAC,MAAA;IAAA,IAAdC,IAAI,GAAA1K,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAqE,SAAA,GAAArE,SAAA,MAAG,KAAK;IAC1B,IAAI,CAACyE,MAAM,CAACC,IAAI,CAAC,2CAA2C,CAAC;;IAE7D;IACA,IAAO+E,QAAQ,GAAI,IAAI,CAACxF,KAAK,CAACoE,QAAQ,CAA/BoB,QAAQ;;IAEf;IACA,IAAIiB,IAAI,EAAE;MACR,OAAO,IAAI,CAACC,mBAAmB,CAAC,CAAC,CAC9B/F,IAAI,CAAC;QAAA,OAAM6E,QAAQ,CAACmB,2BAA2B,CAACH,MAAI,CAACtH,YAAY,CAAC;MAAA,EAAC,CACnEuD,KAAK,CAAC,UAACyB,KAAK,EAAK;QAChBsC,MAAI,CAAChG,MAAM,CAAC+E,IAAI,CAACrB,KAAK,CAACQ,OAAO,CAAC;QAE/B,OAAOpC,QAAA,CAAAlG,OAAA,CAAQyG,MAAM,CAAC,IAAI8C,KAAK,CAAC,iDAAiD,CAAC,CAAC;MACrF,CAAC,CAAC;IACN;;IAEA;IACA,IAAI,CAAC,IAAI,CAACtG,UAAU,EAAE;MACpB,OAAOiD,QAAA,CAAAlG,OAAA,CAAQyG,MAAM,CACnB,IAAI8C,KAAK,CAAC,4DAA4D,CACxE,CAAC;IACH;;IAEA;IACA,IAAMiB,KAAK,GAAGpB,QAAQ,CAACmB,2BAA2B,CAAC,IAAI,CAACzH,YAAY,CAAC;;IAErE;IACA,IAAI0H,KAAK,EAAE;MACT,OAAOtE,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAACqE,KAAK,CAAC;IAC/B;IAEA,OAAOtE,QAAA,CAAAlG,OAAA,CAAQyG,MAAM,CAAC,IAAI8C,KAAK,CAAC,iDAAiD,CAAC,CAAC;EACrF,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACEkB,gBAAgB,WAAhBA,gBAAgBA,CAAA,EAAG;IACjB,IAAMC,sBAAsB,GAAG,EAAE;IACjC,IAAI,IAAI,CAACrK,MAAM,CAACsK,sBAAsB,EAAE;MACtC,IAAMC,mBAAmB,GAAG,IAAI,CAAChH,KAAK,CACnCiH,SAAS,CAAC,CAAC,CACXC,cAAc,CAACC,OAAO,CAAC,IAAI,CAAC1K,MAAM,CAACsK,sBAAsB,CAAC;MAC7D,IAAIC,mBAAmB,EAAE;QACvB,IAAMI,aAAa,GAAGC,IAAI,CAACC,KAAK,CAACN,mBAAmB,CAAC;QACrD,IAAAO,QAAA,CAAAnL,OAAA,EAAegL,aAAa,CAAC,CAAClL,OAAO,CAAC,UAAAsL,IAAA,EAAkB;UAAA,IAAAC,KAAA,OAAAC,eAAA,CAAAtL,OAAA,EAAAoL,IAAA;YAAhBG,GAAG,GAAAF,KAAA;YAAEG,KAAK,GAAAH,KAAA;UAChDX,sBAAsB,CAAClL,IAAI,CAAC;YAC1B+L,GAAG,EAAHA,GAAG;YACHE,GAAG,EAAED,KAAK,GAAG,MAAM,GAAG,OAAO;YAC7BE,OAAO,EAAE,IAAI;YACbC,YAAY,EAAE,IAAItE,IAAI,CAAC,CAAC,CAACuE,WAAW,CAAC;UACvC,CAAC,CAAC;QACJ,CAAC,CAAC;MACJ;IACF;IAEA,OAAOlB,sBAAsB;EAC/B,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACEtE,0BAA0B,WAA1BA,0BAA0BA,CAACJ,QAAQ,EAAE;IAAA,IAAA6F,cAAA;MAAAC,MAAA;IACnC,IAAI,CAAC1H,MAAM,CAACC,IAAI,CAAC,uCAAuC,CAAC;;IAEzD;IACA,IAAMI,IAAI,GAAA/E,aAAA,KAAOsG,QAAQ,CAACvB,IAAI,CAAC;;IAE/B;IACA,OAAOA,IAAI,CAAC2E,QAAQ;IACpB,OAAO3E,IAAI,CAACsH,cAAc;IAE1B,IAAAC,KAAA,GAAehG,QAAQ,CAACjB,OAAO,IAAI,CAAC,CAAC;MAA9BH,IAAI,GAAAoH,KAAA,CAAJpH,IAAI;IAEX,IAAI,IAAI,CAACA,IAAI,IAAIA,IAAI,IAAI,IAAI,CAACA,IAAI,KAAKA,IAAI,EAAE;MAC3C;MACA;MACA;MACA,IAAO3D,QAAQ,GAAIwD,IAAI,CAAhBxD,QAAQ;MAEf,OAAOwD,IAAI,CAACxD,QAAQ;MACpB;MACA,IAAI,CAACA,QAAQ,CAACgL,IAAI,CAACC,KAAK,CAACjL,QAAQ,CAACgL,IAAI,CAAC;MACvC,IAAI,CAAChL,QAAQ,CAACkL,WAAW,CAACD,KAAK,CAACjL,QAAQ,CAACkL,WAAW,CAAC;IACvD,CAAC,MAAM,IAAI,IAAI,CAAC9L,MAAM,CAACsK,sBAAsB,IAAIlG,IAAI,aAAJA,IAAI,gBAAAoH,cAAA,GAAJpH,IAAI,CAAExD,QAAQ,cAAA4K,cAAA,eAAdA,cAAA,CAAgBO,SAAS,EAAE;MAC1E;MACA,IAAI;QAAA,IAAAC,qBAAA;QACF,IAAMrB,aAAa,GAAG,IAAI,CAACP,gBAAgB,CAAC,CAAC;QAC7C,CAAA4B,qBAAA,GAAA5H,IAAI,CAACxD,QAAQ,CAACmL,SAAS,EAAC5M,IAAI,CAAAC,KAAA,CAAA4M,qBAAA,MAAAC,mBAAA,CAAAtM,OAAA,EAAIgL,aAAa,EAAC;MAChD,CAAC,CAAC,OAAOlD,KAAK,EAAE;QACd,IAAI,CAAC1D,MAAM,CAAC0D,KAAK,CAAC,6DAA6D,EAAEA,KAAK,CAAC;MACzF;IACF;;IAEA;IACA,IAAI,CAACtC,GAAG,CAACf,IAAI,CAAC;;IAEd;IACA,IAAI,CAACe,GAAG,CAAC;MAACZ,IAAI,EAAJA;IAAI,CAAC,CAAC;;IAEhB;IACA,IAAI,IAAI,CAACvE,MAAM,CAACC,SAAS,EAAE;MACzB,IAAI,CAAC8D,MAAM,CAACC,IAAI,CAAC,kCAAkC,CAAC;MAEpD,IAAMkI,KAAK,GAAG,CAAC,IAAI,CAAClM,MAAM,CAACyE,kBAAkB,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI;MAE9D,IAAI,CAAC0H,YAAY,GAAG,IAAAC,4BAAc,EAAC;QAAA,OAAMX,MAAI,CAAC7H,OAAO,CAAC,CAAC;MAAA,GAAEsI,KAAK,CAAC;IACjE;;IAEA;IACA,IAAI,CAAC1I,OAAO,CAAC6I,4CAAiC,EAAE,IAAI,CAAC;EACvD,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACE/C,gBAAgB,WAAhBA,gBAAgBA,CAAA,EAAG;IACjB,IAAI,CAACvF,MAAM,CAACC,IAAI,CAAC,gCAAgC,CAAC;;IAElD;IACAsI,YAAY,CAAC,IAAI,CAACtJ,WAAW,CAAC;;IAE9B;IACA,IAAI,CAACuJ,GAAG,CAAC,6BAA6B,CAAC;;IAEvC;IACA,IAAI,CAACC,KAAK,CAAC,aAAa,CAAC;;IAEzB;IACA;IACA,IACE,CAAC,IAAI,CAACpJ,WAAW,IACjB,IAAI,CAACpD,MAAM,CAACyM,2BAA2B,IACvC,IAAI,CAACvJ,qBAAqB,EAC1B;MACA,IAAI,IAAI,CAACG,WAAW,EAAE;QACpB,IAAI,CAACqJ,cAAc,CAAC,IAAI,CAAClL,2BAA2B,CAAC;MACvD,CAAC,MAAM;QACL,IAAI,CAACkL,cAAc,CAAC,IAAI,CAACpL,0BAA0B,CAAC;MACtD;IACF;EACF,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACEoL,cAAc,WAAdA,cAAcA,CAACC,QAAQ,EAAE;IAAA,IAAAC,MAAA;IACvB,IAAI,CAAC7I,MAAM,CAACC,IAAI,CAAC,8BAA8B,CAAC;IAEhD,IAAI,CAAC2I,QAAQ,IAAIA,QAAQ,IAAI,CAAC,EAAE;MAC9B;IACF;;IAEA;IACA,IAAI,CAACE,EAAE,CAAC,6BAA6B,EAAE,YAAM;MAC3CD,MAAI,CAACtD,gBAAgB,CAAC,CAAC;IACzB,CAAC,CAAC;;IAEF;IACA,IAAI,CAACtG,WAAW,GAAG,IAAAoJ,4BAAc,EAAC,YAAM;MACtCQ,MAAI,CAACrJ,KAAK,CAACuJ,MAAM,CAAC,CAAC;IACrB,CAAC,EAAEH,QAAQ,GAAG,IAAI,CAAC;EACrB,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACE1C,mBAAmB,WAAnBA,mBAAmBA,CAAA,EAAe;IAAA,IAAA8C,MAAA;IAAA,IAAdC,OAAO,GAAA1N,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAqE,SAAA,GAAArE,SAAA,MAAG,EAAE;IAC9B,IAAI,CAACyE,MAAM,CAACC,IAAI,CAAC,kCAAkC,CAAC;IAEpD,OAAO,IAAA6B,QAAA,CAAAlG,OAAA,CAAY,UAACmG,OAAO,EAAEM,MAAM,EAAK;MACtC,IAAI2G,MAAI,CAACnK,UAAU,EAAE;QACnBkD,OAAO,CAAC,CAAC;MACX;MAEA,IAAMmH,YAAY,GAAG,IAAAb,4BAAc,EACjC;QAAA,OAAMhG,MAAM,CAAC,IAAI8C,KAAK,CAAC,wDAAwD,CAAC,CAAC;MAAA,GACjF8D,OAAO,GAAG,IACZ,CAAC;MAEDD,MAAI,CAACG,IAAI,CAACb,4CAAiC,EAAE,YAAM;QACjDC,YAAY,CAACW,YAAY,CAAC;QAC1BnH,OAAO,CAAC,CAAC;MACX,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ,CAAC;EAWDqH,sBAAsB,WAAtBA,sBAAsBA,CAAC7K,GAAG,EAAE;IAC1B,OAAOuD,QAAA,CAAAlG,OAAA,CAAQmG,OAAO,CAAC,IAAI,CAACvC,KAAK,CAACoE,QAAQ,CAACoB,QAAQ,CAACqE,aAAa,CAAC9K,GAAG,CAAC,CAAC;EACzE,CAAC;EAaD+K,UAAU,WAAVA,UAAUA,CAAA,EAAU;IAAA,IAAAC,MAAA;IAAA,SAAAC,KAAA,GAAAjO,SAAA,CAAAC,MAAA,EAANkK,IAAI,OAAAC,KAAA,CAAA6D,KAAA,GAAAC,KAAA,MAAAA,KAAA,GAAAD,KAAA,EAAAC,KAAA;MAAJ/D,IAAI,CAAA+D,KAAA,IAAAlO,SAAA,CAAAkO,KAAA;IAAA;IAChB;IACA,IAAA5D,MAAA,CAAAjK,OAAA,EAAcQ,sBAAW,CAAC0J,SAAS,CAACwD,UAAU,EAAE,IAAI,EAAE5D,IAAI,CAAC;IAE3D,IAAI,CAACgE,YAAY,CAAC,IAAI,CAAClK,KAAK,EAAE,eAAe,EAAE,YAAM;MACnD;MACA,IAAI+J,MAAI,CAAClD,gBAAgB,CAACkD,MAAI,CAACtN,MAAM,CAACsK,sBAAsB,CAAC,CAAC/K,MAAM,GAAG,CAAC,EAAE;QACxE+N,MAAI,CAACnI,GAAG,CAAC,MAAM,EAAExB,SAAS,CAAC;MAC7B;IACF,CAAC,CAAC;;IAEF;IACA+J,mCAAwB,CAACjO,OAAO,CAAC,UAACkO,cAAc,EAAK;MACnDL,MAAI,CAAC1M,QAAQ,CAACiM,EAAE,WAAApH,MAAA,CAAWkI,cAAc,GAAI,UAACC,KAAK,EAAEzC,KAAK,EAAE0C,OAAO,EAAK;QACtEP,MAAI,CAAC9J,OAAO,CAAC,QAAQ,EAAE8J,MAAI,EAAEO,OAAO,CAAC;QACrCP,MAAI,CAAC9J,OAAO,CAAC,iBAAiB,EAAE8J,MAAI,EAAEA,MAAI,CAAC1M,QAAQ,EAAEiN,OAAO,CAAC;MAC/D,CAAC,CAAC;IACJ,CAAC,CAAC;;IAEF;IACA,IAAI,CAAChB,EAAE,CAAC,mCAAmC,EAAE,YAAM;MACjDS,MAAI,CAAClE,wBAAwB,CAAC,CAAC;IACjC,CAAC,CAAC;;IAEF;IACA,IAAI,CAACyD,EAAE,CAAC,mCAAmC,EAAE,YAAM;MACjDS,MAAI,CAAClE,wBAAwB,CAAC,CAAC;IACjC,CAAC,CAAC;;IAEF;IACA,IAAI,CAACyD,EAAE,CAAC,oCAAoC,EAAE,YAAM;MAClDS,MAAI,CAAClE,wBAAwB,CAAC,CAAC;IACjC,CAAC,CAAC;;IAEF;IACA,IAAI,CAAC0E,QAAQ,CAAC,IAAI,CAACvK,KAAK,EAAE,eAAe,EAAE,YAAM;MAC/C+J,MAAI,CAACrK,oBAAoB,GAAG,IAAA8K,IAAA,CAAApO,OAAA,EAAS,CAAC;IACxC,CAAC,CAAC;;IAEF;IACA,IAAI,CAACmO,QAAQ,CAAC,IAAI,CAACvK,KAAK,EAAE,iBAAiB,EAAE,YAAM;MACjD+J,MAAI,CAAClK,WAAW,GAAG,IAAI;MACvBkK,MAAI,CAAChE,gBAAgB,CAAC,CAAC;IACzB,CAAC,CAAC;;IAEF;IACA,IAAI,CAACwE,QAAQ,CAAC,IAAI,CAACvK,KAAK,EAAE,eAAe,EAAE,YAAM;MAC/C+J,MAAI,CAAClK,WAAW,GAAG,KAAK;MACxBkK,MAAI,CAAChE,gBAAgB,CAAC,CAAC;IACzB,CAAC,CAAC;EACJ,CAAC,CACD;EAAA0E,OAAA;AACF,CAAC,MAAAC,0BAAA,CAAAtO,OAAA,EAAAnB,IAAA,cAjpBE0P,iBAAS,EAAAhQ,IAAA,OAAAiQ,yBAAA,CAAAxO,OAAA,EAAAnB,IAAA,cAAAA,IAAA,OAAAyP,0BAAA,CAAAtO,OAAA,EAAAnB,IAAA,eAAAL,KAAA,OAAAgQ,yBAAA,CAAAxO,OAAA,EAAAnB,IAAA,eAAAA,IAAA,OAAAyP,0BAAA,CAAAtO,OAAA,EAAAnB,IAAA,wBA2KT0P,iBAAS,EAAA9P,KAAA,OAAA+P,yBAAA,CAAAxO,OAAA,EAAAnB,IAAA,wBAAAA,IAAA,OAAAyP,0BAAA,CAAAtO,OAAA,EAAAnB,IAAA,iBA8ET0P,iBAAS,EAAA7P,KAAA,OAAA8P,yBAAA,CAAAxO,OAAA,EAAAnB,IAAA,iBAAAA,IAAA,OAAAyP,0BAAA,CAAAtO,OAAA,EAAAnB,IAAA,6BAAAF,KAAA,OAAA6P,yBAAA,CAAAxO,OAAA,EAAAnB,IAAA,6BAAAA,IAAA,OAAAyP,0BAAA,CAAAtO,OAAA,EAAAnB,IAAA,iBAAAD,KAAA,OAAA4P,yBAAA,CAAAxO,OAAA,EAAAnB,IAAA,iBAAAA,IAAA,GAAAA,IAAA,CAwZX,CAAC;AAAC,IAAA4P,QAAA,GAAAC,OAAA,CAAA1O,OAAA,GAEYO,MAAM","ignoreList":[]}
@@ -180,7 +180,7 @@ var IpNetworkDetector = _webexCore.WebexPlugin.extend({
180
180
  var _arguments = arguments,
181
181
  _this2 = this;
182
182
  return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
183
- var force, results, pc, forceParam;
183
+ var force, results, pc, _pc, forceParam;
184
184
  return _regenerator.default.wrap(function (_context2) {
185
185
  while (1) switch (_context2.prev = _context2.next) {
186
186
  case 0:
@@ -209,7 +209,7 @@ var IpNetworkDetector = _webexCore.WebexPlugin.extend({
209
209
  results = _context2.sent;
210
210
  case 4:
211
211
  _context2.prev = 4;
212
- pc.close();
212
+ (_pc = pc) === null || _pc === void 0 ? void 0 : _pc.close();
213
213
  _this2.state = STATE.IDLE;
214
214
  return _context2.finish(4);
215
215
  case 5:
@@ -225,7 +225,7 @@ var IpNetworkDetector = _webexCore.WebexPlugin.extend({
225
225
  }, _callee2, null, [[2,, 4, 5]]);
226
226
  }))();
227
227
  },
228
- version: "0.0.0"
228
+ version: "3.12.0-next.1"
229
229
  });
230
230
  var _default = exports.default = IpNetworkDetector;
231
231
  //# sourceMappingURL=ipNetworkDetector.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_webexCore","require","STATE","INITIAL","IN_PROGRESS","IDLE","IpNetworkDetector","WebexPlugin","extend","idAttribute","namespace","props","firstIpV4","firstIpV6","firstMdns","totalTime","state","pendingDetection","undefined","derived","supportsIpV4","deps","fn","receivedOnlyMDnsCandidates","supportsIpV6","gatherLocalCandidates","pc","_this","_asyncToGenerator2","default","_regenerator","mark","_callee","wrap","_context","prev","next","abrupt","_promise","resolve","reject","done","startTime","performance","now","doneGatheringIceCandidates","onicecandidate","event","_event$candidate","candidate","address","endsWith","includes","onicegatheringstatechange","iceGatheringState","createDataChannel","createOffer","then","offer","setLocalDescription","catch","e","webex","logger","error","stop","detect","_arguments","arguments","_this2","_callee2","force","results","forceParam","_context2","length","RTCPeerConnection","sent","close","finish","version","_default","exports"],"sources":["ipNetworkDetector.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {WebexPlugin} from '@webex/webex-core';\n\nconst STATE = {\n INITIAL: 'initial',\n IN_PROGRESS: 'in-progress',\n IDLE: 'idle',\n};\n\n/**\n * @class\n */\nconst IpNetworkDetector = WebexPlugin.extend({\n idAttribute: 'IpNetworkDetectorId',\n\n namespace: 'Device',\n\n props: {\n firstIpV4: ['number', true, -1], // time [ms] it took to receive first IPv4 candidate\n firstIpV6: ['number', true, -1], // time [ms] it took to receive first IPv6 candidate\n firstMdns: ['number', true, -1], // time [ms] it took to receive first mDNS candidate\n totalTime: ['number', true, -1], // total time [ms] it took to do the last IP network detection\n state: ['string', true, STATE.INITIAL],\n pendingDetection: ['object', false, undefined],\n },\n\n derived: {\n /**\n * True if we know we're on an IPv4 network,\n * False if we know that we are not on an IPv4 network,\n * undefined if we are not sure\n */\n supportsIpV4: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV4 prop\n * @returns {boolean | undefined}\n */\n fn() {\n if (this.firstIpV4 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n /**\n * True if we know we're on an IPv6 network,\n * False if we know that we are not on an IPv6 network,\n * undefined if we are not sure\n */\n supportsIpV6: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV6 prop\n * @returns {boolean | undefined}\n */ fn() {\n if (this.firstIpV6 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n },\n\n /**\n * Returns true if we have received only mDNS candidates - browsers usually do that if we don't have any user media permissions\n *\n * @private\n * @returns {boolean}\n */\n receivedOnlyMDnsCandidates() {\n return this.totalTime >= 0 && this.firstMdns >= 0 && this.firstIpV4 < 0 && this.firstIpV6 < 0;\n },\n\n /**\n *\n * @param {RTCPeerConnection} pc Peer connection to use\n * @private\n * @returns {Promise<void>}\n */\n async gatherLocalCandidates(pc: RTCPeerConnection): Promise<void> {\n return new Promise((resolve, reject) => {\n let done = false;\n\n this.firstIpV4 = -1;\n this.firstIpV6 = -1;\n this.firstMdns = -1;\n this.totalTime = -1;\n const startTime = performance.now();\n\n const doneGatheringIceCandidates = () => {\n if (done) {\n return;\n }\n done = true;\n\n this.totalTime = performance.now() - startTime;\n\n resolve();\n };\n\n pc.onicecandidate = (event) => {\n if (event.candidate?.address) {\n if (event.candidate.address.endsWith('.local')) {\n // if we don't have camera/mic permissions, browser just gives us mDNS candidates\n if (this.firstMdns === -1) {\n this.firstMdns = performance.now() - startTime;\n }\n } else if (event.candidate.address.includes(':')) {\n if (this.firstIpV6 === -1) {\n this.firstIpV6 = performance.now() - startTime;\n }\n } else if (this.firstIpV4 === -1) {\n this.firstIpV4 = performance.now() - startTime;\n }\n\n if (this.firstIpV4 >= 0 && this.firstIpV6 >= 0) {\n // if we've got both ipv4 and ipv6 candidates, there is no need to wait for any more candidates, we can resolve now\n resolve();\n }\n } else if (event.candidate === null) {\n doneGatheringIceCandidates();\n }\n };\n\n pc.onicegatheringstatechange = () => {\n if (pc.iceGatheringState === 'complete') {\n doneGatheringIceCandidates();\n }\n };\n\n pc.createDataChannel('data');\n\n pc.createOffer()\n .then((offer) => pc.setLocalDescription(offer))\n .catch((e) => {\n this.webex.logger.error('Failed to detect ip network version:', e);\n reject(e);\n });\n });\n },\n\n /**\n * Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the\n * supportsIpV4 and supportsIpV6 props to find out the result.\n *\n * @param {boolean} force - if false, the detection will only be done if we haven't managed to get any meaningful results yet\n * @returns {Promise<void>}\n */\n async detect(force = false) {\n let results;\n let pc;\n\n if (this.state === STATE.IN_PROGRESS) {\n this.pendingDetection = {force};\n\n return;\n }\n\n if (!force && this.state !== STATE.INITIAL && !this.receivedOnlyMDnsCandidates()) {\n // we already have the results, no need to do the detection again\n return;\n }\n\n try {\n this.state = STATE.IN_PROGRESS;\n\n pc = new RTCPeerConnection();\n\n results = await this.gatherLocalCandidates(pc);\n } finally {\n pc.close();\n this.state = STATE.IDLE;\n }\n\n if (this.pendingDetection) {\n const {force: forceParam} = this.pendingDetection;\n\n this.pendingDetection = undefined;\n this.detect(forceParam);\n }\n },\n});\n\nexport default IpNetworkDetector;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_webexCore","require","STATE","INITIAL","IN_PROGRESS","IDLE","IpNetworkDetector","WebexPlugin","extend","idAttribute","namespace","props","firstIpV4","firstIpV6","firstMdns","totalTime","state","pendingDetection","undefined","derived","supportsIpV4","deps","fn","receivedOnlyMDnsCandidates","supportsIpV6","gatherLocalCandidates","pc","_this","_asyncToGenerator2","default","_regenerator","mark","_callee","wrap","_context","prev","next","abrupt","_promise","resolve","reject","done","startTime","performance","now","doneGatheringIceCandidates","onicecandidate","event","_event$candidate","candidate","address","endsWith","includes","onicegatheringstatechange","iceGatheringState","createDataChannel","createOffer","then","offer","setLocalDescription","catch","e","webex","logger","error","stop","detect","_arguments","arguments","_this2","_callee2","force","results","_pc","forceParam","_context2","length","RTCPeerConnection","sent","close","finish","version","_default","exports"],"sources":["ipNetworkDetector.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {WebexPlugin} from '@webex/webex-core';\n\nconst STATE = {\n INITIAL: 'initial',\n IN_PROGRESS: 'in-progress',\n IDLE: 'idle',\n};\n\n/**\n * @class\n */\nconst IpNetworkDetector = WebexPlugin.extend({\n idAttribute: 'IpNetworkDetectorId',\n\n namespace: 'Device',\n\n props: {\n firstIpV4: ['number', true, -1], // time [ms] it took to receive first IPv4 candidate\n firstIpV6: ['number', true, -1], // time [ms] it took to receive first IPv6 candidate\n firstMdns: ['number', true, -1], // time [ms] it took to receive first mDNS candidate\n totalTime: ['number', true, -1], // total time [ms] it took to do the last IP network detection\n state: ['string', true, STATE.INITIAL],\n pendingDetection: ['object', false, undefined],\n },\n\n derived: {\n /**\n * True if we know we're on an IPv4 network,\n * False if we know that we are not on an IPv4 network,\n * undefined if we are not sure\n */\n supportsIpV4: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV4 prop\n * @returns {boolean | undefined}\n */\n fn() {\n if (this.firstIpV4 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n /**\n * True if we know we're on an IPv6 network,\n * False if we know that we are not on an IPv6 network,\n * undefined if we are not sure\n */\n supportsIpV6: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV6 prop\n * @returns {boolean | undefined}\n */ fn() {\n if (this.firstIpV6 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n },\n\n /**\n * Returns true if we have received only mDNS candidates - browsers usually do that if we don't have any user media permissions\n *\n * @private\n * @returns {boolean}\n */\n receivedOnlyMDnsCandidates() {\n return this.totalTime >= 0 && this.firstMdns >= 0 && this.firstIpV4 < 0 && this.firstIpV6 < 0;\n },\n\n /**\n *\n * @param {RTCPeerConnection} pc Peer connection to use\n * @private\n * @returns {Promise<void>}\n */\n async gatherLocalCandidates(pc: RTCPeerConnection): Promise<void> {\n return new Promise((resolve, reject) => {\n let done = false;\n\n this.firstIpV4 = -1;\n this.firstIpV6 = -1;\n this.firstMdns = -1;\n this.totalTime = -1;\n const startTime = performance.now();\n\n const doneGatheringIceCandidates = () => {\n if (done) {\n return;\n }\n done = true;\n\n this.totalTime = performance.now() - startTime;\n\n resolve();\n };\n\n pc.onicecandidate = (event) => {\n if (event.candidate?.address) {\n if (event.candidate.address.endsWith('.local')) {\n // if we don't have camera/mic permissions, browser just gives us mDNS candidates\n if (this.firstMdns === -1) {\n this.firstMdns = performance.now() - startTime;\n }\n } else if (event.candidate.address.includes(':')) {\n if (this.firstIpV6 === -1) {\n this.firstIpV6 = performance.now() - startTime;\n }\n } else if (this.firstIpV4 === -1) {\n this.firstIpV4 = performance.now() - startTime;\n }\n\n if (this.firstIpV4 >= 0 && this.firstIpV6 >= 0) {\n // if we've got both ipv4 and ipv6 candidates, there is no need to wait for any more candidates, we can resolve now\n resolve();\n }\n } else if (event.candidate === null) {\n doneGatheringIceCandidates();\n }\n };\n\n pc.onicegatheringstatechange = () => {\n if (pc.iceGatheringState === 'complete') {\n doneGatheringIceCandidates();\n }\n };\n\n pc.createDataChannel('data');\n\n pc.createOffer()\n .then((offer) => pc.setLocalDescription(offer))\n .catch((e) => {\n this.webex.logger.error('Failed to detect ip network version:', e);\n reject(e);\n });\n });\n },\n\n /**\n * Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the\n * supportsIpV4 and supportsIpV6 props to find out the result.\n *\n * @param {boolean} force - if false, the detection will only be done if we haven't managed to get any meaningful results yet\n * @returns {Promise<void>}\n */\n async detect(force = false) {\n let results;\n let pc;\n\n if (this.state === STATE.IN_PROGRESS) {\n this.pendingDetection = {force};\n\n return;\n }\n\n if (!force && this.state !== STATE.INITIAL && !this.receivedOnlyMDnsCandidates()) {\n // we already have the results, no need to do the detection again\n return;\n }\n\n try {\n this.state = STATE.IN_PROGRESS;\n\n pc = new RTCPeerConnection();\n\n results = await this.gatherLocalCandidates(pc);\n } finally {\n pc?.close();\n this.state = STATE.IDLE;\n }\n\n if (this.pendingDetection) {\n const {force: forceParam} = this.pendingDetection;\n\n this.pendingDetection = undefined;\n this.detect(forceParam);\n }\n },\n});\n\nexport default IpNetworkDetector;\n"],"mappings":";;;;;;;;;;;AAIA,IAAAA,UAAA,GAAAC,OAAA;AAJA;AACA;AACA;;AAIA,IAAMC,KAAK,GAAG;EACZC,OAAO,EAAE,SAAS;EAClBC,WAAW,EAAE,aAAa;EAC1BC,IAAI,EAAE;AACR,CAAC;;AAED;AACA;AACA;AACA,IAAMC,iBAAiB,GAAGC,sBAAW,CAACC,MAAM,CAAC;EAC3CC,WAAW,EAAE,qBAAqB;EAElCC,SAAS,EAAE,QAAQ;EAEnBC,KAAK,EAAE;IACLC,SAAS,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAAE;IACjCC,SAAS,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAAE;IACjCC,SAAS,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAAE;IACjCC,SAAS,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAAE;IACjCC,KAAK,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAEd,KAAK,CAACC,OAAO,CAAC;IACtCc,gBAAgB,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAEC,SAAS;EAC/C,CAAC;EAEDC,OAAO,EAAE;IACP;AACJ;AACA;AACA;AACA;IACIC,YAAY,EAAE;MACZC,IAAI,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC;MAC1D;AACN;AACA;AACA;MACMC,EAAE,WAAFA,EAAEA,CAAA,EAAG;QACH,IAAI,IAAI,CAACV,SAAS,IAAI,CAAC,EAAE;UACvB,OAAO,IAAI;QACb;QACA,IAAI,IAAI,CAACG,SAAS,GAAG,CAAC,EAAE;UACtB;UACA,OAAOG,SAAS;QAClB;QACA,IAAI,IAAI,CAACK,0BAA0B,CAAC,CAAC,EAAE;UACrC,OAAOL,SAAS;QAClB;QAEA,OAAO,KAAK;MACd;IACF,CAAC;IACD;AACJ;AACA;AACA;AACA;IACIM,YAAY,EAAE;MACZH,IAAI,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC;MAC1D;AACN;AACA;AACA;MAAUC,EAAE,WAAFA,EAAEA,CAAA,EAAG;QACP,IAAI,IAAI,CAACT,SAAS,IAAI,CAAC,EAAE;UACvB,OAAO,IAAI;QACb;QACA,IAAI,IAAI,CAACE,SAAS,GAAG,CAAC,EAAE;UACtB;UACA,OAAOG,SAAS;QAClB;QACA,IAAI,IAAI,CAACK,0BAA0B,CAAC,CAAC,EAAE;UACrC,OAAOL,SAAS;QAClB;QAEA,OAAO,KAAK;MACd;IACF;EACF,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACEK,0BAA0B,WAA1BA,0BAA0BA,CAAA,EAAG;IAC3B,OAAO,IAAI,CAACR,SAAS,IAAI,CAAC,IAAI,IAAI,CAACD,SAAS,IAAI,CAAC,IAAI,IAAI,CAACF,SAAS,GAAG,CAAC,IAAI,IAAI,CAACC,SAAS,GAAG,CAAC;EAC/F,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACQY,qBAAqB,WAArBA,qBAAqBA,CAACC,EAAqB,EAAiB;IAAA,IAAAC,KAAA;IAAA,WAAAC,kBAAA,CAAAC,OAAA,eAAAC,YAAA,CAAAD,OAAA,CAAAE,IAAA,UAAAC,QAAA;MAAA,OAAAF,YAAA,CAAAD,OAAA,CAAAI,IAAA,WAAAC,QAAA;QAAA,kBAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAAE,IAAA;UAAA;YAAA,OAAAF,QAAA,CAAAG,MAAA,WACzD,IAAAC,QAAA,CAAAT,OAAA,CAAY,UAACU,OAAO,EAAEC,MAAM,EAAK;cACtC,IAAIC,IAAI,GAAG,KAAK;cAEhBd,KAAI,CAACf,SAAS,GAAG,CAAC,CAAC;cACnBe,KAAI,CAACd,SAAS,GAAG,CAAC,CAAC;cACnBc,KAAI,CAACb,SAAS,GAAG,CAAC,CAAC;cACnBa,KAAI,CAACZ,SAAS,GAAG,CAAC,CAAC;cACnB,IAAM2B,SAAS,GAAGC,WAAW,CAACC,GAAG,CAAC,CAAC;cAEnC,IAAMC,0BAA0B,GAAG,SAA7BA,0BAA0BA,CAAA,EAAS;gBACvC,IAAIJ,IAAI,EAAE;kBACR;gBACF;gBACAA,IAAI,GAAG,IAAI;gBAEXd,KAAI,CAACZ,SAAS,GAAG4B,WAAW,CAACC,GAAG,CAAC,CAAC,GAAGF,SAAS;gBAE9CH,OAAO,CAAC,CAAC;cACX,CAAC;cAEDb,EAAE,CAACoB,cAAc,GAAG,UAACC,KAAK,EAAK;gBAAA,IAAAC,gBAAA;gBAC7B,KAAAA,gBAAA,GAAID,KAAK,CAACE,SAAS,cAAAD,gBAAA,eAAfA,gBAAA,CAAiBE,OAAO,EAAE;kBAC5B,IAAIH,KAAK,CAACE,SAAS,CAACC,OAAO,CAACC,QAAQ,CAAC,QAAQ,CAAC,EAAE;oBAC9C;oBACA,IAAIxB,KAAI,CAACb,SAAS,KAAK,CAAC,CAAC,EAAE;sBACzBa,KAAI,CAACb,SAAS,GAAG6B,WAAW,CAACC,GAAG,CAAC,CAAC,GAAGF,SAAS;oBAChD;kBACF,CAAC,MAAM,IAAIK,KAAK,CAACE,SAAS,CAACC,OAAO,CAACE,QAAQ,CAAC,GAAG,CAAC,EAAE;oBAChD,IAAIzB,KAAI,CAACd,SAAS,KAAK,CAAC,CAAC,EAAE;sBACzBc,KAAI,CAACd,SAAS,GAAG8B,WAAW,CAACC,GAAG,CAAC,CAAC,GAAGF,SAAS;oBAChD;kBACF,CAAC,MAAM,IAAIf,KAAI,CAACf,SAAS,KAAK,CAAC,CAAC,EAAE;oBAChCe,KAAI,CAACf,SAAS,GAAG+B,WAAW,CAACC,GAAG,CAAC,CAAC,GAAGF,SAAS;kBAChD;kBAEA,IAAIf,KAAI,CAACf,SAAS,IAAI,CAAC,IAAIe,KAAI,CAACd,SAAS,IAAI,CAAC,EAAE;oBAC9C;oBACA0B,OAAO,CAAC,CAAC;kBACX;gBACF,CAAC,MAAM,IAAIQ,KAAK,CAACE,SAAS,KAAK,IAAI,EAAE;kBACnCJ,0BAA0B,CAAC,CAAC;gBAC9B;cACF,CAAC;cAEDnB,EAAE,CAAC2B,yBAAyB,GAAG,YAAM;gBACnC,IAAI3B,EAAE,CAAC4B,iBAAiB,KAAK,UAAU,EAAE;kBACvCT,0BAA0B,CAAC,CAAC;gBAC9B;cACF,CAAC;cAEDnB,EAAE,CAAC6B,iBAAiB,CAAC,MAAM,CAAC;cAE5B7B,EAAE,CAAC8B,WAAW,CAAC,CAAC,CACbC,IAAI,CAAC,UAACC,KAAK;gBAAA,OAAKhC,EAAE,CAACiC,mBAAmB,CAACD,KAAK,CAAC;cAAA,EAAC,CAC9CE,KAAK,CAAC,UAACC,CAAC,EAAK;gBACZlC,KAAI,CAACmC,KAAK,CAACC,MAAM,CAACC,KAAK,CAAC,sCAAsC,EAAEH,CAAC,CAAC;gBAClErB,MAAM,CAACqB,CAAC,CAAC;cACX,CAAC,CAAC;YACN,CAAC,CAAC;UAAA;UAAA;YAAA,OAAA3B,QAAA,CAAA+B,IAAA;QAAA;MAAA,GAAAjC,OAAA;IAAA;EACJ,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;EACQkC,MAAM,WAANA,MAAMA,CAAA,EAAgB;IAAA,IAAAC,UAAA,GAAAC,SAAA;MAAAC,MAAA;IAAA,WAAAzC,kBAAA,CAAAC,OAAA,eAAAC,YAAA,CAAAD,OAAA,CAAAE,IAAA,UAAAuC,SAAA;MAAA,IAAAC,KAAA,EAAAC,OAAA,EAAA9C,EAAA,EAAA+C,GAAA,EAAAC,UAAA;MAAA,OAAA5C,YAAA,CAAAD,OAAA,CAAAI,IAAA,WAAA0C,SAAA;QAAA,kBAAAA,SAAA,CAAAxC,IAAA,GAAAwC,SAAA,CAAAvC,IAAA;UAAA;YAAfmC,KAAK,GAAAJ,UAAA,CAAAS,MAAA,QAAAT,UAAA,QAAAjD,SAAA,GAAAiD,UAAA,MAAG,KAAK;YAAA,MAIpBE,MAAI,CAACrD,KAAK,KAAKd,KAAK,CAACE,WAAW;cAAAuE,SAAA,CAAAvC,IAAA;cAAA;YAAA;YAClCiC,MAAI,CAACpD,gBAAgB,GAAG;cAACsD,KAAK,EAALA;YAAK,CAAC;YAAC,OAAAI,SAAA,CAAAtC,MAAA;UAAA;YAAA,MAK9B,CAACkC,KAAK,IAAIF,MAAI,CAACrD,KAAK,KAAKd,KAAK,CAACC,OAAO,IAAI,CAACkE,MAAI,CAAC9C,0BAA0B,CAAC,CAAC;cAAAoD,SAAA,CAAAvC,IAAA;cAAA;YAAA;YAAA,OAAAuC,SAAA,CAAAtC,MAAA;UAAA;YAAAsC,SAAA,CAAAxC,IAAA;YAM9EkC,MAAI,CAACrD,KAAK,GAAGd,KAAK,CAACE,WAAW;YAE9BsB,EAAE,GAAG,IAAImD,iBAAiB,CAAC,CAAC;YAACF,SAAA,CAAAvC,IAAA;YAAA,OAEbiC,MAAI,CAAC5C,qBAAqB,CAACC,EAAE,CAAC;UAAA;YAA9C8C,OAAO,GAAAG,SAAA,CAAAG,IAAA;UAAA;YAAAH,SAAA,CAAAxC,IAAA;YAEP,CAAAsC,GAAA,GAAA/C,EAAE,cAAA+C,GAAA,uBAAFA,GAAA,CAAIM,KAAK,CAAC,CAAC;YACXV,MAAI,CAACrD,KAAK,GAAGd,KAAK,CAACG,IAAI;YAAC,OAAAsE,SAAA,CAAAK,MAAA;UAAA;YAG1B,IAAIX,MAAI,CAACpD,gBAAgB,EAAE;cACXyD,UAAU,GAAIL,MAAI,CAACpD,gBAAgB,CAA1CsD,KAAK;cAEZF,MAAI,CAACpD,gBAAgB,GAAGC,SAAS;cACjCmD,MAAI,CAACH,MAAM,CAACQ,UAAU,CAAC;YACzB;UAAC;UAAA;YAAA,OAAAC,SAAA,CAAAV,IAAA;QAAA;MAAA,GAAAK,QAAA;IAAA;EACH,CAAC;EAAAW,OAAA;AACH,CAAC,CAAC;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAtD,OAAA,GAEYvB,iBAAiB","ignoreList":[]}
package/package.json CHANGED
@@ -25,10 +25,10 @@
25
25
  "@webex/eslint-config-legacy": "0.0.0",
26
26
  "@webex/jest-config-legacy": "0.0.0",
27
27
  "@webex/legacy-tools": "0.0.0",
28
- "@webex/test-helper-chai": "3.11.0",
29
- "@webex/test-helper-mocha": "3.11.0",
30
- "@webex/test-helper-mock-webex": "3.11.0",
31
- "@webex/test-helper-test-users": "3.11.0",
28
+ "@webex/test-helper-chai": "3.11.0-next.1",
29
+ "@webex/test-helper-mocha": "3.11.0-next.1",
30
+ "@webex/test-helper-mock-webex": "3.11.0-next.1",
31
+ "@webex/test-helper-test-users": "3.11.0-next.1",
32
32
  "chai": "^4.3.4",
33
33
  "chai-as-promised": "^7.1.1",
34
34
  "eslint": "^8.24.0",
@@ -36,11 +36,11 @@
36
36
  "sinon": "^9.2.4"
37
37
  },
38
38
  "dependencies": {
39
- "@webex/common": "3.11.0",
40
- "@webex/common-timers": "3.11.0",
41
- "@webex/http-core": "3.11.0",
42
- "@webex/internal-plugin-metrics": "3.11.0",
43
- "@webex/webex-core": "3.11.0",
39
+ "@webex/common": "3.11.0-next.1",
40
+ "@webex/common-timers": "3.11.0-next.1",
41
+ "@webex/http-core": "3.11.0-next.1",
42
+ "@webex/internal-plugin-metrics": "3.12.0-next.1",
43
+ "@webex/webex-core": "3.12.0-next.1",
44
44
  "ampersand-collection": "^2.0.2",
45
45
  "ampersand-state": "^5.0.3",
46
46
  "lodash": "^4.17.21",
@@ -55,5 +55,5 @@
55
55
  "test:style": "eslint ./src/**/*.*",
56
56
  "test:unit": "webex-legacy-tools test --unit --runner jest"
57
57
  },
58
- "version": "3.11.0"
58
+ "version": "3.12.0-next.1"
59
59
  }
package/src/config.js CHANGED
@@ -62,14 +62,21 @@ export default {
62
62
  * @type {boolean}
63
63
  */
64
64
  energyForecast: false,
65
- },
66
65
 
67
- /**
68
- * installationId is used exclusively as web client for fraud prevention,
69
- * and is aliased to as machineId by CA.
70
- *
71
- * @alias device.machineId
72
- * @type {string}
73
- */
74
- installationId: undefined,
66
+ /**
67
+ * debugFeatureTogglesKey
68
+ * The session storage key for debug feature toggles
69
+ * @type {string}
70
+ */
71
+ debugFeatureTogglesKey: undefined,
72
+
73
+ /**
74
+ * installationId is used exclusively as web client for fraud prevention,
75
+ * and is aliased to as machineId by CA.
76
+ *
77
+ * @alias device.machineId
78
+ * @type {string}
79
+ */
80
+ installationId: undefined,
81
+ },
75
82
  };
package/src/device.js CHANGED
@@ -786,6 +786,34 @@ const Device = WebexPlugin.extend({
786
786
  return Promise.reject(new Error('device: failed to get the current websocket url'));
787
787
  },
788
788
 
789
+ /**
790
+ * Get sanitized processed debug features from session storage
791
+ * these should be JSON encoded and in the form {feature1: true, feature2: false}
792
+ *
793
+ * @returns {Array<Object>} - Array of sanitized debug feature toggles
794
+ */
795
+ getDebugFeatures() {
796
+ const sanitizedDebugFeatures = [];
797
+ if (this.config.debugFeatureTogglesKey) {
798
+ const debugFeaturesString = this.webex
799
+ .getWindow()
800
+ .sessionStorage.getItem(this.config.debugFeatureTogglesKey);
801
+ if (debugFeaturesString) {
802
+ const debugFeatures = JSON.parse(debugFeaturesString);
803
+ Object.entries(debugFeatures).forEach(([key, value]) => {
804
+ sanitizedDebugFeatures.push({
805
+ key,
806
+ val: value ? 'true' : 'false',
807
+ mutable: true,
808
+ lastModified: new Date().toISOString(),
809
+ });
810
+ });
811
+ }
812
+ }
813
+
814
+ return sanitizedDebugFeatures;
815
+ },
816
+
789
817
  /**
790
818
  * Process a successful device registration.
791
819
  *
@@ -814,6 +842,14 @@ const Device = WebexPlugin.extend({
814
842
  // When using the etag feature cache, user and entitlement features are still returned
815
843
  this.features.user.reset(features.user);
816
844
  this.features.entitlement.reset(features.entitlement);
845
+ } else if (this.config.debugFeatureTogglesKey && body?.features?.developer) {
846
+ // Add the debug feature toggles from session storage if available
847
+ try {
848
+ const debugFeatures = this.getDebugFeatures();
849
+ body.features.developer.push(...debugFeatures);
850
+ } catch (error) {
851
+ this.logger.error('Failed to parse debug feature toggles from session storage:', error);
852
+ }
817
853
  }
818
854
 
819
855
  // Assign the recieved DTO from **WDM** to this device.
@@ -946,6 +982,13 @@ const Device = WebexPlugin.extend({
946
982
  // Prototype the extended class in order to preserve the parent member.
947
983
  Reflect.apply(WebexPlugin.prototype.initialize, this, args);
948
984
 
985
+ this.listenToOnce(this.webex, 'change:config', () => {
986
+ // If debug feature toggles exist, clear the etag to ensure developer feature toggles are fetched
987
+ if (this.getDebugFeatures(this.config.debugFeatureTogglesKey).length > 0) {
988
+ this.set('etag', undefined);
989
+ }
990
+ });
991
+
949
992
  // Initialize feature events and listeners.
950
993
  FEATURE_COLLECTION_NAMES.forEach((collectionName) => {
951
994
  this.features.on(`change:${collectionName}`, (model, value, options) => {
@@ -188,7 +188,7 @@ const IpNetworkDetector = WebexPlugin.extend({
188
188
 
189
189
  results = await this.gatherLocalCandidates(pc);
190
190
  } finally {
191
- pc.close();
191
+ pc?.close();
192
192
  this.state = STATE.IDLE;
193
193
  }
194
194
 
@@ -20,10 +20,19 @@ describe('plugin-device', () => {
20
20
  let device;
21
21
 
22
22
  beforeEach(() => {
23
+ const fakeStorage = {};
23
24
  webex = new MockWebex({
24
25
  children: {
25
26
  device: Device,
26
27
  },
28
+ getWindow: () => ({
29
+ sessionStorage: {
30
+ setItem: (key, value) => {
31
+ fakeStorage[key] = value;
32
+ },
33
+ getItem: (key) => fakeStorage[key],
34
+ },
35
+ }),
27
36
  });
28
37
 
29
38
  const clonedDTO = cloneDeep(dto);
@@ -103,6 +112,54 @@ describe('plugin-device', () => {
103
112
  });
104
113
  });
105
114
  });
115
+
116
+ describe('when the config is changed', () => {
117
+ it("should unset the 'etag' if debug features are set", () => {
118
+ device.set('etag', 'etag-value');
119
+ device.config.debugFeatureTogglesKey = 'debug-feature-toggles';
120
+
121
+ webex.getWindow().sessionStorage.setItem(
122
+ 'debug-feature-toggles',
123
+ JSON.stringify({
124
+ test_feature: true,
125
+ })
126
+ );
127
+ assert.equal(device.etag, 'etag-value');
128
+
129
+ webex.trigger('change:config');
130
+ assert.isUndefined(device.etag);
131
+ });
132
+
133
+ it("should not unset the 'etag' if debug features are not set", () => {
134
+ device.set('etag', 'etag-value');
135
+ device.config.debugFeatureTogglesKey = 'debug-feature-toggles';
136
+
137
+ assert.equal(device.etag, 'etag-value');
138
+
139
+ webex.trigger('change:config');
140
+ assert.equal(device.etag, 'etag-value');
141
+ });
142
+
143
+ it("should only unset the 'etag' the first time the event is sent", () => {
144
+ device.set('etag', 'etag-value');
145
+ device.config.debugFeatureTogglesKey = 'debug-feature-toggles';
146
+
147
+ webex.getWindow().sessionStorage.setItem(
148
+ 'debug-feature-toggles',
149
+ JSON.stringify({
150
+ test_feature: true,
151
+ })
152
+ );
153
+ assert.equal(device.etag, 'etag-value');
154
+
155
+ webex.trigger('change:config');
156
+ assert.isUndefined(device.etag);
157
+
158
+ device.set('etag', 'etag-value');
159
+ webex.trigger('change:config');
160
+ assert.equal(device.etag, 'etag-value');
161
+ });
162
+ });
106
163
  });
107
164
 
108
165
  describe('derived properties', () => {
@@ -424,18 +481,17 @@ describe('plugin-device', () => {
424
481
 
425
482
  assert.calledOnce(device.processRegistrationSuccess);
426
483
  });
427
-
428
484
  });
429
485
 
430
486
  describe('deleteDevices()', () => {
431
487
  const setup = (deviceType) => {
432
488
  device.config.defaults = {body: {deviceType}};
433
489
  };
434
- ['WEB', 'WEBCLIENT'].forEach(deviceType => {
435
- it(`should delete correct number of devices for ${deviceType}`, async () => {
436
- setup(deviceType);
437
- const response = {
438
- body: {
490
+ ['WEB', 'WEBCLIENT'].forEach((deviceType) => {
491
+ it(`should delete correct number of devices for ${deviceType}`, async () => {
492
+ setup(deviceType);
493
+ const response = {
494
+ body: {
439
495
  devices: [
440
496
  {url: 'url3', modificationTime: '2023-10-03T10:00:00Z', deviceType},
441
497
  {url: 'url4', modificationTime: '2023-10-04T10:00:00Z', deviceType: 'notweb'},
@@ -445,49 +501,50 @@ describe('plugin-device', () => {
445
501
  {url: 'url6', modificationTime: '2023-09-50T10:00:00Z', deviceType},
446
502
  {url: 'url7', modificationTime: '2023-09-30T10:00:00Z', deviceType},
447
503
  {url: 'url8', modificationTime: '2023-08-30T10:00:00Z', deviceType},
448
- ]
449
- }
450
- };
451
- const requestStub = sinon.stub(device, 'request');
452
- requestStub.withArgs(sinon.match({method: 'GET'})).resolves(response);
453
- requestStub.withArgs(sinon.match({method: 'DELETE'})).resolves();
504
+ ],
505
+ },
506
+ };
507
+ const requestStub = sinon.stub(device, 'request');
508
+ requestStub.withArgs(sinon.match({method: 'GET'})).resolves(response);
509
+ requestStub.withArgs(sinon.match({method: 'DELETE'})).resolves();
454
510
 
455
- await device.deleteDevices();
511
+ await device.deleteDevices();
456
512
 
457
- const expectedDeletions = ['url8', 'url7', 'url1'];
513
+ const expectedDeletions = ['url8', 'url7', 'url1'];
458
514
 
459
- expectedDeletions.forEach(url => {
460
- assert(requestStub.calledWith(sinon.match({uri: url, method: 'DELETE'})));
461
- });
515
+ expectedDeletions.forEach((url) => {
516
+ assert(requestStub.calledWith(sinon.match({uri: url, method: 'DELETE'})));
517
+ });
462
518
 
463
- const notDeletedUrls = ['url2', 'url3', 'url5', 'url6', 'url4'];
464
- notDeletedUrls.forEach(url => {
465
- assert(requestStub.neverCalledWith(sinon.match({uri: url, method: 'DELETE'})));
519
+ const notDeletedUrls = ['url2', 'url3', 'url5', 'url6', 'url4'];
520
+ notDeletedUrls.forEach((url) => {
521
+ assert(requestStub.neverCalledWith(sinon.match({uri: url, method: 'DELETE'})));
522
+ });
523
+ });
466
524
  });
467
- });});
468
-
469
- it('does not delete when there are just 2 devices', async () => {
470
- setup('WEB');
471
- const response = {
472
- body: {
473
- devices: [
474
- {url: 'url1', modificationTime: '2023-10-01T10:00:00Z', deviceType: 'WEB'},
475
- {url: 'url2', modificationTime: '2023-10-02T10:00:00Z', deviceType: 'WEB'},
476
- ]
477
- }
478
- };
479
525
 
480
- const requestStub = sinon.stub(device, 'request');
481
- requestStub.withArgs(sinon.match({method: 'GET'})).resolves(response);
482
- requestStub.withArgs(sinon.match({method: 'DELETE'})).resolves();
526
+ it('does not delete when there are just 2 devices', async () => {
527
+ setup('WEB');
528
+ const response = {
529
+ body: {
530
+ devices: [
531
+ {url: 'url1', modificationTime: '2023-10-01T10:00:00Z', deviceType: 'WEB'},
532
+ {url: 'url2', modificationTime: '2023-10-02T10:00:00Z', deviceType: 'WEB'},
533
+ ],
534
+ },
535
+ };
536
+
537
+ const requestStub = sinon.stub(device, 'request');
538
+ requestStub.withArgs(sinon.match({method: 'GET'})).resolves(response);
539
+ requestStub.withArgs(sinon.match({method: 'DELETE'})).resolves();
483
540
 
484
- await device.deleteDevices();
485
- const notDeletedUrls = ['url1', 'url2'];
486
- notDeletedUrls.forEach(url => {
541
+ await device.deleteDevices();
542
+ const notDeletedUrls = ['url1', 'url2'];
543
+ notDeletedUrls.forEach((url) => {
487
544
  assert(requestStub.neverCalledWith(sinon.match({uri: url, method: 'DELETE'})));
545
+ });
488
546
  });
489
547
  });
490
- });
491
548
 
492
549
  describe('#unregister()', () => {
493
550
  it('resolves immediately if the device is not registered', async () => {
@@ -563,11 +620,17 @@ describe('plugin-device', () => {
563
620
  it('calls delete devices when errors with User has excessive device registrations', async () => {
564
621
  setup();
565
622
  sinon.stub(device, 'canRegister').callsFake(() => Promise.resolve());
566
- const deleteDeviceSpy = sinon.stub(device, 'deleteDevices').callsFake(() => Promise.resolve());
623
+ const deleteDeviceSpy = sinon
624
+ .stub(device, 'deleteDevices')
625
+ .callsFake(() => Promise.resolve());
567
626
  const registerStub = sinon.stub(device, '_registerInternal');
568
-
569
- registerStub.onFirstCall().rejects({body: {message: 'User has excessive device registrations'}});
570
- registerStub.onSecondCall().callsFake(() => Promise.resolve({exampleKey: 'example response value',}));
627
+
628
+ registerStub
629
+ .onFirstCall()
630
+ .rejects({body: {message: 'User has excessive device registrations'}});
631
+ registerStub
632
+ .onSecondCall()
633
+ .callsFake(() => Promise.resolve({exampleKey: 'example response value'}));
571
634
 
572
635
  const result = await device.register();
573
636
 
@@ -582,8 +645,12 @@ describe('plugin-device', () => {
582
645
  setup();
583
646
 
584
647
  sinon.stub(device, 'canRegister').callsFake(() => Promise.resolve());
585
- const deleteDeviceSpy = sinon.stub(device, 'deleteDevices').callsFake(() => Promise.resolve());
586
- const registerStub = sinon.stub(device, '_registerInternal').rejects(new Error('some error'));
648
+ const deleteDeviceSpy = sinon
649
+ .stub(device, 'deleteDevices')
650
+ .callsFake(() => Promise.resolve());
651
+ const registerStub = sinon
652
+ .stub(device, '_registerInternal')
653
+ .rejects(new Error('some error'));
587
654
 
588
655
  try {
589
656
  await device.register({deleteFlag: true});
@@ -633,7 +700,7 @@ describe('plugin-device', () => {
633
700
  resolve({
634
701
  body: {
635
702
  exampleKey: 'example response value',
636
- }
703
+ },
637
704
  });
638
705
 
639
706
  await resultPromise;
@@ -670,7 +737,6 @@ describe('plugin-device', () => {
670
737
  assert.calledOnce(device.processRegistrationSuccess);
671
738
  });
672
739
 
673
-
674
740
  it('checks that submitInternalEvent gets called with internal.register.device.response on success', async () => {
675
741
  setup();
676
742
  sinon.stub(device, 'canRegister').callsFake(() => Promise.resolve());
@@ -822,7 +888,7 @@ describe('plugin-device', () => {
822
888
 
823
889
  it('works when request returns 404 when already registered', async () => {
824
890
  setup();
825
-
891
+
826
892
  sinon.stub(device, 'canRegister').callsFake(() => Promise.resolve());
827
893
 
828
894
  const requestStub = sinon.stub(device, 'request');
@@ -838,7 +904,52 @@ describe('plugin-device', () => {
838
904
  });
839
905
  });
840
906
 
907
+ describe('getDebugFeatures()', () => {
908
+ it('returns empty list if debugFeatureTogglesKey is not set', () => {
909
+ assert.isUndefined(device.config.debugFeatureTogglesKey);
910
+ const debugFeatures = device.getDebugFeatures();
911
+
912
+ assert.deepEqual(debugFeatures, []);
913
+ });
914
+
915
+ it('returns empty list if no debug features in session storage', () => {
916
+ device.config.debugFeatureTogglesKey = 'debug-feature-toggles';
917
+ assert.isUndefined(webex.getWindow().sessionStorage.getItem('debug-feature-toggles'));
918
+ const debugFeatures = device.getDebugFeatures();
919
+
920
+ assert.deepEqual(debugFeatures, []);
921
+ });
922
+
923
+ it('returns debug features from session storage', () => {
924
+ device.config.debugFeatureTogglesKey = 'debug-feature-toggles';
925
+ webex.getWindow().sessionStorage.setItem(
926
+ 'debug-feature-toggles',
927
+ JSON.stringify({
928
+ feature_to_debug_enable: true,
929
+ feature_to_debug_disable: false,
930
+ })
931
+ );
932
+ const debugFeatures = device.getDebugFeatures();
933
+
934
+ assert.equal(debugFeatures.length, 2);
935
+
936
+ assert.properties(debugFeatures[0], ['key', 'val', 'mutable', 'lastModified']);
937
+ assert.equal(debugFeatures[0].key, 'feature_to_debug_enable');
938
+ assert.equal(debugFeatures[0].val, 'true');
939
+ assert.isTrue(debugFeatures[0].mutable);
940
+ assert.isISODate(debugFeatures[0].lastModified);
941
+
942
+ assert.properties(debugFeatures[1], ['key', 'val', 'mutable', 'lastModified']);
943
+ assert.equal(debugFeatures[1].key, 'feature_to_debug_disable');
944
+ assert.equal(debugFeatures[1].val, 'false');
945
+ assert.isTrue(debugFeatures[1].mutable);
946
+ assert.isISODate(debugFeatures[1].lastModified);
947
+ });
948
+ });
949
+
841
950
  describe('#processRegistrationSuccess()', () => {
951
+ const initialDTOFeatureCounts = {developer: 2, entitlement: 1, user: 1};
952
+
842
953
  const getClonedDTO = (overrides) => {
843
954
  const clonedDTO = cloneDeep(dto);
844
955
 
@@ -852,6 +963,22 @@ describe('plugin-device', () => {
852
963
  mutable: true,
853
964
  lastModified: '2015-06-29T20:02:48.033Z',
854
965
  },
966
+ {
967
+ key: 'feature_to_debug_enable',
968
+ type: 'boolean',
969
+ val: 'false',
970
+ value: false,
971
+ mutable: true,
972
+ lastModified: '2015-06-29T20:02:48.033Z',
973
+ },
974
+ {
975
+ key: 'feature_to_debug_disable',
976
+ type: 'boolean',
977
+ val: 'true',
978
+ value: true,
979
+ mutable: true,
980
+ lastModified: '2015-06-29T20:02:48.033Z',
981
+ },
855
982
  ],
856
983
  entitlement: [
857
984
  {
@@ -875,16 +1002,21 @@ describe('plugin-device', () => {
875
1002
  return clonedDTO;
876
1003
  };
877
1004
 
1005
+ const checkFeatureTypeCounts = (expectedCounts) => {
1006
+ Object.entries(expectedCounts).forEach(([type, expectedCount]) => {
1007
+ assert.equal(device.features[type].length, expectedCount);
1008
+ });
1009
+ };
1010
+
878
1011
  const checkFeatureNotPresent = (type, key) => {
879
1012
  assert.isUndefined(device.features[type].get(key));
880
1013
  };
881
1014
 
882
1015
  const checkFeature = (type, key, expectedValue) => {
883
- assert.equal(device.features[type].length, 1);
884
1016
  assert.deepEqual(device.features[type].get(key).get('value'), expectedValue);
885
1017
  };
886
1018
 
887
- it('features are set correctly if etag not in headers', () => {
1019
+ it('features are set correctly if etag not in headers, no debug features', () => {
888
1020
  const clonedDTO = getClonedDTO();
889
1021
 
890
1022
  const response = {
@@ -894,13 +1026,61 @@ describe('plugin-device', () => {
894
1026
  headers: {},
895
1027
  };
896
1028
 
1029
+ checkFeatureTypeCounts(initialDTOFeatureCounts);
897
1030
  checkFeatureNotPresent('developer', '1');
1031
+ checkFeatureNotPresent('developer', 'feature_to_debug_enable');
1032
+ checkFeatureNotPresent('developer', 'feature_to_debug_disable');
1033
+ checkFeatureNotPresent('developer', 'feature_debug_only');
898
1034
  checkFeatureNotPresent('entitlement', '2');
899
1035
  checkFeatureNotPresent('user', '3');
900
1036
 
901
1037
  device.processRegistrationSuccess(response);
902
1038
 
1039
+ checkFeatureTypeCounts({developer: 3, entitlement: 1, user: 1});
903
1040
  checkFeature('developer', '1', true);
1041
+ checkFeature('developer', 'feature_to_debug_enable', false);
1042
+ checkFeature('developer', 'feature_to_debug_disable', true);
1043
+ checkFeatureNotPresent('developer', 'feature_debug_only');
1044
+ checkFeature('entitlement', '2', true);
1045
+ checkFeature('user', '3', true);
1046
+ });
1047
+
1048
+ it('features are set correctly if etag not in headers, debug features in session storage', () => {
1049
+ const clonedDTO = getClonedDTO();
1050
+
1051
+ const response = {
1052
+ body: {
1053
+ ...clonedDTO,
1054
+ },
1055
+ headers: {},
1056
+ };
1057
+
1058
+ device.config.debugFeatureTogglesKey = 'debug-feature-toggles';
1059
+
1060
+ webex.getWindow().sessionStorage.setItem(
1061
+ 'debug-feature-toggles',
1062
+ JSON.stringify({
1063
+ feature_to_debug_enable: true,
1064
+ feature_to_debug_disable: false,
1065
+ feature_debug_only: true,
1066
+ })
1067
+ );
1068
+
1069
+ checkFeatureTypeCounts(initialDTOFeatureCounts);
1070
+ checkFeatureNotPresent('developer', '1');
1071
+ checkFeatureNotPresent('developer', 'feature_to_debug_enable');
1072
+ checkFeatureNotPresent('developer', 'feature_to_debug_disable');
1073
+ checkFeatureNotPresent('developer', 'feature_debug_only');
1074
+ checkFeatureNotPresent('entitlement', '2');
1075
+ checkFeatureNotPresent('user', '3');
1076
+
1077
+ device.processRegistrationSuccess(response);
1078
+
1079
+ checkFeatureTypeCounts({developer: 4, entitlement: 1, user: 1});
1080
+ checkFeature('developer', '1', true);
1081
+ checkFeature('developer', 'feature_to_debug_enable', true);
1082
+ checkFeature('developer', 'feature_to_debug_disable', false);
1083
+ checkFeature('developer', 'feature_debug_only', true);
904
1084
  checkFeature('entitlement', '2', true);
905
1085
  checkFeature('user', '3', true);
906
1086
  });
@@ -919,12 +1099,17 @@ describe('plugin-device', () => {
919
1099
  },
920
1100
  };
921
1101
 
1102
+ checkFeatureTypeCounts(initialDTOFeatureCounts);
922
1103
  checkFeatureNotPresent('developer', '1');
1104
+ checkFeatureNotPresent('developer', 'feature_to_debug_enable');
1105
+ checkFeatureNotPresent('developer', 'feature_to_debug_disable');
1106
+ checkFeatureNotPresent('developer', 'feature_debug_only');
923
1107
  checkFeatureNotPresent('entitlement', '2');
924
1108
  checkFeatureNotPresent('user', '3');
925
1109
 
926
1110
  device.processRegistrationSuccess(response);
927
1111
 
1112
+ checkFeatureTypeCounts(initialDTOFeatureCounts.developer);
928
1113
  checkFeatureNotPresent('developer', '1');
929
1114
  checkFeature('entitlement', '2', true);
930
1115
  checkFeature('user', '3', true);
@@ -947,12 +1132,21 @@ describe('plugin-device', () => {
947
1132
  },
948
1133
  };
949
1134
 
1135
+ checkFeatureTypeCounts(initialDTOFeatureCounts);
950
1136
  checkFeatureNotPresent('developer', '1');
1137
+ checkFeatureNotPresent('developer', 'feature_to_debug_enable');
1138
+ checkFeatureNotPresent('developer', 'feature_to_debug_disable');
1139
+ checkFeatureNotPresent('developer', 'feature_debug_only');
951
1140
  checkFeatureNotPresent('entitlement', '2');
952
1141
  checkFeatureNotPresent('user', '3');
953
1142
 
954
1143
  device.processRegistrationSuccess(response);
955
1144
 
1145
+ checkFeatureTypeCounts({
1146
+ developer: initialDTOFeatureCounts.developer,
1147
+ entitlement: 1,
1148
+ user: 1,
1149
+ });
956
1150
  checkFeatureNotPresent('developer', '1');
957
1151
  checkFeature('entitlement', '2', true);
958
1152
  checkFeature('user', '3', true);
@@ -975,12 +1169,17 @@ describe('plugin-device', () => {
975
1169
  },
976
1170
  };
977
1171
 
1172
+ checkFeatureTypeCounts(initialDTOFeatureCounts);
978
1173
  checkFeatureNotPresent('developer', '1');
1174
+ checkFeatureNotPresent('developer', 'feature_to_debug_enable');
1175
+ checkFeatureNotPresent('developer', 'feature_to_debug_disable');
1176
+ checkFeatureNotPresent('developer', 'feature_debug_only');
979
1177
  checkFeatureNotPresent('entitlement', '2');
980
1178
  checkFeatureNotPresent('user', '3');
981
1179
 
982
1180
  device.processRegistrationSuccess(response);
983
1181
 
1182
+ checkFeatureTypeCounts({developer: 3, entitlement: 1, user: 1});
984
1183
  checkFeature('developer', '1', true);
985
1184
  checkFeature('entitlement', '2', true);
986
1185
  checkFeature('user', '3', true);
@@ -1029,6 +1228,7 @@ describe('plugin-device', () => {
1029
1228
  device.processRegistrationSuccess(newResponse);
1030
1229
 
1031
1230
  // only the entitlement and user features should have been changed to false
1231
+ checkFeatureTypeCounts({developer: 3, entitlement: 1, user: 1});
1032
1232
  checkFeature('developer', '1', true);
1033
1233
  checkFeature('entitlement', '2', false);
1034
1234
  checkFeature('user', '3', false);